diff options
author | lresende <lresende@13f79535-47bb-0310-9956-ffa450edef68> | 2009-11-11 23:26:33 +0000 |
---|---|---|
committer | lresende <lresende@13f79535-47bb-0310-9956-ffa450edef68> | 2009-11-11 23:26:33 +0000 |
commit | a40e527938d76ba71f211da7e327adb50384ba69 (patch) | |
tree | cb8f99f1727122b040a3f0fbb6649292b6a74302 /sca-java-1.x/tags/kernel | |
parent | 968721109881107520d7aefa91d7fcc0519d7739 (diff) |
Moving 1.x tags
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@835157 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-1.x/tags/kernel')
958 files changed, 86299 insertions, 0 deletions
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/LICENSE.txt b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/LICENSE.txt new file mode 100644 index 0000000000..0084319535 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/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/sca-java-1.x/tags/kernel/2.0-alpha-incubating/NOTICE.txt b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/NOTICE.txt new file mode 100644 index 0000000000..e78268b863 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/NOTICE.txt @@ -0,0 +1,14 @@ +Apache Tuscany SCA Kernel Sub-Project +Copyright (c) 2005 - 2007 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/sca-java-1.x/tags/kernel/2.0-alpha-incubating/README.txt b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/README.txt new file mode 100644 index 0000000000..ca024316d5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/README.txt @@ -0,0 +1,44 @@ +This Release of the Apache Tuscany SCA Kernel is designed as a baseline for extension development +and early access to the Java programming model based on the SCA 1.0 Java Common Annotations +and API Specification and the Java Component Implementation Specification. Copies of the +specifications may be obtained from http://www.osoa.org. + +*** Please Note that extension SPIs are subject to change in future alpha and beta releases *** + +Release Features +---------------- +A goal of the release has been closer alignment with the SCA specifications, and in particular, +the implementation of new Java annotations and APIs introduced in the 1.0 version. +New features include: + +- Support for full composite recursion (N-levels) +- Improved and simplified non-blocking operations +- Support for SCA 1.0 conversational callbacks, including synchronous operations +- Support for many of the SCA 1.0 Annotations and APIs, including: scopes, + conversational annotations, ComponentContext, callback annotations, +- Support for SCA 1.0 autowire +- Support for service target syntax +- Support for reference promotion syntax (multiple level promotion is not yet implemented + but planned for the next release) +- Support for exception formatting +- Improved exception handling +- Reduced disk and memory footprint + + +This release also includes significant architectural enhancements and refactors. +Much of this work has been focused on simplification of the core architecture. +In addition, changes have been introduced to support federated service networks +and multi-VM wiring. It is expected that those features will be added in the next alpha release. + +- Greatly simplified wiring architecture, including elimination of inbound and outbound wiring +- Support for sparse component trees distributed across multiple-VMs +- Improved autowire support including changes to enable federated autowire in the next release +- Introduction of a ComponentManager +- Refactored Connector +- Refactored Component interface and hierarchy +- Increased test coverage (~70%) +- An early implementation of federated assembly changeset marshalling + + +In bocca al lupo! +The Tuscany Team diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/.checkstyle b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/.checkstyle new file mode 100644 index 0000000000..3e57539570 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/.checkstyle @@ -0,0 +1,24 @@ +<?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. +--> +<fileset-config file-format-version="1.2.0" simple-config="true"> + <fileset name="all" enabled="true" check-config-name="Tuscany Checks" local="false"> + <file-match-pattern match-pattern="." include-pattern="true"/> + </fileset> +</fileset-config> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/.pmd b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/.pmd new file mode 100644 index 0000000000..ffc4fe2bbb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/.pmd @@ -0,0 +1,20 @@ +<?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. +--> +<pmd><useProjectRuleSet>true</useProjectRuleSet><rules/></pmd> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/.ruleset b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/.ruleset new file mode 100644 index 0000000000..3886f07f2d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/.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/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/LICENSE.txt b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/LICENSE.txt new file mode 100644 index 0000000000..0084319535 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/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/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/NOTICE.txt b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/NOTICE.txt new file mode 100644 index 0000000000..d83ebbe236 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/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/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/pom.xml b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/pom.xml new file mode 100644 index 0000000000..3bd0d719bc --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/pom.xml @@ -0,0 +1,42 @@ +<?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</groupId> + <artifactId>kernel</artifactId> + <version>2.0-alpha-incubating</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <groupId>org.apache.tuscany.sca.kernel</groupId> + <artifactId>tuscany-api</artifactId> + <name>Apache Tuscany SCA API</name> + <description>Tuscany Application Programming Interfaces.</description> + + <dependencies> + <dependency> + <groupId>org.osoa</groupId> + <artifactId>sca-api-r${scaSpecVersion}</artifactId> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + </dependencies> +</project> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/TuscanyException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/TuscanyException.java new file mode 100644 index 0000000000..346972bbee --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/TuscanyException.java @@ -0,0 +1,124 @@ +/* + * 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.api; + +import java.io.PrintWriter; + +/** + * The root checked exception for the Tuscany runtime. + * + * @version $Rev$ $Date$ + */ +public abstract class TuscanyException extends Exception { + private static final long serialVersionUID = -7847121698339635268L; + private final String identifier; + + /** + * Override constructor from Exception. + * + * @see Exception + */ + public TuscanyException() { + super(); + this.identifier = null; + } + + /** + * Override constructor from Exception. + * + * @param message passed to Exception + * @see Exception + */ + public TuscanyException(String message) { + super(message); + this.identifier = null; + } + + /** + * Override constructor from Exception. + * + * @param message passed to Exception + * @param identifier additional error information referred to in the error message + * @see Exception + */ + public TuscanyException(String message, String identifier) { + super(message); + this.identifier = identifier; + } + + /** + * Override constructor from Exception. + * + * @param message passed to Exception + * @param cause passed to Exception + * @see Exception + */ + public TuscanyException(String message, Throwable cause) { + super(message, cause); + this.identifier = null; + } + + /** + * Override constructor from Exception. + * + * @param message passed to Exception + * @param identifier additional error information referred to in the error message + * @param cause passed to Exception + * @see Exception + */ + public TuscanyException(String message, String identifier, Throwable cause) { + super(message, cause); + this.identifier = identifier; + } + + /** + * Override constructor from Exception. + * + * @param cause passed to Exception + * @see Exception + */ + public TuscanyException(Throwable cause) { + super(cause); + this.identifier = null; + } + + /** + * Returns a string representing additional error information referred to in the error message. + * + * @return additional error information + */ + public String getIdentifier() { + return identifier; + } + + public PrintWriter appendBaseMessage(PrintWriter writer) { + if (identifier == null) { + if (super.getMessage() == null) { + return writer; + } + return writer.append(super.getMessage()); + } + if (super.getMessage() != null) { + writer.append(super.getMessage()); + } + writer.append(" [").append(identifier).append(']'); + return writer; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/TuscanyRuntimeException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/TuscanyRuntimeException.java new file mode 100644 index 0000000000..aec4b774e4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/TuscanyRuntimeException.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.api; + +import java.io.PrintWriter; + +/** + * The root unchecked exception for the Tuscany runtime. + * + * @version $Rev$ $Date$ + */ + +public abstract class TuscanyRuntimeException extends RuntimeException { + private static final long serialVersionUID = -759677431966121786L; + private final String identifier; + + /** + * Override constructor from RuntimeException. + * + * @see RuntimeException + */ + public TuscanyRuntimeException() { + super(); + this.identifier = null; + } + + /** + * Override constructor from RuntimeException. + * + * @param message passed to RuntimeException + * @see RuntimeException + */ + public TuscanyRuntimeException(String message) { + super(message); + this.identifier = null; + } + + + /** + * Override constructor from Exception. + * + * @param message passed to Exception + * @param identifier additional error information referred to in the error message + * @see Exception + */ + protected TuscanyRuntimeException(String message, String identifier) { + super(message); + this.identifier = identifier; + } + + /** + * Override constructor from RuntimeException. + * + * @param message passed to RuntimeException + * @param cause passed to RuntimeException + * @see RuntimeException + */ + public TuscanyRuntimeException(String message, Throwable cause) { + super(message, cause); + this.identifier = null; + } + + + /** + * Override constructor from Exception. + * + * @param message passed to Exception + * @param identifier additional error information referred to in the error message + * @param cause passed to RuntimeException + * @see Exception + */ + protected TuscanyRuntimeException(String message, String identifier, Throwable cause) { + super(message, cause); + this.identifier = identifier; + } + + /** + * Override constructor from RuntimeException. + * + * @param cause passed to RuntimeException + * @see RuntimeException + */ + public TuscanyRuntimeException(Throwable cause) { + super(cause); + this.identifier = null; + } + + /** + * Returns a string representing additional error information referred to in the error message. + * + * @return additional error information + */ + public String getIdentifier() { + return identifier; + } + + public PrintWriter appendBaseMessage(PrintWriter writer) { + if (identifier == null) { + if (super.getMessage() == null) { + return writer; + } + return writer.append(super.getMessage()); + } + if (super.getMessage() != null) { + writer.append(super.getMessage()); + } + writer.append(" [").append(identifier).append(']'); + return writer; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/DataContext.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/DataContext.java new file mode 100644 index 0000000000..ab74ba9e5c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/DataContext.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.api.annotation; + +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Target; + +/** + * A key/value pair to represent information pertaining to a {@link DataType} + */ +@Target(ANNOTATION_TYPE) +@Retention(RUNTIME) +public @interface DataContext { + /** + * @return key for the context entry + */ + String key(); + + /** + * @return key for the context value + */ + String value(); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/DataType.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/DataType.java new file mode 100644 index 0000000000..439aa837d2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/DataType.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.api.annotation; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Target; + +/** + * Used to demarcate expected data types for an operation + * + * @version $Rev$ $Date$ + */ +@Target({TYPE, METHOD}) +@Retention(RUNTIME) +public @interface DataType { + + /** + * Returns the unique name of the data binding + * @return the unique name of the data binding + */ + String name(); + + /** + * Returns the logical data type + * @return the logical data type + */ + Class logicalType() default Object.class; + + /** + * Returns the physical data type + * @return the physical data type + */ + Class physicalType() default Object.class; + + /** + * Returns an array of extensibility elements + * @return an array of extensibility elements + */ + DataContext[] context() default {}; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/LogLevel.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/LogLevel.java new file mode 100644 index 0000000000..83c5df26d9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/LogLevel.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.api.annotation; + +import static java.lang.annotation.ElementType.METHOD; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Target; + +/** + * Annotation that can be applied to methods in a monitoring interface to indicate to logging frameworks the severity of + * the event. + * + * @version $Rev$ $Date$ + */ +@Target({METHOD}) +@Retention(RUNTIME) +public @interface LogLevel { + + /** + * The log level as specified by {@link java.util.logging.Level}. + */ + @SuppressWarnings({"JavaDoc"}) String value(); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/Monitor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/Monitor.java new file mode 100644 index 0000000000..dea9489e5b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/Monitor.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.api.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * A system annotation to inject a monitor + * + * @version $Rev$ $Date$ + */ +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Monitor { +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/Resource.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/Resource.java new file mode 100644 index 0000000000..a7158ab6b8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/Resource.java @@ -0,0 +1,49 @@ +/* + * 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.api.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation used to indicate a resource should be provided to an implementation by the runtime. + * + * @version $Rev$ $Date$ + */ +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Resource { + + /** + * Denotes the name of the resource declared by the implementation. + */ + String name() default ""; + + /** + * Denotes if the resource is optional + */ + boolean optional() default false; + + /** + * Denotes the default name of the resource provided by the runtime environment. + */ + String mappedName() default ""; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/package-info.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/package-info.java new file mode 100644 index 0000000000..3968efe1da --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/annotation/package-info.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. + */ + +/** + * Annotations that enable Apache Tuscany programming model extensions + * in application components. + */ +package org.apache.tuscany.api.annotation;
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/package-info.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/package-info.java new file mode 100644 index 0000000000..19f187edbf --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/main/java/org/apache/tuscany/api/package-info.java @@ -0,0 +1,80 @@ +/* + * 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. + */ + +/** + * Overview of Apache Tuscany Application Programming Interface. + * + * This package contains classes and annotations intended for use by application code. + * In general, the programming models supported by Apache Tuscany are designed to be + * non-intrusive. The goal is for application code to be portable to any framework + * supporting an Inversion of Control style programming model and as such does + * not require application code to inherit from framework classes or to implement + * framework specific interfaces. Where additional information is required by the + * framework, Java annotations are used. + * + * <h1>Monitoring Framework</h1> + * + * Apache Tuscany provides a monitoring framework that application code can use to + * send management events to the host's logging framework in a manner that is + * independent of the actual framework used by the runtime environment. This is + * the same infrastructure as used by Tuscany itself, allowing events from + * applications, the Apache Tuscany runtime and the host itself to all be handled + * by the host's logging infrastructure. These events can be combined in one stream + * or seperated as supported by the host infrastructure. + * + * To use this framework, application code should define a component-specific interface + * defining the monitoring events that it wishes to send and mark a field, setter or + * constructor with the {@link org.apache.tuscany.api.annotation.Monitor @Monitor} annotation. + * The framework will inject a implementation of the monitoring interface that dispatches + * events to the underlying infrastructure. + * + * <pre> + * public class MyComponent { + * private final MyComponentMonitor monitor; + * + * public MyComponent(@Monitor MyComponentMonitor monitor) { + * this.monitor = monitor; + * } + * + * public void start() { + * monitor.started(); + * } + * + * public void stop() { + * monitor.stopped(); + * } + * + * public interface MyComponentMonitor { + * void started(); + * void stopped(); + * } + * } + * </pre> + * + * The {@link org.apache.tuscany.api.annotation.LogLevel @LogLevel} annotation + * can be used to provide a hint for the logging level to associate with the event. + * The actual level used is determined by the configuration of the monitoring framework. + * + * For performance reasons, the objects passed as parameters should typically be instances + * that are already in use by the application code; operations that allocate new objects + * (such as string concatenation) should be avoided. + * + * <h1></h1> + */ +package org.apache.tuscany.api;
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/test/java/org/apache/tuscany/api/TuscanyExceptionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/test/java/org/apache/tuscany/api/TuscanyExceptionTestCase.java new file mode 100644 index 0000000000..ace75e6b10 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/test/java/org/apache/tuscany/api/TuscanyExceptionTestCase.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.api; + +import java.io.PrintWriter; +import java.io.StringWriter; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class TuscanyExceptionTestCase extends TestCase { + private static final Throwable CAUSE = new Throwable("Cause"); + private static final String IDENTIFIER = "IDENTIFIER"; + private static final String MESSAGE = "Message"; + + public void testNoArgConstructor() { + TuscanyException ex = new DummyException(); + assertNull(ex.getMessage()); + assertNull(ex.getCause()); + assertNull(ex.getIdentifier()); + } + + public void testMessageConstructor() { + TuscanyException ex = new DummyException(MESSAGE); + assertEquals(MESSAGE, ex.getMessage()); + assertNull(ex.getCause()); + assertNull(ex.getIdentifier()); + } + + public void testAppendBaseMessage() { + TuscanyException ex = new DummyException(MESSAGE, IDENTIFIER); + StringWriter writer = new StringWriter(); + PrintWriter pw = new PrintWriter(writer); + ex.appendBaseMessage(pw); + assertEquals("Message [IDENTIFIER]", writer.toString()); + } + + public void testAppendBaseMessageNoIdentifier() { + TuscanyException ex = new DummyException(MESSAGE); + StringWriter writer = new StringWriter(); + PrintWriter pw = new PrintWriter(writer); + ex.appendBaseMessage(pw); + assertEquals("Message", writer.toString()); + } + + public void testThrowableConstructor() { + TuscanyException ex = new DummyException(CAUSE); + assertEquals(CAUSE.getClass().getName() + ": " + CAUSE.getMessage(), ex.getMessage()); + assertEquals(CAUSE, ex.getCause()); + assertNull(ex.getIdentifier()); + } + + public void testMessageThrowableConstructor() { + TuscanyException ex = new DummyException(MESSAGE, CAUSE); + assertEquals(MESSAGE, ex.getMessage()); + assertEquals(CAUSE, ex.getCause()); + assertNull(ex.getIdentifier()); + } + + public void testGetMessage() throws Exception { + TuscanyException e = new DummyException(); + e.getMessage(); + } + + public void testFullMessage() throws Exception { + TuscanyException e = new DummyException("message", "foo"); + e.getMessage(); + } + + public static class DummyException extends TuscanyException { + + public DummyException() { + } + + public DummyException(String message) { + super(message); + } + + + public DummyException(String message, String identifier) { + super(message, identifier); + } + + public DummyException(String message, Throwable cause) { + super(message, cause); + } + + public DummyException(Throwable cause) { + super(cause); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/test/java/org/apache/tuscany/api/TuscanyRuntimeExceptionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/test/java/org/apache/tuscany/api/TuscanyRuntimeExceptionTestCase.java new file mode 100644 index 0000000000..a32bdbb1a6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/api/src/test/java/org/apache/tuscany/api/TuscanyRuntimeExceptionTestCase.java @@ -0,0 +1,105 @@ +/* + * 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.api; + +import java.io.PrintWriter; +import java.io.StringWriter; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class TuscanyRuntimeExceptionTestCase extends TestCase { + private static final Throwable CAUSE = new Throwable("Cause"); + private static final String MESSAGE = "Message"; + private static final String IDENTIFIER = "IDENTIFIER"; + private static final String CONTEXT1 = "CONTEXT1"; + private static final String CONTEXT2 = "CONTEXT2"; + + public void testNoArgConstructor() { + TuscanyRuntimeException ex = new DummyException(); + assertNull(ex.getMessage()); + assertNull(ex.getCause()); + assertNull(ex.getIdentifier()); + } + + public void testMessageConstructor() { + TuscanyRuntimeException ex = new DummyException(MESSAGE); + assertSame(MESSAGE, ex.getMessage()); + assertNull(ex.getCause()); + assertNull(ex.getIdentifier()); + } + + public void testThrowableConstructor() { + TuscanyRuntimeException ex = new DummyException(CAUSE); + assertEquals(CAUSE.getClass().getName() + ": " + CAUSE.getMessage(), ex.getMessage()); + assertSame(CAUSE, ex.getCause()); + assertNull(ex.getIdentifier()); + } + + public void testMessageThrowableConstructor() { + TuscanyRuntimeException ex = new DummyException(MESSAGE, CAUSE); + assertSame(MESSAGE, ex.getMessage()); + assertSame(CAUSE, ex.getCause()); + assertNull(ex.getIdentifier()); + } + + public void testIdentifier() { + TuscanyRuntimeException ex = new DummyException(MESSAGE, IDENTIFIER); + assertEquals(IDENTIFIER, ex.getIdentifier()); + } + + public void testAppendBaseMessage() { + TuscanyRuntimeException ex = new DummyException(MESSAGE, IDENTIFIER); + StringWriter writer = new StringWriter(); + PrintWriter pw = new PrintWriter(writer); + ex.appendBaseMessage(pw); + assertEquals("Message [IDENTIFIER]", writer.toString()); + } + + public void testAppendBaseMessageNoIdentifier() { + TuscanyRuntimeException ex = new DummyException(MESSAGE); + StringWriter writer = new StringWriter(); + PrintWriter pw = new PrintWriter(writer); + ex.appendBaseMessage(pw); + assertEquals("Message", writer.toString()); + } + + public static class DummyException extends TuscanyRuntimeException { + public DummyException() { + } + + public DummyException(String message) { + super(message); + } + + public DummyException(String message, String identifier) { + super(message, identifier); + } + + public DummyException(String message, Throwable cause) { + super(message, cause); + } + + public DummyException(Throwable cause) { + super(cause); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/.pmd b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/.pmd new file mode 100644 index 0000000000..ffc4fe2bbb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/.pmd @@ -0,0 +1,20 @@ +<?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. +--> +<pmd><useProjectRuleSet>true</useProjectRuleSet><rules/></pmd> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/.ruleset b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/.ruleset new file mode 100644 index 0000000000..ba9b5ce886 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/.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/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/LICENSE.txt b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/LICENSE.txt new file mode 100644 index 0000000000..0084319535 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/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/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/NOTICE.txt b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/NOTICE.txt new file mode 100644 index 0000000000..d83ebbe236 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/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/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/pom.xml b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/pom.xml new file mode 100644 index 0000000000..171f6bc3c6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/pom.xml @@ -0,0 +1,98 @@ +<?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</groupId> + <artifactId>kernel</artifactId> + <version>2.0-alpha-incubating</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <groupId>org.apache.tuscany.sca.kernel</groupId> + <artifactId>tuscany-core</artifactId> + <packaging>jar</packaging> + <name>Apache Tuscany SCA Core</name> + <description>Core Tuscany runtime.</description> + + <dependencies> + <dependency> + <groupId>org.apache.tuscany.sca.kernel</groupId> + <artifactId>tuscany-spi</artifactId> + <version>${project.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.apache.tuscany</groupId> + <artifactId>commonj-api_r1.1</artifactId> + <version>1.0-incubator-M2</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.codehaus.woodstox</groupId> + <artifactId>wstx-asl</artifactId> + </dependency> + + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-j2ee-connector_1.5_spec</artifactId> + <version>1.0.1</version> + </dependency> + + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymockclassextension</artifactId> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + </resource> + <resource> + <directory>${notice.dir}</directory> + <targetPath>META-INF</targetPath> + <filtering>true</filtering> + <includes> + <include>LICENSE.txt</include> + <include>NOTICE.txt</include> + </includes> + </resource> + </resources> + </build> +</project> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/AbstractLocalTargetInvoker.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/AbstractLocalTargetInvoker.java new file mode 100644 index 0000000000..34c8eced5a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/AbstractLocalTargetInvoker.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.core.binding.local; + +import java.lang.reflect.InvocationTargetException; + +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.TargetInvoker; + +/** + * Base class for dispatching to a composite reference using the local binding + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractLocalTargetInvoker implements TargetInvoker { + protected boolean cacheable; + + public boolean isCacheable() { + return cacheable; + } + + public void setCacheable(boolean cacheable) { + this.cacheable = cacheable; + } + + public boolean isOptimizable() { + return isCacheable(); // we only need to check if the scopes are correct + } + + public Object invokeTarget(final Object payload, short sequence) throws InvocationTargetException { + throw new InvocationTargetException(new UnsupportedOperationException()); + } + + protected Message invoke(InvocationChain chain, TargetInvoker invoker, Message msg) throws Throwable { + Interceptor headInterceptor = chain.getHeadInterceptor(); + if (headInterceptor == null) { + try { + // short-circuit the dispatch and invoke the target directly + if (invoker == null) { + String name = chain.getOperation().getName(); + throw new AssertionError("No target invoker [" + name + "]"); + } + return invoker.invoke(msg); + } catch (InvocationRuntimeException e) { + // the cause was thrown by the target so throw it + throw e.getCause(); + } + } else { + msg.setTargetInvoker(invoker); + return headInterceptor.invoke(msg); + } + } + + @Override + public AbstractLocalTargetInvoker clone() throws CloneNotSupportedException { + return (AbstractLocalTargetInvoker) super.clone(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingBuilder.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingBuilder.java new file mode 100644 index 0000000000..63a9147b29 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingBuilder.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.core.binding.local; + +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.component.ReferenceBinding; +import org.apache.tuscany.spi.component.ServiceBinding; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.BindingBuilderExtension; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceDefinition; + +/** + * Creates runtime artifacts for the local binding + * + * @version $Rev$ $Date$ + */ +public class LocalBindingBuilder extends BindingBuilderExtension<LocalBindingDefinition> { + + protected Class<LocalBindingDefinition> getBindingType() { + return LocalBindingDefinition.class; + } + + public ServiceBinding build(ServiceDefinition serviceDefinition, + LocalBindingDefinition bindingDefinition, + DeploymentContext context) throws BuilderException { + return new LocalServiceBinding(serviceDefinition.getUri()); + } + + + public ReferenceBinding build(ReferenceDefinition referenceDefinition, + LocalBindingDefinition bindingDefinition, + DeploymentContext context) throws BuilderException { + return new LocalReferenceBinding(referenceDefinition.getUri(), bindingDefinition.getTargetUri()); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingDefinition.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingDefinition.java new file mode 100644 index 0000000000..9317a47457 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingDefinition.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.binding.local; + +import java.net.URI; + +import org.apache.tuscany.spi.model.BindingDefinition; + + +/** + * Represents the local by-reference binding + * + * @version $Rev$ $Date$ + */ +public class LocalBindingDefinition extends BindingDefinition { + + public LocalBindingDefinition() { + } + + public LocalBindingDefinition(URI targetUri) { + super(targetUri); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingLoader.java new file mode 100644 index 0000000000..3442f1ca4c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingLoader.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.core.binding.local; + +import java.net.URI; +import java.net.URISyntaxException; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.osoa.sca.annotations.Reference; + +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.model.ModelObject; +import org.apache.tuscany.spi.wire.Wire; + +/** + * Loader responsible for handling the local binding + * + * @version $Rev$ $Date$ + */ +public class LocalBindingLoader extends LoaderExtension<LocalBindingDefinition> { + + /** + * Constructor specifies the registry to register with. + * + * @param registry the LoaderRegistry this loader should register with + */ + public LocalBindingLoader(@Reference LoaderRegistry registry) { + super(registry); + } + + public QName getXMLType() { + return Wire.LOCAL_BINDING; + } + + public LocalBindingDefinition load( + ModelObject object, + XMLStreamReader reader, + DeploymentContext deploymentContext) throws XMLStreamException, LoaderException { + String uri = reader.getAttributeValue(null, "uri"); + if (uri != null) { + try { + return new LocalBindingDefinition(new URI(uri)); + } catch (URISyntaxException e) { + throw new LoaderException(e); + } + } + return new LocalBindingDefinition(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvoker.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvoker.java new file mode 100644 index 0000000000..c505ee99ab --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvoker.java @@ -0,0 +1,69 @@ +/* + * 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.core.binding.local; + +import java.util.Map; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; + +/** + * Dispatches a callback invocation to the callback instance + * + * @version $Rev$ $Date$ + */ +public class LocalCallbackTargetInvoker extends AbstractLocalTargetInvoker { + private Operation operation; + private Wire wire; + + public LocalCallbackTargetInvoker(Operation operation, Wire wire) { + assert operation != null : "Operation method cannot be null"; + this.operation = operation; + this.wire = wire; + } + + public Message invoke(Message msg) throws InvocationRuntimeException { + try { + return invoke(operation, msg); + } catch (Throwable e) { + Message faultMsg = new MessageImpl(); + faultMsg.setBodyWithFault(e); + return faultMsg; + } + } + + private Message invoke(Operation operation, Message msg) throws Throwable { + //TODO optimize as this is slow in local invocations + Map<Operation<?>, InvocationChain> chains = wire.getCallbackInvocationChains(); + InvocationChain chain = chains.get(operation); + TargetInvoker invoker = chain.getTargetInvoker(); + return invoke(chain, invoker, msg); + } + + @Override + public LocalCallbackTargetInvoker clone() throws CloneNotSupportedException { + return (LocalCallbackTargetInvoker) super.clone(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalReferenceBinding.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalReferenceBinding.java new file mode 100644 index 0000000000..69c5bcd35d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalReferenceBinding.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.core.binding.local; + +import java.net.URI; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.CoreRuntimeException; +import org.apache.tuscany.spi.component.TargetInvokerCreationException; +import org.apache.tuscany.spi.extension.ReferenceBindingExtension; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; + +/** + * The runtime representaion of the local reference binding + * + * @version $Rev$ $Date$ + */ +public class LocalReferenceBinding extends ReferenceBindingExtension { + + public LocalReferenceBinding(URI name, URI targetUri) throws CoreRuntimeException { + super(name, targetUri); + } + + public QName getBindingType() { + return Wire.LOCAL_BINDING; + } + + public TargetInvoker createTargetInvoker(String name, Operation operation) + throws TargetInvokerCreationException { + if (operation.isCallback()) { + return new LocalCallbackTargetInvoker(operation, wire); + } else { + return new LocalTargetInvoker(operation, wire); + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalServiceBinding.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalServiceBinding.java new file mode 100644 index 0000000000..864dfea2f9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalServiceBinding.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.core.binding.local; + +import java.net.URI; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.CoreRuntimeException; +import org.apache.tuscany.spi.component.TargetInvokerCreationException; +import org.apache.tuscany.spi.extension.ServiceBindingExtension; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; + +/** + * The runtime representaion of the local service binding + * + * @version $Rev$ $Date$ + */ +public class LocalServiceBinding extends ServiceBindingExtension { + + public LocalServiceBinding(URI name) throws CoreRuntimeException { + super(name); + } + + public QName getBindingType() { + return Wire.LOCAL_BINDING; + } + + public TargetInvoker createTargetInvoker(String name, Operation operation) + throws TargetInvokerCreationException { + if (operation.isCallback()) { + return new LocalCallbackTargetInvoker(operation, getWire()); + } else { + return new LocalTargetInvoker(operation, getWire()); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalTargetInvoker.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalTargetInvoker.java new file mode 100644 index 0000000000..b89a70a9e0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/binding/local/LocalTargetInvoker.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.core.binding.local; + +import java.net.URI; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.util.UriHelper; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; + +/** + * Dispatches an invocation through a composite service or reference using the local binding + * + * @version $Rev$ $Date$ + */ +public class LocalTargetInvoker extends AbstractLocalTargetInvoker { + private InvocationChain chain; + private URI fromAddress; + private boolean contractHasCallback; + + public LocalTargetInvoker(Operation operation, Wire wire) { + assert operation != null; + chain = wire.getInvocationChains().get(operation); + assert chain != null; + if (wire.getSourceUri() != null) { + fromAddress = URI.create(UriHelper.getBaseName(wire.getSourceUri())); + } + contractHasCallback = !wire.getCallbackInvocationChains().isEmpty(); + } + + @Override + public LocalTargetInvoker clone() throws CloneNotSupportedException { + return (LocalTargetInvoker) super.clone(); + } + + public Message invoke(Message msg) throws InvocationRuntimeException { + try { + TargetInvoker invoker = chain.getTargetInvoker(); + assert invoker != null; + // Pushing the from address only needs to happen in the outbound (forward) direction for callbacks + if (contractHasCallback) { + //JFM do we need this? + msg.pushCallbackUri(fromAddress); + } + + return invoke(chain, invoker, msg); + } catch (Throwable e) { + Message faultMsg = new MessageImpl(); + faultMsg.setBodyWithFault(e); + return faultMsg; + } + } + + + public boolean isOptimizable() { + return true; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/bootstrap/Bootstrapper.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/bootstrap/Bootstrapper.java new file mode 100644 index 0000000000..a5083f77a9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/bootstrap/Bootstrapper.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.core.bootstrap; + +import org.apache.tuscany.spi.builder.Connector; +import org.apache.tuscany.spi.component.ScopeRegistry; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.deployer.Deployer; +import org.apache.tuscany.spi.implementation.java.Introspector; +import org.apache.tuscany.spi.loader.Loader; +import org.apache.tuscany.spi.loader.PropertyObjectFactory; + +import org.apache.tuscany.core.resolver.AutowireResolver; +import org.apache.tuscany.host.MonitorFactory; + +/** + * Interface that abstracts the process used to create a running Tuscany system. Implementation of this may provide + * different mechanisms for creating the primoridal system components used to boot the core to the level where it can + * support end-user applications. + * + * @version $Rev$ $Date$ + */ +public interface Bootstrapper { + /** + * Return the MonitorFactory being used by the implementation to provide monitor interfaces for the primordial + * components. + * + * @return the MonitorFactory being used by the bootstrapper + */ + MonitorFactory getMonitorFactory(); + + /** + * Create a Deployer that can be used to deploy the system definition. This will most likely only support a small + * subset of the available programming model. + * + * @return a new primordial Deployer + */ + Deployer createDeployer(); + + /** + * Create a Loader for parsing a system definition represented as a XML SCDL file. + * + * @param propertyFactory the StAXPropertyFactory to be used to parse property values + * @param introspector the introspector to be used to extract component type information from a Java class + * @return a new prmordial Loader + */ + Loader createLoader(PropertyObjectFactory propertyFactory, Introspector introspector); + + /** + * Create a ScopeRegistry that supports the Scopes supported for primordial components + * + * @param workContext the WorkContext the Scopes should use + * @return a new primordial ScopeRegistry + */ + ScopeRegistry createScopeRegistry(WorkContext workContext); + + /** + * Create a Connector that can wire together primordial components. + * + * @return a new primordial Connector + */ + Connector getConnector(); + + /** + * Returns the AutowireResolver that resolves autowire targets + * + * @return the AutowireResolver that resolves autowire targets + */ + AutowireResolver getAutowireResolver(); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/bootstrap/DefaultBootstrapper.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/bootstrap/DefaultBootstrapper.java new file mode 100644 index 0000000000..073b9770f8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/bootstrap/DefaultBootstrapper.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.core.bootstrap; + +import javax.xml.stream.XMLInputFactory; + +import org.apache.tuscany.spi.builder.Builder; +import org.apache.tuscany.spi.builder.Connector; +import org.apache.tuscany.spi.component.ScopeContainerMonitor; +import org.apache.tuscany.spi.component.ScopeRegistry; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.deployer.Deployer; +import org.apache.tuscany.spi.extension.LoaderExtension; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService; +import org.apache.tuscany.spi.implementation.java.Introspector; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.PropertyObjectFactory; + +import org.apache.tuscany.core.binding.local.LocalBindingBuilder; +import org.apache.tuscany.core.binding.local.LocalBindingDefinition; +import org.apache.tuscany.core.binding.local.LocalBindingLoader; +import org.apache.tuscany.core.builder.BuilderRegistryImpl; +import org.apache.tuscany.core.component.ComponentManager; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.component.scope.CompositeScopeObjectFactory; +import org.apache.tuscany.core.component.scope.ScopeRegistryImpl; +import org.apache.tuscany.core.deployer.DeployerImpl; +import org.apache.tuscany.core.idl.java.InterfaceJavaLoader; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.implementation.IntrospectionRegistryImpl; +import org.apache.tuscany.core.implementation.composite.CompositeLoader; +import org.apache.tuscany.core.implementation.composite.SystemCompositeBuilder; +import org.apache.tuscany.core.implementation.processor.ConstructorProcessor; +import org.apache.tuscany.core.implementation.processor.DestroyProcessor; +import org.apache.tuscany.core.implementation.processor.EagerInitProcessor; +import org.apache.tuscany.core.implementation.processor.HeuristicPojoProcessor; +import org.apache.tuscany.core.implementation.processor.ImplementationProcessorServiceImpl; +import org.apache.tuscany.core.implementation.processor.InitProcessor; +import org.apache.tuscany.core.implementation.processor.MonitorProcessor; +import org.apache.tuscany.core.implementation.processor.PropertyProcessor; +import org.apache.tuscany.core.implementation.processor.ReferenceProcessor; +import org.apache.tuscany.core.implementation.processor.ResourceProcessor; +import org.apache.tuscany.core.implementation.processor.ScopeProcessor; +import org.apache.tuscany.core.implementation.processor.ServiceProcessor; +import org.apache.tuscany.core.implementation.system.builder.SystemComponentBuilder; +import org.apache.tuscany.core.implementation.system.loader.SystemComponentTypeLoader; +import org.apache.tuscany.core.implementation.system.loader.SystemCompositeComponentTypeLoader; +import org.apache.tuscany.core.implementation.system.loader.SystemImplementationLoader; +import org.apache.tuscany.core.implementation.system.model.SystemCompositeImplementation; +import org.apache.tuscany.core.implementation.system.model.SystemImplementation; +import org.apache.tuscany.core.loader.ComponentLoader; +import org.apache.tuscany.core.loader.ComponentTypeElementLoader; +import org.apache.tuscany.core.loader.IncludeLoader; +import org.apache.tuscany.core.loader.LoaderRegistryImpl; +import org.apache.tuscany.core.loader.PropertyLoader; +import org.apache.tuscany.core.loader.ReferenceLoader; +import org.apache.tuscany.core.loader.ServiceLoader; +import org.apache.tuscany.core.property.PropertyObjectFactoryImpl; +import org.apache.tuscany.core.resolver.AutowireResolver; +import org.apache.tuscany.host.MonitorFactory; + +/** + * A default implementation of a Bootstrapper. Please see the documentation on the individual methods for how the + * primordial components are created. + * + * @version $Rev$ $Date$ + */ +public class DefaultBootstrapper implements Bootstrapper { + private final MonitorFactory monitorFactory; + private final XMLInputFactory xmlFactory; + private final ComponentManager componentManager; + private final AutowireResolver resolver; + private final Connector connector; + + /** + * Create a default bootstrapper. + * + * @param monitorFactory the MonitorFactory to be used to create monitors for the primordial components + * @param xmlFactory the XMLInputFactory to be used by the components to load XML artifacts + * @param componentManager the component manager for the runtime instance + * @param resolver the autowire resolver for the runtime instance + * @param connector the connector for the runtime instance + */ + public DefaultBootstrapper(MonitorFactory monitorFactory, + XMLInputFactory xmlFactory, + ComponentManager componentManager, + AutowireResolver resolver, + Connector connector + ) { + this.monitorFactory = monitorFactory; + this.xmlFactory = xmlFactory; + this.componentManager = componentManager; + this.resolver = resolver; + this.connector = connector; + } + + /** + * Returns the MonitorFactory being used by this bootstrapper. + * + * @return the MonitorFactory being used by this bootstrapper + */ + public MonitorFactory getMonitorFactory() { + return monitorFactory; + } + + /** + * Create primordial deployer that can be used to load the system definition. + * + * @return the primordial deployer + */ + public Deployer createDeployer() { + ScopeRegistry scopeRegistry = createScopeRegistry(new WorkContextImpl()); + Builder builder = createBuilder(scopeRegistry); + JavaInterfaceProcessorRegistry interfaceIntrospector = new JavaInterfaceProcessorRegistryImpl(); + Introspector introspector = createIntrospector(interfaceIntrospector); + LoaderRegistry loader = createLoader(new PropertyObjectFactoryImpl(), introspector); + DeployerImpl deployer = new DeployerImpl(xmlFactory, loader, builder, componentManager, resolver, connector); + deployer.setMonitor(getMonitorFactory().getMonitor(ScopeContainerMonitor.class)); + return deployer; + } + + /** + * Create a basic ScopeRegistry containing the ScopeContainers that are available to components in the system + * definition. The implementation returned only support COMPOSITE scope. + * + * @param workContext the WorkContext the scopes should use + * @return a new ScopeRegistry + */ + public ScopeRegistry createScopeRegistry(WorkContext workContext) { + ScopeRegistry scopeRegistry = new ScopeRegistryImpl(); + new CompositeScopeObjectFactory(scopeRegistry, monitorFactory.getMonitor(ScopeContainerMonitor.class)); + return scopeRegistry; + } + + /** + * Create a Loader that can be used to parse an XML file containing the SCDL for the system definition. The + * following Implementation types are supported: <ul> <li>SystemImplementation</li> + * <li>SystemCompositeImplementation</li> </ul> and the following SCDL elements are supported: <ul> + * <li>composite</li> <li>component</li> <li>componentType</li> <li>interface.java</li> <li>property</li> + * <li>reference</li> <li>service</li> <li>implementation.system</li> </ul> Note the Java component type and the + * WSDL interface type are not supported. + * + * @param propertyFactory the StAXPropertyFactory to be used for parsing Property values + * @param introspector the Introspector to be used to inspect component implementations + * @return a new StAX XML loader + */ + public LoaderRegistry createLoader(PropertyObjectFactory propertyFactory, Introspector introspector) { + LoaderRegistryImpl loaderRegistry = + new LoaderRegistryImpl(monitorFactory.getMonitor(LoaderRegistryImpl.Monitor.class)); + + // register component type loaders + loaderRegistry.registerLoader(SystemImplementation.class, new SystemComponentTypeLoader(introspector)); + loaderRegistry.registerLoader(SystemCompositeImplementation.class, + new SystemCompositeComponentTypeLoader(loaderRegistry)); + + // register element loaders + registerLoader(loaderRegistry, new ComponentLoader(loaderRegistry, propertyFactory)); + registerLoader(loaderRegistry, new ComponentTypeElementLoader(loaderRegistry)); + registerLoader(loaderRegistry, new CompositeLoader(loaderRegistry, null)); + registerLoader(loaderRegistry, new IncludeLoader(loaderRegistry)); + JavaInterfaceProcessorRegistryImpl processorRegistry = new JavaInterfaceProcessorRegistryImpl(); + registerLoader(loaderRegistry, new InterfaceJavaLoader(loaderRegistry, processorRegistry)); + registerLoader(loaderRegistry, new PropertyLoader(loaderRegistry)); + registerLoader(loaderRegistry, new ReferenceLoader(loaderRegistry)); + registerLoader(loaderRegistry, new ServiceLoader(loaderRegistry)); + registerLoader(loaderRegistry, new SystemImplementationLoader(loaderRegistry)); + registerLoader(loaderRegistry, new LocalBindingLoader(loaderRegistry)); + return loaderRegistry; + } + + /** + * Create new Introspector for extracting a ComponentType definition from a Java class. + * + * @return a new Introspector + */ + public Introspector createIntrospector(JavaInterfaceProcessorRegistry registry) { + ImplementationProcessorService service = new ImplementationProcessorServiceImpl(registry); + IntrospectionRegistryImpl.Monitor monitor = monitorFactory.getMonitor(IntrospectionRegistryImpl.Monitor.class); + IntrospectionRegistryImpl introspectionRegistry = new IntrospectionRegistryImpl(monitor); + introspectionRegistry.registerProcessor(new ConstructorProcessor(service)); + introspectionRegistry.registerProcessor(new DestroyProcessor()); + introspectionRegistry.registerProcessor(new InitProcessor()); + introspectionRegistry.registerProcessor(new EagerInitProcessor()); + introspectionRegistry.registerProcessor(new ScopeProcessor()); + introspectionRegistry.registerProcessor(new PropertyProcessor(service)); + introspectionRegistry.registerProcessor(new ReferenceProcessor(registry)); + introspectionRegistry.registerProcessor(new ResourceProcessor()); + introspectionRegistry.registerProcessor(new ServiceProcessor(service)); + introspectionRegistry.registerProcessor(new HeuristicPojoProcessor(service)); + introspectionRegistry.registerProcessor(new MonitorProcessor(monitorFactory, service)); + return introspectionRegistry; + } + + /** + * Create a new Connector that can be used to wire primordial components together. + * + * @return a new Connector + */ + public Connector getConnector() { + return connector; + } + + + public AutowireResolver getAutowireResolver() { + return resolver; + } + + /** + * Helper method for registering a loader with the registry. The Loader is registered once for the QName returned by + * its {@link LoaderExtension#getXMLType()} method. + * + * @param registry the LoaderRegistry to register with + * @param loader the Loader to register + */ + protected void registerLoader(LoaderRegistry registry, LoaderExtension<?> loader) { + registry.registerLoader(loader.getXMLType(), loader); + } + + /** + * Create a Builder that can be used to build the components in the system definition. The default implementation + * only supports implementations from the system programming model. + * + * @param scopeRegistry the ScopeRegistry defining the component scopes that will be supported + * @return a new Builder + */ + private Builder createBuilder(ScopeRegistry scopeRegistry) { + BuilderRegistryImpl builderRegistry = + new BuilderRegistryImpl(scopeRegistry); + SystemCompositeBuilder builder = new SystemCompositeBuilder(builderRegistry); + builderRegistry.register(SystemCompositeImplementation.class, builder); + builderRegistry.register(SystemImplementation.class, new SystemComponentBuilder()); + builderRegistry.register(LocalBindingDefinition.class, new LocalBindingBuilder()); + return builderRegistry; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/BuilderRegistryImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/BuilderRegistryImpl.java new file mode 100644 index 0000000000..33dd2175f9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/BuilderRegistryImpl.java @@ -0,0 +1,185 @@ +/* + * 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.core.builder; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +import org.osoa.sca.annotations.EagerInit; + +import org.apache.tuscany.spi.builder.BindingBuilder; +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.builder.BuilderRegistry; +import org.apache.tuscany.spi.builder.ComponentBuilder; +import org.apache.tuscany.spi.builder.ScopeNotFoundException; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.ReferenceBinding; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.ScopeRegistry; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.component.ServiceBinding; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.BindingDefinition; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.ReferenceDefinition; +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.core.binding.local.LocalBindingDefinition; +import org.apache.tuscany.core.implementation.composite.ReferenceImpl; +import org.apache.tuscany.core.implementation.composite.ServiceImpl; + +/** + * The default builder registry in the runtime + * + * @version $Rev$ $Date$ + */ +@EagerInit +public class BuilderRegistryImpl implements BuilderRegistry { + private ScopeRegistry scopeRegistry; + + private final Map<Class<? extends Implementation<?>>, ComponentBuilder<? extends Implementation<?>>> componentBuilders = + new HashMap<Class<? extends Implementation<?>>, ComponentBuilder<? extends Implementation<?>>>(); + private final Map<Class<? extends BindingDefinition>, BindingBuilder<? extends BindingDefinition>> bindingBuilders = + new HashMap<Class<? extends BindingDefinition>, BindingBuilder<? extends BindingDefinition>>(); + + public BuilderRegistryImpl(@org.osoa.sca.annotations.Reference ScopeRegistry scopeRegistry) { + this.scopeRegistry = scopeRegistry; + } + + public <I extends Implementation<?>> void register(Class<I> implClass, ComponentBuilder<I> builder) { + componentBuilders.put(implClass, builder); + } + + public <I extends Implementation<?>> void unregister(Class<I> implClass) { + componentBuilders.remove(implClass); + } + + public <B extends BindingDefinition> void register(Class<B> implClass, BindingBuilder<B> builder) { + bindingBuilders.put(implClass, builder); + } + + @SuppressWarnings("unchecked") + public <I extends Implementation<?>> Component build( + ComponentDefinition<I> componentDefinition, + DeploymentContext context) throws BuilderException { + Class<?> implClass = componentDefinition.getImplementation().getClass(); + // noinspection SuspiciousMethodCalls + ComponentBuilder<I> componentBuilder = (ComponentBuilder<I>) componentBuilders.get(implClass); + if (componentBuilder == null) { + String name = implClass.getName(); + throw new NoRegisteredBuilderException("No builder registered for implementation", name); + } + Component component = componentBuilder.build(componentDefinition, context); + assert component != null; + component.setDefaultPropertyValues(componentDefinition.getPropertyValues()); + Scope scope = componentDefinition.getImplementation().getComponentType().getImplementationScope(); + if (scope == Scope.SYSTEM || scope == Scope.COMPOSITE) { + component.setScopeContainer(context.getCompositeScope()); + } else { + // Check for conversational contract if conversational scope + if (scope == Scope.CONVERSATION) { + boolean hasConversationalContract = false; + ComponentType<ServiceDefinition, ReferenceDefinition, ?> componentType = + componentDefinition.getImplementation().getComponentType(); + Map<String, ServiceDefinition> services = componentType.getServices(); + for (ServiceDefinition serviceDef : services.values()) { + ServiceContract<?> contract = serviceDef.getServiceContract(); + if (contract.isConversational()) { + hasConversationalContract = true; + break; + } + } + if (!hasConversationalContract) { + String name = implClass.getName(); + throw new NoConversationalContractException( + "No conversational contract for conversational implementation", name); + } + } + // Now it's ok to set the scope container + ScopeContainer scopeContainer = scopeRegistry.getScopeContainer(scope); + if (scopeContainer == null) { + throw new ScopeNotFoundException(scope.toString()); + } + component.setScopeContainer(scopeContainer); + } + context.getComponents().put(component.getUri(), component); + ComponentType<?, ?, ?> componentType = componentDefinition.getImplementation().getComponentType(); + assert componentType != null : "Component type must be set"; + return component; + } + + @SuppressWarnings({"unchecked"}) + public Service build(ServiceDefinition serviceDefinition, DeploymentContext context) throws BuilderException { + URI uri = serviceDefinition.getUri(); + ServiceContract<?> serviceContract = serviceDefinition.getServiceContract(); + if (serviceDefinition.getBindings().isEmpty()) { + // if no bindings are configured, default to the local binding. + // this should be changed to allow runtime selection + if (serviceDefinition.getBindings().isEmpty()) { + // TODO JFM implement capability for the runtime to choose a binding + serviceDefinition.addBinding(new LocalBindingDefinition()); + } + } + URI targetUri = serviceDefinition.getTarget(); + Service service = new ServiceImpl(uri, serviceContract, targetUri); + for (BindingDefinition definition : serviceDefinition.getBindings()) { + Class<?> bindingClass = definition.getClass(); + // noinspection SuspiciousMethodCalls + BindingBuilder bindingBuilder = bindingBuilders.get(bindingClass); + if (bindingBuilder == null) { + throw new NoRegisteredBuilderException("No builder registered for type", bindingClass.getName()); + } + ServiceBinding binding = bindingBuilder.build(serviceDefinition, definition, context); + service.addServiceBinding(binding); + } + return service; + } + + @SuppressWarnings("unchecked") + public Reference build(ReferenceDefinition referenceDefinition, DeploymentContext context) throws BuilderException { + URI uri = referenceDefinition.getUri(); + ServiceContract<?> contract = referenceDefinition.getServiceContract(); + if (referenceDefinition.getBindings().isEmpty()) { + // if no bindings are configured, default to the local binding. + // this should be changed to allow runtime selection + if (referenceDefinition.getBindings().isEmpty()) { + // TODO JFM implement capability for the runtime to choose a binding + referenceDefinition.addBinding(new LocalBindingDefinition()); + } + } + + Reference reference = new ReferenceImpl(uri, contract); + for (BindingDefinition bindingDefinition : referenceDefinition.getBindings()) { + Class<?> bindingClass = bindingDefinition.getClass(); + // noinspection SuspiciousMethodCalls + BindingBuilder bindingBuilder = bindingBuilders.get(bindingClass); + ReferenceBinding binding = bindingBuilder.build(referenceDefinition, bindingDefinition, context); + reference.addReferenceBinding(binding); + + } + return reference; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/ComponentNotFoundException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/ComponentNotFoundException.java new file mode 100644 index 0000000000..a46e038cb9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/ComponentNotFoundException.java @@ -0,0 +1,36 @@ +/* + * 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.core.builder; + +import java.net.URI; + +import org.apache.tuscany.spi.builder.WiringException; + +/** + * Indicates a component was not found during wiring + * + * @version $Rev$ $Date$ + */ +public class ComponentNotFoundException extends WiringException { + + public ComponentNotFoundException(String message, URI name) { + super(message, name, name); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/ConnectorImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/ConnectorImpl.java new file mode 100644 index 0000000000..2e1af8d8f5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/ConnectorImpl.java @@ -0,0 +1,346 @@ +/* + * 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.core.builder; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import javax.xml.namespace.QName; + +import org.osoa.sca.annotations.Constructor; + +import org.apache.tuscany.spi.builder.Connector; +import org.apache.tuscany.spi.builder.WiringException; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.Invocable; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.ReferenceBinding; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.component.ServiceBinding; +import org.apache.tuscany.spi.component.TargetInvokerCreationException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ReferenceTarget; +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.spi.model.physical.PhysicalWireDefinition; +import org.apache.tuscany.spi.services.work.WorkScheduler; +import org.apache.tuscany.spi.util.UriHelper; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; +import org.apache.tuscany.spi.wire.WirePostProcessorRegistry; + +import org.apache.tuscany.core.component.ComponentManager; +import org.apache.tuscany.core.wire.InvocationChainImpl; +import org.apache.tuscany.core.wire.InvokerInterceptor; +import org.apache.tuscany.core.wire.NonBlockingInterceptor; +import org.apache.tuscany.core.wire.WireImpl; +import org.apache.tuscany.core.wire.WireUtils; + +/** + * The default connector implmentation + * + * @version $$Rev$$ $$Date$$ + */ +public class ConnectorImpl implements Connector { + private WirePostProcessorRegistry postProcessorRegistry; + private ComponentManager componentManager; + private WorkContext workContext; + private WorkScheduler scheduler; + + public ConnectorImpl(ComponentManager componentManager) { + this.componentManager = componentManager; + } + + @Constructor + public ConnectorImpl( + @org.osoa.sca.annotations.Reference WirePostProcessorRegistry processorRegistry, + @org.osoa.sca.annotations.Reference ComponentManager componentManager, + @org.osoa.sca.annotations.Reference WorkScheduler scheduler, + @org.osoa.sca.annotations.Reference WorkContext workContext) { + this.postProcessorRegistry = processorRegistry; + this.componentManager = componentManager; + this.scheduler = scheduler; + this.workContext = workContext; + } + + /** + * <strong>Note this method will not work yet</strong> + * <p/> + * Wires a source and target component based on a wire defintion + * + * @param definition the wire definition + * @throws WiringException + */ + public void connect(PhysicalWireDefinition definition) throws WiringException { + URI sourceUri = definition.getSourceUri(); + assert sourceUri != null; + URI targetUri = definition.getTargetUri(); + assert targetUri != null; + URI baseSourceUri = UriHelper.getDefragmentedName(sourceUri); + URI baseTargetUri = UriHelper.getDefragmentedName(targetUri); + String targetFragment = targetUri.getFragment(); + Component source = componentManager.getComponent(baseSourceUri); + if (source == null) { + throw new ComponentNotFoundException("Wire source component not found", baseSourceUri); + } + Component target = componentManager.getComponent(baseTargetUri); + if (target == null) { + throw new ComponentNotFoundException("Wire target component not found", baseTargetUri); + } + ServiceContract<?> contract = null; + Wire wire = createWire(sourceUri, targetUri, contract, definition.getBindingType()); + try { + attachInvokers(targetFragment, wire, source, target); + } catch (TargetInvokerCreationException e) { + throw new WireCreationException("Error creating invoker", sourceUri, targetUri, e); + } + source.attachWire(wire); + throw new UnsupportedOperationException(); + } + + public void connect(ComponentDefinition<? extends Implementation<?>> definition) throws WiringException { + URI sourceUri = definition.getUri(); + Component source = componentManager.getComponent(sourceUri); + if (source == null) { + throw new ComponentNotFoundException("Source not found", sourceUri); + } + ComponentType<?, ?, ?> type = definition.getImplementation().getComponentType(); + if (type instanceof CompositeComponentType) { + CompositeComponentType<?, ?, ?> compositeType = (CompositeComponentType<?, ?, ?>) type; + for (ComponentDefinition<? extends Implementation<?>> child : compositeType.getComponents().values()) { + connect(child); + } + for (ServiceDefinition child : compositeType.getServices().values()) { + connect(child); + } + for (ReferenceDefinition child : compositeType.getReferences().values()) { + connect(child); + } + } + Map<String, ReferenceTarget> targets = definition.getReferenceTargets(); + for (ReferenceTarget referenceTarget : targets.values()) { + List<Wire> wires = new ArrayList<Wire>(); + String refName = referenceTarget.getReferenceName().getFragment(); + ReferenceDefinition refDefinition = type.getReferences().get(refName); + assert refDefinition != null; + List<URI> uris = referenceTarget.getTargets(); + for (URI uri : uris) { + URI targetUri = UriHelper.getDefragmentedName(uri); + Component target = componentManager.getComponent(targetUri); + if (target == null && !refDefinition.isRequired()) { + // a non-required reference, just skip + continue; + } + if (target == null) { + throw new ComponentNotFoundException("Target not found", targetUri); + } + String fragment = uri.getFragment(); + URI sourceURI = refDefinition.getUri(); + Wire wire = createWire(sourceURI, uri, refDefinition.getServiceContract(), Wire.LOCAL_BINDING); + try { + attachInvokers(fragment, wire, source, target); + } catch (TargetInvokerCreationException e) { + throw new WireCreationException("Error creating invoker", sourceUri, targetUri, e); + } + if (postProcessorRegistry != null) { + postProcessorRegistry.process(wire); + } + optimize(source, target, wire); + wires.add(wire); + if (!wire.getCallbackInvocationChains().isEmpty()) { + target.attachCallbackWire(wire); + } + } + if (wires.size() > 1) { + // attach as a multiplicity + source.attachWires(wires); + } else if (wires.size() == 1) { + // attach as a single wire + Wire wire = wires.get(0); + source.attachWire(wire); + } + } + } + + /** + * @deprecated + */ + protected void connect(ServiceDefinition definition) throws WiringException { + URI uri = definition.getUri(); + URI sourceUri = UriHelper.getDefragmentedName(uri); + URI targetUri = definition.getTarget(); + URI baseTargetUri = UriHelper.getDefragmentedName(targetUri); + Component source = componentManager.getComponent(sourceUri); + if (source == null) { + throw new ComponentNotFoundException("Source not found", sourceUri); + } + Service service = source.getService(uri.getFragment()); + if (service == null) { + throw new SourceServiceNotFoundException("Service not found on composite", uri); + } + Component target = componentManager.getComponent(baseTargetUri); + if (target == null) { + throw new ComponentNotFoundException("Target not found", sourceUri); + } + ServiceContract<?> contract = definition.getServiceContract(); + // TODO if no binding, do local + for (ServiceBinding binding : service.getServiceBindings()) { + Wire wire = createWire(uri, targetUri, contract, binding.getBindingType()); + binding.setWire(wire); + if (postProcessorRegistry != null) { + postProcessorRegistry.process(wire); + } + try { + attachInvokers(definition.getTarget().getFragment(), wire, binding, target); + } catch (TargetInvokerCreationException e) { + throw new WireCreationException("Error creating invoker", sourceUri, baseTargetUri, e); + } + } + } + + /** + * @deprecated + */ + protected void connect(ReferenceDefinition definition) throws WiringException { + URI uri = definition.getUri(); + URI sourceUri = UriHelper.getDefragmentedName(uri); + Component source = componentManager.getComponent(sourceUri); + if (source == null) { + throw new ComponentNotFoundException("Source not found", sourceUri); + } + Reference reference = source.getReference(uri.getFragment()); + if (reference == null) { + throw new SourceServiceNotFoundException("Reference not found on composite", uri); + } + + for (ReferenceBinding binding : reference.getReferenceBindings()) { + // create wire + if (Wire.LOCAL_BINDING.equals(binding.getBindingType())) { + URI targetUri = binding.getTargetUri(); + ServiceContract<?> contract = binding.getBindingServiceContract(); + QName type = binding.getBindingType(); + Wire wire = createWire(sourceUri, targetUri, contract, type); + binding.setWire(wire); + // wire local bindings to their targets + Component target = componentManager.getComponent(UriHelper.getDefragmentedName(targetUri)); + if (target == null) { + throw new ComponentNotFoundException("Target not found", sourceUri); + } + try { + attachInvokers(targetUri.getFragment(), wire, binding, target); + } catch (TargetInvokerCreationException e) { + throw new WireCreationException("Error creating invoker", sourceUri, targetUri, e); + } + } else { + Wire wire = createWire(sourceUri, null, binding.getBindingServiceContract(), binding.getBindingType()); + if (postProcessorRegistry != null) { + postProcessorRegistry.process(wire); + } + binding.setWire(wire); + } + } + } + + protected Wire createWire(URI sourceURI, URI targetUri, ServiceContract<?> contract, QName bindingType) { + Wire wire = new WireImpl(bindingType); + wire.setSourceContract(contract); + wire.setSourceUri(sourceURI); + wire.setTargetUri(targetUri); + for (Operation<?> operation : contract.getOperations().values()) { + InvocationChain chain = new InvocationChainImpl(operation); + if (operation.isNonBlocking()) { + chain.addInterceptor(new NonBlockingInterceptor(scheduler, workContext)); + } + chain.addInterceptor(new InvokerInterceptor()); + wire.addInvocationChain(operation, chain); + + } + for (Operation<?> operation : contract.getCallbackOperations().values()) { + InvocationChain chain = new InvocationChainImpl(operation); + if (operation.isNonBlocking()) { + chain.addInterceptor(new NonBlockingInterceptor(scheduler, workContext)); + } + chain.addInterceptor(new InvokerInterceptor()); + wire.addCallbackInvocationChain(operation, chain); + } + return wire; + } + + private void attachInvokers(String name, Wire wire, Invocable source, Invocable target) + throws TargetInvokerCreationException { + for (InvocationChain chain : wire.getInvocationChains().values()) { + //String name = target.getUri().getFragment(); + chain.setTargetInvoker(target.createTargetInvoker(name, chain.getOperation())); + } + for (InvocationChain chain : wire.getCallbackInvocationChains().values()) { + chain.setTargetInvoker(source.createTargetInvoker(null, chain.getOperation())); + } + } + + protected void optimize(Component source, Component target, Wire wire) { + boolean optimizableScopes = isOptimizable(source.getScope(), target.getScope()); + if (optimizableScopes && target.isOptimizable() && WireUtils.isOptimizable(wire)) { + wire.setOptimizable(true); + wire.setTarget((AtomicComponent) target); + } else { + wire.setOptimizable(false); + } + } + + protected boolean isOptimizable(Scope pReferrer, Scope pReferee) { + if (pReferrer == Scope.UNDEFINED + || pReferee == Scope.UNDEFINED + || pReferrer == Scope.CONVERSATION + || pReferee == Scope.CONVERSATION) { + return false; + } + if (pReferee == pReferrer) { + return true; + } else if (pReferrer == Scope.STATELESS) { + return true; + } else if (pReferee == Scope.STATELESS) { + return false; + } else if (pReferrer == Scope.REQUEST && pReferee == Scope.SESSION) { + return true; + } else if (pReferrer == Scope.REQUEST && pReferee == Scope.COMPOSITE) { + return true; + } else if (pReferrer == Scope.REQUEST && pReferee == Scope.SYSTEM) { + return true; + } else if (pReferrer == Scope.SESSION && pReferee == Scope.COMPOSITE) { + return true; + } else if (pReferrer == Scope.SESSION && pReferee == Scope.SYSTEM) { + return true; + } else //noinspection SimplifiableIfStatement + if (pReferrer == Scope.SYSTEM && pReferee == Scope.COMPOSITE) { + // case where a service context points to a composite scoped component + return true; + } else { + return pReferrer == Scope.COMPOSITE && pReferee == Scope.SYSTEM; + } + } +}
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/IllegalCallbackException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/IllegalCallbackException.java new file mode 100644 index 0000000000..183ccea1b8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/IllegalCallbackException.java @@ -0,0 +1,36 @@ +/* + * 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.core.builder; + +import java.net.URI; + +import org.apache.tuscany.spi.builder.WiringException; + +/** + * Denotes an illegal callback + * + * @version $Rev$ $Date$ + */ +public class IllegalCallbackException extends WiringException { + + public IllegalCallbackException(String message, String identifier, URI sourceUri, URI targetUri) { + super(message, identifier, sourceUri, targetUri); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/IncompatibleInterfacesException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/IncompatibleInterfacesException.java new file mode 100644 index 0000000000..1a9c74aa3b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/IncompatibleInterfacesException.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.builder; + +import java.net.URI; + +import org.apache.tuscany.spi.builder.WiringException; + +/** + * Denotes an attempt to wire incompatible interfaces + * + * @version $Rev$ $Date$ + */ +public class IncompatibleInterfacesException extends WiringException { + + public IncompatibleInterfacesException(URI source, URI target) { + super("Incompatible source and target interfaces", source, target); + } + + public IncompatibleInterfacesException(URI source, URI target, Throwable throwable) { + super("Incompatible source and target interfaces", source, target, throwable); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/InvalidSourceTypeException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/InvalidSourceTypeException.java new file mode 100644 index 0000000000..d9df445530 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/InvalidSourceTypeException.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.builder; + +import java.net.URI; + +import org.apache.tuscany.spi.builder.WiringException; + +/** + * Denotes an invalid source type for a wire + * + * @version $Rev$ $Date$ + */ +public class InvalidSourceTypeException extends WiringException { + + public InvalidSourceTypeException(String message, URI sourceUri, URI targetUri) { + super(message, sourceUri, targetUri); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/InvalidTargetTypeException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/InvalidTargetTypeException.java new file mode 100644 index 0000000000..e3c26c75d2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/InvalidTargetTypeException.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.builder; + +import java.net.URI; + +import org.apache.tuscany.spi.builder.WiringException; + +/** + * Denotes an invalid target service for a wire + * + * @version $Rev$ $Date$ + */ +public class InvalidTargetTypeException extends WiringException { + + public InvalidTargetTypeException(String message, URI sourceUri, URI targetUri) { + super(message, sourceUri, targetUri); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/NoBindingException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/NoBindingException.java new file mode 100644 index 0000000000..c351013297 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/NoBindingException.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.builder; + +import java.net.URI; + +import org.apache.tuscany.spi.builder.WiringException; + +/** + * Denotes no binding was specified for a wire + * + * @version $Rev$ $Date$ + */ +public class NoBindingException extends WiringException { + + public NoBindingException(String message, URI sourceUri, URI targetUri) { + super(message, sourceUri, targetUri); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/NoCompatibleBindingsException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/NoCompatibleBindingsException.java new file mode 100644 index 0000000000..3c49767333 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/NoCompatibleBindingsException.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.core.builder; + +import java.net.URI; + +import org.apache.tuscany.spi.builder.WiringException; + +/** + * @version $Rev$ $Date$ + */ +public class NoCompatibleBindingsException extends WiringException { + + public NoCompatibleBindingsException(URI sourceName, URI targetName) { + super("No compatible bindings for source and target", sourceName, targetName); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/NoConversationalContractException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/NoConversationalContractException.java new file mode 100644 index 0000000000..71eb9ebd26 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/NoConversationalContractException.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.core.builder;
+
+import org.apache.tuscany.spi.builder.BuilderException;
+
+/**
+ * Raised when a component has conversational scope but no conversational contract
+ *
+ * @version $Rev: 487877 $ $Date: 2006-12-16 15:32:16 -0500 (Sat, 16 Dec 2006) $
+ */
+public class NoConversationalContractException extends BuilderException {
+
+ public NoConversationalContractException(String message, String identifier) {
+ super(message, identifier);
+ }
+
+ public NoConversationalContractException(String message) {
+ super(message);
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/NoRegisteredBuilderException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/NoRegisteredBuilderException.java new file mode 100644 index 0000000000..340a20f239 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/NoRegisteredBuilderException.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.core.builder; + +import org.apache.tuscany.spi.builder.BuilderException; + +/** + * Raised when a builder cannot be found for a SCDL entry type + * + * @version $Rev$ $Date$ + */ +public class NoRegisteredBuilderException extends BuilderException { + + public NoRegisteredBuilderException(String message, String identifier) { + super(message, identifier); + } + + public NoRegisteredBuilderException(String message) { + super(message); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/SourceServiceNotFoundException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/SourceServiceNotFoundException.java new file mode 100644 index 0000000000..7d3d49b937 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/SourceServiceNotFoundException.java @@ -0,0 +1,36 @@ +/* + * 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.core.builder; + +import java.net.URI; + +import org.apache.tuscany.spi.builder.WiringException; + +/** + * Indicates the source service of a wire was not found + * + * @version $Rev$ $Date$ + */ +public class SourceServiceNotFoundException extends WiringException { + + public SourceServiceNotFoundException(String message, URI sourceName) { + super(message, sourceName, null); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/TargetServiceNotFoundException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/TargetServiceNotFoundException.java new file mode 100644 index 0000000000..f22b421aa7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/TargetServiceNotFoundException.java @@ -0,0 +1,36 @@ +/* + * 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.core.builder; + +import java.net.URI; + +import org.apache.tuscany.spi.builder.WiringException; + +/** + * Indicates the target service of a reference was not found + * + * @version $Rev$ $Date$ + */ +public class TargetServiceNotFoundException extends WiringException { + + public TargetServiceNotFoundException(String message, URI sourceName, URI targetName) { + super(message, sourceName, targetName); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/WireCreationException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/WireCreationException.java new file mode 100644 index 0000000000..117bb23180 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/WireCreationException.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.builder; + +import java.net.URI; + +import org.apache.tuscany.spi.builder.WiringException; + +/** + * Denotes an error creating a wire + * + * @version $Rev$ $Date$ + */ +public class WireCreationException extends WiringException { + + public WireCreationException(String message, URI sourceUri, Throwable e) { + super(message, sourceUri, null, e); + } + + public WireCreationException(String message, URI sourceUri, URI targetUri, Throwable e) { + super(message, sourceUri, targetUri, e); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/WirePostProcessorRegistryImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/WirePostProcessorRegistryImpl.java new file mode 100644 index 0000000000..6f611956be --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/WirePostProcessorRegistryImpl.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.core.builder; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.spi.wire.Wire; +import org.apache.tuscany.spi.wire.WirePostProcessor; +import org.apache.tuscany.spi.wire.WirePostProcessorRegistry; + +/** + * The default implementation of a <code>WirePostProcessor</code> + * + * @version $Rev$ $Date$ + */ +public class WirePostProcessorRegistryImpl implements WirePostProcessorRegistry { + + private final List<WirePostProcessor> processors = new ArrayList<WirePostProcessor>(); + + public void process(Wire wire) { + for (WirePostProcessor processor : processors) { + processor.process(wire); + } + } + + public void register(WirePostProcessor processor) { + processors.add(processor); + } + + public void unregister(WirePostProcessor processor) { + processors.remove(processor); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/WiringExceptionFormatter.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/WiringExceptionFormatter.java new file mode 100644 index 0000000000..661dc8bfea --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/WiringExceptionFormatter.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.builder; + +import java.io.PrintWriter; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.builder.WiringException; + +import org.apache.tuscany.host.monitor.ExceptionFormatter; +import org.apache.tuscany.host.monitor.FormatterRegistry; + +/** + * Formats {@link WiringException}s + * + * @version $Rev$ $Date$ + */ +@EagerInit +public class WiringExceptionFormatter implements ExceptionFormatter { + private FormatterRegistry factory; + + public WiringExceptionFormatter(@Reference FormatterRegistry factory) { + this.factory = factory; + factory.register(this); + } + + public boolean canFormat(Class<?> type) { + return WiringException.class.isAssignableFrom(type); + } + + @Destroy + public void destroy() { + factory.unregister(this); + } + + public PrintWriter write(PrintWriter writer, Throwable exception) { + assert exception instanceof WiringException; + WiringException e = (WiringException) exception; + e.appendBaseMessage(writer); + if (e.getSourceUri() != null) { + writer.write("\nSource : " + e.getSourceUri()); + } + if (e.getTargetUri() != null) { + writer.write("\nTarget : " + e.getTargetUri()); + } + return writer; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/physical/DefaultPhysicalComponentBuilderRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/physical/DefaultPhysicalComponentBuilderRegistry.java new file mode 100644 index 0000000000..c1baa27ed2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/builder/physical/DefaultPhysicalComponentBuilderRegistry.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.core.builder.physical; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.builder.physical.PhysicalComponentBuilder; +import org.apache.tuscany.spi.builder.physical.PhysicalComponentBuilderRegistry; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.model.physical.PhysicalComponentDefinition; + +/** + * Default map-based implementation of the physical component builder registry. + * <p/> + * TODO may be we can factor out all the registries into a parameterized one. + * + * @version $Rev$ $Date$ + */ +public class DefaultPhysicalComponentBuilderRegistry implements PhysicalComponentBuilderRegistry { + + // Internal cache + private Map<Class<? extends PhysicalComponentDefinition>, + PhysicalComponentBuilder<? extends PhysicalComponentDefinition, ? extends Component>> registry = + new ConcurrentHashMap<Class<? extends PhysicalComponentDefinition>, + PhysicalComponentBuilder<? extends PhysicalComponentDefinition, ? extends Component>>(); + + /** + * Registers a physical component builder. + * + * @param <PCD> Type of the physical component definition. + * @param definitionClass Class of the physical component definition. + * @param builder Builder for the physical component definition. + */ + public <PCD extends PhysicalComponentDefinition, + C extends Component> void register(Class<PCD> definitionClass, PhysicalComponentBuilder<PCD, C> builder) { + registry.put(definitionClass, builder); + } + + /** + * Builds a physical component from component definition. + * @param componentDefinition Component definition. + * @return Component to be built. + */ + @SuppressWarnings("unchecked") + public Component build(PhysicalComponentDefinition componentDefinition) throws BuilderException { + + PhysicalComponentBuilder builder = registry.get(componentDefinition.getClass()); + return builder.build(componentDefinition); + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/CallableReferenceImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/CallableReferenceImpl.java new file mode 100644 index 0000000000..e674112a89 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/CallableReferenceImpl.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.component; + +import org.osoa.sca.CallableReference; +import org.osoa.sca.Conversation; + +import org.apache.tuscany.spi.ObjectFactory; + +/** + * Base class for implementations of service and callback references. + * + * @version $Rev$ $Date$ + * @param <B> the type of the business interface + */ +public abstract class CallableReferenceImpl<B> implements CallableReference<B> { + private final Class<B> businessInterface; + private final ObjectFactory<B> factory; + + protected CallableReferenceImpl(Class<B> businessInterface, ObjectFactory<B> factory) { + this.businessInterface = businessInterface; + this.factory = factory; + } + + public B getService() { + return factory.getInstance(); + } + + public Class<B> getBusinessInterface() { + return businessInterface; + } + + public boolean isConversational() { + return false; + } + + public Conversation getConversation() { + return null; + } + + public Object getCallbackID() { + return null; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/CallbackReferenceImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/CallbackReferenceImpl.java new file mode 100644 index 0000000000..532a8b2bad --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/CallbackReferenceImpl.java @@ -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. + */ +package org.apache.tuscany.core.component; + +import org.apache.tuscany.spi.ObjectFactory; + +/** + * Default implementation of a callback reference. + * + * @version $Rev$ $Date$ + * @param <CB> the type of the business interface + */ +public class CallbackReferenceImpl<CB> extends CallableReferenceImpl<CB> { + public CallbackReferenceImpl(Class<CB> businessInterface, ObjectFactory<CB> factory) { + super(businessInterface, factory); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ComponentContextImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ComponentContextImpl.java new file mode 100644 index 0000000000..c2da089178 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ComponentContextImpl.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.core.component; + +import org.osoa.sca.CallableReference; +import org.osoa.sca.ComponentContext; +import org.osoa.sca.RequestContext; +import org.osoa.sca.ServiceReference; +import org.osoa.sca.ServiceRuntimeException; + +import org.apache.tuscany.api.TuscanyRuntimeException; + +/** + * Implementation of ComponentContext that delegates to a ComponentContextProvider. + * + * @version $Rev$ $Date$ + */ +public class ComponentContextImpl implements ComponentContext { + private final ComponentContextProvider component; + + public ComponentContextImpl(ComponentContextProvider component) { + this.component = component; + } + + public String getURI() { + try { + return component.getUri().toString(); + } catch (TuscanyRuntimeException e) { + throw new ServiceRuntimeException(e.getMessage(), e); + } + } + + public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException { + try { + return (R) component.cast(target); + } catch (TuscanyRuntimeException e) { + throw new ServiceRuntimeException(e.getMessage(), e); + } + } + + public <B> B getService(Class<B> businessInterface, String referenceName) { + try { + return component.getService(businessInterface, referenceName); + } catch (TuscanyRuntimeException e) { + throw new ServiceRuntimeException(e.getMessage(), e); + } + } + + public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, String referenceName) { + try { + return component.getServiceReference(businessInterface, referenceName); + } catch (TuscanyRuntimeException e) { + throw new ServiceRuntimeException(e.getMessage(), e); + } + } + + public <B> B getProperty(Class<B> type, String propertyName) { + try { + return component.getProperty(type, propertyName); + } catch (TuscanyRuntimeException e) { + throw new ServiceRuntimeException(e.getMessage(), e); + } + } + + public <B> ServiceReference<B> createSelfReference(Class<B> businessInterface) { + return null; + } + + public <B> ServiceReference<B> createSelfReference(Class<B> businessInterface, String serviceName) { + return null; + } + + public RequestContext getRequestContext() { + return null; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ComponentContextProvider.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ComponentContextProvider.java new file mode 100644 index 0000000000..4237d8b09f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ComponentContextProvider.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.component; + +import java.net.URI; + +import org.osoa.sca.ComponentContext; +import org.osoa.sca.ServiceReference; +import org.osoa.sca.CallableReference; + +/** + * Interface implemented by Component's that want to expose a ComponentContext. + * + * @version $Rev$ $Date$ + */ +public interface ComponentContextProvider { + ComponentContext getComponentContext(); + + URI getUri(); + + <B> B getService(Class<B> businessInterface, String referenceName); + + <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, String referenceName); + + <B> B getProperty(Class<B> type, String propertyName); + + <B, R extends CallableReference<B>> R cast(B target); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ComponentManager.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ComponentManager.java new file mode 100644 index 0000000000..fcd1702bb3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ComponentManager.java @@ -0,0 +1,86 @@ +/* + * 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.core.component; + +import java.net.URI; +import java.util.List; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.RegistrationException; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.model.ServiceContract; + +/** + * Responsible for tracking and managing the component tree for a runtime instance. The tree corresponds to components + * deployed to the current runtime and hence may be sparse in comparison to the assembly component hierarchy for the SCA + * domain as parents and children may be distributed to different runtimes. + * + * @version $Rev$ $Date$ + */ +public interface ComponentManager extends RuntimeEventListener { + + /** + * Registers a component which will be managed by the runtime + * + * @param component the component + * @throws RegistrationException + */ + void register(Component component) throws RegistrationException; + + /** + * Deregisters a component + * + * @param component the component to deregister + * @throws RegistrationException + */ + void unregister(Component component) throws RegistrationException; + + /** + * Register a simple Java Object as a system component. This is primarily intended for use by bootstrap code to + * create the initial configuration components. + * + * @param uri the uri of the resulting component + * @param service the service contract the component should expose + * @param instance the Object that will become the component's implementation + * @throws RegistrationException + */ + <S, I extends S> void registerJavaObject(URI uri, ServiceContract<S> service, I instance) + throws RegistrationException; + + /** + * Register a simple Java Object as a system component. This is primarily intended for use by bootstrap code to + * create the initial configuration components. + * + * @param uri the name of the resulting component + * @param services the service contracts the component should expose + * @param instance the Object that will become the component's implementation + * @throws RegistrationException + */ + <S, I extends S> void registerJavaObject(URI uri, List<ServiceContract<?>> services, I instance) + throws RegistrationException; + + /** + * Returns the component with the given URI + * + * @param uri the component URI + * @return the component or null if not found + */ + Component getComponent(URI uri); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ComponentManagerImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ComponentManagerImpl.java new file mode 100644 index 0000000000..1c4f55332d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ComponentManagerImpl.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.core.component; + +import java.net.URI; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.DuplicateNameException; +import org.apache.tuscany.spi.component.RegistrationException; +import org.apache.tuscany.spi.event.Event; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.services.management.TuscanyManagementService; + +import org.apache.tuscany.core.resolver.AutowireResolver; + +/** + * Default implementation of the component manager + * + * @version $Rev$ $Date$ + */ +public class ComponentManagerImpl implements ComponentManager { + private TuscanyManagementService managementService; + private AutowireResolver resolver; + private Map<URI, Component> components; + + public ComponentManagerImpl() { + components = new ConcurrentHashMap<URI, Component>(); + } + + public ComponentManagerImpl(TuscanyManagementService managementService, AutowireResolver resolver) { + this(); + this.managementService = managementService; + this.resolver = resolver; + } + + public synchronized void register(Component component) throws RegistrationException { + URI uri = component.getUri(); + assert uri != null; + assert !uri.toString().endsWith("/"); + if (components.containsKey(uri)) { + throw new DuplicateNameException(uri.toString()); + } + components.put(uri, component); + + if (managementService != null && component instanceof AtomicComponent) { + // FIXME shouldn't it take the canonical name and also not distinguish atomic components? + managementService.registerComponent(component.getUri().toString(), component); + } + } + + public <S, I extends S> void registerJavaObject(URI uri, ServiceContract<S> service, I instance) + throws RegistrationException { + SystemSingletonAtomicComponent<S, I> component = + new SystemSingletonAtomicComponent<S, I>(uri, service, instance); + register(component); + if (resolver != null) { + for (ServiceContract contract : component.getServiceContracts()) { + resolver.addHostUri(contract, uri); + } + } + } + + public <S, I extends S> void registerJavaObject(URI uri, List<ServiceContract<?>> services, I instance) + throws RegistrationException { + SystemSingletonAtomicComponent<S, I> component = + new SystemSingletonAtomicComponent<S, I>(uri, services, instance); + register(component); + if (resolver != null) { + for (ServiceContract contract : component.getServiceContracts()) { + resolver.addHostUri(contract, uri); + } + } + } + + public synchronized void unregister(Component component) throws RegistrationException { + URI uri = component.getUri(); + components.remove(uri); + } + + public Component getComponent(URI name) { + return components.get(name); + } + + public void onEvent(Event event) { + throw new UnsupportedOperationException(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/InstanceFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/InstanceFactory.java new file mode 100644 index 0000000000..696db2ee2d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/InstanceFactory.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.core.component; + +import org.apache.tuscany.core.component.scope.InstanceWrapper; + +/** + * Interface for a factory that returns an injected component instance. + * This is used by a Component implementation to create new instances of + * application implementation objects as determined by the component scope's + * lifecycle. + * <p/> + * The implementation of this interface may be supplied by the user, + * may be generated during deployment, or may be dynamic. + * + * @version $Rev$ $Date$ + * @param <T> Type of the instance generated by the factory. + */ +public interface InstanceFactory<T> { + /** + * Creates a new instance of the component. + * All injected values must be set but any @Init methods must not have been invoked. + * + * @return A wrapper for the created component instance. + */ + InstanceWrapper<T> newInstance(); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ScopeIdentifier.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ScopeIdentifier.java new file mode 100644 index 0000000000..35125b85ef --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ScopeIdentifier.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.component; + +/** + * Implementations enable lazy retrieval of a scope id associated with a request, i.e. an id (and presumably a context) + * do not have to be generated if the scope is never accessed. Identifiers are associated with the current request + * thread and keyed on scope type. + * + * @version $Rev$ $Date$ + * @see org.apache.tuscany.spi.component.WorkContext + */ +public interface ScopeIdentifier { + + /** + * Returns the scope id for the request. + */ + Object getIdentifier(); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ServiceReferenceImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ServiceReferenceImpl.java new file mode 100644 index 0000000000..4d57d3efe0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/ServiceReferenceImpl.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.core.component; + +import org.osoa.sca.ServiceReference; + +import org.apache.tuscany.spi.ObjectFactory; + +/** + * Default implementation of a ServiceReference. + * + * @version $Rev$ $Date$ + * @param <B> the type of the business interface + */ +public class ServiceReferenceImpl<B> extends CallableReferenceImpl<B> implements ServiceReference<B> { + public ServiceReferenceImpl(Class<B> businessInterface, ObjectFactory<B> factory) { + super(businessInterface, factory); + } + + public Object getConversationID() { + return null; + } + + public void setConversationID(Object conversationId) throws IllegalStateException { + } + + public void setCallbackID(Object callbackID) { + } + + public Object getCallback() { + return null; + } + + public void setCallback(Object callback) { + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/SystemSingletonAtomicComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/SystemSingletonAtomicComponent.java new file mode 100644 index 0000000000..df2c88e2ea --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/SystemSingletonAtomicComponent.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.core.component; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.TargetDestructionException; +import org.apache.tuscany.spi.component.TargetInitializationException; +import org.apache.tuscany.spi.component.TargetResolutionException; +import org.apache.tuscany.spi.extension.AbstractComponentExtension; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; + +/** + * An {@link org.apache.tuscany.spi.component.AtomicComponent} used when registering objects directly into a composite + * + * @version $$Rev$$ $$Date$$ + */ +public class SystemSingletonAtomicComponent<S, T extends S> extends AbstractComponentExtension + implements AtomicComponent { + private T instance; + private List<ServiceContract> serviceContracts = new ArrayList<ServiceContract>(); + + public SystemSingletonAtomicComponent(URI name, ServiceContract<S> contract, T instance) { + super(name); + this.instance = instance; + this.serviceContracts.add(contract); + } + + public SystemSingletonAtomicComponent(URI name, List<ServiceContract<?>> services, T instance) { + super(name); + this.instance = instance; + for (ServiceContract<?> contract : services) { + serviceContracts.add(contract); + } + } + + public Scope getScope() { + return Scope.COMPOSITE; + } + + public boolean isEagerInit() { + return false; + } + + public boolean isDestroyable() { + return false; + } + + public int getInitLevel() { + return 0; + } + + public long getMaxIdleTime() { + return -1; + } + + public long getMaxAge() { + return -1; + } + + public T getTargetInstance() throws TargetResolutionException { + return instance; + } + + public void init(Object instance) throws TargetInitializationException { + + } + + public void destroy(Object instance) throws TargetDestructionException { + + } + + public Object createInstance() throws ObjectCreationException { + throw new UnsupportedOperationException(); + } + + public void removeInstance() { + throw new UnsupportedOperationException(); + } + + public boolean isOptimizable() { + return true; + } + + public void attachWire(Wire wire) { + throw new UnsupportedOperationException(); + } + + public void attachWires(List<Wire> wires) { + throw new UnsupportedOperationException(); + } + + + public List<Wire> getWires(String name) { + throw new UnsupportedOperationException(); + } + + public void attachCallbackWire(Wire wire) { + throw new UnsupportedOperationException(); + } + + public TargetInvoker createTargetInvoker(String targetName, Operation operation) { + return null; + } + + public List<ServiceContract> getServiceContracts() { + return serviceContracts; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/WorkContextImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/WorkContextImpl.java new file mode 100644 index 0000000000..e7725307ff --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/WorkContextImpl.java @@ -0,0 +1,212 @@ +/* + * 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.core.component; + +import java.net.URI; +import java.util.ArrayList; +import java.util.IdentityHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.WorkContext; + +/** + * An implementation of an {@link org.apache.tuscany.spi.component.WorkContext} that handles event-to-thread + * associations using an <code>InheritableThreadLocal</code> + * + * @version $Rev$ $Date$ + */ +public class WorkContextImpl implements WorkContext { + private static final Object REMOTE_CONTEXT = new Object(); + private static final Object CORRELATION_ID = new Object(); + private static final Object CALLBACK_URIS = new Object(); + private static final Object CURRENT_ATOMIC = new Object(); + private static final Object CURRENT_SERVICE_NAMES = new Object(); + + // [rfeng] We cannot use InheritableThreadLocal for message ids here since it's shared by parent and children + private ThreadLocal<Map<Object, Object>> workContext = new ThreadLocal<Map<Object, Object>>(); + + // [rfeng] Session id requires InheritableThreadLocal + private ThreadLocal<Map<Object, Object>> inheritableContext = new InheritableThreadLocal<Map<Object, Object>>(); + + public WorkContextImpl() { + super(); + } + + public Object getCorrelationId() { + Map<Object, Object> map = workContext.get(); + if (map == null) { + return null; + } + return map.get(CORRELATION_ID); + } + + public void setCorrelationId(Object id) { + Map<Object, Object> map = getWorkContextMap(); + map.put(CORRELATION_ID, id); + } + + public AtomicComponent getCurrentAtomicComponent() { + Map<Object, Object> map = workContext.get(); + if (map == null) { + return null; + } + return (AtomicComponent) map.get(CURRENT_ATOMIC); + } + + public void setCurrentAtomicComponent(AtomicComponent component) { + Map<Object, Object> map = getWorkContextMap(); + map.put(CURRENT_ATOMIC, component); + } + + @SuppressWarnings("unchecked") + public LinkedList<URI> getCallbackUris() { + Map<Object, Object> map = workContext.get(); + if (map == null) { + return null; + } + return (LinkedList<URI>) map.get(CALLBACK_URIS); + } + + public void setCallbackUris(LinkedList<URI> uris) { + Map<Object, Object> map = getWorkContextMap(); + map.put(CALLBACK_URIS, uris); + } + + public Component getRemoteComponent() { + Map<Object, Object> map = workContext.get(); + if (map == null) { + return null; + } + return (Component) map.get(REMOTE_CONTEXT); + } + + + public void setRemoteComponent(Component component) { + Map<Object, Object> map = getWorkContextMap(); + map.put(REMOTE_CONTEXT, component); + } + + public Object getIdentifier(Object type) { + Map<Object, Object> map = inheritableContext.get(); + if (map == null) { + return null; + } + Object currentId = map.get(type); + if (currentId instanceof ScopeIdentifier) { + currentId = ((ScopeIdentifier) currentId).getIdentifier(); + // once we have accessed the id, replace the lazy wrapper + map.put(type, currentId); + } + return currentId; + } + + public void setIdentifier(Object type, Object identifier) { + Map<Object, Object> map = inheritableContext.get(); + if (map == null) { + map = new IdentityHashMap<Object, Object>(); + inheritableContext.set(map); + } + map.put(type, identifier); + } + + public void clearIdentifier(Object type) { + if (type == null) { + return; + } + Map map = inheritableContext.get(); + if (map != null) { + map.remove(type); + } + } + + public void clearIdentifiers() { + inheritableContext.remove(); + } + + @SuppressWarnings({"unchecked"}) + public String popServiceName() { + Map<Object, Object> map = inheritableContext.get(); + if (map == null) { + return null; + } + List<String> stack = (List) map.get(CURRENT_SERVICE_NAMES); + if (stack == null || stack.size() < 1) { + return null; + } + String name = stack.remove(stack.size() - 1); + if (stack.size() == 0) { + // cleanup to avoid leaks + map.remove(CURRENT_SERVICE_NAMES); + } + return name; + } + + @SuppressWarnings({"unchecked"}) + public String getCurrentServiceName() { + Map<Object, Object> map = inheritableContext.get(); + if (map == null) { + return null; + } + List<String> stack = (List) map.get(CURRENT_SERVICE_NAMES); + if (stack == null || stack.size() < 1) { + return null; + } + return stack.get(stack.size() - 1); + } + + @SuppressWarnings({"unchecked"}) + public void pushServiceName(String name) { + Map<Object, Object> map = inheritableContext.get(); + List<String> names; + if (map == null) { + map = new IdentityHashMap<Object, Object>(); + inheritableContext.set(map); + names = new ArrayList<String>(); + map.put(CURRENT_SERVICE_NAMES, names); + } else { + names = (List<String>) map.get(CURRENT_SERVICE_NAMES); + if (names == null) { + names = new ArrayList<String>(); + map.put(CURRENT_SERVICE_NAMES, names); + } + } + names.add(name); + } + + public void clearServiceNames() { + Map<Object, Object> map = inheritableContext.get(); + if (map == null) { + return; + } + map.remove(CURRENT_SERVICE_NAMES); + } + + private Map<Object, Object> getWorkContextMap() { + Map<Object, Object> map = workContext.get(); + if (map == null) { + map = new IdentityHashMap<Object, Object>(); + workContext.set(map); + } + return map; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/AbstractEvent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/AbstractEvent.java new file mode 100644 index 0000000000..6d026ca08c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/AbstractEvent.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.component.event; + +import org.apache.tuscany.spi.event.Event; + +/** + * A basic implementation of a runtime event + * + * @version $$Rev$$ $$Date$$ + */ +public abstract class AbstractEvent implements Event { + protected Object source; + + public AbstractEvent(Object source) { + assert source != null : "Source id was null"; + this.source = source; + } + + public Object getSource() { + return source; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/AbstractRequestEvent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/AbstractRequestEvent.java new file mode 100644 index 0000000000..762b917600 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/AbstractRequestEvent.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.core.component.event; + +/** + * Base implementation of a request event + * + * @version $$Rev$$ $$Date$$ + */ +public abstract class AbstractRequestEvent extends AbstractEvent implements RequestEvent { + + /** + * Creates a new event + * + * @param source the source of the event + */ + public AbstractRequestEvent(Object source) { + super(source); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ComponentEvent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ComponentEvent.java new file mode 100644 index 0000000000..7de32a56d0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ComponentEvent.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.core.component.event; + +import java.net.URI; + +import org.apache.tuscany.spi.event.Event; + +/** + * Implemented by runtime events associated with a component, e.g. lifecycle events + * + * @version $$Rev$$ $$Date$$ + */ +public interface ComponentEvent extends Event { + + URI getComponentUri(); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ComponentStart.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ComponentStart.java new file mode 100644 index 0000000000..6be1c88d3f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ComponentStart.java @@ -0,0 +1,47 @@ +/* + * 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.core.component.event; + +import java.net.URI; + +/** + * Propagated when a component starts + * + * @version $$Rev$$ $$Date$$ + */ +public class ComponentStart extends AbstractEvent implements ComponentEvent { + + private URI uri; + + /** + * Creates a component start event + * + * @param source the source of the event + * @param componentURI the uri of the component being started + */ + public ComponentStart(Object source, URI componentURI) { + super(source); + this.uri = componentURI; + } + + public URI getComponentUri() { + return uri; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ComponentStop.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ComponentStop.java new file mode 100644 index 0000000000..ac0a7fd5c0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ComponentStop.java @@ -0,0 +1,46 @@ +/* + * 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.core.component.event; + +import java.net.URI; + +/** + * Propagated when a component stops + * + * @version $$Rev$$ $$Date$$ + */ +public class ComponentStop extends AbstractEvent implements ComponentEvent { + + private URI uri; + + /** + * Creates a component stop event + * + * @param source the source of the event + * @param componentUri the composite component associated the component being stopped + */ + public ComponentStop(Object source, URI componentUri) { + super(source); + this.uri = componentUri; + } + + public URI getComponentUri() { + return uri; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ConversationEnd.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ConversationEnd.java new file mode 100644 index 0000000000..4a51d970c3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ConversationEnd.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.core.component.event;
+
+/**
+ * Propagated when a conversation session is expired
+ *
+ * @version $$Rev: 430937 $$ $$Date: 2006-08-11 21:17:56 -0400 (Fri, 11 Aug 2006) $$
+ */
+public class ConversationEnd extends ConversationalEvent {
+
+ public ConversationEnd(Object source, Object id) {
+ super(source, id);
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ConversationStart.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ConversationStart.java new file mode 100644 index 0000000000..5725369bf6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ConversationStart.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.core.component.event;
+
+/**
+ * Propagated when a conversation session has started
+ *
+ * @version $$Rev: 430937 $$ $$Date: 2006-08-11 21:17:56 -0400 (Fri, 11 Aug 2006) $$
+ */
+public class ConversationStart extends ConversationalEvent {
+
+ public ConversationStart(Object source, Object id) {
+ super(source, id);
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ConversationalEvent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ConversationalEvent.java new file mode 100644 index 0000000000..a75086e745 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/ConversationalEvent.java @@ -0,0 +1,39 @@ +/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+/**
+ * A base implementation of conversational session events in the runtime
+ *
+ * @version $$Rev: 430937 $$ $$Date: 2006-08-11 21:17:56 -0400 (Fri, 11 Aug 2006) $$
+ */
+public class ConversationalEvent extends AbstractEvent {
+
+ private Object id;
+
+ public ConversationalEvent(Object source, Object id) {
+ super(source);
+ assert id != null : "Conversation id was null";
+ this.id = id;
+ }
+
+ public Object getId() {
+ return id;
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/HttpRequestEnded.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/HttpRequestEnded.java new file mode 100644 index 0000000000..01bd769031 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/HttpRequestEnded.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.core.component.event;
+
+/**
+ * Propagated when an HTTP-based request has ended.
+ *
+ * @version $$Rev: 430937 $$ $$Date: 2006-08-11 21:17:56 -0400 (Fri, 11 Aug 2006) $$
+ */
+public class HttpRequestEnded extends HttpSessionEvent {
+
+ /**
+ * Creates a new event
+ *
+ * @param source the source of the event
+ * @param id the id of the HTTP session being ended
+ */
+ public HttpRequestEnded(Object source, Object id) {
+ super(source, id);
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/HttpRequestStart.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/HttpRequestStart.java new file mode 100644 index 0000000000..9d0ff80dd7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/HttpRequestStart.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.core.component.event;
+
+/**
+ * Propagated when an HTTP-based request has started
+ *
+ * @version $$Rev: 430937 $$ $$Date: 2006-08-11 21:17:56 -0400 (Fri, 11 Aug 2006) $$
+ */
+public class HttpRequestStart extends HttpSessionEvent {
+
+ /**
+ * Creates a new event
+ *
+ * @param source the source of the event
+ * @param id the id of the HTTP session being ended
+ */
+ public HttpRequestStart(Object source, Object id) {
+ super(source, id);
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionEnd.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionEnd.java new file mode 100644 index 0000000000..7f2bebe94a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionEnd.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.core.component.event; + +/** + * Propagated when an HTTP-based session is expired + * + * @version $$Rev$$ $$Date$$ + */ +public class HttpSessionEnd extends HttpSessionEvent { + + /** + * Creates a new event + * + * @param source the source of the event + * @param id the id of the HTTP session being ended + */ + public HttpSessionEnd(Object source, Object id) { + super(source, id); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionEvent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionEvent.java new file mode 100644 index 0000000000..ed245d0930 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionEvent.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.core.component.event; + +/** + * A base implementation of HTTP-based session events in the runtime + * + * @version $$Rev$$ $$Date$$ + */ +public abstract class HttpSessionEvent extends AbstractEvent { + + private Object id; + + public HttpSessionEvent(Object source, Object id) { + super(source); + assert id != null : "Session id was null"; + this.id = id; + } + + + public Object getSource() { + return source; + } + + public Object getId() { + return id; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionStart.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionStart.java new file mode 100644 index 0000000000..7f9c0fadea --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionStart.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.core.component.event; + +/** + * Propagated when an HTTP-based session has started + * + * @version $$Rev$$ $$Date$$ + */ +public class HttpSessionStart extends HttpSessionEvent { + + /** + * Creates a new event + * + * @param source the source of the event + * @param id the id of the HTTP session being ended + */ + public HttpSessionStart(Object source, Object id) { + super(source, id); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/RequestEnd.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/RequestEnd.java new file mode 100644 index 0000000000..25856e86f8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/RequestEnd.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.core.component.event; + +/** + * Propagated when a request completes or is ended + * + * @version $$Rev$$ $$Date$$ + */ +public class RequestEnd extends AbstractRequestEvent { + + /** + * Creates a new event + * + * @param source the source of the event + */ + public RequestEnd(Object source) { + super(source); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/RequestEvent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/RequestEvent.java new file mode 100644 index 0000000000..9a6d767236 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/RequestEvent.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.core.component.event; + +/** + * Implemented by runtime events associated request + * + * @version $$Rev$$ $$Date$$ + */ +public interface RequestEvent { + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/RequestStart.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/RequestStart.java new file mode 100644 index 0000000000..466f52551a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/event/RequestStart.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.core.component.event; + +/** + * Propagated when a request is started in the runtime + * + * @version $$Rev$$ $$Date$$ + */ +public class RequestStart extends AbstractRequestEvent { + + /** + * Creates a new event + * + * @param source the source of the event + */ + public RequestStart(Object source) { + super(source); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/AbstractScopeContainer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/AbstractScopeContainer.java new file mode 100644 index 0000000000..7f1d507a1b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/AbstractScopeContainer.java @@ -0,0 +1,158 @@ +/* + * 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.core.component.scope; + + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.apache.tuscany.spi.AbstractLifecycle; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.PersistenceException; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.ScopeContainerMonitor; +import org.apache.tuscany.spi.component.TargetNotFoundException; +import org.apache.tuscany.spi.component.TargetResolutionException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.event.Event; +import org.apache.tuscany.spi.event.EventFilter; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.event.TrueFilter; + +/** + * Implements functionality common to scope contexts. + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractScopeContainer extends AbstractLifecycle implements ScopeContainer { + private static final EventFilter TRUE_FILTER = new TrueFilter(); + + protected WorkContext workContext; + protected ScopeContainerMonitor monitor; + private Map<EventFilter, List<RuntimeEventListener>> listeners; + + public AbstractScopeContainer(WorkContext workContext, ScopeContainerMonitor monitor) { + this.workContext = workContext; + this.monitor = monitor; + } + + public void addListener(RuntimeEventListener listener) { + addListener(TRUE_FILTER, listener); + } + + public void removeListener(RuntimeEventListener listener) { + assert listener != null; + synchronized (getListeners()) { + for (List<RuntimeEventListener> currentList : getListeners().values()) { + for (RuntimeEventListener current : currentList) { + if (current == listener) { + currentList.remove(current); + return; + } + } + } + } + } + + public void addListener(EventFilter filter, RuntimeEventListener listener) { + assert listener != null; + synchronized (getListeners()) { + List<RuntimeEventListener> list = getListeners().get(filter); + if (list == null) { + list = new CopyOnWriteArrayList<RuntimeEventListener>(); + listeners.put(filter, list); + } + list.add(listener); + } + } + + public void publish(Event event) { + assert event != null; + for (Map.Entry<EventFilter, List<RuntimeEventListener>> entry : getListeners().entrySet()) { + if (entry.getKey().match(event)) { + for (RuntimeEventListener listener : entry.getValue()) { + listener.onEvent(event); + } + } + } + } + + public Object getInstance(AtomicComponent component) throws TargetResolutionException { + InstanceWrapper ctx = getInstanceWrapper(component, true); + if (ctx != null) { + if (!ctx.isStarted()) { + ctx.start(); + } + return ctx.getInstance(); + } + return null; + } + + public Object getAssociatedInstance(AtomicComponent component) throws TargetResolutionException { + InstanceWrapper ctx = getInstanceWrapper(component, false); + if (ctx != null) { + if (!ctx.isStarted()) { + ctx.start(); + } + return ctx.getInstance(); + } + throw new TargetNotFoundException(component.getUri().toString()); + } + + public void persistNew(AtomicComponent component, String id, Object instance, long expiration) + throws PersistenceException { + throw new UnsupportedOperationException("Scope does not support persistence"); + + } + + public void persist(AtomicComponent component, String id, Object instance, long expiration) + throws PersistenceException { + throw new UnsupportedOperationException("Scope does not support persistence"); + } + + public void remove(AtomicComponent component) throws PersistenceException { + throw new UnsupportedOperationException("Scope does not support persistence"); + } + + protected Map<EventFilter, List<RuntimeEventListener>> getListeners() { + if (listeners == null) { + listeners = new ConcurrentHashMap<EventFilter, List<RuntimeEventListener>>(); + } + return listeners; + } + + protected void checkInit() { + if (getLifecycleState() != RUNNING) { + throw new IllegalStateException("Scope container not running [" + getLifecycleState() + "]"); + } + } + + protected WorkContext getWorkContext() { + return workContext; + } + + public String toString() { + return "In state [" + super.toString() + ']'; + } + + protected abstract InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create) + throws TargetResolutionException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeContainer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeContainer.java new file mode 100644 index 0000000000..623704fbee --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeContainer.java @@ -0,0 +1,184 @@ +/* + * 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.core.component.scope; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainerMonitor; +import org.apache.tuscany.spi.component.TargetDestructionException; +import org.apache.tuscany.spi.component.TargetInitializationException; +import org.apache.tuscany.spi.component.TargetResolutionException; +import org.apache.tuscany.spi.event.Event; +import org.apache.tuscany.spi.model.Scope; + +import org.apache.tuscany.core.component.event.ComponentStart; +import org.apache.tuscany.core.component.event.ComponentStop; + +/** + * A scope context which manages atomic component instances keyed by composite + * + * @version $Rev$ $Date$ + */ +public class CompositeScopeContainer extends AbstractScopeContainer { + private static final InstanceWrapper EMPTY = new EmptyWrapper(); + private static final ComponentInitComparator COMPARATOR = new ComponentInitComparator(); + + private final Map<AtomicComponent, InstanceWrapper> instanceWrappers; + // the queue of instanceWrappers to destroy, in the order that their instances were created + private final List<InstanceWrapper> destroyQueue; + + public CompositeScopeContainer(ScopeContainerMonitor monitor) { + super(null, monitor); + instanceWrappers = new ConcurrentHashMap<AtomicComponent, InstanceWrapper>(); + destroyQueue = new ArrayList<InstanceWrapper>(); + } + + public Scope getScope() { + return Scope.COMPOSITE; + } + + public void onEvent(Event event) { + checkInit(); + if (event instanceof ComponentStart) { + try { + eagerInitComponents(); + } catch (ObjectCreationException e) { + monitor.eagerInitializationError(e); + } catch (TargetResolutionException e) { + monitor.eagerInitializationError(e); + } + lifecycleState = RUNNING; + } else if (event instanceof ComponentStop) { + shutdownContexts(); + } + } + + public synchronized void start() { + if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) { + throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]"); + } + lifecycleState = RUNNING; + } + + public synchronized void stop() { + checkInit(); + instanceWrappers.clear(); + synchronized (destroyQueue) { + destroyQueue.clear(); + } + lifecycleState = STOPPED; + } + + /** + * Notifies instanceWrappers of a shutdown in reverse order to which they were started + */ + private void shutdownContexts() { + if (destroyQueue.size() == 0) { + return; + } + synchronized (destroyQueue) { + // shutdown destroyable instances in reverse instantiation order + ListIterator<InstanceWrapper> iter = destroyQueue.listIterator(destroyQueue.size()); + while (iter.hasPrevious()) { + try { + iter.previous().stop(); + } catch (TargetDestructionException e) { + monitor.destructionError(e); + } + } + destroyQueue.clear(); + } + } + + public void register(AtomicComponent component) { + checkInit(); + instanceWrappers.put(component, EMPTY); + } + + protected InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create) + throws TargetResolutionException { + checkInit(); + InstanceWrapper ctx = instanceWrappers.get(component); + assert ctx != null; + if (ctx == EMPTY && !create) { + return null; + } + if (ctx == EMPTY) { + ctx = new InstanceWrapperImpl(component, component.createInstance()); + ctx.start(); + instanceWrappers.put(component, ctx); + synchronized (destroyQueue) { + destroyQueue.add(ctx); + } + } + return ctx; + } + + private void eagerInitComponents() throws ObjectCreationException, TargetResolutionException { + List<AtomicComponent> componentList = new ArrayList<AtomicComponent>(instanceWrappers.keySet()); + Collections.sort(componentList, COMPARATOR); + // start each group + for (AtomicComponent component : componentList) { + if (component.getInitLevel() <= 0) { + // Don't eagerly init + continue; + } + // the instance could have been created from a depth-first traversal + InstanceWrapper ctx = instanceWrappers.get(component); + if (ctx == EMPTY) { + ctx = new InstanceWrapperImpl(component, component.createInstance()); + ctx.start(); + instanceWrappers.put(component, ctx); + destroyQueue.add(ctx); + } + } + } + + private static class ComponentInitComparator implements Comparator<AtomicComponent> { + public int compare(AtomicComponent o1, AtomicComponent o2) { + return o1.getInitLevel() - o2.getInitLevel(); + } + } + + private static class EmptyWrapper implements InstanceWrapper { + public Object getInstance() { + return null; + } + + public boolean isStarted() { + return true; + } + + public void start() throws TargetInitializationException { + + } + + public void stop() throws TargetDestructionException { + + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactory.java new file mode 100644 index 0000000000..fc89bbc609 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactory.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.core.component.scope; + +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.component.ScopeContainerMonitor; +import org.apache.tuscany.spi.component.ScopeRegistry; +import org.apache.tuscany.spi.model.Scope; + +import org.apache.tuscany.api.annotation.Monitor; + +/** + * Creates a new composite scope context + * + * @version $$Rev$$ $$Date$$ + */ +@EagerInit +public class CompositeScopeObjectFactory implements ObjectFactory<CompositeScopeContainer> { + private ScopeContainerMonitor monitor; + + public CompositeScopeObjectFactory(@Reference ScopeRegistry registry, + @Monitor ScopeContainerMonitor monitor) { + registry.registerFactory(Scope.COMPOSITE, this); + this.monitor = monitor; + } + + public CompositeScopeContainer getInstance() throws ObjectCreationException { + return new CompositeScopeContainer(monitor); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainer.java new file mode 100644 index 0000000000..eb4a06602f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainer.java @@ -0,0 +1,217 @@ +/*
+ * 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.core.component.scope;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.PersistenceException;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.component.TargetNotFoundException;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.services.store.Store;
+import org.apache.tuscany.spi.services.store.StoreExpirationEvent;
+import org.apache.tuscany.spi.services.store.StoreReadException;
+import org.apache.tuscany.spi.services.store.StoreWriteException;
+
+/**
+ * A scope context which manages atomic component instances keyed on a conversation session
+ *
+ * @version $Rev: 452655 $ $Date: 2006-10-03 18:09:02 -0400 (Tue, 03 Oct 2006) $
+ */
+public class ConversationalScopeContainer extends AbstractScopeContainer implements ScopeContainer {
+ private Store nonDurableStore;
+ private Map<AtomicComponent, AtomicComponent> components;
+
+ public ConversationalScopeContainer(Store store, WorkContext workContext, final ScopeContainerMonitor monitor) {
+ super(workContext, monitor);
+ this.nonDurableStore = store;
+ if (store != null) {
+ store.addListener(new ExpirationListener(monitor));
+ }
+ components = new ConcurrentHashMap<AtomicComponent, AtomicComponent>();
+ }
+
+ public Scope getScope() {
+ return Scope.CONVERSATION;
+ }
+
+ public void onEvent(Event event) {
+ checkInit();
+ }
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
+ }
+ lifecycleState = RUNNING;
+ }
+
+ public synchronized void stop() {
+ lifecycleState = STOPPED;
+ }
+
+ public void register(AtomicComponent component) {
+ components.put(component, component);
+ component.addListener(this);
+ }
+
+ @Override
+ public Object getInstance(AtomicComponent component) throws TargetResolutionException {
+ String conversationId = getConversationId();
+ try {
+ workContext.setCurrentAtomicComponent(component);
+ Object instance = nonDurableStore.readRecord(component, conversationId);
+ if (instance != null) {
+ if (component.getMaxIdleTime() > 0) {
+ // update expiration
+ long expire = System.currentTimeMillis() + component.getMaxIdleTime();
+ nonDurableStore.updateRecord(component, conversationId, instance, expire);
+ }
+ } else {
+ instance = component.createInstance();
+ long expire = calculateExpiration(component);
+ nonDurableStore.insertRecord(component, conversationId, instance, expire);
+ component.init(instance);
+ }
+ return instance;
+ } catch (StoreReadException e) {
+ throw new TargetResolutionException("Error retrieving target instance", e);
+ } catch (StoreWriteException e) {
+ throw new TargetResolutionException("Error persisting target instance", e);
+ } finally {
+ workContext.setCurrentAtomicComponent(null);
+ }
+ }
+
+ public Object getAssociatedInstance(AtomicComponent component) throws TargetResolutionException {
+ String conversationId = getConversationId();
+ try {
+ workContext.setCurrentAtomicComponent(component);
+ Object instance = nonDurableStore.readRecord(component, conversationId);
+ if (instance != null) {
+ if (component.getMaxIdleTime() > 0) {
+ // update expiration
+ long expire = System.currentTimeMillis() + component.getMaxIdleTime();
+ nonDurableStore.updateRecord(component, conversationId, instance, expire);
+ }
+ return instance;
+ } else {
+ throw new TargetNotFoundException(component.getUri().toString());
+ }
+ } catch (StoreReadException e) {
+ throw new TargetResolutionException("Error retrieving target instance", e);
+ } catch (StoreWriteException e) {
+ throw new TargetResolutionException("Error persisting target instance", e);
+ } finally {
+ workContext.setCurrentAtomicComponent(null);
+ }
+ }
+
+ public void persistNew(AtomicComponent component, String id, Object instance, long expiration)
+ throws PersistenceException {
+ try {
+ nonDurableStore.insertRecord(component, id, instance, expiration);
+ } catch (StoreWriteException e) {
+ throw new PersistenceException(e);
+ }
+ }
+
+ public void persist(AtomicComponent component, String id, Object instance, long expiration)
+ throws PersistenceException {
+ try {
+ nonDurableStore.updateRecord(component, id, instance, expiration);
+ } catch (StoreWriteException e) {
+ throw new PersistenceException(e);
+ }
+ }
+
+ public void remove(AtomicComponent component) throws PersistenceException {
+ String conversationId = getConversationId();
+ try {
+ workContext.setCurrentAtomicComponent(component);
+ Object instance = nonDurableStore.readRecord(component, conversationId);
+ if (instance != null) {
+ nonDurableStore.removeRecord(component, conversationId);
+ }
+ } catch (StoreReadException e) {
+ throw new PersistenceException(e);
+ } catch (StoreWriteException e) {
+ throw new PersistenceException(e);
+ }
+ }
+
+ protected InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the conversation id associated with the current invocation context
+ */
+ private String getConversationId() {
+ String conversationId = (String) workContext.getIdentifier(Scope.CONVERSATION);
+ assert conversationId != null;
+ return conversationId;
+ }
+
+ private long calculateExpiration(AtomicComponent component) {
+ if (component.getMaxAge() > 0) {
+ long now = System.currentTimeMillis();
+ return now + component.getMaxAge();
+ } else if (component.getMaxIdleTime() > 0) {
+ long now = System.currentTimeMillis();
+ return now + component.getMaxIdleTime();
+ } else {
+ return Store.DEFAULT_EXPIRATION_OFFSET;
+ }
+ }
+
+ /**
+ * Receives expiration events from the store and notifies the corresponding atomic component
+ */
+ private static class ExpirationListener implements RuntimeEventListener {
+ private final ScopeContainerMonitor monitor;
+
+ public ExpirationListener(ScopeContainerMonitor monitor) {
+ this.monitor = monitor;
+ }
+
+ public void onEvent(Event event) {
+ if (event instanceof StoreExpirationEvent) {
+ StoreExpirationEvent expiration = (StoreExpirationEvent) event;
+ SCAObject object = expiration.getOwner();
+ assert object instanceof AtomicComponent;
+ AtomicComponent owner = (AtomicComponent) object;
+ try {
+ owner.destroy(expiration.getInstance());
+ } catch (TargetDestructionException e) {
+ monitor.destructionError(e);
+ }
+ }
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeObjectFactory.java new file mode 100644 index 0000000000..30a4487215 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeObjectFactory.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.core.component.scope;
+
+import org.osoa.sca.annotations.EagerInit;
+import org.osoa.sca.annotations.Reference;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.services.store.Store;
+
+import org.apache.tuscany.api.annotation.Monitor;
+
+/**
+ * Creates a new Session Scope context
+ *
+ * @version $$Rev: 450456 $$ $$Date: 2006-09-27 10:28:36 -0400 (Wed, 27 Sep 2006) $$
+ */
+@EagerInit
+public class ConversationalScopeObjectFactory implements ObjectFactory<ConversationalScopeContainer> {
+ private WorkContext context;
+ private Store store;
+ private ScopeContainerMonitor monitor;
+
+ public ConversationalScopeObjectFactory(@Reference ScopeRegistry registry,
+ @Reference WorkContext context,
+ @Reference Store store,
+ @Monitor ScopeContainerMonitor monitor) {
+ registry.registerFactory(Scope.CONVERSATION, this);
+ this.context = context;
+ this.store = store;
+ this.monitor = monitor;
+ }
+
+ public ConversationalScopeContainer getInstance() throws ObjectCreationException {
+ return new ConversationalScopeContainer(store, context, monitor);
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeContainer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeContainer.java new file mode 100644 index 0000000000..83c79b2367 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeContainer.java @@ -0,0 +1,135 @@ +/* + * 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.core.component.scope; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainerMonitor; +import org.apache.tuscany.spi.component.TargetDestructionException; +import org.apache.tuscany.spi.component.TargetResolutionException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.event.Event; +import org.apache.tuscany.spi.model.Scope; + +import org.apache.tuscany.core.component.event.HttpSessionEnd; + +/** + * A scope context which manages atomic component instances keyed on HTTP session + * + * @version $Rev$ $Date$ + */ +public class HttpSessionScopeContainer extends AbstractScopeContainer { + private final Map<AtomicComponent, Map<Object, InstanceWrapper>> contexts; + private final Map<Object, List<InstanceWrapper>> destroyQueues; + + public HttpSessionScopeContainer(WorkContext workContext, ScopeContainerMonitor monitor) { + super(workContext, monitor); + contexts = new ConcurrentHashMap<AtomicComponent, Map<Object, InstanceWrapper>>(); + destroyQueues = new ConcurrentHashMap<Object, List<InstanceWrapper>>(); + } + + public Scope getScope() { + return Scope.SESSION; + } + + public void onEvent(Event event) { + checkInit(); + if (event instanceof HttpSessionEnd) { + Object key = ((HttpSessionEnd) event).getId(); + shutdownInstances(key); + workContext.clearIdentifier(key); + } + } + + public synchronized void start() { + if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) { + throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]"); + } + lifecycleState = RUNNING; + } + + public synchronized void stop() { + contexts.clear(); + synchronized (destroyQueues) { + destroyQueues.clear(); + } + lifecycleState = STOPPED; + } + + public void register(AtomicComponent component) { + contexts.put(component, new ConcurrentHashMap<Object, InstanceWrapper>()); + component.addListener(this); + } + + protected InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create) + throws TargetResolutionException { + Object key = workContext.getIdentifier(Scope.SESSION); + assert key != null : "HTTP session key not bound in work context"; + return getInstance(component, key, create); + } + + private InstanceWrapper getInstance(AtomicComponent component, Object key, boolean create) + throws TargetResolutionException { + Map<Object, InstanceWrapper> wrappers = contexts.get(component); + InstanceWrapper ctx = wrappers.get(key); + if (ctx == null && !create) { + return null; + } + if (ctx == null) { + ctx = new InstanceWrapperImpl(component, component.createInstance()); + ctx.start(); + wrappers.put(key, ctx); + List<InstanceWrapper> destroyQueue = destroyQueues.get(key); + if (destroyQueue == null) { + destroyQueue = new ArrayList<InstanceWrapper>(); + destroyQueues.put(key, destroyQueue); + } + synchronized (destroyQueue) { + destroyQueue.add(ctx); + } + } + return ctx; + + } + + private void shutdownInstances(Object key) { + List<InstanceWrapper> destroyQueue = destroyQueues.remove(key); + if (destroyQueue != null) { + for (Map<Object, InstanceWrapper> map : contexts.values()) { + map.remove(key); + } + ListIterator<InstanceWrapper> iter = destroyQueue.listIterator(destroyQueue.size()); + synchronized (destroyQueue) { + while (iter.hasPrevious()) { + try { + iter.previous().stop(); + } catch (TargetDestructionException e) { + monitor.destructionError(e); + } + } + } + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeObjectFactory.java new file mode 100644 index 0000000000..5fae335e6b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeObjectFactory.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.core.component.scope; + +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.component.ScopeContainerMonitor; +import org.apache.tuscany.spi.component.ScopeRegistry; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.Scope; + +import org.apache.tuscany.api.annotation.Monitor; + +/** + * Creates a new HTTP session scope context + * + * @version $$Rev$$ $$Date$$ + */ +@EagerInit +public class HttpSessionScopeObjectFactory implements ObjectFactory<HttpSessionScopeContainer> { + private WorkContext context; + private ScopeContainerMonitor monitor; + + public HttpSessionScopeObjectFactory(@Reference ScopeRegistry registry, + @Reference WorkContext context, + @Monitor ScopeContainerMonitor monitor) { + registry.registerFactory(Scope.SESSION, this); + this.context = context; + this.monitor = monitor; + } + + public HttpSessionScopeContainer getInstance() throws ObjectCreationException { + return new HttpSessionScopeContainer(context, monitor); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapper.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapper.java new file mode 100644 index 0000000000..121a6d3b70 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapper.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.core.component.scope; + +import org.apache.tuscany.spi.component.TargetDestructionException; +import org.apache.tuscany.spi.component.TargetInitializationException; + +/** + * Provides lifecycle management for an implementation instance associated with an {@link + * org.apache.tuscany.spi.component.AtomicComponent} for use by the atomic component's associated {@link + * org.apache.tuscany.spi.component.ScopeContainer} + * + * @version $Rev$ $Date$ + */ +public interface InstanceWrapper<T> { + + T getInstance(); + + boolean isStarted(); + + void start() throws TargetInitializationException; + + void stop() throws TargetDestructionException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperBase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperBase.java new file mode 100644 index 0000000000..e52b20fe84 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperBase.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.core.component.scope; + +import org.apache.tuscany.spi.component.TargetDestructionException; +import org.apache.tuscany.spi.component.TargetInitializationException; + +/** + * @version $Rev$ $Date$ + */ +public class InstanceWrapperBase<T> implements InstanceWrapper<T> { + protected final T instance; + private boolean started; + + public InstanceWrapperBase(T instance) { + assert instance != null; + this.instance = instance; + } + + public T getInstance() { + assert started; + return instance; + } + + public boolean isStarted() { + return started; + } + + public void start() throws TargetInitializationException { + started = true; + } + + public void stop() throws TargetDestructionException { + started = false; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperImpl.java new file mode 100644 index 0000000000..200f9a6e6d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperImpl.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.core.component.scope; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.TargetDestructionException; +import org.apache.tuscany.spi.component.TargetInitializationException; + +/** + * Default implementation of an <code>InstanceWrapper</code> + * + * @version $$Rev$$ $$Date$$ + */ +public class InstanceWrapperImpl extends InstanceWrapperBase<Object> { + private AtomicComponent component; + + public InstanceWrapperImpl(AtomicComponent component, Object instance) { + super(instance); + assert component != null; + this.component = component; + } + + public void start() throws TargetInitializationException { + component.init(instance); + super.start(); + } + + public void stop() throws TargetDestructionException { + super.stop(); + component.destroy(instance); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeContainer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeContainer.java new file mode 100644 index 0000000000..22beaae740 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeContainer.java @@ -0,0 +1,126 @@ +/* + * 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.core.component.scope; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainerMonitor; +import org.apache.tuscany.spi.component.TargetDestructionException; +import org.apache.tuscany.spi.component.TargetResolutionException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.event.Event; +import org.apache.tuscany.spi.model.Scope; + +import org.apache.tuscany.core.component.event.RequestEnd; + +/** + * A scope context which manages atomic component instances keyed on the current request context + * + * @version $Rev$ $Date$ + */ +public class RequestScopeContainer extends AbstractScopeContainer { + private final Map<AtomicComponent, Map<Thread, InstanceWrapper>> contexts; + private final Map<Thread, List<InstanceWrapper>> destroyQueues; + + public RequestScopeContainer(WorkContext workContext, ScopeContainerMonitor monitor) { + super(workContext, monitor); + contexts = new ConcurrentHashMap<AtomicComponent, Map<Thread, InstanceWrapper>>(); + destroyQueues = new ConcurrentHashMap<Thread, List<InstanceWrapper>>(); + } + + public Scope getScope() { + return Scope.REQUEST; + } + + public void onEvent(Event event) { + checkInit(); + if (event instanceof RequestEnd) { + shutdownInstances(Thread.currentThread()); + } + } + + public synchronized void start() { + if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) { + throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]"); + } + lifecycleState = RUNNING; + } + + public synchronized void stop() { + contexts.clear(); + synchronized (destroyQueues) { + destroyQueues.clear(); + } + lifecycleState = STOPPED; + } + + public void register(AtomicComponent component) { + contexts.put(component, new ConcurrentHashMap<Thread, InstanceWrapper>()); + } + + protected InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create) + throws TargetResolutionException { + Map<Thread, InstanceWrapper> instanceContextMap = contexts.get(component); + assert instanceContextMap != null : "Atomic component not registered"; + InstanceWrapper ctx = instanceContextMap.get(Thread.currentThread()); + if (ctx == null && !create) { + return null; + } + if (ctx == null) { + ctx = new InstanceWrapperImpl(component, component.createInstance()); + ctx.start(); + instanceContextMap.put(Thread.currentThread(), ctx); + List<InstanceWrapper> destroyQueue = destroyQueues.get(Thread.currentThread()); + if (destroyQueue == null) { + destroyQueue = new ArrayList<InstanceWrapper>(); + destroyQueues.put(Thread.currentThread(), destroyQueue); + } + synchronized (destroyQueue) { + destroyQueue.add(ctx); + } + } + return ctx; + } + + private void shutdownInstances(Thread key) { + List<InstanceWrapper> destroyQueue = destroyQueues.remove(key); + if (destroyQueue != null && destroyQueue.size() > 0) { + Thread thread = Thread.currentThread(); + for (Map<Thread, InstanceWrapper> map : contexts.values()) { + map.remove(thread); + } + ListIterator<InstanceWrapper> iter = destroyQueue.listIterator(destroyQueue.size()); + synchronized (destroyQueue) { + while (iter.hasPrevious()) { + try { + iter.previous().stop(); + } catch (TargetDestructionException e) { + monitor.destructionError(e); + } + } + } + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeObjectFactory.java new file mode 100644 index 0000000000..7ad2603eeb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeObjectFactory.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.core.component.scope; + +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.component.ScopeContainerMonitor; +import org.apache.tuscany.spi.component.WorkContext; + +import org.apache.tuscany.api.annotation.Monitor; + +/** + * Creates a new request scope context + * + * @version $$Rev$$ $$Date$$ + */ +public class RequestScopeObjectFactory implements ObjectFactory<RequestScopeContainer> { + private WorkContext context; + private ScopeContainerMonitor monitor; + + + public RequestScopeObjectFactory(@Reference WorkContext context, @Monitor ScopeContainerMonitor monitor) { + this.context = context; + this.monitor = monitor; + } + + public RequestScopeContainer getInstance() throws ObjectCreationException { + return new RequestScopeContainer(context, monitor); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ScopeRegistryImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ScopeRegistryImpl.java new file mode 100644 index 0000000000..da338dd0ef --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/ScopeRegistryImpl.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.core.component.scope; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.ScopeRegistry; +import org.apache.tuscany.spi.model.Scope; + +/** + * The default implementation of a scope registry + * + * @version $Rev$ $Date$ + */ +public class ScopeRegistryImpl implements ScopeRegistry { + private final Map<Scope, ScopeContainer> scopeCache = + new ConcurrentHashMap<Scope, ScopeContainer>(); + private final Map<Scope, ObjectFactory<? extends ScopeContainer>> factoryCache = + new ConcurrentHashMap<Scope, ObjectFactory<? extends ScopeContainer>>(); + + public ScopeContainer getScopeContainer(Scope scope) { + assert Scope.COMPOSITE != scope; + ScopeContainer container = scopeCache.get(scope); + if (container == null) { + ObjectFactory<? extends ScopeContainer> factory = factoryCache.get(scope); + if (factory != null) { + container = factory.getInstance(); + container.start(); + scopeCache.put(scope, container); + } + } + return container; + } + + public <T extends ScopeContainer> void registerFactory(Scope scope, ObjectFactory<T> factory) { + factoryCache.put(scope, factory); + } + + public void deregisterFactory(Scope scope) { + factoryCache.remove(scope); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeContainer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeContainer.java new file mode 100644 index 0000000000..cbd47b6cdd --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeContainer.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.core.component.scope; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainerMonitor; +import org.apache.tuscany.spi.component.TargetResolutionException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.event.Event; +import org.apache.tuscany.spi.model.Scope; + +/** + * A scope context which manages stateless atomic component instances in a non-pooled fashion + * + * @version $Rev$ $Date$ + */ +public class StatelessScopeContainer extends AbstractScopeContainer { + + public StatelessScopeContainer(WorkContext workContext, ScopeContainerMonitor monitor) { + super(workContext, monitor); + } + + public Scope getScope() { + return Scope.STATELESS; + } + + public synchronized void start() { + if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) { + throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]"); + } + lifecycleState = RUNNING; + } + + public synchronized void stop() { + if (lifecycleState != RUNNING) { + throw new IllegalStateException("Scope in wrong state [" + lifecycleState + "]"); + } + lifecycleState = STOPPED; + } + + public void onEvent(Event event) { + } + + public void register(AtomicComponent component) { + checkInit(); + } + + protected InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create) + throws TargetResolutionException { + // there never is a previously associated instance, return null + if (!create) { + return null; + } + InstanceWrapper ctx = new InstanceWrapperImpl(component, component.createInstance()); + ctx.start(); + return ctx; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactory.java new file mode 100644 index 0000000000..1522f6c528 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactory.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.core.component.scope; + +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.component.ScopeContainerMonitor; +import org.apache.tuscany.spi.component.ScopeRegistry; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.Scope; + +import org.apache.tuscany.api.annotation.Monitor; + +/** + * Creates a new stateless scope context + * + * @version $$Rev$$ $$Date$$ + */ +@EagerInit +public class StatelessScopeObjectFactory implements ObjectFactory<StatelessScopeContainer> { + private WorkContext context; + private ScopeContainerMonitor monitor; + + public StatelessScopeObjectFactory(@Reference ScopeRegistry registry, + @Reference WorkContext context, + @Monitor ScopeContainerMonitor monitor) { + registry.registerFactory(Scope.STATELESS, this); + this.context = context; + this.monitor = monitor; + } + + public StatelessScopeContainer getInstance() throws ObjectCreationException { + return new StatelessScopeContainer(context, monitor); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingInteceptor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingInteceptor.java new file mode 100644 index 0000000000..7eef28f786 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingInteceptor.java @@ -0,0 +1,125 @@ +/* + * 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.core.databinding.impl; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.spi.databinding.Mediator; +import org.apache.tuscany.spi.model.DataType; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.Wire; + +/** + * An interceptor to transform data accross databindings on the wire + * + * @version $Rev$ $Date$ + */ +public class DataBindingInteceptor implements Interceptor { + private Interceptor next; + + private Operation<?> sourceOperation; + + private Operation<?> targetOperation; + + private Mediator mediator; + + public DataBindingInteceptor(Wire sourceWire, Operation<?> sourceOperation, Operation<?> targetOperation) { + super(); + // this.sourceWire = sourceWire; + this.sourceOperation = sourceOperation; + // this.targetWire = targetWire; + this.targetOperation = targetOperation; + } + + /** + * @see org.apache.tuscany.spi.wire.Interceptor#getNext() + */ + public Interceptor getNext() { + return next; + } + + /** + * @see org.apache.tuscany.spi.wire.Interceptor#invoke(org.apache.tuscany.spi.wire.Message) + */ + public Message invoke(Message msg) { + Object input = transform(msg.getBody(), sourceOperation.getInputType(), targetOperation.getInputType()); + msg.setBody(input); + Message resultMsg = next.invoke(msg); + Object result = resultMsg.getBody(); + // FIXME: How to deal with faults? + if (resultMsg.isFault()) { + // We need to figure out what fault type it is and then transform it back the source fault type + // throw new InvocationRuntimeException((Throwable) result); + return resultMsg; + } else { + if (sourceOperation.isNonBlocking()) { + // Not to reset the message body + return resultMsg; + } + // FIXME: Should we fix the Operation model so that getOutputType returns DataType<DataType<T>>? + DataType<DataType> targetType = + new DataType<DataType>("idl:output", Object.class, targetOperation.getOutputType()); + + targetType.setOperation(targetOperation.getOutputType().getOperation()); + DataType<DataType> sourceType = + new DataType<DataType>("idl:output", Object.class, sourceOperation.getOutputType()); + sourceType.setOperation(sourceOperation.getOutputType().getOperation()); + + Object newResult = transform(result, targetType, sourceType); + if (newResult != result) { + resultMsg.setBody(newResult); + } + } + return resultMsg; + } + + private Object transform(Object source, DataType sourceType, DataType targetType) { + if (sourceType == targetType || (sourceType != null && sourceType.equals(targetType))) { + return source; + } + Map<Class<?>, Object> metadata = new HashMap<Class<?>, Object>(); + return mediator.mediate(source, sourceType, targetType, metadata); + } + + /** + * @see org.apache.tuscany.spi.wire.Interceptor#isOptimizable() + */ + public boolean isOptimizable() { + return false; + } + + /** + * @see org.apache.tuscany.spi.wire.Interceptor#setNext(org.apache.tuscany.spi.wire.Interceptor) + */ + public void setNext(Interceptor next) { + this.next = next; + } + + /** + * @param mediator the mediator to set + */ + public void setMediator(Mediator mediator) { + this.mediator = mediator; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingJavaInterfaceProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingJavaInterfaceProcessor.java new file mode 100644 index 0000000000..0da1ff90c1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingJavaInterfaceProcessor.java @@ -0,0 +1,121 @@ +/* + * 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.core.databinding.impl; + +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import javax.xml.datatype.Duration; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorExtension; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.model.Operation; + +import org.apache.tuscany.api.annotation.DataContext; +import org.apache.tuscany.api.annotation.DataType; + +/** + * The databinding annotation processor for java interfaces + * + * @version $Rev$ $Date$ + */ +public class DataBindingJavaInterfaceProcessor extends JavaInterfaceProcessorExtension { + + private static final String SIMPLE_JAVA_OBJECTS = "java.lang.Object"; + + private static final Class[] SIMPLE_JAVA_TYPES = + {Byte.class, Character.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Date.class, + Calendar.class, GregorianCalendar.class, Duration.class, XMLGregorianCalendar.class, BigInteger.class, + BigDecimal.class}; + + private static final Set<Class> SIMPLE_TYPE_SET = new HashSet<Class>(Arrays.asList(SIMPLE_JAVA_TYPES)); + + public void visitInterface(Class<?> clazz, Class<?> callbackClass, JavaServiceContract contract) + throws InvalidServiceContractException { + Map<String, Operation<Type>> operations = contract.getOperations(); + processInterface(clazz, contract, operations); + if (callbackClass != null) { + Map<String, Operation<Type>> callbackOperations = contract.getCallbackOperations(); + processInterface(callbackClass, contract, callbackOperations); + } + } + + private void processInterface(Class<?> clazz, + JavaServiceContract contract, + Map<String, Operation<Type>> operations) { + DataType interfaceDataType = clazz.getAnnotation(DataType.class); + if (interfaceDataType != null) { + contract.setDataBinding(interfaceDataType.name()); + // FIXME: [rfeng] Keep data context as metadata? + for (DataContext c : interfaceDataType.context()) { + contract.setMetaData(c.key(), c.value()); + } + } + for (Method method : clazz.getMethods()) { + Operation<?> operation = operations.get(method.getName()); + DataType operationDataType = method.getAnnotation(DataType.class); + + if (operationDataType != null) { + operation.setDataBinding(operationDataType.name()); + // FIXME: [rfeng] Keep data context as metadata? + for (DataContext c : operationDataType.context()) { + operation.setMetaData(c.key(), c.value()); + } + } + + String dataBinding = operation.getDataBinding(); + + // FIXME: We need a better way to identify simple java types + for (org.apache.tuscany.spi.model.DataType<?> d : operation.getInputType().getLogical()) { + adjustSimpleType(d, dataBinding); + } + if (operation.getOutputType() != null) { + adjustSimpleType(operation.getOutputType(), dataBinding); + } + for (org.apache.tuscany.spi.model.DataType<?> d : operation.getFaultTypes()) { + adjustSimpleType(d, dataBinding); + } + } + } + + private void adjustSimpleType(org.apache.tuscany.spi.model.DataType<?> dataType, String dataBinding) { + Type type = dataType.getPhysical(); + if (!(type instanceof Class)) { + return; + } + Class cls = (Class) dataType.getPhysical(); + if (cls.isPrimitive() || SIMPLE_TYPE_SET.contains(cls)) { + dataType.setDataBinding(SIMPLE_JAVA_OBJECTS); + } else if (cls == String.class && (dataBinding == null || !dataBinding.equals(String.class.getName()))) { + // Identify the String as a simple type + dataType.setDataBinding(SIMPLE_JAVA_OBJECTS); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingRegistryImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingRegistryImpl.java new file mode 100644 index 0000000000..3880d0ed12 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingRegistryImpl.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.core.databinding.impl; + +import java.util.HashMap; +import java.util.Map; + +import org.osoa.sca.annotations.EagerInit; + +import org.apache.tuscany.core.databinding.javabeans.JavaBeansDataBinding; +import org.apache.tuscany.spi.databinding.DataBinding; +import org.apache.tuscany.spi.databinding.DataBindingRegistry; +import org.apache.tuscany.spi.model.DataType; + +/** + * The default implementation of a data binding registry + * + * @version $Rev$ $Date$ + */ +@EagerInit +public class DataBindingRegistryImpl implements DataBindingRegistry { + private final Map<String, DataBinding> bindings = new HashMap<String, DataBinding>(); + + public DataBinding getDataBinding(String id) { + if (id == null) { + return null; + } + return bindings.get(id.toLowerCase()); + } + + public void register(DataBinding dataBinding) { + bindings.put(dataBinding.getName().toLowerCase(), dataBinding); + } + + public DataBinding unregister(String id) { + if (id == null) { + return null; + } + return bindings.remove(id.toLowerCase()); + } + + public DataType introspectType(Class<?> javaType) { + DataType dataType = null; + for (DataBinding binding : bindings.values()) { + //don't introspect for JavaBeansDatabinding as all javatypes will anyways match to its basetype + //which is java.lang.Object. Default to this only if no databinding results + if (!binding.getName().equals(JavaBeansDataBinding.NAME)) { + dataType = binding.introspect(javaType); + } + + if (dataType != null) { + return dataType; + } + } + return new DataType<Class>(JavaBeansDataBinding.NAME, Object.class, javaType); + } + + public DataType introspectType(Object value) { + DataType dataType = null; + for (DataBinding binding : bindings.values()) { + //don't introspect for JavaBeansDatabinding as all javatypes will anyways match to its basetype + //which is java.lang.Object. Default to this only if no databinding results + if (!binding.getName().equals(JavaBeansDataBinding.NAME)) { + dataType = binding.introspect(value); + } + if (dataType != null) { + return dataType; + } + } + return new DataType<Class>(JavaBeansDataBinding.NAME, Object.class, value.getClass()); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessor.java new file mode 100644 index 0000000000..8bd1b810d4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessor.java @@ -0,0 +1,121 @@ +/* + * 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.core.databinding.impl; + +import java.util.Collection; +import java.util.Map; + +import org.osoa.sca.annotations.Constructor; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.databinding.Mediator; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; +import org.apache.tuscany.spi.wire.WirePostProcessorExtension; + +/** + * This processor is responsible to add an interceptor to invocation chain if the source and target operations have + * different databinding requirements + * + * @version $Rev$ $Date$ + */ +public class DataBindingWirePostProcessor extends WirePostProcessorExtension { + private Mediator mediator; + + @Constructor({"mediator"}) + public DataBindingWirePostProcessor(@Reference Mediator mediator) { + super(); + this.mediator = mediator; + } + + public void process(Wire wire) { + Map<Operation<?>, InvocationChain> chains = wire.getInvocationChains(); + for (Map.Entry<Operation<?>, InvocationChain> entry : chains.entrySet()) { + Operation<?> sourceOperation = entry.getKey(); + ServiceContract<?> serviceContract = wire.getTargetContract(); + if (serviceContract == null) { + continue; + } + Collection<? extends Operation<?>> operations = serviceContract.getOperations().values(); + Operation<?> targetOperation = getTargetOperation(operations, sourceOperation.getName()); + String sourceDataBinding = sourceOperation.getDataBinding(); + String targetDataBinding = targetOperation.getDataBinding(); + if (sourceDataBinding == null && targetDataBinding == null) { + continue; + } + if (sourceDataBinding == null || targetDataBinding == null + || !sourceDataBinding.equals(targetDataBinding)) { + // Add the interceptor to the source side because multiple + // references can be wired + // to the same service + DataBindingInteceptor interceptor = + new DataBindingInteceptor(wire, sourceOperation, targetOperation); + interceptor.setMediator(mediator); + entry.getValue().addInterceptor(0, interceptor); + } + } + + // Check if there's a callback + Map callbackOperations = wire.getSourceContract().getCallbackOperations(); + if (callbackOperations == null || callbackOperations.isEmpty()) { + return; + } + //Object targetAddress = UriHelper.getBaseName(source.getUri()); + Map<Operation<?>, InvocationChain> callbackChains = wire.getCallbackInvocationChains(); + if (callbackChains == null) { + // callback chains could be null + return; + } + for (Map.Entry<Operation<?>, InvocationChain> entry : callbackChains.entrySet()) { + Operation<?> sourceOperation = entry.getKey(); + Operation<?> targetOperation = + getTargetOperation(wire.getCallbackInvocationChains().keySet(), sourceOperation + .getName()); + String sourceDataBinding = sourceOperation.getDataBinding(); + String targetDataBinding = targetOperation.getDataBinding(); + if (sourceDataBinding == null && targetDataBinding == null) { + continue; + } + if (sourceDataBinding == null || targetDataBinding == null + || !sourceDataBinding.equals(targetDataBinding)) { + // Add the interceptor to the source side because multiple + // references can be wired + // to the same service + DataBindingInteceptor interceptor = + new DataBindingInteceptor(wire, sourceOperation, targetOperation); + interceptor.setMediator(mediator); + entry.getValue().addInterceptor(0, interceptor); + } + } + } + + + private Operation getTargetOperation(Collection<? extends Operation<?>> operations, String operationName) { + for (Operation<?> op : operations) { + if (op.getName().equals(operationName)) { + return op; + } + } + return null; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataTypeLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataTypeLoader.java new file mode 100644 index 0000000000..4f7d52b1cf --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataTypeLoader.java @@ -0,0 +1,66 @@ +/* + * 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.core.databinding.impl; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.osoa.sca.annotations.Constructor; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.LoaderExtension; +import org.apache.tuscany.spi.loader.InvalidValueException; +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.model.DataType; +import org.apache.tuscany.spi.model.ModelObject; + +/** + * The StAX loader for data type + */ +public class DataTypeLoader extends LoaderExtension<DataType> { + public static final QName DATA_BINDING = + new QName("http://tuscany.apache.org/xmlns/sca/databinding/1.0", "databinding"); + + @Constructor({"registry"}) + public DataTypeLoader(@Reference LoaderRegistry registry) { + super(registry); + } + + @Override + public QName getXMLType() { + return DATA_BINDING; + } + + public DataType load( + ModelObject object, XMLStreamReader reader, + DeploymentContext deploymentContext) throws XMLStreamException, LoaderException { + assert DATA_BINDING.equals(reader.getName()); + String name = reader.getAttributeValue(null, "name"); + LoaderUtil.skipToEndElement(reader); + if (name == null) { + throw new InvalidValueException("The 'name' attrbiute is required"); + } + DataType dataType = new DataType<Class>(name, Object.class, Object.class); + return dataType; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DirectedGraph.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DirectedGraph.java new file mode 100755 index 0000000000..02adf5860c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/DirectedGraph.java @@ -0,0 +1,357 @@ +/* + * 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.core.databinding.impl; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Directed, weighted graph + * + * @param <V> The type of vertex object + * @param <E> The type of edge object + */ +public class DirectedGraph<V, E> { + private final Map<V, Vertex> vertices = new HashMap<V, Vertex>(); + + /** + * Key for the shortest path cache + */ + private final class VertexPair { + private Vertex source; + + private Vertex target; + + /** + * @param source + * @param target + */ + private VertexPair(Vertex source, Vertex target) { + super(); + this.source = source; + this.target = target; + } + + public boolean equals(Object object) { + if (!VertexPair.class.isInstance(object)) { + return false; + } + VertexPair pair = (VertexPair)object; + return source == pair.source && target == pair.target; + } + + public int hashCode() { + int x = source == null ? 0 : source.hashCode(); + int y = target == null ? 0 : target.hashCode(); + return x ^ y; + } + + } + + private final Map<VertexPair, Path> paths = new HashMap<VertexPair, Path>(); + + /** + * Vertex of a graph + */ + public final class Vertex { + private V value; + + // TODO: Do we want to support multiple edges for a vertex pair? If so, + // we should use a List instead of Map + private Map<Vertex, Edge> outEdges = new HashMap<Vertex, Edge>(); + + private Vertex(V value) { + this.value = value; + } + + public String toString() { + return "(" + value + ")"; + } + + public V getValue() { + return value; + } + + public Map<Vertex, Edge> getOutEdges() { + return outEdges; + } + + } + + /** + * An Edge connects two vertices in one direction + */ + public final class Edge { + private Vertex sourceVertex; + + private Vertex targetVertex; + + private E value; + + private int weight; + + public Edge(Vertex source, Vertex target, E value, int weight) { + this.sourceVertex = source; + this.targetVertex = target; + this.value = value; + this.weight = weight; + } + + public String toString() { + return sourceVertex + "->" + targetVertex + "[" + value + "," + weight + "]"; + } + + public E getValue() { + return value; + } + + public void setValue(E value) { + this.value = value; + } + + public Vertex getTargetVertex() { + return targetVertex; + } + + public void setTargetVertex(Vertex vertex) { + this.targetVertex = vertex; + } + + public int getWeight() { + return weight; + } + + public void setWeight(int weight) { + this.weight = weight; + } + + public Vertex getSourceVertex() { + return sourceVertex; + } + + public void setSourceVertex(Vertex sourceVertex) { + this.sourceVertex = sourceVertex; + } + } + + private final class Node implements Comparable<Node> { + + private long distance = Integer.MAX_VALUE; + + private Node previous; // NOPMD by rfeng on 9/26/06 9:17 PM + + private Vertex vertex; // NOPMD by rfeng on 9/26/06 9:17 PM + + private Node(Vertex vertex) { + this.vertex = vertex; + } + + public int compareTo(Node o) { + return (distance > o.distance) ? 1 : ((distance == o.distance) ? 0 : -1); + } + } + + public void addEdge(V source, V target, E edgeValue, int weight) { + Vertex s = getVertex(source); + if (s == null) { + s = new Vertex(source); + vertices.put(source, s); + } + Vertex t = getVertex(target); + if (t == null) { + t = new Vertex(target); + vertices.put(target, t); + } + Edge edge = new Edge(s, t, edgeValue, weight); + s.outEdges.put(t, edge); + } + + public Vertex getVertex(V source) { + Vertex s = vertices.get(source); + return s; + } + + public boolean removeEdge(V source, V target) { + Vertex s = getVertex(source); + if (s == null) { + return false; + } + + Vertex t = getVertex(target); + if (t == null) { + return false; + } + + return s.outEdges.remove(t) != null; + + } + + public Edge getEdge(Vertex source, Vertex target) { + return source.outEdges.get(target); + } + + public Edge getEdge(V source, V target) { + return getEdge(getVertex(source), getVertex(target)); + } + + /** + * Get the shortes path from the source vertex to the target vertex using + * Dijkstra's algorithm. If there's no path, null will be returned. If the + * source is the same as the target, it returns a path with empty edges with + * weight 0. + * + * @param sourceValue The value identifies the source + * @param targetValue The value identifies the target + * @return The shortest path + */ + public Path getShortestPath(V sourceValue, V targetValue) { + Vertex source = getVertex(sourceValue); + if (source == null) { + return null; + } + Vertex target = getVertex(targetValue); + if (target == null) { + return null; + } + + VertexPair pair = new VertexPair(source, target); + if (paths.containsKey(pair)) { + return paths.get(pair); + } + + // HACK: To support same vertex + if (source == target) { + Path path = new Path(); + Edge edge = getEdge(source, target); + if (edge != null) { + path.addEdge(edge); + } + paths.put(pair, path); + return path; + } + + Map<Vertex, Node> nodes = new HashMap<Vertex, Node>(); + for (Vertex v : vertices.values()) { + Node node = new Node(v); + if (v == source) { + node.distance = 0; + } + nodes.put(v, node); + } + + Set<Node> otherNodes = new HashSet<Node>(nodes.values()); + Set<Node> nodesOnPath = new HashSet<Node>(); + while (!otherNodes.isEmpty()) { + Node nextNode = extractMin(otherNodes); + if (nextNode.vertex == target) { + Path path = getPath(nextNode); + paths.put(pair, path); // Cache it + return path; + } + nodesOnPath.add(nextNode); + for (Edge edge : nextNode.vertex.outEdges.values()) { + Node adjacentNode = nodes.get(edge.targetVertex); + if (nextNode.distance + edge.weight < adjacentNode.distance) { + adjacentNode.distance = nextNode.distance + edge.weight; + adjacentNode.previous = nextNode; + } + } + } + paths.put(pair, null); // Cache it + return null; + } + + /** + * Searches for the vertex u in the vertex set Q that has the least d[u] + * value. That vertex is removed from the set Q and returned to the user. + * + * @param nodes + * @return + */ + private Node extractMin(Set<Node> nodes) { + Node node = Collections.min(nodes); + nodes.remove(node); + return node; + } + + /** + * The path between two vertices + */ + public final class Path { + private List<Edge> edges = new LinkedList<Edge>(); + + private int weight; + + public int getWeight() { + return weight; + } + + public List<Edge> getEdges() { + return edges; + } + + public void addEdge(Edge edge) { + edges.add(0, edge); + weight += edge.weight; + } + + public String toString() { + return edges + ", " + weight; + } + } + + private Path getPath(Node t) { + if (t.distance == Integer.MAX_VALUE) { + return null; + } + Path path = new Path(); + Node u = t; + while (u.previous != null) { + Edge edge = getEdge(u.previous.vertex, u.vertex); + path.addEdge(edge); + u = u.previous; + } + return path; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + for (Vertex v : vertices.values()) { + sb.append(v.outEdges.values()).append("\n"); + } + return sb.toString(); + } + + public Map<V, Vertex> getVertices() { + return vertices; + } + + public void addGraph(DirectedGraph<V, E> otherGraph) { + for (Vertex v : otherGraph.vertices.values()) { + for (Edge e : v.outEdges.values()) { + addEdge(e.sourceVertex.value, e.targetVertex.value, e.value, e.weight); + } + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/Input2InputTransformer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/Input2InputTransformer.java new file mode 100644 index 0000000000..ba1de2132c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/Input2InputTransformer.java @@ -0,0 +1,215 @@ +/* + * 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.core.databinding.impl; + +import java.util.List; +import javax.xml.namespace.QName; + +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Service; + +import org.apache.tuscany.spi.databinding.DataBinding; +import org.apache.tuscany.spi.databinding.DataBindingRegistry; +import org.apache.tuscany.spi.databinding.Mediator; +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.WrapperHandler; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.apache.tuscany.spi.model.ElementInfo; +import org.apache.tuscany.spi.model.DataType; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.WrapperInfo; + +/** + * This is a special transformer to transform the input from one IDL to the other one + */ +@Service(Transformer.class) +public class Input2InputTransformer extends TransformerExtension<Object[], Object[]> implements + PullTransformer<Object[], Object[]> { + + private static final String IDL_INPUT = "idl:input"; + + protected DataBindingRegistry dataBindingRegistry; + + protected Mediator mediator; + + public Input2InputTransformer() { + super(); + } + + @Override + public String getSourceDataBinding() { + return IDL_INPUT; + } + + @Override + public String getTargetDataBinding() { + return IDL_INPUT; + } + + /** + * @param mediator the mediator to set + */ + @Reference + public void setMediator(Mediator mediator) { + this.mediator = mediator; + } + + /** + * @param dataBindingRegistry the dataBindingRegistry to set + */ + @Reference + public void setDataBindingRegistry(DataBindingRegistry dataBindingRegistry) { + this.dataBindingRegistry = dataBindingRegistry; + } + + /** + * @see org.apache.tuscany.spi.databinding.extension.TransformerExtension#getSourceType() + */ + @Override + protected Class getSourceType() { + return Object[].class; + } + + /** + * @see org.apache.tuscany.spi.databinding.extension.TransformerExtension#getTargetType() + */ + @Override + protected Class getTargetType() { + return Object[].class; + } + + /** + * @see org.apache.tuscany.spi.databinding.Transformer#getWeight() + */ + public int getWeight() { + return 10000; + } + + @SuppressWarnings("unchecked") + public Object[] transform(Object[] source, TransformationContext context) { + DataType<List<DataType<?>>> sourceType = context.getSourceDataType(); + Operation<?> sourceOp = (Operation<?>) sourceType.getOperation(); + boolean sourceWrapped = sourceOp != null && sourceOp.isWrapperStyle(); + + WrapperHandler sourceWrapperHandler = null; + if (sourceWrapped) { + sourceWrapperHandler = getWapperHandler(sourceType.getOperation().getDataBinding(), true); + } + + DataType<List<DataType<QName>>> targetType = context.getTargetDataType(); + Operation<?> targetOp = (Operation<?>) targetType.getOperation(); + boolean targetWrapped = targetOp != null && targetOp.isWrapperStyle(); + WrapperHandler targetWrapperHandler = null; + if (targetWrapped) { + targetWrapperHandler = getWapperHandler(targetType.getOperation().getDataBinding(), true); + } + + if ((!sourceWrapped) && targetWrapped) { + // Unwrapped --> Wrapped + WrapperInfo wrapper = targetOp.getWrapper(); + ElementInfo wrapperElement = wrapper.getInputWrapperElement(); + + // If the source can be wrapped, wrapped it first + if (sourceWrapperHandler != null) { + Object sourceWrapper = sourceWrapperHandler.create(wrapperElement, context); + for (int i = 0; i < source.length; i++) { + ElementInfo argElement = wrapper.getInputChildElements().get(i); + sourceWrapperHandler.setChild(sourceWrapper, i, argElement, source[0]); + } + } + Object targetWrapper = targetWrapperHandler.create(wrapperElement, context); + if (source == null) { + return new Object[]{targetWrapper}; + } + List<DataType<QName>> argTypes = wrapper.getUnwrappedInputType().getLogical(); + + for (int i = 0; i < source.length; i++) { + ElementInfo argElement = wrapper.getInputChildElements().get(i); + DataType<QName> argType = argTypes.get(i); + Object child = source[i]; + child = + mediator.mediate(source[i], sourceType.getLogical().get(i), argType, context + .getMetadata()); + targetWrapperHandler.setChild(targetWrapper, i, argElement, child); + } + return new Object[]{targetWrapper}; + } else if (sourceWrapped && (!targetWrapped)) { + // Wrapped to Unwrapped + Object sourceWrapper = source[0]; + List<ElementInfo> childElements = sourceOp.getWrapper().getInputChildElements(); + Object[] target = new Object[childElements.size()]; + + targetWrapperHandler = getWapperHandler(targetType.getOperation().getDataBinding(), false); + if (targetWrapperHandler != null) { + ElementInfo wrapperElement = sourceOp.getWrapper().getInputWrapperElement(); + // Object targetWrapper = + // targetWrapperHandler.create(wrapperElement, context); + DataType<QName> targetWrapperType = + new DataType<QName>(targetType.getOperation().getDataBinding(), Object.class, + wrapperElement.getQName()); + Object targetWrapper = + mediator.mediate(sourceWrapper, + sourceType.getLogical().get(0), + targetWrapperType, + context.getMetadata()); + for (int i = 0; i < childElements.size(); i++) { + ElementInfo childElement = childElements.get(i); + target[i] = targetWrapperHandler.getChild(targetWrapper, i, childElement); + } + } else { + for (int i = 0; i < childElements.size(); i++) { + ElementInfo childElement = childElements.get(i); + Object child = sourceWrapperHandler.getChild(sourceWrapper, i, childElement); + DataType<QName> childType = + sourceOp.getWrapper().getUnwrappedInputType().getLogical().get(i); + target[i] = + mediator.mediate(child, childType, targetType.getLogical().get(i), context + .getMetadata()); + } + } + return target; + } else { + // Assuming wrapper to wrapper conversion can be handled here as + // well + Object[] newArgs = new Object[source.length]; + for (int i = 0; i < source.length; i++) { + Object child = + mediator.mediate(source[i], sourceType.getLogical().get(i), targetType.getLogical() + .get(i), context.getMetadata()); + newArgs[i] = child; + } + return newArgs; + } + } + + private WrapperHandler getWapperHandler(String dataBindingId, boolean required) { + DataBinding dataBinding = dataBindingRegistry.getDataBinding(dataBindingId); + WrapperHandler wrapperHandler = dataBinding == null ? null : dataBinding.getWrapperHandler(); + if (wrapperHandler == null && required) { + throw new TransformationException( + "No wrapper handler is provided for databinding: " + dataBindingId); + } + return wrapperHandler; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/MediatorImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/MediatorImpl.java new file mode 100644 index 0000000000..589a96ed71 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/MediatorImpl.java @@ -0,0 +1,168 @@ +/* + * 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.core.databinding.impl; + +import java.util.List; +import java.util.Map; + +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; + +import org.apache.tuscany.spi.databinding.DataBindingRegistry; +import org.apache.tuscany.spi.databinding.DataPipe; +import org.apache.tuscany.spi.databinding.Mediator; +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.PushTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.TransformerRegistry; +import org.apache.tuscany.spi.model.DataType; + +/** + * Default Mediator implementation + */ +@Scope("COMPOSITE") +public class MediatorImpl implements Mediator { + + private DataBindingRegistry dataBindingRegistry; + + private TransformerRegistry transformerRegistry; + + @Reference + public void setTransformerRegistry(TransformerRegistry transformerRegistry) { + this.transformerRegistry = transformerRegistry; + } + + /** + * @param dataBindingRegistry the dataBindingRegistry to set + */ + @Reference + public void setDataBindingRegistry(DataBindingRegistry dataBindingRegistry) { + this.dataBindingRegistry = dataBindingRegistry; + } + + /** + * @see org.apache.tuscany.spi.databinding.Mediator#mediate(java.lang.Object,org.apache.tuscany.spi.model.DataType, + *org.apache.tuscany.spi.model.DataType,Map) + */ + @SuppressWarnings("unchecked") + public Object mediate(Object source, + DataType sourceDataType, + DataType targetDataType, + Map<Class<?>, Object> metadata) { + if (sourceDataType == null) { + sourceDataType = dataBindingRegistry.introspectType(source); + } + if (sourceDataType == null) { + return source; + } else if (sourceDataType.equals(targetDataType)) { + return source; + } + + List<Transformer> path = getTransformerChain(sourceDataType, targetDataType); + + Object result = source; + int size = path.size(); + int i = 0; + while (i < size) { + Transformer transformer = path.get(i); + TransformationContext context = + createTransformationContext(sourceDataType, targetDataType, size, i, transformer, metadata); + // the source and target type + if (transformer instanceof PullTransformer) { + // For intermediate node, set data type to null + result = ((PullTransformer) transformer).transform(result, context); + } else if (transformer instanceof PushTransformer) { + DataPipe dataPipe = (i < size - 1) ? (DataPipe) path.get(++i) : null; + ((PushTransformer) transformer).transform(result, dataPipe.getSink(), context); + result = dataPipe.getResult(); + } + i++; + } + + return result; + } + + private TransformationContext createTransformationContext(DataType sourceDataType, + DataType targetDataType, + int size, + int index, + Transformer transformer, + Map<Class<?>, Object> metadata) { + DataType sourceType = + (index == 0) ? sourceDataType : new DataType<Object>(transformer.getSourceDataBinding(), + Object.class, null); + DataType targetType = + (index == size - 1) ? targetDataType : new DataType<Object>(transformer.getTargetDataBinding(), + Object.class, null); + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + TransformationContext context = + new TransformationContextImpl(sourceType, targetType, classLoader, metadata); + return context; + } + + @SuppressWarnings("unchecked") + public void mediate(Object source, + Object target, + DataType sourceDataType, + DataType targetDataType, + Map<Class<?>, Object> metadata) { + if (source == null) { + // Shortcut for null value + return; + } + if (sourceDataType == null) { + sourceDataType = dataBindingRegistry.introspectType(source); + } + if (sourceDataType == null) { + return; + } else if (sourceDataType.equals(targetDataType)) { + return; + } + + List<Transformer> path = getTransformerChain(sourceDataType, targetDataType); + Object result = source; + int size = path.size(); + for (int i = 0; i < size; i++) { + Transformer transformer = path.get(i); + TransformationContext context = + createTransformationContext(sourceDataType, targetDataType, size, i, transformer, metadata); + + if (transformer instanceof PullTransformer) { + result = ((PullTransformer) transformer).transform(result, context); + } else if (transformer instanceof PushTransformer) { + DataPipe dataPipe = (i < size - 1) ? (DataPipe) path.get(++i) : null; + Object sink = dataPipe != null ? dataPipe.getSink() : target; + ((PushTransformer) transformer).transform(result, sink, context); + result = (dataPipe != null) ? dataPipe.getResult() : null; + } + } + } + + private List<Transformer> getTransformerChain(DataType sourceDataType, DataType targetDataType) { + String sourceId = sourceDataType.getDataBinding(); + String targetId = targetDataType.getDataBinding(); + List<Transformer> path = transformerRegistry.getTransformerChain(sourceId, targetId); + if (path == null) { + throw new TransformationException("No path found for the transformation"); + } + return path; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/Output2OutputTransformer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/Output2OutputTransformer.java new file mode 100644 index 0000000000..c9c7b1239f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/Output2OutputTransformer.java @@ -0,0 +1,200 @@ +/* + * 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.core.databinding.impl; + +import java.util.List; +import javax.xml.namespace.QName; + +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Service; + +import org.apache.tuscany.spi.databinding.DataBinding; +import org.apache.tuscany.spi.databinding.DataBindingRegistry; +import org.apache.tuscany.spi.databinding.Mediator; +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.WrapperHandler; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.apache.tuscany.spi.model.ElementInfo; +import org.apache.tuscany.spi.model.DataType; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.WrapperInfo; + +/** + * This is a special transformer to transform the output from one IDL to the other one + */ +@Service(Transformer.class) +public class Output2OutputTransformer extends TransformerExtension<Object, Object> implements + PullTransformer<Object, Object> { + private static final String IDL_OUTPUT = "idl:output"; + + protected DataBindingRegistry dataBindingRegistry; + + protected Mediator mediator; + + /** + * + */ + public Output2OutputTransformer() { + super(); + } + + /** + * @param mediator the mediator to set + */ + @Reference + public void setMediator(Mediator mediator) { + this.mediator = mediator; + } + + /** + * @param dataBindingRegistry the dataBindingRegistry to set + */ + @Reference + public void setDataBindingRegistry(DataBindingRegistry dataBindingRegistry) { + this.dataBindingRegistry = dataBindingRegistry; + } + + @Override + public String getSourceDataBinding() { + return IDL_OUTPUT; + } + + @Override + public String getTargetDataBinding() { + return IDL_OUTPUT; + } + + /** + * @see org.apache.tuscany.spi.databinding.extension.TransformerExtension#getSourceType() + */ + @Override + protected Class getSourceType() { + return Object.class; + } + + /** + * @see org.apache.tuscany.spi.databinding.extension.TransformerExtension#getTargetType() + */ + @Override + protected Class getTargetType() { + return Object.class; + } + + /** + * @see org.apache.tuscany.spi.databinding.Transformer#getWeight() + */ + public int getWeight() { + return 10; + } + + private WrapperHandler getWapperHandler(Operation<?> operation) { + String dataBindingId; + dataBindingId = operation.getDataBinding(); + DataBinding dataBinding = dataBindingRegistry.getDataBinding(dataBindingId); + WrapperHandler wrapperHandler = dataBinding == null ? null : dataBinding.getWrapperHandler(); + if (wrapperHandler == null) { + throw new TransformationException( + "No wrapper handler is provided for databinding: " + dataBindingId); + } + return wrapperHandler; + } + + private WrapperHandler getWapperHandler(String dataBindingId) { + DataBinding dataBinding = dataBindingRegistry.getDataBinding(dataBindingId); + return dataBinding == null ? null : dataBinding.getWrapperHandler(); + } + + @SuppressWarnings("unchecked") + public Object transform(Object response, TransformationContext context) { + try { + DataType<DataType> sourceType = context.getSourceDataType(); + Operation<?> sourceOp = (Operation<?>) sourceType.getOperation(); + boolean sourceWrapped = sourceOp != null && sourceOp.isWrapperStyle(); + WrapperHandler sourceWrapperHandler = null; + if (sourceWrapped) { + sourceWrapperHandler = getWapperHandler(sourceOp); + } + + DataType<DataType> targetType = context.getTargetDataType(); + Operation<?> targetOp = (Operation<?>) targetType.getOperation(); + boolean targetWrapped = targetOp != null && targetOp.isWrapperStyle(); + WrapperHandler targetWrapperHandler = null; + if (targetWrapped) { + targetWrapperHandler = getWapperHandler(targetOp); + } + + if ((!sourceWrapped) && targetWrapped) { + // Unwrapped --> Wrapped + WrapperInfo wrapper = targetOp.getWrapper(); + Object targetWrapper = + targetWrapperHandler.create(wrapper.getOutputWrapperElement(), context); + + List<ElementInfo> childElements = wrapper.getOutputChildElements(); + if (childElements.isEmpty()) { + // void output + return targetWrapper; + } + ElementInfo argElement = childElements.get(0); + DataType<QName> argType = wrapper.getUnwrappedOutputType(); + Object child = response; + child = mediator.mediate(response, sourceType.getLogical(), argType, context.getMetadata()); + targetWrapperHandler.setChild(targetWrapper, 0, argElement, child); + return targetWrapper; + } else if (sourceWrapped && (!targetWrapped)) { + // Wrapped to Unwrapped + Object sourceWrapper = response; + List<ElementInfo> childElements = sourceOp.getWrapper().getOutputChildElements(); + if (childElements.isEmpty()) { + // The void output + return null; + } + ElementInfo childElement = childElements.get(0); + + targetWrapperHandler = getWapperHandler(targetType.getLogical().getDataBinding()); + if (targetWrapperHandler != null) { + ElementInfo wrapperElement = sourceOp.getWrapper().getInputWrapperElement(); + // Object targetWrapper = + // targetWrapperHandler.create(wrapperElement, context); + DataType<QName> targetWrapperType = + new DataType<QName>(targetType.getLogical().getDataBinding(), Object.class, + wrapperElement.getQName()); + Object targetWrapper = + mediator.mediate(sourceWrapper, sourceType.getLogical(), targetWrapperType, context + .getMetadata()); + return targetWrapperHandler.getChild(targetWrapper, 0, childElement); + } else { + Object child = sourceWrapperHandler.getChild(sourceWrapper, 0, childElement); + DataType<?> childType = sourceOp.getWrapper().getUnwrappedOutputType(); + return mediator.mediate(child, childType, targetType.getLogical(), context.getMetadata()); + } + } else { + // FIXME: Do we want to handle wrapped to wrapped? + return mediator.mediate(response, sourceType.getLogical(), targetType.getLogical(), context + .getMetadata()); + } + } catch (Exception e) { + throw new TransformationException(e); + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/PassByValueInterceptor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/PassByValueInterceptor.java new file mode 100644 index 0000000000..1252885244 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/PassByValueInterceptor.java @@ -0,0 +1,244 @@ +/*
+ * 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.core.databinding.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.databinding.DataBinding;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+
+import org.apache.tuscany.core.util.JavaIntrospectionHelper;
+
+/**
+ * An interceptor to enforce pass-by-value semantics for remotable interfaces
+ *
+ * @version $Rev$ $Date$
+ */
+public class PassByValueInterceptor implements Interceptor {
+ private DataBinding[] argsDataBindings;
+ private DataBinding resultDataBinding;
+
+ private DataBinding dataBinding;
+
+ private Interceptor next;
+
+ public Interceptor getNext() {
+ return next;
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+
+ public void setNext(Interceptor next) {
+ this.next = next;
+ }
+
+ public Message invoke(Message msg) {
+ Object obj = msg.getBody();
+ msg.setBody(copy((Object[]) obj));
+ Message result = getNext().invoke(msg);
+
+ if (!result.isFault()) {
+ result.setBody(copy(result.getBody(), getResultDataBinding()));
+ }
+ return result;
+ }
+
+
+ public Object[] copy(Object[] args) {
+ if (args == null) {
+ return null;
+ }
+ Object[] copiedArgs = new Object[args.length];
+ Map<Object, Object> map = new IdentityHashMap<Object, Object>();
+ for (int i = 0; i < args.length; i++) {
+ if (args[i] == null) {
+ copiedArgs[i] = null;
+ } else {
+ Object copiedArg = map.get(args[i]);
+ if (copiedArg != null) {
+ copiedArgs[i] = copiedArg;
+ } else {
+ DataBinding dataBinding =
+ (getArgsDataBindings() != null) ? getArgsDataBindings()[i] : null;
+ copiedArg = copy(args[i], dataBinding);
+ map.put(args[i], copiedArg);
+ copiedArgs[i] = copiedArg;
+ }
+ }
+ }
+ return copiedArgs;
+ }
+
+ public Object copy(Object arg, DataBinding argDataBinding) {
+ if (arg == null) {
+ return null;
+ }
+ Object copiedArg;
+ if (dataBinding != null) {
+ copiedArg = dataBinding.copy(arg);
+ } else {
+ if (argDataBinding != null) {
+ copiedArg = argDataBinding.copy(arg);
+ } else {
+ final Class clazz = arg.getClass();
+ if (JavaIntrospectionHelper.isImmutable(clazz)) {
+ // Immutable classes
+ return arg;
+ }
+ copiedArg = copyJavaObject(arg);
+ }
+ }
+ return copiedArg;
+ }
+
+ private Object copyJavaObject(Object arg) {
+ try {
+ return deserializeJavaObject(serializeJavaObject(arg));
+ } catch (IllegalArgumentException e) {
+ throw e;
+ //System.out.println("Problem serializing...");
+ //return arg;
+ }
+ }
+
+ public byte[] serializeJavaObject(Object arg) throws IllegalArgumentException {
+ if (arg == null) {
+ return null;
+ }
+
+ ByteArrayOutputStream bos = null;
+ ObjectOutputStream oos = null;
+
+ try {
+ if (arg instanceof Serializable) {
+ bos = new ByteArrayOutputStream();
+ oos = getObjectOutputStream(bos);
+ oos.writeObject(arg);
+
+ return bos.toByteArray();
+ } else {
+ throw new IllegalArgumentException("Unable to serialize using Java Serialization");
+ }
+ } catch (IOException e) {
+ throw new IllegalArgumentException("Exception while serializing argument ", e);
+ } finally {
+ try {
+ if (oos != null) {
+ oos.close();
+ }
+ if (bos != null) {
+ bos.close();
+ }
+ } catch (IOException e) {
+ throw new IllegalArgumentException("Exception while serializing argument ", e);
+ }
+ }
+ }
+
+ public Object deserializeJavaObject(byte[] arg) {
+ if (arg == null) {
+ return null;
+ }
+ final Class clazz = arg.getClass();
+ if (JavaIntrospectionHelper.isImmutable(clazz)) {
+ // Immutable classes
+ return arg;
+ }
+
+ ByteArrayInputStream bis = null;
+ ObjectInputStream ois = null;
+
+ try {
+ bis = new ByteArrayInputStream(arg);
+ ois = getObjectInputStream(bis, clazz.getClassLoader());
+
+ return ois.readObject();
+ } catch (IOException e) {
+ throw new IllegalArgumentException("Exception when attempting to Java Deserialization of object ", e);
+ } catch (ClassNotFoundException e) {
+ throw new IllegalArgumentException("Exception when attempting to Java Deserialization of object ", e);
+ } finally {
+ try {
+ if (ois != null) {
+ ois.close();
+ }
+ assert bis != null;
+ bis.close();
+ } catch (IOException e) {
+ throw new IllegalArgumentException("Exception when attempting to Java Deserialization of object ", e);
+ }
+ }
+ }
+
+ protected ObjectOutputStream getObjectOutputStream(OutputStream os) throws IOException {
+ return new ObjectOutputStream(os);
+ }
+
+ protected ObjectInputStream getObjectInputStream(InputStream is, final ClassLoader cl) throws IOException {
+ return new ObjectInputStream(is) {
+ @Override
+ protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
+ try {
+ return Class.forName(desc.getName(), false, cl);
+ } catch (ClassNotFoundException e) {
+ return super.resolveClass(desc);
+ }
+ }
+
+ };
+ }
+
+ public DataBinding getDataBinding() {
+ return dataBinding;
+ }
+
+ public void setDataBinding(DataBinding dataBinding) {
+ this.dataBinding = dataBinding;
+ }
+
+ public DataBinding[] getArgsDataBindings() {
+ return argsDataBindings;
+ }
+
+ public void setArgsDataBindings(DataBinding[] argsDataBindings) {
+ this.argsDataBindings = argsDataBindings;
+ }
+
+ public DataBinding getResultDataBinding() {
+ return resultDataBinding;
+ }
+
+ public void setResultDataBinding(DataBinding retDataBinding) {
+ this.resultDataBinding = retDataBinding;
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/PassByValueWirePostProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/PassByValueWirePostProcessor.java new file mode 100644 index 0000000000..ad4598f063 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/PassByValueWirePostProcessor.java @@ -0,0 +1,182 @@ +/*
+ * 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.core.databinding.impl;
+
+import org.osoa.sca.annotations.Reference;
+
+import org.apache.tuscany.spi.databinding.DataBindingRegistry;
+import org.apache.tuscany.spi.wire.Wire;
+import org.apache.tuscany.spi.wire.WirePostProcessorExtension;
+
+/**
+ * This processor is responsible for enforcing the pass-by-value semantics required of Remotable interfaces. This is
+ * done by adding a pass-by-value interceptor to the inbound invocation chain of a target if the target interface is
+ * Remotable.
+ *
+ * @version $Rev$ $Date$
+ */
+public class PassByValueWirePostProcessor extends WirePostProcessorExtension {
+ //private DataBindingRegistry dataBindingRegistry;
+
+ public PassByValueWirePostProcessor() {
+ super();
+
+ }
+
+ /**
+ * @param dataBindingRegistry the dataBindingRegistry to set
+ */
+ @Reference
+ public void setDataBindingRegistry(DataBindingRegistry dataBindingRegistry) {
+ // this.dataBindingRegistry = dataBindingRegistry;
+ }
+
+ public void process(Wire wire) {
+
+ }
+
+// public void process(SCAObject source, OutboundWire sourceWire, SCAObject target, InboundWire targetWire) {
+// Interceptor tailInterceptor;
+// PassByValueInterceptor passByValueInterceptor;
+// Operation<?> targetOperation;
+// Operation<?> sourceOperation;
+// DataBinding[] argsDataBindings;
+// DataBinding resultDataBinding;
+//
+// boolean allowsPassByReference = false;
+// // JFM this needs to be fixed
+// if (target instanceof AtomicComponentExtension) {
+// allowsPassByReference =
+// ((AtomicComponentExtension) target).isAllowsPassByReference();
+// }
+// if (targetWire.getSourceContract().isRemotable()
+// && !allowsPassByReference) {
+// Map<Operation<?>, InboundInvocationChain> chains = targetWire.getInboundInvocationChains();
+// for (Map.Entry<Operation<?>, InboundInvocationChain> entry : chains.entrySet()) {
+// targetOperation = entry.getKey();
+// sourceOperation =
+// getSourceOperation(sourceWire.getOutboundInvocationChains().keySet(), targetOperation.getName());
+//
+//
+// if (null != sourceOperation) {
+// argsDataBindings = resolveArgsDataBindings(targetOperation);
+// resultDataBinding = resolveResultDataBinding(targetOperation);
+// passByValueInterceptor = new PassByValueInterceptor();
+// passByValueInterceptor.setDataBinding(getDataBinding(targetOperation));
+// passByValueInterceptor.setArgsDataBindings(argsDataBindings);
+// passByValueInterceptor.setResultDataBinding(resultDataBinding);
+// entry.getValue().addInterceptor(0, passByValueInterceptor);
+// tailInterceptor =
+// sourceWire.getOutboundInvocationChains().get(sourceOperation).getTailInterceptor();
+// if (tailInterceptor != null) {
+// tailInterceptor.setNext(passByValueInterceptor);
+// }
+// }
+// }
+// }
+//
+// // Check if there's a callback
+// Map callbackOperations = sourceWire.getSourceContract().getCallbackOperations();
+// allowsPassByReference = false;
+// if (source instanceof AtomicComponentExtension) {
+// allowsPassByReference =
+// ((AtomicComponentExtension) source).isAllowsPassByReference();
+// }
+//
+// if (sourceWire.getSourceContract().isRemotable()
+// && !allowsPassByReference
+// && callbackOperations != null
+// && !callbackOperations.isEmpty()) {
+// //URI targetAddress = UriHelper.getBaseName(source.getUri());
+// Map<Operation<?>, InboundInvocationChain> callbackChains = sourceWire.getTargetCallbackInvocationChains();
+// for (Map.Entry<Operation<?>, InboundInvocationChain> entry : callbackChains.entrySet()) {
+// targetOperation = entry.getKey();
+// sourceOperation =
+// getSourceOperation(targetWire.getSourceCallbackInvocationChains(
+// sourceWire.getSourceUri()).keySet(),
+// targetOperation.getName());
+//
+// argsDataBindings = resolveArgsDataBindings(targetOperation);
+// resultDataBinding = resolveResultDataBinding(targetOperation);
+//
+// passByValueInterceptor = new PassByValueInterceptor();
+// passByValueInterceptor.setDataBinding(getDataBinding(targetOperation));
+// passByValueInterceptor.setArgsDataBindings(argsDataBindings);
+// passByValueInterceptor.setResultDataBinding(resultDataBinding);
+//
+// entry.getValue().addInterceptor(0, passByValueInterceptor);
+// tailInterceptor =
+// targetWire.getSourceCallbackInvocationChains(sourceWire.getSourceUri()).get(sourceOperation)
+// .getTailInterceptor();
+// if (tailInterceptor != null) {
+// tailInterceptor.setNext(passByValueInterceptor);
+// }
+// }
+// }
+// }
+
+// private Operation getSourceOperation(Set<Operation<?>> operations, String operationName) {
+// for (Operation<?> op : operations) {
+// if (op.getName().equals(operationName)) {
+// return op;
+// }
+// }
+// return null;
+// }
+//
+// private DataBinding getDataBinding(Operation<?> operation) {
+// String dataBinding = operation.getDataBinding();
+// if (dataBinding == null) {
+// ServiceContract<?> serviceContract = operation.getServiceContract();
+// dataBinding = serviceContract.getDataBinding();
+// }
+// return dataBindingRegistry.getDataBinding(dataBinding);
+//
+// }
+
+// @SuppressWarnings("unchecked")
+// private DataBinding[] resolveArgsDataBindings(Operation operation) {
+// List<DataType<?>> argumentTypes = (List<DataType<?>>) operation.getInputType().getLogical();
+// DataBinding[] argDataBindings = new DataBinding[argumentTypes.size()];
+// int count = 0;
+// for (DataType argType : argumentTypes) {
+// argDataBindings[count] = null;
+// if (argType != null) {
+// if (argType.getLogical() instanceof Class) {
+// argDataBindings[count] =
+// dataBindingRegistry.getDataBinding(((Class) argType.getLogical()).getName());
+// }
+// }
+// ++count;
+// }
+// return argDataBindings;
+// }
+//
+// private DataBinding resolveResultDataBinding(Operation operation) {
+// DataType<?> resultType = (DataType<?>) operation.getOutputType();
+// DataBinding resultBinding = null;
+// if (resultType != null && resultType.getLogical() instanceof Class) {
+// Class<?> logical = (Class<?>) resultType.getLogical();
+// resultBinding = dataBindingRegistry.getDataBinding(logical.getName());
+// }
+// return resultBinding;
+// }
+//
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/PipedTransformer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/PipedTransformer.java new file mode 100755 index 0000000000..388ea710a7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/PipedTransformer.java @@ -0,0 +1,66 @@ +/* + * 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.core.databinding.impl; + +import org.apache.tuscany.spi.databinding.DataPipe; +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.PushTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; + +/** + * A utility class to connect PushTransformer and DataPipe to create a + * PullTransformer + * + * @param <S> Source type + * @param <I> Intermidate type + * @param <R> Result type + */ +public class PipedTransformer<S, I, R> implements PullTransformer<S, R> { + private PushTransformer<S, I> pusher; + + private DataPipe<I, R> pipe; + + /** + * @param pumper + * @param pipe + */ + public PipedTransformer(PushTransformer<S, I> pumper, DataPipe<I, R> pipe) { + super(); + this.pusher = pumper; + this.pipe = pipe; + } + + public R transform(S source, TransformationContext context) { + pusher.transform(source, pipe.getSink(), context); + return pipe.getResult(); + } + + public String getSourceDataBinding() { + return pusher.getSourceDataBinding(); + } + + public String getTargetDataBinding() { + return pipe.getTargetDataBinding(); + } + + public int getWeight() { + return pusher.getWeight() + pipe.getWeight(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/SimpleDataBinding.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/SimpleDataBinding.java new file mode 100644 index 0000000000..b1550c9f0a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/SimpleDataBinding.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.core.databinding.impl; + +import org.osoa.sca.annotations.Property; + +import org.apache.tuscany.spi.databinding.extension.DataBindingExtension; +import org.apache.tuscany.spi.loader.MissingResourceException; + +/** + * Simple databinding represented by a base java type. A SCDL property className is used to customize this component. + * <p/> + * The following illustrates how a simple data binding can be registered as a SCA component. + * <p/> + * <pre> + * <component name="databinding.MyDataBinding"><br> + * <system:implementation.java + * class="org.apache.tuscany.databinding.impl.SimpleDataBinding"/><br> + * <property name="className">my.Type</property><br> + * </component> + * </pre> + * + * @version $Rv$ $Date$ + */ +public class SimpleDataBinding extends DataBindingExtension { + + public SimpleDataBinding(@Property(name = "className")String className) throws MissingResourceException { + super(resolve(className)); + } + + private static Class<?> resolve(String className) throws MissingResourceException { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + try { + return Class.forName(className, false, classLoader); + } catch (ClassNotFoundException e) { + classLoader = SimpleDataBinding.class.getClassLoader(); + try { + return Class.forName(className, false, classLoader); + } catch (ClassNotFoundException e1) { + throw new MissingResourceException(className, e1); + } + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/TransformationContextImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/TransformationContextImpl.java new file mode 100755 index 0000000000..47f340097b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/TransformationContextImpl.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.core.databinding.impl; + +import java.lang.ref.WeakReference; +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.model.DataType; + +public class TransformationContextImpl implements TransformationContext { + private DataType sourceDataType; + + private DataType targetDataType; + + private final Map<Class<?>, Object> metadata = new HashMap<Class<?>, Object>(); + + private WeakReference<ClassLoader> classLoaderRef; + + public TransformationContextImpl() { + super(); + setClassLoader(Thread.currentThread().getContextClassLoader()); + } + + public TransformationContextImpl(DataType sourceDataType, + DataType targetDataType, + ClassLoader classLoader, + Map<Class<?>, Object> metadata) { + super(); + this.sourceDataType = sourceDataType; + this.targetDataType = targetDataType; + setClassLoader(classLoader); + if (metadata != null) { + this.metadata.putAll(metadata); + } + } + + public DataType getSourceDataType() { + return sourceDataType; + } + + public DataType getTargetDataType() { + return targetDataType; + } + + public void setSourceDataType(DataType sourceDataType) { + this.sourceDataType = sourceDataType; + } + + public void setTargetDataType(DataType targetDataType) { + this.targetDataType = targetDataType; + } + + public final void setClassLoader(ClassLoader classLoader) { + this.classLoaderRef = new WeakReference<ClassLoader>(classLoader); + } + + public ClassLoader getClassLoader() { + return classLoaderRef.get(); + } + + public Map<Class<?>, Object> getMetadata() { + return metadata; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/TransformerRegistryImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/TransformerRegistryImpl.java new file mode 100755 index 0000000000..c8bfa1cc8c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/impl/TransformerRegistryImpl.java @@ -0,0 +1,73 @@ +/* + * 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.core.databinding.impl; + +import java.util.ArrayList; +import java.util.List; + +import org.osoa.sca.annotations.EagerInit; + +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.TransformerRegistry; + +/** + * @version $Rev$ $Date$ + */ +@EagerInit +public class TransformerRegistryImpl implements TransformerRegistry { + + private final DirectedGraph<Object, Transformer> graph = new DirectedGraph<Object, Transformer>(); + + public void registerTransformer(String sourceType, String resultType, int weight, Transformer transformer) { + graph.addEdge(sourceType, resultType, transformer, weight); + } + + public void registerTransformer(Transformer transformer) { + graph.addEdge(transformer.getSourceDataBinding(), + transformer.getTargetDataBinding(), + transformer, + transformer.getWeight()); + } + + public boolean unregisterTransformer(String sourceType, String resultType) { + return graph.removeEdge(sourceType, resultType); + } + + public Transformer getTransformer(String sourceType, String resultType) { + DirectedGraph<Object, Transformer>.Edge edge = graph.getEdge(sourceType, resultType); + return (edge == null) ? null : edge.getValue(); + } + + public List<Transformer> getTransformerChain(String sourceType, String resultType) { + List<Transformer> transformers = new ArrayList<Transformer>(); + DirectedGraph<Object, Transformer>.Path path = graph.getShortestPath(sourceType, resultType); + if (path == null) { + return null; + } + for (DirectedGraph<Object, Transformer>.Edge edge : path.getEdges()) { + transformers.add(edge.getValue()); + } + return transformers; + } + + public String toString() { + return graph.toString(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/DOMNode2JavaBeanTransformer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/DOMNode2JavaBeanTransformer.java new file mode 100644 index 0000000000..38f02cdc28 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/DOMNode2JavaBeanTransformer.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.core.databinding.javabeans;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Transformer to convert data from DOM Node to JavaBean
+ */
+@Service(Transformer.class)
+public class DOMNode2JavaBeanTransformer extends XML2JavaBeanTransformer<Node> {
+
+ @Override
+ public List<Node> getChildElements(Node parent) throws XML2JavaMapperException {
+ NodeList nodeList = parent.getChildNodes();
+ List<Node> nodeArrayList = new ArrayList<Node>(nodeList.getLength());
+ for (int count = 0; count < nodeList.getLength(); ++count) {
+ nodeArrayList.add(nodeList.item(count));
+ }
+
+ return nodeArrayList;
+ }
+
+ @Override
+ public String getElementName(Node element) throws XML2JavaMapperException {
+ return element.getNodeName();
+ }
+
+ @Override
+ public String getText(Node element) throws XML2JavaMapperException {
+ if (element instanceof Document) {
+ element = ((Document) element).getDocumentElement();
+ }
+ return element.getTextContent();
+ }
+
+ @Override
+ public boolean isTextElement(Node element) throws XML2JavaMapperException {
+ return element.getNodeType() == Node.TEXT_NODE;
+ }
+
+ public Class getSourceType() {
+ return Node.class;
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/Java2XMLMapperException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/Java2XMLMapperException.java new file mode 100644 index 0000000000..3f88a4ee89 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/Java2XMLMapperException.java @@ -0,0 +1,69 @@ +/*
+ * 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.core.databinding.javabeans;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.api.TuscanyRuntimeException;
+
+/**
+ * This exception is used to encapsulate and rethrow exceptions that arise out
+ * of converting JavaBean objects to XML
+ */
+public class Java2XMLMapperException extends TuscanyRuntimeException {
+ private static final long serialVersionUID = 6811924384399578686L;
+
+ private QName xmlElementName;
+ private String javaFieldName;
+ private Class javaType;
+
+ public Java2XMLMapperException(String message) {
+ super(message);
+ }
+
+ public Java2XMLMapperException(Throwable cause) {
+ super(cause);
+ }
+
+ public String getJavaFieldName() {
+ return javaFieldName;
+ }
+
+ public void setJavaFieldName(String javaFieldName) {
+ this.javaFieldName = javaFieldName;
+ }
+
+ public Class getJavaType() {
+ return javaType;
+ }
+
+ public void setJavaType(Class javaType) {
+ this.javaType = javaType;
+ }
+
+ public QName getXmlElementName() {
+ return xmlElementName;
+ }
+
+ public void setXmlElementName(QName xmlElementName) {
+ this.xmlElementName = xmlElementName;
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2DOMNodeTransformer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2DOMNodeTransformer.java new file mode 100644 index 0000000000..5925e87b69 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2DOMNodeTransformer.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.core.databinding.javabeans;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.DOMHelper;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * Transformer to convert data from a JavaBean object to DOM Node
+ */
+@Service(Transformer.class)
+public class JavaBean2DOMNodeTransformer extends JavaBean2XMLTransformer<Node> {
+
+ public static final String COLON = ":";
+ private Document factory;
+
+ public JavaBean2DOMNodeTransformer() {
+ super();
+ try {
+ factory = DOMHelper.newDocument();
+ } catch (ParserConfigurationException e) {
+ throw new Java2XMLMapperException(e);
+ }
+ }
+
+ @Override
+ public void appendChild(Node parentElement, Node childElement) throws Java2XMLMapperException {
+ parentElement.appendChild(childElement);
+ }
+
+ @Override
+ public Node createElement(QName qName) throws Java2XMLMapperException {
+ String qualifedName =
+ (qName.getPrefix() == null || qName.getPrefix().length() <= 0) ? qName.getLocalPart()
+ : qName.getPrefix() + COLON + qName.getLocalPart();
+ return factory.createElementNS(qName.getNamespaceURI(), qualifedName);
+ }
+
+ @Override
+ public Node createText(String textData) throws Java2XMLMapperException {
+ return factory.createTextNode(textData);
+ }
+
+ public Class getTargetType() {
+ return Node.class;
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2XMLTransformer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2XMLTransformer.java new file mode 100644 index 0000000000..5d4b69ffbb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2XMLTransformer.java @@ -0,0 +1,221 @@ +/*
+ * 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.core.databinding.javabeans;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+
+/**
+ * Transformer to convert data from a JavaBean object to xml
+ */
+@Service(Transformer.class)
+public abstract class JavaBean2XMLTransformer<T> extends TransformerExtension<Object, T> implements
+ PullTransformer<Object, T> {
+
+ public static final String GET = "get";
+ public static final String PREFIX = "n";
+ public static final String PERIOD = ".";
+ public static final String FWD_SLASH = "/";
+ public static final String HTTP = "http://";
+ private static int prefixCount = 1;
+
+ protected SimpleTypeMapperExtension mapper;
+
+ public JavaBean2XMLTransformer() {
+ this.mapper = new SimpleTypeMapperExtension();
+ }
+
+ public T transform(Object source, TransformationContext context) {
+ QName rootElementName = (QName)context.getTargetDataType().getMetadata("RootElementName");
+ if (rootElementName == null) {
+ rootElementName = new QName(resolveRootElementName(source.getClass()));
+ }
+ T root = createElement(rootElementName);
+ appendChildElements(root,
+ resolveElementName(source.getClass()),
+ source.getClass(),
+ source,
+ context);
+ return root;
+ }
+
+ private void appendChildElements(T parent,
+ QName elementName,
+ Class javaType,
+ Object javaObject,
+ TransformationContext context) {
+ T element = null;
+ if (javaObject != null) {
+ if (javaType.isPrimitive() || isSimpleJavaType(javaObject)) {
+ appendChild(parent, createText(mapper.toXMLLiteral(null, javaObject, context)));
+ } else if (javaType.isArray()) {
+ boolean arrayDone = false;
+ Object arrayObject = null;
+ for (int count = 0; !arrayDone; ++count) {
+ try {
+ arrayObject = Array.get(javaObject, count);
+ element = createElement(elementName);
+ appendChild(parent, element);
+ appendChildElements(element,
+ elementName,
+ javaType.getComponentType(),
+ arrayObject,
+ context);
+ } catch (ArrayIndexOutOfBoundsException e1) {
+ arrayDone = true;
+ }
+ }
+ } else {
+ Field[] javaFields = javaType.getFields();
+ for (Field aField : javaFields) {
+ try {
+ QName fieldElementName = new QName(aField.getName());
+ if (!aField.getType().isArray()) {
+ element = createElement(fieldElementName);
+ appendChild(parent, element);
+ appendChildElements(element,
+ fieldElementName,
+ aField.getType(),
+ aField.get(javaObject),
+ context);
+ } else {
+ appendChildElements(parent,
+ fieldElementName,
+ aField.getType(),
+ aField.get(javaObject),
+ context);
+ }
+ } catch (IllegalAccessException e) {
+ Java2XMLMapperException java2xmlEx = new Java2XMLMapperException(e);
+ java2xmlEx.setJavaFieldName(aField.getName());
+ java2xmlEx.setJavaType(javaType);
+ throw java2xmlEx;
+ }
+ }
+
+ Method[] methods = javaType.getDeclaredMethods();
+ String fieldName = null;
+ for (Method aMethod : methods) {
+ try {
+ if (Modifier.isPublic(aMethod.getModifiers()) && aMethod.getName().startsWith(GET)
+ && aMethod.getParameterTypes().length == 0) {
+ fieldName = resolveFieldFromMethod(aMethod.getName());
+ try {
+ javaType.getField(fieldName);
+ } catch (NoSuchFieldException e) {
+ QName fieldElementName = new QName(fieldName);
+ if (aMethod.getReturnType().isArray()) {
+ appendChildElements(parent, fieldElementName, aMethod.getReturnType(), aMethod
+ .invoke(javaObject, new Object[0]), context);
+ } else {
+ element = createElement(fieldElementName);
+ appendChild(parent, element);
+ appendChildElements(element, fieldElementName, aMethod.getReturnType(), aMethod
+ .invoke(javaObject, new Object[0]), context);
+ }
+ }
+ }
+ } catch (IllegalAccessException e) {
+ Java2XMLMapperException java2xmlEx = new Java2XMLMapperException(e);
+ java2xmlEx.setJavaFieldName(fieldName);
+ java2xmlEx.setJavaType(javaType);
+ throw java2xmlEx;
+ } catch (InvocationTargetException e) {
+ Java2XMLMapperException java2xmlEx = new Java2XMLMapperException(e);
+ java2xmlEx.setJavaFieldName(fieldName);
+ java2xmlEx.setJavaType(javaType);
+ throw java2xmlEx;
+ }
+ }
+ }
+ }
+ }
+
+ public Class getSourceType() {
+ return Object.class;
+ }
+
+ private boolean isSimpleJavaType(Object javaObject) {
+ if (javaObject instanceof String) {
+ return true;
+ }
+ if (javaObject instanceof Byte || javaObject instanceof Character
+ || javaObject instanceof Short
+ || javaObject instanceof Integer
+ || javaObject instanceof Long
+ || javaObject instanceof Float
+ || javaObject instanceof Double) {
+ return true;
+ }
+ if (javaObject instanceof GregorianCalendar || javaObject instanceof Date
+ || javaObject instanceof XMLGregorianCalendar
+ || javaObject instanceof byte[]
+ || javaObject instanceof QName) {
+ return true;
+ }
+ return false;
+ }
+
+ private String resolveRootElementName(Class javaType) {
+ if (javaType.isArray()) {
+ return javaType.getComponentType().getSimpleName() + "_collection";
+ } else {
+ return javaType.getSimpleName() + "_instance";
+ }
+ }
+
+
+ private QName resolveElementName(Class javaType) {
+ if (javaType.isArray()) {
+ return new QName(javaType.getComponentType().getSimpleName());
+ } else {
+ return new QName(javaType.getSimpleName());
+ }
+ }
+
+ private String resolveFieldFromMethod(String methodName) {
+ StringBuffer fieldName = new StringBuffer();
+ fieldName.append(Character.toLowerCase(methodName.charAt(GET.length())));
+ fieldName.append(methodName.substring(GET.length() + 1));
+ return fieldName.toString();
+ }
+
+ public String getNexPrefix() {
+ return PREFIX + prefixCount++;
+ }
+
+ public abstract T createElement(QName qName) throws Java2XMLMapperException;
+ public abstract T createText(String textData) throws Java2XMLMapperException;
+ public abstract void appendChild(T parentElement, T childElement) throws Java2XMLMapperException;
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBeansDataBinding.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBeansDataBinding.java new file mode 100644 index 0000000000..a944706918 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBeansDataBinding.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.core.databinding.javabeans;
+
+import org.apache.tuscany.spi.databinding.DataBinding;
+import org.apache.tuscany.spi.databinding.extension.DataBindingExtension;
+import org.osoa.sca.annotations.Service;
+
+/**
+ * DataBinding for JavaBeans
+ */
+@Service(DataBinding.class)
+public class JavaBeansDataBinding extends DataBindingExtension {
+
+ public static final String NAME = Object.class.getName();
+
+ public JavaBeansDataBinding() {
+ super(Object.class);
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/XML2JavaBeanTransformer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/XML2JavaBeanTransformer.java new file mode 100644 index 0000000000..7f9753259c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/XML2JavaBeanTransformer.java @@ -0,0 +1,299 @@ +/*
+ * 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.core.databinding.javabeans;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.apache.tuscany.spi.model.ElementInfo;
+import org.apache.tuscany.spi.model.TypeInfo;
+
+import org.osoa.sca.annotations.Service;
+
+/**
+ * Transformer to convert data from XML to JavaBean
+ */
+@Service(Transformer.class)
+public abstract class XML2JavaBeanTransformer<T> extends TransformerExtension<T, Object> implements
+ PullTransformer<T, Object> {
+
+ public static final String SET = "set";
+
+ protected SimpleTypeMapperExtension mapper;
+
+ public XML2JavaBeanTransformer() {
+ this.mapper = new SimpleTypeMapperExtension();
+ }
+
+ public Object transform(T source, TransformationContext context) {
+ TypeInfo xmlType =
+ (TypeInfo) context.getSourceDataType().getMetadata(TypeInfo.class.getName());
+ if (xmlType == null) {
+ ElementInfo element =
+ (ElementInfo) context.getSourceDataType()
+ .getMetadata(ElementInfo.class.getName());
+ xmlType = (TypeInfo) element.getType();
+ }
+
+ return toJavaObject(xmlType, source, context);
+ }
+
+ public Object toJavaObject(TypeInfo xmlType, T xmlElement, TransformationContext context) {
+ if (xmlType.isSimpleType()) {
+ return mapper.toJavaObject(xmlType, getText(xmlElement), context);
+ } else {
+ Class<?> javaType = (Class<?>) context.getTargetDataType().getLogical();
+ return createJavaObject(xmlElement, javaType, context);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private <L> L createJavaObject(T element, Class<L> javaType, TransformationContext context)
+ throws XML2JavaMapperException {
+ List<T> childElements = getChildElements(element);
+ if (childElements.size() == 1 && isTextElement(childElements.get(0))) {
+ return (L) mapper.toJavaObject(mapper.getXMLType(javaType),
+ getText(childElements.get(0)),
+ context);
+ } else {
+ String fieldName = null;
+ try {
+ L javaInstance = javaType.newInstance();
+ Map<Field, List<Object>> arrayFields = new Hashtable<Field, List<Object>>();
+ Map<Method, List<Object>> arraySetters = new Hashtable<Method, List<Object>>();
+ for (int count = 0; count < childElements.size(); ++count) {
+ if (!isTextElement(childElements.get(count))) {
+ fieldName = getElementName(childElements.get(count));
+ try {
+ Field javaField = javaType.getField(fieldName);
+ setFieldValue(javaInstance,
+ javaField,
+ childElements.get(count),
+ arrayFields,
+ context);
+
+ } catch (NoSuchFieldException e1) {
+ setFieldValueUsingSetter(javaType,
+ javaInstance,
+ fieldName,
+ childElements.get(count),
+ arraySetters,
+ context);
+ }
+ }
+ }
+
+ setArrayValues(javaInstance, arrayFields, arraySetters);
+ return javaInstance;
+ } catch (Exception e2) {
+ XML2JavaMapperException xml2JavaEx = new XML2JavaMapperException(e2);
+ xml2JavaEx.setJavaType(javaType);
+ xml2JavaEx.setJavaFieldName(fieldName);
+ throw xml2JavaEx;
+ }
+ }
+ }
+
+ private void setFieldValue(Object javaInstance,
+ Field javaField,
+ T fieldValue,
+ Map<Field, List<Object>> arrayFields,
+ TransformationContext context) throws IllegalAccessException {
+ Class<?> javaFieldType = (Class<?>) javaField.getType();
+
+ if (javaFieldType.isArray()) {
+ Class<?> componentType = javaFieldType.getComponentType();
+ List<Object> fldValueArray = arrayFields.get(javaField);
+ if (fldValueArray == null) {
+ fldValueArray = new ArrayList<Object>();
+ arrayFields.put(javaField, fldValueArray);
+ }
+ fldValueArray.add(createJavaObject(fieldValue, componentType, context));
+ } else {
+ javaField.setAccessible(true);
+ javaField.set(javaInstance, createJavaObject(fieldValue, javaFieldType, context));
+ }
+ }
+
+ private void setFieldValueUsingSetter(Class javaType,
+ Object javaInstance,
+ String fieldName,
+ T fieldValue,
+ Map<Method, List<Object>> arraySetters,
+ TransformationContext context) throws IllegalAccessException,
+ InvocationTargetException {
+ char firstChar = Character.toUpperCase(fieldName.charAt(0));
+ StringBuilder methodName = new StringBuilder(SET + fieldName);
+ methodName.setCharAt(SET.length(), firstChar);
+ boolean methodNotFound = true;
+
+ for (int methodCount = 0; methodNotFound && methodCount < javaType.getMethods().length; ++methodCount) {
+ Method aMethod = javaType.getMethods()[methodCount];
+ if (aMethod.getName().equals(methodName.toString())
+ && aMethod.getParameterTypes().length == 1) {
+ Class<?> paramType = aMethod.getParameterTypes()[0];
+
+ if (paramType.isArray()) {
+ Class<?> componentType = paramType.getComponentType();
+ List<Object> setterValueArray = arraySetters.get(aMethod);
+ if (setterValueArray == null) {
+ setterValueArray = new ArrayList<Object>();
+ arraySetters.put(aMethod, setterValueArray);
+ }
+ setterValueArray.add(createJavaObject(fieldValue, componentType, context));
+ } else {
+ aMethod.invoke(javaInstance, new Object[] {createJavaObject(fieldValue,
+ paramType,
+ context)});
+ }
+ methodNotFound = false;
+ }
+ }
+
+ if (methodNotFound) {
+ XML2JavaMapperException xml2JavaEx =
+ new XML2JavaMapperException("No field or setter method to configure xml data");
+ xml2JavaEx.setJavaFieldName(fieldName);
+ xml2JavaEx.setJavaType(javaType);
+ throw xml2JavaEx;
+ }
+ }
+
+ private void setArrayValues(Object javaInstance,
+ Map<Field, List<Object>> arrayFields,
+ Map<Method, List<Object>> arraySetters) throws IllegalAccessException,
+ InvocationTargetException {
+ if (arrayFields.size() > 0) {
+ for (Field javaField : arrayFields.keySet()) {
+ javaField.setAccessible(true);
+
+ if (javaField.getType().getComponentType().isPrimitive()) {
+ javaField.set(javaInstance, createPrimitiveArray(javaField.getType()
+ .getComponentType(),
+ arrayFields.get(javaField)));
+ } else {
+ javaField.set(javaInstance,
+ createNonPrimitiveArray(javaField.getType().getComponentType(),
+ arrayFields.get(javaField)));
+ }
+ }
+ }
+
+ if (arraySetters.size() > 0) {
+ for (Method aMethod : arraySetters.keySet()) {
+ Class paramType = aMethod.getParameterTypes()[0];
+ if (paramType.getComponentType().isPrimitive()) {
+ aMethod.invoke(javaInstance,
+ new Object[] {createPrimitiveArray(paramType.getComponentType(),
+ arraySetters.get(aMethod))});
+ } else {
+ aMethod.invoke(javaInstance,
+ new Object[] {createNonPrimitiveArray(paramType.getComponentType(),
+ arraySetters.get(aMethod))});
+ }
+ }
+ }
+ }
+
+ private Object createNonPrimitiveArray(Class fieldType, List values) {
+ Object objectArray = Array.newInstance(fieldType, values.size());
+ for (int count = 0; count < values.size(); ++count) {
+ Array.set(objectArray, count, values.get(count));
+ }
+ return objectArray;
+ }
+
+ private Object createPrimitiveArray(Class fieldType, List values) {
+ if (fieldType.isPrimitive()) {
+ if (fieldType.getName().equals("int")) {
+ int[] primitiveValues = new int[values.size()];
+ for (int count = 0; count < values.size(); ++count) {
+ primitiveValues[count] = ((Integer) values.get(count)).intValue();
+ }
+ return primitiveValues;
+ } else if (fieldType.getName().equals("float")) {
+ float[] primitiveValues = new float[values.size()];
+ for (int count = 0; count < values.size(); ++count) {
+ primitiveValues[count] = ((Float) values.get(count)).floatValue();
+ }
+ return primitiveValues;
+ } else if (fieldType.getName().equals("boolean")) {
+ boolean[] primitiveValues = new boolean[values.size()];
+ for (int count = 0; count < values.size(); ++count) {
+ primitiveValues[count] = ((Boolean) values.get(count)).booleanValue();
+ }
+ return primitiveValues;
+ } else if (fieldType.getName().equals("char")) {
+ char[] primitiveValues = new char[values.size()];
+ for (int count = 0; count < values.size(); ++count) {
+ primitiveValues[count] = ((Character) values.get(count)).charValue();
+ }
+ return primitiveValues;
+ } else if (fieldType.getName().equals("byte")) {
+ byte[] primitiveValues = new byte[values.size()];
+ for (int count = 0; count < values.size(); ++count) {
+ primitiveValues[count] = ((Byte) values.get(count)).byteValue();
+ }
+ return primitiveValues;
+ } else if (fieldType.getName().equals("short")) {
+ short[] primitiveValues = new short[values.size()];
+ for (int count = 0; count < values.size(); ++count) {
+ primitiveValues[count] = ((Short) values.get(count)).shortValue();
+ }
+ return primitiveValues;
+ } else if (fieldType.getName().equals("long")) {
+ long[] primitiveValues = new long[values.size()];
+ for (int count = 0; count < values.size(); ++count) {
+ primitiveValues[count] = ((Long) values.get(count)).longValue();
+ }
+ return primitiveValues;
+ } else if (fieldType.getName().equals("double")) {
+ double[] primitiveValues = new double[values.size()];
+ for (int count = 0; count < values.size(); ++count) {
+ primitiveValues[count] = ((Double) values.get(count)).doubleValue();
+ }
+ return primitiveValues;
+ }
+ }
+ return values;
+ }
+
+ public abstract String getText(T source) throws XML2JavaMapperException;
+
+ public abstract List<T> getChildElements(T parent) throws XML2JavaMapperException;
+
+ public abstract String getElementName(T element) throws XML2JavaMapperException;
+
+ public abstract boolean isTextElement(T element) throws XML2JavaMapperException;
+
+ public Class getTargetType() {
+ return Object.class;
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/XML2JavaMapperException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/XML2JavaMapperException.java new file mode 100644 index 0000000000..f2910e6946 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/XML2JavaMapperException.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.core.databinding.javabeans;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.api.TuscanyRuntimeException;
+
+/**
+ * This exception is used to encapsulate and rethrow exceptions that arise out of converting XML Data to Java Objects.
+ *
+ * @version $Rev$ $Date$
+ */
+public class XML2JavaMapperException extends TuscanyRuntimeException {
+ private static final long serialVersionUID = 6596530102591630642L;
+
+ private QName xmlElementName;
+ private String javaFieldName;
+ private Class javaType;
+
+ public XML2JavaMapperException(String message) {
+ super(message);
+ }
+
+ public XML2JavaMapperException(Throwable cause) {
+ super(cause);
+ }
+
+ public QName getXmlElementName() {
+ return xmlElementName;
+ }
+
+ public void setXmlElementName(QName xmlElementName) {
+ this.xmlElementName = xmlElementName;
+ }
+
+ public String getJavaFieldName() {
+ return javaFieldName;
+ }
+
+ public void setJavaFieldName(String javaFieldName) {
+ this.javaFieldName = javaFieldName;
+ }
+
+ public Class getJavaType() {
+ return javaType;
+ }
+
+ public void setJavaType(Class javaType) {
+ this.javaType = javaType;
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMDataBinding.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMDataBinding.java new file mode 100644 index 0000000000..d2df8cf888 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMDataBinding.java @@ -0,0 +1,56 @@ +/* + * 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.core.databinding.xml; + + +import org.w3c.dom.Node; + +import org.apache.tuscany.spi.databinding.WrapperHandler; +import org.apache.tuscany.spi.databinding.extension.DataBindingExtension; + +/** + * DOM DataBinding + * + * @version $Rev$ $Date$ + */ +public class DOMDataBinding extends DataBindingExtension { + public static final String NAME = Node.class.getName(); + + public DOMDataBinding() { + super(Node.class); + } + + @Override + public WrapperHandler getWrapperHandler() { + return new DOMWrapperHandler(); + } + + public Object copy(Object source) { + if (Node.class.isAssignableFrom(source.getClass())) { + Node nodeSource = (Node) source; + Node2String strTransformer = new Node2String(); + String stringCopy = strTransformer.transform(nodeSource, null); + + String2Node nodeTransformer = new String2Node(); + return nodeTransformer.transform(stringCopy, null); + } + + return super.copy(source); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMWrapperHandler.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMWrapperHandler.java new file mode 100644 index 0000000000..4ef0af6701 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMWrapperHandler.java @@ -0,0 +1,80 @@ +/* + * 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.core.databinding.xml; + +import javax.xml.namespace.QName; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.WrapperHandler; +import org.apache.tuscany.spi.databinding.extension.DOMHelper; +import org.apache.tuscany.spi.model.ElementInfo; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class DOMWrapperHandler implements WrapperHandler<Node> { + + private Document document; + + public DOMWrapperHandler() { + super(); + try { + this.document = DOMHelper.newDocument(); + } catch (ParserConfigurationException e) { + throw new TransformationException(e); + } + } + + public Node create(ElementInfo element, TransformationContext context) { + QName name = element.getQName(); + return DOMHelper.createElement(document, name); + } + + public Object getChild(Node wrapper, int i, ElementInfo element) { + int index = 0; + NodeList nodes = wrapper.getChildNodes(); + for (int j = 0; j < nodes.getLength(); j++) { + Node node = nodes.item(j); + if (node.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + if (index != i) { + index++; + } else { + QName name = DOMHelper.getQName(node); + if (name.equals(element.getQName())) { + return node; + } + } + } + return null; + } + + public void setChild(Node wrapper, int i, ElementInfo childElement, Object value) { + Node node = (Node) value; + if (node.getNodeType() == Node.DOCUMENT_NODE) { + node = ((Document) node).getDocumentElement(); + } + wrapper.appendChild(wrapper.getOwnerDocument().importNode(node, true)); + } +}
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMXMLStreamReader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMXMLStreamReader.java new file mode 100644 index 0000000000..f94ddd545f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMXMLStreamReader.java @@ -0,0 +1,1415 @@ +/* + * 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.core.databinding.xml; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import javax.xml.XMLConstants; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; + +import org.w3c.dom.Attr; +import org.w3c.dom.CharacterData; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import org.apache.tuscany.core.databinding.xml.StAXHelper.XMLFragmentStreamReader; + +public class DOMXMLStreamReader implements XMLFragmentStreamReader { + protected static class DelegatingNamespaceContext implements NamespaceContext { + private int counter; + + private NamespaceContext parent; + + private Map<String, String> prefixToNamespaceMapping = new HashMap<String, String>(); + + public DelegatingNamespaceContext(NamespaceContext parent) { + super(); + this.parent = parent; + + prefixToNamespaceMapping.put("xml", "http://www.w3.org/XML/1998/namespace"); + prefixToNamespaceMapping.put("xmlns", "http://www.w3.org/2000/xmlns/"); + prefixToNamespaceMapping.put("xsi", "http://www.w3.org/2001/XMLSchema-instance"); + } + + public synchronized QName createQName(String nsURI, String name) { + String prefix = nsURI != null ? (String) getPrefix(nsURI) : null; + if (prefix == null && nsURI != null && !nsURI.equals("")) { + prefix = "p" + (counter++); + } + if (prefix == null) { + prefix = ""; + } + if (nsURI != null) { + prefixToNamespaceMapping.put(prefix, nsURI); + } + return new QName(nsURI, name, prefix); + } + + public String getNamespaceURI(String prefix) { + if (prefix == null) { + throw new IllegalArgumentException("Prefix is null"); + } + + String ns = (String) prefixToNamespaceMapping.get(prefix); + if (ns != null) { + return ns; + } else if (parent != null) { + return parent.getNamespaceURI(prefix); + } else { + return null; + } + } + + public String getPrefix(String nsURI) { + if (nsURI == null) { + throw new IllegalArgumentException("Namespace is null"); + } + for (Map.Entry<String, String> entry1 : prefixToNamespaceMapping.entrySet()) { + Map.Entry entry = entry1; + if (entry.getValue().equals(nsURI)) { + return (String) entry.getKey(); + } + } + if (parent != null) { + return parent.getPrefix(nsURI); + } else { + return null; + } + } + + public Iterator getPrefixes(String nsURI) { + List<String> prefixList = new ArrayList<String>(); + for (Map.Entry<String, String> entry : prefixToNamespaceMapping.entrySet()) { + if (entry.getValue().equals(nsURI)) { + prefixList.add(entry.getKey()); + } + } + if (parent != null) { + for (Iterator i = parent.getPrefixes(nsURI); i.hasNext();) { + prefixList.add((String) i.next()); + } + } + return prefixList.iterator(); + } + + public void registerMapping(String prefix, String nsURI) { + prefixToNamespaceMapping.put(prefix, nsURI); + } + + public void removeMapping(String prefix) { + prefixToNamespaceMapping.remove(prefix); + } + + public void setParent(NamespaceContext parent) { + this.parent = parent; + } + } + + protected static class NameValuePair implements Map.Entry { + private Object key; + + private Object value; + + public NameValuePair(Object key, Object value) { + this.key = key; + this.value = value; + } + + public Object getKey() { + return key; + } + + public Object getValue() { + return value; + } + + public Object setValue(Object value) { + Object v = this.value; + this.value = value; + return v; + } + + } + + protected static class SimpleElementStreamReader implements XMLFragmentStreamReader { + + private static final int END_ELEMENT_STATE = 2; + + private static final int START_ELEMENT_STATE = 0; + + private static final int START_ELEMENT_STATE_WITH_NULL = 3; + + private static final int TEXT_STATE = 1; + + private static final QName XSI_NIL_QNAME = + new QName("http://www.w3.org/2001/XMLSchema-instance", "nil", "xsi"); + + private QName name; + + private DelegatingNamespaceContext namespaceContext = new DelegatingNamespaceContext(null); + + private int state = START_ELEMENT_STATE; + + private String value; + + public SimpleElementStreamReader(QName name, String value) { + this.name = name; + this.value = value; + if (value == null) { + state = START_ELEMENT_STATE_WITH_NULL; + } + } + + public void close() throws XMLStreamException { + // Do nothing - we've nothing to free here + } + + public int getAttributeCount() { + if (state == START_ELEMENT_STATE_WITH_NULL) { + return 1; + } + if (state == START_ELEMENT_STATE) { + return 0; + } else { + throw new IllegalStateException(); + } + + } + + public String getAttributeLocalName(int i) { + if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) { + return XSI_NIL_QNAME.getLocalPart(); + } + if (state == START_ELEMENT_STATE) { + return null; + } else { + throw new IllegalStateException(); + } + } + + public QName getAttributeName(int i) { + if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) { + return XSI_NIL_QNAME; + } + if (state == START_ELEMENT_STATE) { + return null; + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeNamespace(int i) { + if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) { + return XSI_NIL_QNAME.getNamespaceURI(); + } + if (state == START_ELEMENT_STATE) { + return null; + } else { + throw new IllegalStateException(); + } + } + + public String getAttributePrefix(int i) { + if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) { + return XSI_NIL_QNAME.getPrefix(); + } + if (state == START_ELEMENT_STATE) { + return null; + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeType(int i) { + return null; // not implemented + } + + public String getAttributeValue(int i) { + if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) { + return "true"; + } + if (state == START_ELEMENT_STATE) { + return null; + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeValue(String string, String string1) { + if (state == TEXT_STATE) { + // todo something + return null; + } else { + return null; + } + + } + + public String getCharacterEncodingScheme() { + return null; + } + + public String getElementText() throws XMLStreamException { + if (state == START_ELEMENT) { + // move to the end state and return the value + state = END_ELEMENT_STATE; + return value; + } else { + throw new XMLStreamException(); + } + + } + + public String getEncoding() { + return "UTF-8"; + } + + public int getEventType() { + switch (state) { + case START_ELEMENT_STATE: + case START_ELEMENT_STATE_WITH_NULL: + return START_ELEMENT; + case END_ELEMENT_STATE: + return END_ELEMENT; + case TEXT_STATE: + return CHARACTERS; + default: + throw new UnsupportedOperationException(); + // we've no idea what this is!!!!! + } + + } + + public String getLocalName() { + if (state != TEXT_STATE) { + return name.getLocalPart(); + } else { + return null; + } + } + + public Location getLocation() { + return new Location() { + public int getCharacterOffset() { + return 0; + } + + public int getColumnNumber() { + return 0; + } + + public int getLineNumber() { + return 0; + } + + public String getPublicId() { + return null; + } + + public String getSystemId() { + return null; + } + }; + } + + public QName getName() { + if (state != TEXT_STATE) { + return name; + } else { + return null; + } + } + + public NamespaceContext getNamespaceContext() { + return this.namespaceContext; + } + + public int getNamespaceCount() { + if (state == START_ELEMENT_STATE_WITH_NULL && isXsiNamespacePresent()) { + return 1; + } else { + return 0; + } + + } + + public String getNamespacePrefix(int i) { + if (state == START_ELEMENT_STATE_WITH_NULL && isXsiNamespacePresent() && i == 0) { + return XSI_NIL_QNAME.getPrefix(); + } else { + return null; + } + } + + public String getNamespaceURI() { + if (state != TEXT_STATE) { + return name.getNamespaceURI(); + } else { + return null; + } + + } + + public String getNamespaceURI(int i) { + if (state == START_ELEMENT_STATE_WITH_NULL && isXsiNamespacePresent() && i == 0) { + return XSI_NIL_QNAME.getNamespaceURI(); + } else { + return null; + } + } + + public String getNamespaceURI(String prefix) { + return namespaceContext.getNamespaceURI(prefix); + } + + public String getPIData() { + return null; + } + + public String getPITarget() { + return null; + } + + public String getPrefix() { + if (state != TEXT_STATE) { + return name.getPrefix(); + } else { + return null; + } + } + + public Object getProperty(String key) throws IllegalArgumentException { + return null; + } + + public String getText() { + if (state == TEXT_STATE) { + return value; + } else { + throw new IllegalStateException(); + } + } + + public char[] getTextCharacters() { + if (state == TEXT_STATE) { + return value.toCharArray(); + } else { + throw new IllegalStateException(); + } + } + + public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException { + // not implemented + throw new UnsupportedOperationException(); + } + + public int getTextLength() { + if (state == TEXT_STATE) { + return value.length(); + } else { + throw new IllegalStateException(); + } + + } + + public int getTextStart() { + if (state == TEXT_STATE) { + return 0; + } else { + throw new IllegalStateException(); + } + } + + public String getVersion() { + return null; // todo 1.0 ? + } + + public boolean hasName() { + return state != TEXT_STATE; + + } + + public boolean hasNext() throws XMLStreamException { + return state != END_ELEMENT_STATE; + } + + public boolean hasText() { + return state == TEXT_STATE; + } + + public void init() { + // just add the current elements namespace and prefix to the this + // elements nscontext + registerNamespace(name.getPrefix(), name.getNamespaceURI()); + + } + + public boolean isAttributeSpecified(int i) { + return false; // no attribs here + } + + public boolean isCharacters() { + return state == TEXT_STATE; + } + + public boolean isEndElement() { + return state == END_ELEMENT_STATE; + } + + public boolean isEndOfFragment() { + return state == END_ELEMENT_STATE; + } + + public boolean isStandalone() { + return false; + } + + public boolean isStartElement() { + return state == START_ELEMENT_STATE || state == START_ELEMENT_STATE_WITH_NULL; + } + + public boolean isWhiteSpace() { + return false; // no whitespaces here + } + + /** + * Test whether the xsi namespace is present + * + * @return + */ + private boolean isXsiNamespacePresent() { + return namespaceContext.getNamespaceURI(XSI_NIL_QNAME.getPrefix()) != null; + } + + public int next() throws XMLStreamException { + switch (state) { + case START_ELEMENT_STATE: + state = TEXT_STATE; + return CHARACTERS; + case START_ELEMENT_STATE_WITH_NULL: + state = END_ELEMENT_STATE; + return END_ELEMENT; + case END_ELEMENT_STATE: + // oops, not supposed to happen! + throw new XMLStreamException("end already reached!"); + case TEXT_STATE: + state = END_ELEMENT_STATE; + return END_ELEMENT; + default: + throw new XMLStreamException("unknown event type!"); + } + } + + public int nextTag() throws XMLStreamException { + return 0; // todo + } + + /** + * @param prefix + * @param uri + */ + private void registerNamespace(String prefix, String uri) { + // todo - need to fix this up to cater for cases where + // namespaces are having no prefixes + if (!uri.equals(namespaceContext.getNamespaceURI(prefix))) { + // this namespace is not there. Need to declare it + namespaceContext.registerMapping(prefix, uri); + } + } + + public void require(int i, String string, String string1) throws XMLStreamException { + // not implemented + } + + public void setParentNamespaceContext(NamespaceContext nsContext) { + this.namespaceContext.setParent(nsContext); + } + + public boolean standaloneSet() { + return false; + } + + } + + private static final int DELEGATED_STATE = 2; + + private static final int END_ELEMENT_STATE = 1; + + // states for this pullparser - it can only have three states + private static final int START_ELEMENT_STATE = 0; + + private static final int TEXT_STATE = 3; + + private Map.Entry[] attributes; + + // reference to the child reader + private XMLFragmentStreamReader childReader; + + // current property index + private int currentPropertyIndex; + + private Map<String, String> declaredNamespaceMap = new HashMap<String, String>(); + + private QName elementQName; + + // we always create a new namespace context + private DelegatingNamespaceContext namespaceContext = new DelegatingNamespaceContext(null); + + private Map.Entry[] properties; + + private Element rootElement; + + private String rootElementName; + + private String rootElementURI; + + // integer field that keeps the state of this + // parser. + private int state = START_ELEMENT_STATE; + + public DOMXMLStreamReader(Node node) { + switch (node.getNodeType()) { + case Node.DOCUMENT_NODE: + this.rootElement = ((Document) node).getDocumentElement(); + break; + case Node.ELEMENT_NODE: + this.rootElement = (Element) node; + break; + default: + throw new IllegalArgumentException("Illegal Node"); + } + this.rootElementName = rootElement.getLocalName(); + this.rootElementURI = rootElement.getNamespaceURI(); + + declaredNamespaceMap.put("xml", "http://www.w3.org/XML/1998/namespace"); + declaredNamespaceMap.put("xmlns", "http://www.w3.org/2000/xmlns/"); + declaredNamespaceMap.put("xsi", "http://www.w3.org/2001/XMLSchema-instance"); + + populateProperties(); + } + + /* + * we need to pass in a namespace context since when delegated, we've no + * idea of the current namespace context. So it needs to be passed on here! + */ + protected DOMXMLStreamReader(QName elementQName, Map.Entry[] properties, Map.Entry[] attributes) { + // validate the lengths, since both the arrays are supposed + // to have + this.properties = properties; + this.elementQName = elementQName; + this.attributes = attributes; + + } + + public void close() throws XMLStreamException { + // do nothing here - we have no resources to free + } + + public int getAttributeCount() { + return (state == DELEGATED_STATE) ? childReader.getAttributeCount() + : ((attributes != null) && (state == START_ELEMENT_STATE) ? attributes.length : 0); + } + + public String getAttributeLocalName(int i) { + if (state == DELEGATED_STATE) { + return childReader.getAttributeLocalName(i); + } else if (state == START_ELEMENT_STATE) { + QName name = getAttributeName(i); + if (name == null) { + return null; + } else { + return name.getLocalPart(); + } + } else { + throw new IllegalStateException(); + } + } + + /** + * @param i + * @return + */ + public QName getAttributeName(int i) { + if (state == DELEGATED_STATE) { + return childReader.getAttributeName(i); + } else if (state == START_ELEMENT_STATE) { + if (attributes == null) { + return null; + } else { + if ((i >= (attributes.length)) || i < 0) { // out of range + return null; + } else { + // get the attribute pointer + Object attribPointer = attributes[i].getKey(); + // case one - attrib name is null + // this should be the pointer to the OMAttribute then + if (attribPointer instanceof String) { + return new QName((String) attribPointer); + } else if (attribPointer instanceof QName) { + return (QName) attribPointer; + } else { + return null; + } + } + } + } else { + throw new IllegalStateException(); // as per the api contract + } + + } + + public String getAttributeNamespace(int i) { + if (state == DELEGATED_STATE) { + return childReader.getAttributeNamespace(i); + } else if (state == START_ELEMENT_STATE) { + QName name = getAttributeName(i); + if (name == null) { + return null; + } else { + return name.getNamespaceURI(); + } + } else { + throw new IllegalStateException(); + } + } + + public String getAttributePrefix(int i) { + if (state == DELEGATED_STATE) { + return childReader.getAttributePrefix(i); + } else if (state == START_ELEMENT_STATE) { + QName name = getAttributeName(i); + if (name == null) { + return null; + } else { + return name.getPrefix(); + } + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeType(int i) { + return null; // not supported + } + + public String getAttributeValue(int i) { + if (state == DELEGATED_STATE) { + return childReader.getAttributeValue(i); + } else if (state == START_ELEMENT_STATE) { + if (attributes == null) { + return null; + } else { + if ((i >= (attributes.length)) || i < 0) { // out of range + return null; + } else { + // get the attribute pointer + Object attribPointer = attributes[i].getKey(); + Object omAttribObj = attributes[i].getValue(); + // case one - attrib name is null + // this should be the pointer to the OMAttribute then + if (attribPointer instanceof String) { + return (String) omAttribObj; + } else if (attribPointer instanceof QName) { + return (String) omAttribObj; + } else { + return null; + } + } + } + } else { + throw new IllegalStateException(); + } + + } + + public String getAttributeValue(String nsUri, String localName) { + + int attribCount = getAttributeCount(); + String returnValue = null; + QName attribQualifiedName; + for (int i = 0; i < attribCount; i++) { + attribQualifiedName = getAttributeName(i); + if (nsUri == null) { + if (localName.equals(attribQualifiedName.getLocalPart())) { + returnValue = getAttributeValue(i); + break; + } + } else { + if (localName.equals(attribQualifiedName.getLocalPart()) && nsUri.equals(attribQualifiedName + .getNamespaceURI())) { + returnValue = getAttributeValue(i); + break; + } + } + + } + + return returnValue; + } + + public String getCharacterEncodingScheme() { + return null; // todo - should we return something for this ? + } + + /** + * todo implement the right contract for this + * + * @return + * @throws XMLStreamException + */ + public String getElementText() throws XMLStreamException { + if (state == DELEGATED_STATE) { + return childReader.getElementText(); + } else { + return null; + } + + } + + public String getEncoding() { + if (state == DELEGATED_STATE) { + return childReader.getEncoding(); + } else { + // we've no idea what the encoding is going to be in this case + // perhaps we ought to return some constant here, which the user + // might + // have access to change! + return null; + } + } + + // ///////////////////////////////////////////////////////////////////////// + // / attribute handling + // ///////////////////////////////////////////////////////////////////////// + + public int getEventType() { + if (state == START_ELEMENT_STATE) { + return START_ELEMENT; + } else if (state == END_ELEMENT_STATE) { + return END_ELEMENT; + } else { // this is the delegated state + return childReader.getEventType(); + } + + } + + public String getLocalName() { + if (state == DELEGATED_STATE) { + return childReader.getLocalName(); + } else if (state != TEXT_STATE) { + return elementQName.getLocalPart(); + } else { + throw new IllegalStateException(); + } + } + + /** + * @return + */ + public Location getLocation() { + // return a default location + return new Location() { + public int getCharacterOffset() { + return 0; + } + + public int getColumnNumber() { + return 0; + } + + public int getLineNumber() { + return 0; + } + + public String getPublicId() { + return null; + } + + public String getSystemId() { + return null; + } + }; + } + + public QName getName() { + if (state == DELEGATED_STATE) { + return childReader.getName(); + } else if (state != TEXT_STATE) { + return elementQName; + } else { + throw new IllegalStateException(); + } + + } + + public NamespaceContext getNamespaceContext() { + if (state == DELEGATED_STATE) { + return childReader.getNamespaceContext(); + } else { + return namespaceContext; + } + + } + + public int getNamespaceCount() { + if (state == DELEGATED_STATE) { + return childReader.getNamespaceCount(); + } else { + return declaredNamespaceMap.size(); + } + } + + /** + * @param i + * @return + */ + public String getNamespacePrefix(int i) { + if (state == DELEGATED_STATE) { + return childReader.getNamespacePrefix(i); + } else if (state != TEXT_STATE) { + // order the prefixes + String[] prefixes = makePrefixArray(); + if ((i >= prefixes.length) || (i < 0)) { + return null; + } else { + return prefixes[i]; + } + + } else { + throw new IllegalStateException(); + } + + } + + public String getNamespaceURI() { + if (state == DELEGATED_STATE) { + return childReader.getNamespaceURI(); + } else if (state == TEXT_STATE) { + return null; + } else { + return elementQName.getNamespaceURI(); + } + } + + public String getNamespaceURI(int i) { + if (state == DELEGATED_STATE) { + return childReader.getNamespaceURI(i); + } else if (state != TEXT_STATE) { + String namespacePrefix = getNamespacePrefix(i); + return namespacePrefix == null ? null : (String) declaredNamespaceMap.get(namespacePrefix); + } else { + throw new IllegalStateException(); + } + + } + + // ///////////////////////////////////////////////////////////////////////// + // //////////// end of attribute handling + // ///////////////////////////////////////////////////////////////////////// + + // ////////////////////////////////////////////////////////////////////////// + // //////////// namespace handling + // ////////////////////////////////////////////////////////////////////////// + + public String getNamespaceURI(String prefix) { + return namespaceContext.getNamespaceURI(prefix); + } + + public String getPIData() { + throw new UnsupportedOperationException("Yet to be implemented !!"); + } + + public String getPITarget() { + throw new UnsupportedOperationException("Yet to be implemented !!"); + } + + public String getPrefix() { + if (state == DELEGATED_STATE) { + return childReader.getPrefix(); + } else if (state == TEXT_STATE) { + return null; + } else { + return elementQName.getPrefix(); + } + } + + /** + * @param key + * @return + * @throws IllegalArgumentException + */ + public Object getProperty(String key) throws IllegalArgumentException { + if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) { + return null; + } else if (state == TEXT_STATE) { + return null; + } else if (state == DELEGATED_STATE) { + return childReader.getProperty(key); + } else { + return null; + } + + } + + // ///////////////////////////////////////////////////////////////////////// + // /////// end of namespace handling + // ///////////////////////////////////////////////////////////////////////// + + public String getText() { + if (state == DELEGATED_STATE) { + return childReader.getText(); + } else if (state == TEXT_STATE) { + return (String) properties[currentPropertyIndex - 1].getValue(); + } else { + throw new IllegalStateException(); + } + } + + public char[] getTextCharacters() { + if (state == DELEGATED_STATE) { + return childReader.getTextCharacters(); + } else if (state == TEXT_STATE) { + return properties[currentPropertyIndex - 1].getValue() == null ? new char[0] + : ((String) properties[currentPropertyIndex - 1].getValue()).toCharArray(); + } else { + throw new IllegalStateException(); + } + } + + public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException { + if (state == DELEGATED_STATE) { + return childReader.getTextCharacters(i, chars, i1, i2); + } else if (state == TEXT_STATE) { + // todo - implement this + return 0; + } else { + throw new IllegalStateException(); + } + } + + public int getTextLength() { + if (state == DELEGATED_STATE) { + return childReader.getTextLength(); + } else if (state == TEXT_STATE) { + return 0; // assume text always starts at 0 + } else { + throw new IllegalStateException(); + } + } + + public int getTextStart() { + if (state == DELEGATED_STATE) { + return childReader.getTextStart(); + } else if (state == TEXT_STATE) { + return 0; // assume text always starts at 0 + } else { + throw new IllegalStateException(); + } + } + + public String getVersion() { + return null; + } + + public boolean hasName() { + // since this parser always has a name, the hasname + // has to return true if we are still navigating this element + // if not we should ask the child reader for it. + if (state == DELEGATED_STATE) { + return childReader.hasName(); + } else { + return state != TEXT_STATE; + } + } + + /** + * @return + * @throws XMLStreamException + */ + public boolean hasNext() throws XMLStreamException { + if (state == DELEGATED_STATE) { + if (childReader.isEndOfFragment()) { + // the child reader is done. We shouldn't be getting the + // hasnext result from the child pullparser then + return true; + } else { + return childReader.hasNext(); + } + } else { + return state == START_ELEMENT_STATE || state == TEXT_STATE; + + } + } + + /** + * check the validity of this implementation + * + * @return + */ + public boolean hasText() { + if (state == DELEGATED_STATE) { + return childReader.hasText(); + } else { + return state == TEXT_STATE; + } + } + + /** + * we need to split out the calling to the populate namespaces seperately since this needs to be done *after* + * setting the parent namespace context. We cannot assume it will happen at construction! + */ + public void init() { + // here we have an extra issue to attend to. we need to look at the + // prefixes and uris (the combination) and populate a hashmap of + // namespaces. The hashmap of namespaces will be used to serve the + // namespace context + + populateNamespaceContext(); + } + + public boolean isAttributeSpecified(int i) { + return false; // not supported + } + + public boolean isCharacters() { + if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) { + return false; + } + return childReader.isCharacters(); + } + + public boolean isEndElement() { + if (state == START_ELEMENT_STATE) { + return false; + } else if (state == END_ELEMENT_STATE) { + return true; + } + return childReader.isEndElement(); + } + + /** + * are we done ? + * + * @return + */ + public boolean isEndOfFragment() { + return state == END_ELEMENT_STATE; + } + + public boolean isStandalone() { + return true; + } + + public boolean isStartElement() { + if (state == START_ELEMENT_STATE) { + return true; + } else if (state == END_ELEMENT_STATE) { + return false; + } + return childReader.isStartElement(); + } + + public boolean isWhiteSpace() { + if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) { + return false; + } + return childReader.isWhiteSpace(); + } + + /** + * Get the prefix list from the hastable and take that into an array + * + * @return + */ + private String[] makePrefixArray() { + String[] prefixes = + (String[]) declaredNamespaceMap.keySet().toArray(new String[declaredNamespaceMap.size()]); + Arrays.sort(prefixes); + return prefixes; + } + + public int next() throws XMLStreamException { + return updateStatus(); + } + + /** + * todo implement this + * + * @return + * @throws XMLStreamException + */ + public int nextTag() throws XMLStreamException { + return 0; + } + + // ///////////////////////////////////////////////////////////////////////// + // / Other utility methods + // //////////////////////////////////////////////////////////////////////// + + /** + * Populates a namespace context + */ + private void populateNamespaceContext() { + + // first add the current element namespace to the namespace context + // declare it if not found + registerNamespace(elementQName.getPrefix(), elementQName.getNamespaceURI()); + + // traverse through the attributes and populate the namespace context + // the attrib list can be of many combinations + // the valid combinations are + // String - String + // QName - QName + // null - OMAttribute + + if (attributes != null) { + for (int i = 0; i < attributes.length; i++) { // jump in two + Object attribName = attributes[i].getKey(); + if (attribName instanceof String) { + // ignore this case - Nothing to do + } else if (attribName instanceof QName) { + QName attribQName = (QName) attribName; + registerNamespace(attribQName.getPrefix(), attribQName.getNamespaceURI()); + + } + } + } + + } + + public final void populateProperties() { + if (properties != null) { + return; + } + if (elementQName == null) { + elementQName = namespaceContext.createQName(this.rootElementURI, this.rootElementName); + } else { + elementQName = + namespaceContext.createQName(elementQName.getNamespaceURI(), elementQName.getLocalPart()); + } + + List<Object> elementList = new ArrayList<Object>(); + List<Object> attributeList = new ArrayList<Object>(); + NamedNodeMap nodeMap = rootElement.getAttributes(); + for (int i = 0; i < nodeMap.getLength(); i++) { + Attr attr = (Attr) nodeMap.item(i); + if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(attr.getNamespaceURI())) { + // Skip xmlns:xxx + if (!attr.getName().equals(attr.getLocalName())) { + // Skip xmlns="..." + registerNamespace(attr.getLocalName(), attr.getValue()); + } else { + registerNamespace(XMLConstants.DEFAULT_NS_PREFIX, attr.getValue()); + } + continue; + } + QName attrName = new QName(attr.getNamespaceURI(), attr.getLocalName()); + NameValuePair pair = new NameValuePair(attrName, attr.getValue()); + attributeList.add(pair); + } + NodeList nodeList = rootElement.getChildNodes(); + for (int i = 0; i < nodeList.getLength(); i++) { + Node node = nodeList.item(i); + switch (node.getNodeType()) { + case Node.TEXT_NODE: + case Node.CDATA_SECTION_NODE: + NameValuePair pair = new NameValuePair(ELEMENT_TEXT, ((CharacterData) node).getData()); + elementList.add(pair); + break; + + case Node.ELEMENT_NODE: + Element element = (Element) node; + QName elementName = new QName(element.getNamespaceURI(), element.getLocalName()); + pair = new NameValuePair(elementName, new DOMXMLStreamReader(element)); + elementList.add(pair); + break; + } + } + properties = elementList.toArray(new Map.Entry[elementList.size()]); + attributes = attributeList.toArray(new Map.Entry[attributeList.size()]); + } + + /** + * A convenient method to reuse the properties + * + * @return event to be thrown + * @throws XMLStreamException + */ + private int processProperties() throws XMLStreamException { + // move to the next property depending on the current property + // index + Object propPointer = properties[currentPropertyIndex].getKey(); + QName propertyQName = null; + boolean textFound = false; + if (propPointer == null) { + throw new XMLStreamException("property key cannot be null!"); + } else if (propPointer instanceof String) { + // propPointer being a String has a special case + // that is it can be a the special constant ELEMENT_TEXT that + // says this text event + if (ELEMENT_TEXT.equals(propPointer)) { + textFound = true; + } else { + propertyQName = new QName((String) propPointer); + } + } else if (propPointer instanceof QName) { + propertyQName = (QName) propPointer; + } else { + // oops - we've no idea what kind of key this is + throw new XMLStreamException("unidentified property key!!!" + propPointer); + } + + // ok! we got the key. Now look at the value + Object propertyValue = properties[currentPropertyIndex].getValue(); + // cater for the special case now + if (textFound) { + // no delegation here - make the parser null and immediately + // return with the event characters + childReader = null; + state = TEXT_STATE; + currentPropertyIndex++; + return CHARACTERS; + } else if (propertyValue == null || propertyValue instanceof String) { + // strings are handled by the NameValuePairStreamReader + childReader = new SimpleElementStreamReader(propertyQName, (String) propertyValue); + childReader.setParentNamespaceContext(this.namespaceContext); + childReader.init(); + } else if (propertyValue instanceof DOMXMLStreamReader) { + // ADBbean has it's own method to get a reader + XMLFragmentStreamReader reader = (DOMXMLStreamReader) propertyValue; + // we know for sure that this is an ADB XMLStreamreader. + // However we need to make sure that it is compatible + childReader = reader; + childReader.setParentNamespaceContext(this.namespaceContext); + childReader.init(); + } else { + // all special possiblilities has been tried! Let's treat + // the thing as a bean and try generating events from it + throw new UnsupportedOperationException("Not supported"); + // childReader = new + // WrappingXMLStreamReader(BeanUtil.getPullParser(propertyValue, + // propertyQName)); + // we cannot register the namespace context here + } + + // set the state here + state = DELEGATED_STATE; + // we are done with the delegation + // increment the property index + currentPropertyIndex++; + return childReader.getEventType(); + } + + /** + * @param prefix + * @param uri + */ + private void registerNamespace(String prefix, String uri) { + if (!uri.equals(namespaceContext.getNamespaceURI(prefix))) { + namespaceContext.registerMapping(prefix, uri); + declaredNamespaceMap.put(prefix, uri); + } + } + + public void require(int i, String string, String string1) throws XMLStreamException { + throw new UnsupportedOperationException(); + } + + /** + * add the namespace context + */ + + public void setParentNamespaceContext(NamespaceContext nsContext) { + // register the namespace context passed in to this + this.namespaceContext.setParent(nsContext); + + } + + public boolean standaloneSet() { + return true; + } + + /** + * By far this should be the most important method in this class this method changes the state of the parser + * according to the change in the + */ + private int updateStatus() throws XMLStreamException { + int returnEvent = -1; // invalid state is the default state + switch (state) { + case START_ELEMENT_STATE: + // current element is start element. We should be looking at the + // property list and making a pullparser for the property value + if (properties == null || properties.length == 0) { + // no properties - move to the end element state + // straightaway + state = END_ELEMENT_STATE; + returnEvent = END_ELEMENT; + } else { + // there are properties. now we should delegate this task to + // a + // child reader depending on the property type + returnEvent = processProperties(); + + } + break; + case END_ELEMENT_STATE: + // we've reached the end element already. If the user tries to + // push + // further ahead then it is an exception + throw new XMLStreamException("Trying to go beyond the end of the pullparser"); + + case DELEGATED_STATE: + if (childReader.isEndOfFragment()) { + // we've reached the end! + if (currentPropertyIndex > (properties.length - 1)) { + state = END_ELEMENT_STATE; + returnEvent = END_ELEMENT; + } else { + returnEvent = processProperties(); + } + } else { + returnEvent = childReader.next(); + } + break; + + case TEXT_STATE: + // if there are any more event we should be delegating to + // processProperties. if not we just return an end element + if (currentPropertyIndex > (properties.length - 1)) { + state = END_ELEMENT_STATE; + returnEvent = END_ELEMENT; + } else { + returnEvent = processProperties(); + } + break; + } + return returnEvent; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2Node.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2Node.java new file mode 100644 index 0000000000..e9757fa13c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2Node.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.core.databinding.xml; + +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.stream.StreamSource; + +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; +import org.w3c.dom.Node; +import org.xml.sax.InputSource; + +/** + * Push DOM InputSource to Node + */ +@Service(Transformer.class) +public class InputSource2Node extends TransformerExtension<InputSource, Node> implements + PullTransformer<InputSource, Node> { + private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer(); + + public Node transform(InputSource source, TransformationContext context) { + try { + Source streamSource = new StreamSource(source.getCharacterStream()); + DOMResult result = new DOMResult(); + TRANSFORMER.transform(streamSource, result, context); + return result.getNode(); + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return InputSource.class; + } + + public Class getTargetType() { + return Node.class; + } + + public int getWeight() { + return 40; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2SAX.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2SAX.java new file mode 100644 index 0000000000..be78a07ede --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2SAX.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.core.databinding.xml; + +import org.apache.tuscany.spi.databinding.PushTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLReaderFactory; + +/** + * Push InputSource to SAX + */ +@Service(Transformer.class) +public class InputSource2SAX extends TransformerExtension<InputSource, ContentHandler> implements + PushTransformer<InputSource, ContentHandler> { + + public void transform(InputSource source, ContentHandler target, TransformationContext context) { + try { + XMLReader reader = XMLReaderFactory.createXMLReader(); + reader.setFeature("http://xml.org/sax/features/namespaces", true); + reader.setFeature("http://xml.org/sax/features/namespace-prefixes", false); + reader.setContentHandler(target); + reader.parse(source); + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return InputSource.class; + } + + public Class getTargetType() { + return ContentHandler.class; + } + + public int getWeight() { + return 40; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2Node.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2Node.java new file mode 100644 index 0000000000..e103c82b33 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2Node.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.databinding.xml; + +import java.io.InputStream; + +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.sax.SAXSource; + +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; +import org.w3c.dom.Node; +import org.xml.sax.InputSource; + +/** + * Push DOM InputSource to Node + */ +@Service(Transformer.class) +public class InputStream2Node extends TransformerExtension<InputStream, Node> implements + PullTransformer<InputStream, Node> { + private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer(); + + public Node transform(InputStream source, TransformationContext context) { + try { + Source streamSource = new SAXSource(new InputSource(source)); + DOMResult result = new DOMResult(); + TRANSFORMER.transform(streamSource, result, context); + return result.getNode(); + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return InputStream.class; + } + + public Class getTargetType() { + return Node.class; + } + + public int getWeight() { + return 40; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2SAX.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2SAX.java new file mode 100644 index 0000000000..d74863ea95 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2SAX.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.core.databinding.xml; + +import java.io.InputStream; + +import org.apache.tuscany.spi.databinding.PushTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLReaderFactory; + +/** + * Push InputStream to SAX + */ +@Service(Transformer.class) +public class InputStream2SAX extends TransformerExtension<InputStream, ContentHandler> implements + PushTransformer<InputStream, ContentHandler> { + public void transform(InputStream source, ContentHandler target, TransformationContext context) { + try { + XMLReader reader = XMLReaderFactory.createXMLReader(); + reader.setContentHandler(target); + reader.parse(new InputSource(source)); + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return InputStream.class; + } + + public Class getTargetType() { + return ContentHandler.class; + } + + public int getWeight() { + return 40; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2OutputStream.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2OutputStream.java new file mode 100644 index 0000000000..34fbdf8c6f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2OutputStream.java @@ -0,0 +1,66 @@ +/* + * 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.core.databinding.xml; + +import java.io.OutputStream; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.tuscany.spi.databinding.PushTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; +import org.w3c.dom.Node; + +/** + * Push DOM Node to OutputStream + */ +@Service(Transformer.class) +public class Node2OutputStream extends TransformerExtension<Node, OutputStream> implements + PushTransformer<Node, OutputStream> { + private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer(); + + public void transform(Node source, OutputStream writer, TransformationContext context) { + try { + Source domSource = new DOMSource(source); + Result result = new StreamResult(writer); + TRANSFORMER.transform(domSource, result, context); + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return Node.class; + } + + public Class getTargetType() { + return OutputStream.class; + } + + public int getWeight() { + return 40; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2String.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2String.java new file mode 100755 index 0000000000..92378e96a3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2String.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.core.databinding.xml; + +import java.io.StringWriter; + +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; +import org.w3c.dom.Node; + +/** + * Transform DOM Node to XML String + */ +@Service(org.apache.tuscany.spi.databinding.Transformer.class) +public class Node2String extends TransformerExtension<Node, String> implements PullTransformer<Node, String> { + private static final Node2Writer TRANSFORMER = new Node2Writer(); + + public String transform(Node source, TransformationContext context) { + try { + StringWriter writer = new StringWriter(); + TRANSFORMER.transform(source, writer, context); + return writer.toString(); + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return Node.class; + } + + public Class getTargetType() { + return String.class; + } + + public int getWeight() { + return 40; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2Writer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2Writer.java new file mode 100644 index 0000000000..96328fdd2f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2Writer.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.core.databinding.xml; + +import java.io.Writer; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.tuscany.spi.databinding.PushTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; +import org.w3c.dom.Node; + +/** + * Push DOM Node to Writer + */ +@Service(Transformer.class) +public class Node2Writer extends TransformerExtension<Node, Writer> implements PushTransformer<Node, Writer> { + private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer(); + + public void transform(Node source, Writer writer, TransformationContext context) { + try { + Source domSource = new DOMSource(source); + Result result = new StreamResult(writer); + TRANSFORMER.transform(domSource, result, context); + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return Node.class; + } + + public Class getTargetType() { + return Writer.class; + } + + public int getWeight() { + return 40; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2XMLStreamReader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2XMLStreamReader.java new file mode 100644 index 0000000000..bff9051e01 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2XMLStreamReader.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.databinding.xml; + +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.core.databinding.xml.StAXHelper.XMLDocumentStreamReader; +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; +import org.w3c.dom.Node; + +/** + * Transform DOM Node to XML XMLStreamReader + */ +@Service(Transformer.class) +public class Node2XMLStreamReader extends TransformerExtension<Node, XMLStreamReader> implements + PullTransformer<Node, XMLStreamReader> { + + public XMLStreamReader transform(Node source, TransformationContext context) { + try { + DOMXMLStreamReader reader = new DOMXMLStreamReader(source); + return new XMLDocumentStreamReader(reader); + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return Node.class; + } + + public Class getTargetType() { + return XMLStreamReader.class; + } + + public int getWeight() { + return 40; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2Node.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2Node.java new file mode 100644 index 0000000000..02de055c35 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2Node.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.core.databinding.xml; + +import java.io.Reader; + +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.stream.StreamSource; + +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; +import org.w3c.dom.Node; + +/** + * Push DOM Reader to Node + */ +@Service(Transformer.class) +public class Reader2Node extends TransformerExtension<Reader, Node> implements PullTransformer<Reader, Node> { + private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer(); + + public Node transform(Reader source, TransformationContext context) { + try { + Source streamSource = new StreamSource(source); + DOMResult result = new DOMResult(); + TRANSFORMER.transform(streamSource, result, context); + return result.getNode(); + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return Reader.class; + } + + public Class getTargetType() { + return Node.class; + } + + public int getWeight() { + return 40; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2SAX.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2SAX.java new file mode 100644 index 0000000000..0a4504b3de --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2SAX.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.core.databinding.xml; + +import java.io.Reader; + +import org.apache.tuscany.spi.databinding.PushTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; + +/** + * Transform XML string to SAX + */ +@Service(Transformer.class) +public class Reader2SAX extends TransformerExtension<Reader, ContentHandler> implements + PushTransformer<Reader, ContentHandler> { + public void transform(Reader source, ContentHandler target, TransformationContext context) { + try { + new InputSource2SAX().transform(new InputSource(source), target, context); + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return Reader.class; + } + + public Class getTargetType() { + return ContentHandler.class; + } + + public int getWeight() { + return 40; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOM.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOM.java new file mode 100644 index 0000000000..8f8f0f952e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOM.java @@ -0,0 +1,244 @@ +/* + * Copyright 2001-2004 The Apache Software Foundation. + * + * 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.core.databinding.xml; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.tuscany.spi.databinding.extension.DOMHelper; +import org.w3c.dom.Comment; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.ProcessingInstruction; +import org.w3c.dom.Text; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.ext.LexicalHandler; + +/** + * SAX2DOM adapter + */ +public class SAX2DOM implements ContentHandler, LexicalHandler { + public static final String EMPTYSTRING = ""; + public static final String XML_PREFIX = "xml"; + public static final String XMLNS_PREFIX = "xmlns"; + public static final String XMLNS_STRING = "xmlns:"; + public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/"; + + private Node root; + + private Document document; + + private Node nextSibling; + + private Stack<Node> nodeStk = new Stack<Node>(); + + private List<String> namespaceDecls; + + private Node lastSibling; + + public SAX2DOM() throws ParserConfigurationException { + this.document = DOMHelper.newDocument(); + this.root = document; + } + + public SAX2DOM(Node root, Node nextSibling) throws ParserConfigurationException { + this.root = root; + if (root instanceof Document) { + this.document = (Document)root; + } else if (root != null) { + this.document = root.getOwnerDocument(); + } else { + this.document = DOMHelper.newDocument(); + this.root = document; + } + + this.nextSibling = nextSibling; + } + + public SAX2DOM(Node root) throws ParserConfigurationException { + this(root, null); + } + + public Node getDOM() { + return root; + } + + public void characters(char[] ch, int start, int length) { + final Node last = (Node)nodeStk.peek(); + + // No text nodes can be children of root (DOM006 exception) + if (last != document) { + final String text = new String(ch, start, length); + if (lastSibling != null && lastSibling.getNodeType() == Node.TEXT_NODE) { + ((Text)lastSibling).appendData(text); + } else if (last == root && nextSibling != null) { + lastSibling = last.insertBefore(document.createTextNode(text), nextSibling); + } else { + lastSibling = last.appendChild(document.createTextNode(text)); + } + + } + } + + public void startDocument() { + nodeStk.push(root); + } + + public void endDocument() { + nodeStk.pop(); + } + + public void startElement(String namespace, String localName, String qName, Attributes attrs) { + final Element tmp = (Element)document.createElementNS(namespace, qName); + + // Add namespace declarations first + if (namespaceDecls != null) { + final int nDecls = namespaceDecls.size(); + for (int i = 0; i < nDecls; i++) { + final String prefix = (String)namespaceDecls.get(i++); + + if (prefix == null || prefix.equals(EMPTYSTRING)) { + tmp.setAttributeNS(XMLNS_URI, XMLNS_PREFIX, (String)namespaceDecls.get(i)); + } else { + tmp.setAttributeNS(XMLNS_URI, XMLNS_STRING + prefix, (String)namespaceDecls.get(i)); + } + } + namespaceDecls.clear(); + } + + // Add attributes to element + final int nattrs = attrs.getLength(); + for (int i = 0; i < nattrs; i++) { + if (attrs.getLocalName(i) == null) { + tmp.setAttribute(attrs.getQName(i), attrs.getValue(i)); + } else { + tmp.setAttributeNS(attrs.getURI(i), attrs.getQName(i), attrs.getValue(i)); + } + } + + // Append this new node onto current stack node + Node last = (Node)nodeStk.peek(); + + // If the SAX2DOM is created with a non-null next sibling node, + // insert the result nodes before the next sibling under the root. + if (last == root && nextSibling != null) { + last.insertBefore(tmp, nextSibling); + } else { + last.appendChild(tmp); + } + + // Push this node onto stack + nodeStk.push(tmp); + lastSibling = null; + } + + public void endElement(String namespace, String localName, String qName) { + nodeStk.pop(); + lastSibling = null; + } + + public void startPrefixMapping(String prefix, String uri) { + if (namespaceDecls == null) { + namespaceDecls = new ArrayList<String>(2); + } + namespaceDecls.add(prefix); + namespaceDecls.add(uri); + } + + public void endPrefixMapping(String prefix) { + // do nothing + } + + /** + * This class is only used internally so this method should never be called. + */ + public void ignorableWhitespace(char[] ch, int start, int length) { + } + + /** + * adds processing instruction node to DOM. + */ + public void processingInstruction(String target, String data) { + final Node last = (Node)nodeStk.peek(); + ProcessingInstruction pi = document.createProcessingInstruction(target, data); + if (pi != null) { + if (last == root && nextSibling != null) { + last.insertBefore(pi, nextSibling); + } else { + last.appendChild(pi); + } + + lastSibling = pi; + } + } + + /** + * This class is only used internally so this method should never be called. + */ + public void setDocumentLocator(Locator locator) { + } + + /** + * This class is only used internally so this method should never be called. + */ + public void skippedEntity(String name) { + } + + /** + * Lexical Handler method to create comment node in DOM tree. + */ + public void comment(char[] ch, int start, int length) { + final Node last = (Node)nodeStk.peek(); + Comment comment = document.createComment(new String(ch, start, length)); + if (comment != null) { + if (last == root && nextSibling != null) { + last.insertBefore(comment, nextSibling); + } else { + last.appendChild(comment); + } + + lastSibling = comment; + } + } + + // Lexical Handler methods- not implemented + public void startCDATA() { + } + + public void endCDATA() { + } + + public void startEntity(java.lang.String name) { + } + + public void endDTD() { + } + + public void endEntity(String name) { + } + + public void startDTD(String name, String publicId, String systemId) throws SAXException { + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOMPipe.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOMPipe.java new file mode 100644 index 0000000000..79118b4a2c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOMPipe.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.databinding.xml; + +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.tuscany.spi.databinding.DataPipe; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; +import org.w3c.dom.Node; +import org.xml.sax.ContentHandler; + +@Service(Transformer.class) +public class SAX2DOMPipe extends TransformerExtension<ContentHandler, Node> implements + DataPipe<ContentHandler, Node> { + private SAX2DOM pipe; + + /** + * + */ + public SAX2DOMPipe() { + super(); + try { + this.pipe = new SAX2DOM(); + } catch (ParserConfigurationException e) { + throw new IllegalArgumentException(e); + } + } + + public Node getResult() { + return pipe.getDOM(); + } + + public Class getTargetType() { + return Node.class; + } + + public ContentHandler getSink() { + return pipe; + } + + public Class getSourceType() { + return ContentHandler.class; + } + + public int getWeight() { + return 30; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Source2ResultTransformer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Source2ResultTransformer.java new file mode 100755 index 0000000000..7db14efb39 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Source2ResultTransformer.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.databinding.xml; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerFactory; + +import org.apache.tuscany.spi.databinding.PushTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; + +/** + * Transform TrAX Source to Result + */ +@Service(org.apache.tuscany.spi.databinding.Transformer.class) +public class Source2ResultTransformer extends TransformerExtension<Source, Result> implements + PushTransformer<Source, Result> { + private static final TransformerFactory FACTORY = TransformerFactory.newInstance(); + + public void transform(Source source, Result result, TransformationContext context) { + try { + javax.xml.transform.Transformer transformer = FACTORY.newTransformer(); + transformer.transform(source, result); + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return Source.class; + } + + public Class getTargetType() { + return Result.class; + } + + public int getWeight() { + return 40; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAX2SAXAdapter.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAX2SAXAdapter.java new file mode 100644 index 0000000000..63fa53edb4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAX2SAXAdapter.java @@ -0,0 +1,256 @@ +/* + * 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.core.databinding.xml; + +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +/** + * Adapter that converts from StAX to SAX event streams. Currently the following + * SAX events are not generated: + * <ul> + * <li>ignorableWhitespace</li> + * <li>skippedEntity</li> + * <ul> + * Also the following StAX events are not mapped: + * <ul> + * <li>CDATA</li> + * <li>COMMENT</li> + * <li>DTD</li> + * <li>ENTITY_DECLARATION</li> + * <li>ENTITY_REFERENCE</li> + * <li>NOTATION_DECLARATION</li> + * <li>SPACE</li> + * </ul> + * StAX ATTRIBUTE events are ignored but the equivalent attributes (derived from + * the START_ELEMENT event) are supplied in the SAX startElement event's + * Attributes parameter. If the adaptor is configured to pass namespace prefixes + * then namespace information will also be included in the Attributes; StAX + * NAMESPACE events are ignored. <p/> Another issue is namespace processing. If + * the reader is positioned at a sub-node, we cannot capture all the in-scope + * namespace bindings. Therefore we cannot re-create a proper SAX event stream + * from a StAX parser. <p/> For example <p/> <a:root xmlns:a="foo" + * xmlns:b="bar"><b:sub>a:foo</b:sub></a:root> <p/> And if + * you are handed a parser at <b:sub>, then your SAX events should look + * like: <p/> <b:sub xmlns:a="foo" xmlns:b="bar">a:foo</b:sub> <p/> + * not: <p/> <b:sub>a:foo</b:sub> <p/> <p/> Proposal: we change the + * receiver of SAX events (SDOXMLResourceImpl) so that it uses NamespaceContext + * to resolve prefix (as opposed to record start/endPrefixMappings and use it + * for resolution.) + * + * @version $Rev$ $Date$ + */ +public class StAX2SAXAdapter { + private final boolean namespacePrefixes; + + /** + * Construct a new StAX to SAX adapter that will convert a StAX event stream + * into a SAX event stream. + * + * @param namespacePrefixes whether xmlns attributes should be included in + * startElement events; + */ + public StAX2SAXAdapter(boolean namespacePrefixes) { + this.namespacePrefixes = namespacePrefixes; + } + + /** + * Pull events from the StAX stream and dispatch to the SAX ContentHandler. + * The StAX stream would typically be located on a START_DOCUMENT or + * START_ELEMENT event and when this method returns it will be located on + * the associated END_DOCUMENT or END_ELEMENT event. Behaviour with other + * start events is undefined. + * + * @param reader StAX event source to read + * @param handler SAX ContentHandler for processing events + * @throws XMLStreamException if there was a problem reading the stream + * @throws SAXException passed through from the ContentHandler + */ + public void parse(XMLStreamReader reader, ContentHandler handler) throws XMLStreamException, SAXException { + handler.setDocumentLocator(new LocatorAdaptor(reader.getLocation())); + + // remembers the nest level of elements to know when we are done + int level = 0; + int event = reader.getEventType(); + while (true) { + switch (event) { + case XMLStreamConstants.START_DOCUMENT: + level++; + handler.startDocument(); + break; + case XMLStreamConstants.START_ELEMENT: + level++; + handleStartElement(reader, handler); + break; + case XMLStreamConstants.PROCESSING_INSTRUCTION: + handler.processingInstruction(reader.getPITarget(), reader.getPIData()); + break; + case XMLStreamConstants.CHARACTERS: + handler.characters(reader.getTextCharacters(), reader.getTextStart(), reader + .getTextLength()); + break; + case XMLStreamConstants.END_ELEMENT: + handleEndElement(reader, handler); + level--; + if (level == 0) { + return; + } + break; + case XMLStreamConstants.END_DOCUMENT: + handler.endDocument(); + return; + /* + * uncomment to handle all events rather than just mapped + * ones // StAX events that are not mapped to SAX case + * XMLStreamConstants.COMMENT: case + * XMLStreamConstants.SPACE: case + * XMLStreamConstants.ENTITY_REFERENCE: case + * XMLStreamConstants.DTD: case XMLStreamConstants.CDATA: + * case XMLStreamConstants.NOTATION_DECLARATION: case + * XMLStreamConstants.ENTITY_DECLARATION: break; // StAX + * events handled in START_ELEMENT case + * XMLStreamConstants.ATTRIBUTE: case + * XMLStreamConstants.NAMESPACE: break; default: throw new + * AssertionError("Unknown StAX event: " + event); + */ + } + event = reader.next(); + } + } + + private void handleStartElement(XMLStreamReader reader, ContentHandler handler) throws SAXException { + // send startPrefixMapping events immediately before startElement event + int nsCount = reader.getNamespaceCount(); + for (int i = 0; i < nsCount; i++) { + String prefix = reader.getNamespacePrefix(i); + if (prefix == null) { // true for default namespace + prefix = ""; + } + handler.startPrefixMapping(prefix, reader.getNamespaceURI(i)); + } + + // fire startElement + QName qname = reader.getName(); + String prefix = qname.getPrefix(); + String rawname; + if (prefix == null || prefix.length() == 0) { + rawname = qname.getLocalPart(); + } else { + rawname = prefix + ':' + qname.getLocalPart(); + } + Attributes attrs = getAttributes(reader); + handler.startElement(qname.getNamespaceURI(), qname.getLocalPart(), rawname, attrs); + } + + private static void handleEndElement(XMLStreamReader reader, ContentHandler handler) throws SAXException { + // fire endElement + QName qname = reader.getName(); + handler.endElement(qname.getNamespaceURI(), qname.getLocalPart(), qname.toString()); + + // send endPrefixMapping events immediately after endElement event + // we send them in the opposite order to that returned but this is not + // actually required by SAX + int nsCount = reader.getNamespaceCount(); + for (int i = nsCount - 1; i >= 0; i--) { + String prefix = reader.getNamespacePrefix(i); + if (prefix == null) { // true for default namespace + prefix = ""; + } + handler.endPrefixMapping(prefix); + } + } + + /** + * Get the attributes associated with the current START_ELEMENT event. + * + * @return the StAX attributes converted to org.xml.sax.Attributes + */ + private Attributes getAttributes(XMLStreamReader reader) { + assert reader.getEventType() == XMLStreamConstants.START_ELEMENT; + + AttributesImpl attrs = new AttributesImpl(); + + // add namespace declarations if required + if (namespacePrefixes) { + for (int i = 0; i < reader.getNamespaceCount(); i++) { + String prefix = reader.getNamespacePrefix(i); + String uri = reader.getNamespaceURI(i); + attrs.addAttribute(null, prefix, "xmlns:" + prefix, "CDATA", uri); + } + } + + // Regular attributes + for (int i = 0; i < reader.getAttributeCount(); i++) { + String uri = reader.getAttributeNamespace(i); + if (uri == null) { + uri = ""; + } + String localName = reader.getAttributeLocalName(i); + String prefix = reader.getAttributePrefix(i); + String qname; + if (prefix == null || prefix.length() == 0) { + qname = localName; + } else { + qname = prefix + ':' + localName; + } + String type = reader.getAttributeType(i); + String value = reader.getAttributeValue(i); + + attrs.addAttribute(uri, localName, qname, type, value); + } + + return attrs; + } + + /** + * Adaptor for mapping Locator information. + */ + private static final class LocatorAdaptor implements Locator { + private final Location location; + + private LocatorAdaptor(Location location) { + this.location = location; + } + + public int getColumnNumber() { + return location == null ? 0 : location.getColumnNumber(); + } + + public int getLineNumber() { + return location == null ? 0 : location.getLineNumber(); + } + + public String getPublicId() { + return location == null ? "" : location.getPublicId(); + } + + public String getSystemId() { + return location == null ? "" : location.getSystemId(); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAXHelper.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAXHelper.java new file mode 100755 index 0000000000..5426384961 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAXHelper.java @@ -0,0 +1,806 @@ +/* + * 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.core.databinding.xml; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import java.util.NoSuchElementException; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.transform.Source; + +public final class StAXHelper { + private static final XMLInputFactory INPUT_FACTORY = XMLInputFactory.newInstance(); + private static final XMLOutputFactory OUTPUT_FACTORY = XMLOutputFactory.newInstance(); + + private StAXHelper() { + } + + /** + * This class is derived from Apache Axis2 class org.apache.axis2.util.StreamWrapper</a>. It's used wrap a + * XMLStreamReader to create a XMLStreamReader representing a document and it will produce START_DOCUMENT, + * END_DOCUMENT events. + */ + public static class XMLDocumentStreamReader implements XMLStreamReader { + private static final int STATE_COMPLETE_AT_NEXT = 2; // The wrapper + // will produce + // END_DOCUMENT + + private static final int STATE_COMPLETED = 3; // Done + + private static final int STATE_INIT = 0; // The wrapper will produce + // START_DOCUMENT + + private static final int STATE_SWITCHED = 1; // The real reader will + // produce events + + private XMLStreamReader realReader; + + private int state = STATE_INIT; + + public XMLDocumentStreamReader(XMLStreamReader realReader) { + if (realReader == null) { + throw new UnsupportedOperationException("Reader cannot be null"); + } + + this.realReader = realReader; + + // If the real reader is positioned at START_DOCUMENT, always use + // the real reader + if (realReader.getEventType() == START_DOCUMENT) { + state = STATE_SWITCHED; + } + } + + public void close() throws XMLStreamException { + realReader.close(); + } + + public int getAttributeCount() { + if (isDelegating()) { + return realReader.getAttributeCount(); + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeLocalName(int i) { + if (isDelegating()) { + return realReader.getAttributeLocalName(i); + } else { + throw new IllegalStateException(); + } + } + + public QName getAttributeName(int i) { + if (isDelegating()) { + return realReader.getAttributeName(i); + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeNamespace(int i) { + if (isDelegating()) { + return realReader.getAttributeNamespace(i); + } else { + throw new IllegalStateException(); + } + } + + public String getAttributePrefix(int i) { + if (isDelegating()) { + return realReader.getAttributePrefix(i); + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeType(int i) { + if (isDelegating()) { + return realReader.getAttributeType(i); + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeValue(int i) { + if (isDelegating()) { + return realReader.getAttributeValue(i); + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeValue(String s, String s1) { + if (isDelegating()) { + return realReader.getAttributeValue(s, s1); + } else { + throw new IllegalStateException(); + } + } + + public String getCharacterEncodingScheme() { + return realReader.getCharacterEncodingScheme(); + } + + public String getElementText() throws XMLStreamException { + if (isDelegating()) { + return realReader.getElementText(); + } else { + throw new XMLStreamException(); + } + } + + public String getEncoding() { + return realReader.getEncoding(); + } + + public int getEventType() { + int event = -1; + switch (state) { + case STATE_SWITCHED: + case STATE_COMPLETE_AT_NEXT: + event = realReader.getEventType(); + break; + case STATE_INIT: + event = START_DOCUMENT; + break; + case STATE_COMPLETED: + event = END_DOCUMENT; + break; + } + return event; + } + + public String getLocalName() { + if (isDelegating()) { + return realReader.getLocalName(); + } else { + throw new IllegalStateException(); + } + } + + public Location getLocation() { + if (isDelegating()) { + return realReader.getLocation(); + } else { + return null; + } + } + + public QName getName() { + if (isDelegating()) { + return realReader.getName(); + } else { + throw new IllegalStateException(); + } + } + + public NamespaceContext getNamespaceContext() { + return realReader.getNamespaceContext(); + } + + public int getNamespaceCount() { + if (isDelegating()) { + return realReader.getNamespaceCount(); + } else { + throw new IllegalStateException(); + } + } + + public String getNamespacePrefix(int i) { + if (isDelegating()) { + return realReader.getNamespacePrefix(i); + } else { + throw new IllegalStateException(); + } + } + + public String getNamespaceURI() { + if (isDelegating()) { + return realReader.getNamespaceURI(); + } else { + throw new IllegalStateException(); + } + } + + public String getNamespaceURI(int i) { + if (isDelegating()) { + return realReader.getNamespaceURI(i); + } else { + throw new IllegalStateException(); + } + } + + public String getNamespaceURI(String s) { + if (isDelegating()) { + return realReader.getNamespaceURI(s); + } else { + throw new IllegalStateException(); + } + } + + public String getPIData() { + if (isDelegating()) { + return realReader.getPIData(); + } else { + throw new IllegalStateException(); + } + } + + public String getPITarget() { + if (isDelegating()) { + return realReader.getPITarget(); + } else { + throw new IllegalStateException(); + } + } + + public String getPrefix() { + if (isDelegating()) { + return realReader.getPrefix(); + } else { + throw new IllegalStateException(); + } + } + + public Object getProperty(String s) throws IllegalArgumentException { + if (isDelegating()) { + return realReader.getProperty(s); + } else { + throw new IllegalArgumentException(); + } + } + + public String getText() { + if (isDelegating()) { + return realReader.getText(); + } else { + throw new IllegalStateException(); + } + } + + public char[] getTextCharacters() { + if (isDelegating()) { + return realReader.getTextCharacters(); + } else { + throw new IllegalStateException(); + } + } + + public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException { + if (isDelegating()) { + return realReader.getTextCharacters(i, chars, i1, i2); + } else { + throw new IllegalStateException(); + } + } + + public int getTextLength() { + if (isDelegating()) { + return realReader.getTextLength(); + } else { + throw new IllegalStateException(); + } + } + + public int getTextStart() { + if (isDelegating()) { + return realReader.getTextStart(); + } else { + throw new IllegalStateException(); + } + } + + public String getVersion() { + if (isDelegating()) { + return realReader.getVersion(); + } else { + return null; + } + } + + public boolean hasName() { + if (isDelegating()) { + return realReader.hasName(); + } else { + return false; + } + } + + public boolean hasNext() throws XMLStreamException { + if (state == STATE_COMPLETE_AT_NEXT) { + return true; + } else if (state == STATE_COMPLETED) { + return false; + } else if (state == STATE_SWITCHED) { + return realReader.hasNext(); + } else { + return true; + } + } + + public boolean hasText() { + if (isDelegating()) { + return realReader.hasText(); + } else { + return false; + } + } + + public boolean isAttributeSpecified(int i) { + if (isDelegating()) { + return realReader.isAttributeSpecified(i); + } else { + return false; + } + } + + public boolean isCharacters() { + if (isDelegating()) { + return realReader.isCharacters(); + } else { + return false; + } + } + + private boolean isDelegating() { + return state == STATE_SWITCHED || state == STATE_COMPLETE_AT_NEXT; + } + + public boolean isEndElement() { + if (isDelegating()) { + return realReader.isEndElement(); + } else { + return false; + } + } + + public boolean isStandalone() { + if (isDelegating()) { + return realReader.isStandalone(); + } else { + return false; + } + } + + public boolean isStartElement() { + if (isDelegating()) { + return realReader.isStartElement(); + } else { + return false; + } + } + + public boolean isWhiteSpace() { + if (isDelegating()) { + return realReader.isWhiteSpace(); + } else { + return false; + } + } + + public int next() throws XMLStreamException { + int returnEvent; + + switch (state) { + case STATE_SWITCHED: + returnEvent = realReader.next(); + if (returnEvent == END_DOCUMENT) { + state = STATE_COMPLETED; + } else if (!realReader.hasNext()) { + state = STATE_COMPLETE_AT_NEXT; + } + break; + case STATE_INIT: + state = STATE_SWITCHED; + returnEvent = realReader.getEventType(); + break; + case STATE_COMPLETE_AT_NEXT: + state = STATE_COMPLETED; + returnEvent = END_DOCUMENT; + break; + case STATE_COMPLETED: + // oops - no way we can go beyond this + throw new NoSuchElementException("End of stream has reached."); + default: + throw new UnsupportedOperationException(); + } + + return returnEvent; + } + + public int nextTag() throws XMLStreamException { + if (isDelegating()) { + return realReader.nextTag(); + } else { + throw new XMLStreamException(); + } + } + + public void require(int i, String s, String s1) throws XMLStreamException { + if (isDelegating()) { + realReader.require(i, s, s1); + } + } + + public boolean standaloneSet() { + if (isDelegating()) { + return realReader.standaloneSet(); + } else { + return false; + } + } + } + + public static interface XMLFragmentStreamReader extends XMLStreamReader { + + // this will help to handle Text within the current element. + // user should pass the element text to the property list as this + // ELEMENT_TEXT as the key. This key deliberately has a space in it + // so that it is not a valid XML name + String ELEMENT_TEXT = "Element Text"; + + /** + * Initiate the parser - this will do whatever the needed tasks to initiate the parser and must be called before + * attempting any specific parsing using this parser + */ + void init(); + + /** + * Extra method to query the state of the pullparser + */ + boolean isEndOfFragment(); + + /** + * add the parent namespace context to this parser + */ + void setParentNamespaceContext(NamespaceContext nsContext); + } + + /** + * The XMLStreamSerializer pulls events from the XMLStreamReader and dumps into the XMLStreamWriter + */ + public static class XMLStreamSerializer implements XMLStreamConstants { + public static final String NAMESPACE_PREFIX = "ns"; + private static int namespaceSuffix; + + /* + * The behavior of the serializer is such that it returns when it + * encounters the starting element for the second time. The depth + * variable tracks the depth of the serilizer and tells it when to + * return. Note that it is assumed that this serialization starts on an + * Element. + */ + + /** + * Field depth + */ + private int depth; + + /** + * Generates a unique namespace prefix that is not in the scope of the NamespaceContext + * + * @param nsCtxt + * @return string + */ + private String generateUniquePrefix(NamespaceContext nsCtxt) { + String prefix = NAMESPACE_PREFIX + namespaceSuffix++; + // null should be returned if the prefix is not bound! + while (nsCtxt.getNamespaceURI(prefix) != null) { + prefix = NAMESPACE_PREFIX + namespaceSuffix++; + } + + return prefix; + } + + /** + * Method serialize. + * + * @param node + * @param writer + * @throws XMLStreamException + */ + public void serialize(XMLStreamReader node, XMLStreamWriter writer) throws XMLStreamException { + serializeNode(node, writer); + } + + /** + * @param reader + * @param writer + * @throws XMLStreamException + */ + protected void serializeAttributes(XMLStreamReader reader, XMLStreamWriter writer) + throws XMLStreamException { + int count = reader.getAttributeCount(); + String prefix; + String namespaceName; + String writerPrefix; + for (int i = 0; i < count; i++) { + prefix = reader.getAttributePrefix(i); + namespaceName = reader.getAttributeNamespace(i); + /* + * Due to parser implementations returning null as the namespace + * URI (for the empty namespace) we need to make sure that we + * deal with a namespace name that is not null. The best way to + * work around this issue is to set the namespace uri to "" if + * it is null + */ + if (namespaceName == null) { + namespaceName = ""; + } + + writerPrefix = writer.getNamespaceContext().getPrefix(namespaceName); + + if (!"".equals(namespaceName)) { + // prefix has already being declared but this particular + // attrib has a + // no prefix attached. So use the prefix provided by the + // writer + if (writerPrefix != null && (prefix == null || prefix.equals(""))) { + writer.writeAttribute(writerPrefix, + namespaceName, + reader.getAttributeLocalName(i), + reader.getAttributeValue(i)); + + // writer prefix is available but different from the + // current + // prefix of the attrib. We should be decalring the new + // prefix + // as a namespace declaration + } else if (prefix != null && !"".equals(prefix) && !prefix.equals(writerPrefix)) { + writer.writeNamespace(prefix, namespaceName); + writer.writeAttribute(prefix, namespaceName, reader.getAttributeLocalName(i), reader + .getAttributeValue(i)); + + // prefix is null (or empty), but the namespace name is + // valid! it has not + // being written previously also. So we need to generate + // a prefix + // here + } else if (prefix == null || prefix.equals("")) { + prefix = generateUniquePrefix(writer.getNamespaceContext()); + writer.writeNamespace(prefix, namespaceName); + writer.writeAttribute(prefix, namespaceName, reader.getAttributeLocalName(i), reader + .getAttributeValue(i)); + } else { + writer.writeAttribute(prefix, namespaceName, reader.getAttributeLocalName(i), reader + .getAttributeValue(i)); + } + } else { + // empty namespace is equal to no namespace! + writer.writeAttribute(reader.getAttributeLocalName(i), reader.getAttributeValue(i)); + } + + } + } + + /** + * Method serializeCData. + * + * @param reader + * @param writer + * @throws XMLStreamException + */ + protected void serializeCData(XMLStreamReader reader, XMLStreamWriter writer) + throws XMLStreamException { + writer.writeCData(reader.getText()); + } + + /** + * Method serializeComment. + * + * @param reader + * @param writer + * @throws XMLStreamException + */ + protected void serializeComment(XMLStreamReader reader, XMLStreamWriter writer) + throws XMLStreamException { + writer.writeComment(reader.getText()); + } + + /** + * @param reader + * @param writer + * @throws XMLStreamException + */ + protected void serializeElement(XMLStreamReader reader, XMLStreamWriter writer) + throws XMLStreamException { + String prefix = reader.getPrefix(); + String nameSpaceName = reader.getNamespaceURI(); + if (nameSpaceName != null) { + String writerPrefix = writer.getPrefix(nameSpaceName); + if (writerPrefix != null) { + writer.writeStartElement(nameSpaceName, reader.getLocalName()); + } else { + if (prefix != null) { + writer.writeStartElement(prefix, reader.getLocalName(), nameSpaceName); + writer.writeNamespace(prefix, nameSpaceName); + writer.setPrefix(prefix, nameSpaceName); + } else { + writer.writeStartElement(nameSpaceName, reader.getLocalName()); + writer.writeDefaultNamespace(nameSpaceName); + writer.setDefaultNamespace(nameSpaceName); + } + } + } else { + writer.writeStartElement(reader.getLocalName()); + } + + // add the namespaces + int count = reader.getNamespaceCount(); + String namespacePrefix; + for (int i = 0; i < count; i++) { + namespacePrefix = reader.getNamespacePrefix(i); + if (namespacePrefix != null && namespacePrefix.length() == 0) { + continue; + } + + serializeNamespace(namespacePrefix, reader.getNamespaceURI(i), writer); + } + + // add attributes + serializeAttributes(reader, writer); + + } + + /** + * Method serializeEndElement. + * + * @param writer + * @throws XMLStreamException + */ + protected void serializeEndElement(XMLStreamWriter writer) throws XMLStreamException { + writer.writeEndElement(); + } + + /** + * Method serializeNamespace. + * + * @param prefix + * @param uri + * @param writer + * @throws XMLStreamException + */ + private void serializeNamespace(String prefix, String uri, XMLStreamWriter writer) + throws XMLStreamException { + String prefix1 = writer.getPrefix(uri); + if (prefix1 == null) { + writer.writeNamespace(prefix, uri); + writer.setPrefix(prefix, uri); + } + } + + /** + * Method serializeNode. + * + * @param reader + * @param writer + * @throws XMLStreamException + */ + protected void serializeNode(XMLStreamReader reader, XMLStreamWriter writer) + throws XMLStreamException { + // TODO We get the StAXWriter at this point and uses it hereafter + // assuming that this is the only entry point + // to this class. + // If there can be other classes calling methodes of this we might + // need to change methode signatures to + // OMOutputer + while (reader.hasNext()) { + int event = reader.next(); + if (event == START_ELEMENT) { + serializeElement(reader, writer); + depth++; + } else if (event == ATTRIBUTE) { + serializeAttributes(reader, writer); + } else if (event == CHARACTERS) { + serializeText(reader, writer); + } else if (event == COMMENT) { + serializeComment(reader, writer); + } else if (event == CDATA) { + serializeCData(reader, writer); + } else if (event == END_ELEMENT) { + serializeEndElement(writer); + depth--; + } else if (event == START_DOCUMENT) { + depth++; // if a start document is found then increment + // the depth + } else if (event == END_DOCUMENT) { + if (depth != 0) { + depth--; // for the end document - reduce the depth + } + try { + serializeEndElement(writer); + } catch (Exception e) { + // TODO: log exceptions + } + } + if (depth == 0) { + break; + } + } + } + + /** + * @param reader + * @param writer + * @throws XMLStreamException + */ + protected void serializeText(XMLStreamReader reader, XMLStreamWriter writer) + throws XMLStreamException { + writer.writeCharacters(reader.getText()); + } + } + + public static XMLStreamReader createXMLStreamReader(InputStream inputStream) throws XMLStreamException { + return INPUT_FACTORY.createXMLStreamReader(inputStream); + } + + public static XMLStreamReader createXMLStreamReader(Reader reader) throws XMLStreamException { + return INPUT_FACTORY.createXMLStreamReader(reader); + } + + public static XMLStreamReader createXMLStreamReader(Source source) throws XMLStreamException { + return INPUT_FACTORY.createXMLStreamReader(source); + } + + public static XMLStreamReader createXMLStreamReader(String string) throws XMLStreamException { + StringReader reader = new StringReader(string); + return createXMLStreamReader(reader); + } + + public static String save(XMLStreamReader reader) throws XMLStreamException { + StringWriter writer = new StringWriter(); + save(reader, writer); + return writer.toString(); + } + + public static void save(XMLStreamReader reader, OutputStream outputStream) throws XMLStreamException { + XMLStreamSerializer serializer = new XMLStreamSerializer(); + XMLStreamWriter streamWriter = OUTPUT_FACTORY.createXMLStreamWriter(outputStream); + serializer.serialize(reader, streamWriter); + streamWriter.flush(); + } + + public static void save(XMLStreamReader reader, Writer writer) throws XMLStreamException { + XMLStreamSerializer serializer = new XMLStreamSerializer(); + XMLStreamWriter streamWriter = OUTPUT_FACTORY.createXMLStreamWriter(writer); + serializer.serialize(reader, streamWriter); + streamWriter.flush(); + } + + public static void save(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException { + XMLStreamSerializer serializer = new XMLStreamSerializer(); + serializer.serialize(reader, writer); + writer.flush(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/StreamDataPipe.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/StreamDataPipe.java new file mode 100755 index 0000000000..d0b6ce07f2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/StreamDataPipe.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.core.databinding.xml; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.tuscany.spi.databinding.DataPipe; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; + +@Service(Transformer.class) +public class StreamDataPipe extends TransformerExtension<OutputStream, InputStream> implements + DataPipe<OutputStream, InputStream> { + + private ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + public InputStream getResult() { + return new ByteArrayInputStream(outputStream.toByteArray()); + } + + public Class getTargetType() { + return InputStream.class; + } + + public int getWeight() { + return 50; + } + + public OutputStream getSink() { + return outputStream; + } + + public Class getSourceType() { + return OutputStream.class; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2Node.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2Node.java new file mode 100755 index 0000000000..3f878a07b9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2Node.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.databinding.xml; + +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; + +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.DOMHelper; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; +import org.w3c.dom.Node; +import org.xml.sax.InputSource; + +@Service(Transformer.class) +public class String2Node extends TransformerExtension<String, Node> implements PullTransformer<String, Node> { + + public Node transform(String source, TransformationContext context) { + try { + DocumentBuilder builder = DOMHelper.newDocumentBuilder(); + InputSource inputSource = new InputSource(new StringReader(source)); + return builder.parse(inputSource); + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return String.class; + } + + public Class getTargetType() { + return Node.class; + } + + public int getWeight() { + return 50; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2SAX.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2SAX.java new file mode 100644 index 0000000000..50ea110b17 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2SAX.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.core.databinding.xml; + +import java.io.StringReader; + +import org.apache.tuscany.spi.databinding.PushTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; + +/** + * Transform XML string to SAX + */ +@Service(Transformer.class) +public class String2SAX extends TransformerExtension<String, ContentHandler> implements + PushTransformer<String, ContentHandler> { + + public void transform(String source, ContentHandler target, TransformationContext context) { + try { + new InputSource2SAX().transform(new InputSource(new StringReader(source)), target, context); + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return String.class; + } + + public Class getTargetType() { + return ContentHandler.class; + } + + public int getWeight() { + return 40; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2XMLStreamReader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2XMLStreamReader.java new file mode 100755 index 0000000000..9793cc3f7e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2XMLStreamReader.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.core.databinding.xml; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; + +@Service(Transformer.class) +public class String2XMLStreamReader extends TransformerExtension<String, XMLStreamReader> implements + PullTransformer<String, XMLStreamReader> { + + public XMLStreamReader transform(String source, TransformationContext context) { + try { + return StAXHelper.createXMLStreamReader(source); + } catch (XMLStreamException e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return String.class; + } + + public Class getTargetType() { + return XMLStreamReader.class; + } + + public int getWeight() { + return 50; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Writer2ReaderDataPipe.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Writer2ReaderDataPipe.java new file mode 100755 index 0000000000..c66d0fd934 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/Writer2ReaderDataPipe.java @@ -0,0 +1,56 @@ +/* + * 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.core.databinding.xml; + +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; + +import org.apache.tuscany.spi.databinding.DataPipe; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; + +@Service(Transformer.class) +public class Writer2ReaderDataPipe extends TransformerExtension<Writer, Reader> implements DataPipe<Writer, Reader> { + + private StringWriter writer = new StringWriter(); + + public Reader getResult() { + return new StringReader(writer.toString()); + } + + public Class getTargetType() { + return Reader.class; + } + + public int getWeight() { + return 50; + } + + public Writer getSink() { + return writer; + } + + public Class getSourceType() { + return Writer.class; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2Node.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2Node.java new file mode 100644 index 0000000000..6ecaa85be4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2Node.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.core.databinding.xml; + +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; +import org.w3c.dom.Node; + +/** + * Transform DOM Node to XML XMLStreamReader + */ +@Service(Transformer.class) +public class XMLStreamReader2Node extends TransformerExtension<XMLStreamReader, Node> implements + PullTransformer<XMLStreamReader, Node> { + private SAX2DOMPipe pipe = new SAX2DOMPipe(); + + private XMLStreamReader2SAX stax2sax = new XMLStreamReader2SAX(); + + public Node transform(XMLStreamReader source, TransformationContext context) { + try { + stax2sax.transform(source, pipe.getSink(), context); + return pipe.getResult(); + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return XMLStreamReader.class; + } + + public Class getTargetType() { + return Node.class; + } + + public int getWeight() { + return 40; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2SAX.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2SAX.java new file mode 100644 index 0000000000..0c6f0b8df7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2SAX.java @@ -0,0 +1,73 @@ +/* + * 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.core.databinding.xml; + +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.databinding.PushTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; +import org.xml.sax.ContentHandler; + +/** + * XMLStreamReader to SAX events + */ +@Service(Transformer.class) +public class XMLStreamReader2SAX extends TransformerExtension<XMLStreamReader, ContentHandler> implements + PushTransformer<XMLStreamReader, ContentHandler> { + + /** + * @see org.apache.tuscany.spi.databinding.PushTransformer#getSourceType() + */ + public Class getTargetType() { + return ContentHandler.class; + } + + /** + * @see org.apache.tuscany.spi.databinding.PushTransformer#getSourceType() + */ + public Class getSourceType() { + return XMLStreamReader.class; + } + + /** + * @see org.apache.tuscany.spi.databinding.PushTransformer#getWeight() + */ + public int getWeight() { + return 20; + } + + /** + * @see org.apache.tuscany.spi.databinding.PushTransformer#transform(java.lang.Object, + * java.lang.Object, + * org.apache.tuscany.spi.databinding.TransformationContext) + */ + public void transform(XMLStreamReader source, ContentHandler sink, TransformationContext context) { + StAX2SAXAdapter adapter = new StAX2SAXAdapter(false); + try { + adapter.parse(source, sink); + } catch (Exception e) { + throw new TransformationException(e); + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2String.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2String.java new file mode 100755 index 0000000000..85ac7b5af6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2String.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.core.databinding.xml; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; + +@Service(Transformer.class) +public class XMLStreamReader2String extends TransformerExtension<XMLStreamReader, String> implements + PullTransformer<XMLStreamReader, String> { + + public String transform(XMLStreamReader source, TransformationContext context) { + try { + return StAXHelper.save(source); + } catch (XMLStreamException e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return XMLStreamReader.class; + } + + public Class getTargetType() { + return String.class; + } + + public int getWeight() { + return 40; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStringDataBinding.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStringDataBinding.java new file mode 100644 index 0000000000..39e9362524 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStringDataBinding.java @@ -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. + */ + +package org.apache.tuscany.core.databinding.xml; + +import org.apache.tuscany.spi.databinding.extension.DataBindingExtension; + +/** + * A DataBinding for the XML string + */ +public class XMLStringDataBinding extends DataBindingExtension { + public static final String NAME = String.class.getName(); + + public XMLStringDataBinding() { + super(NAME, String.class); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/deployer/AbstractDeploymentContext.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/deployer/AbstractDeploymentContext.java new file mode 100644 index 0000000000..8d24047781 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/deployer/AbstractDeploymentContext.java @@ -0,0 +1,80 @@ +/* + * 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.core.deployer; + +import java.net.URI; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.deployer.DeploymentContext; + +/** + * Base class for DeploymentContext implementations. + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractDeploymentContext implements DeploymentContext { + private final URI componentId; + private boolean autowire; + private final ClassLoader classLoader; + private final URL scdlLocation; + private final Map<URI, Component> components = new HashMap<URI, Component>(); + + /** + * Constructor defining properties of this context. + * + * @param classLoader the classloader for loading application resources + * @param scdlLocation the location of the SCDL defining this composite + * @param componentId the id of the component being deployed + * @param autowire if autowire is enabled + */ + protected AbstractDeploymentContext(ClassLoader classLoader, URL scdlLocation, URI componentId, boolean autowire) { + this.classLoader = classLoader; + this.scdlLocation = scdlLocation; + this.componentId = componentId; + this.autowire = autowire; + } + + public ClassLoader getClassLoader() { + return classLoader; + } + + public URL getScdlLocation() { + return scdlLocation; + } + + public URI getComponentId() { + return componentId; + } + + public boolean isAutowire() { + return autowire; + } + + public void setAutowire(boolean autowire) { + this.autowire = autowire; + } + + @Deprecated + public Map<URI, Component> getComponents() { + return components; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/deployer/ChildDeploymentContext.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/deployer/ChildDeploymentContext.java new file mode 100644 index 0000000000..de523cee78 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/deployer/ChildDeploymentContext.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.core.deployer; + +import java.net.URI; +import java.net.URL; +import javax.xml.stream.XMLInputFactory; + +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.deployer.DeploymentContext; + +/** + * An holder that can be used during the load process to store information that is not part of the logical assembly + * model. This should be regarded as transient and references to this context should not be stored inside the model. + * + * @version $Rev$ $Date$ + */ +public class ChildDeploymentContext extends AbstractDeploymentContext { + private final DeploymentContext parent; + + /** + * Constructor defining properties of this context. + * + * @param parent the parent of this context + * @param classLoader the classloader for loading application resources + * @param scdlLocation the location of the SCDL defining this composite + * @param componentId the id of the component being deployed + * @param autowire if autowire is enabled + */ + public ChildDeploymentContext(DeploymentContext parent, + ClassLoader classLoader, + URL scdlLocation, + URI componentId, + boolean autowire) { + super(classLoader, scdlLocation, componentId, autowire); + assert parent != null; + this.parent = parent; + } + + public DeploymentContext getParent() { + return parent; + } + + public XMLInputFactory getXmlFactory() { + return parent.getXmlFactory(); + } + + public ScopeContainer getCompositeScope() { + return parent.getCompositeScope(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/deployer/DeployerImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/deployer/DeployerImpl.java new file mode 100644 index 0000000000..1524a36b75 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/deployer/DeployerImpl.java @@ -0,0 +1,179 @@ +/* + * 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.core.deployer; + +import java.util.Collection; +import javax.xml.stream.XMLInputFactory; + +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.builder.Builder; +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.builder.BuilderInstantiationException; +import org.apache.tuscany.spi.builder.BuilderRegistry; +import org.apache.tuscany.spi.builder.Connector; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.RegistrationException; +import org.apache.tuscany.spi.component.SCAObject; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.ScopeContainerMonitor; +import org.apache.tuscany.spi.deployer.Deployer; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.event.Event; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.loader.Loader; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.resolver.ResolutionException; + +import org.apache.tuscany.api.annotation.Monitor; +import org.apache.tuscany.core.component.ComponentManager; +import org.apache.tuscany.core.component.event.ComponentStop; +import org.apache.tuscany.core.component.scope.CompositeScopeContainer; +import org.apache.tuscany.core.resolver.AutowireResolver; + +/** + * Default implementation of Deployer. + * + * @version $Rev$ $Date$ + */ +public class DeployerImpl implements Deployer { + private XMLInputFactory xmlFactory; + private Builder builder; + private ScopeContainerMonitor monitor; + private Loader loader; + private AutowireResolver resolver; + private Connector connector; + private ComponentManager componentManager; + + public DeployerImpl(XMLInputFactory xmlFactory, + Loader loader, + Builder builder, + ComponentManager componentManager, + AutowireResolver resolver, + Connector connector) { + this.xmlFactory = xmlFactory; + this.loader = loader; + this.builder = builder; + this.componentManager = componentManager; + this.resolver = resolver; + this.connector = connector; + } + + public DeployerImpl() { + xmlFactory = XMLInputFactory.newInstance("javax.xml.stream.XMLInputFactory", getClass().getClassLoader()); + } + + @Reference + public void setLoader(LoaderRegistry loader) { + this.loader = loader; + } + + @Reference + public void setBuilder(BuilderRegistry builder) { + this.builder = builder; + } + + @Monitor + public void setMonitor(ScopeContainerMonitor monitor) { + this.monitor = monitor; + } + + @Reference + public void setResolver(AutowireResolver resolver) { + this.resolver = resolver; + } + + @Reference + public void setConnector(Connector connector) { + this.connector = connector; + } + + @Reference + public void setComponentManager(ComponentManager componentManager) { + this.componentManager = componentManager; + } + + public <I extends Implementation<?>> Collection<Component> deploy(Component parent, + ComponentDefinition<I> componentDefinition) + throws LoaderException, BuilderException, ResolutionException { + final ScopeContainer scopeContainer = new CompositeScopeContainer(monitor); + scopeContainer.start(); + DeploymentContext deploymentContext = + new RootDeploymentContext(null, null, componentDefinition.getUri(), xmlFactory, scopeContainer, false); + // load the model + load(parent, componentDefinition, deploymentContext); + // resolve autowires + resolver.resolve(null, componentDefinition); + // build runtime artifacts + Component component = (Component) build(parent, componentDefinition, deploymentContext); + // create a listener so the scope container is shutdown when the top-level composite stops + RuntimeEventListener listener = new RuntimeEventListener() { + public void onEvent(Event event) { + scopeContainer.onEvent(event); + if (event instanceof ComponentStop) { + scopeContainer.stop(); + } + } + }; + component.addListener(listener); + + Collection<Component> components = deploymentContext.getComponents().values(); + for (Component toRegister : components) { + try { + componentManager.register(toRegister); + } catch (RegistrationException e) { + throw new BuilderInstantiationException("Error registering component", e); + } + } + connector.connect(componentDefinition); + return components; + } + + /** + * Load the componentDefinition type information for the componentDefinition being deployed. For a typical + * deployment this will result in the SCDL definition being loaded. + * + * @param componentDefinition the componentDefinition being deployed + * @param deploymentContext the current deployment context + */ + protected <I extends Implementation<?>> void load(Component parent, + ComponentDefinition<I> componentDefinition, + DeploymentContext deploymentContext) throws LoaderException { + loader.loadComponentType(componentDefinition.getImplementation(), deploymentContext); + } + + /** + * Build the runtime context for a loaded componentDefinition. + * + * @param parent the context that will be the parent of the new sub-context + * @param componentDefinition the componentDefinition being deployed + * @param deploymentContext the current deployment context + * @return the new runtime context + */ + protected <I extends Implementation<?>> SCAObject build(Component parent, + ComponentDefinition<I> componentDefinition, + DeploymentContext deploymentContext) + throws BuilderException { + return builder.build(componentDefinition, deploymentContext); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/deployer/RootDeploymentContext.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/deployer/RootDeploymentContext.java new file mode 100644 index 0000000000..673cd675fd --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/deployer/RootDeploymentContext.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.core.deployer; + +import java.net.URI; +import java.net.URL; +import javax.xml.stream.XMLInputFactory; + +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.deployer.DeploymentContext; + +/** + * A holder that can be used during the load process to store information that is not part of the logical assembly + * model. This should be regarded as transient and references to this context should not be stored inside the model. + * + * @version $Rev$ $Date$ + */ +public class RootDeploymentContext extends AbstractDeploymentContext { + private final XMLInputFactory xmlFactory; + private final ScopeContainer scopeContainer; + + /** + * Constructor defining properties of this context. + * + * @param classLoader the classloader for loading application resources + * @param scdlLocation the location of the SCDL defining this composite + * @param componentId the id of the component being deployed + * @param xmlFactory a factory that can be used to obtain an StAX XMLStreamReader + * @param scopeContainer the scope context representing this deployment's COMPOSITE scope + * @param autowire if autowire is enabled + */ + public RootDeploymentContext(ClassLoader classLoader, + URL scdlLocation, + URI componentId, + XMLInputFactory xmlFactory, + ScopeContainer scopeContainer, + boolean autowire) { + super(classLoader, scdlLocation, componentId, autowire); + this.xmlFactory = xmlFactory; + this.scopeContainer = scopeContainer; + } + + public DeploymentContext getParent() { + return null; + } + + public XMLInputFactory getXmlFactory() { + return xmlFactory; + } + + public ScopeContainer getCompositeScope() { + return scopeContainer; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/deployer/federation/FederatedDeployer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/deployer/federation/FederatedDeployer.java new file mode 100644 index 0000000000..d1ff543a34 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/deployer/federation/FederatedDeployer.java @@ -0,0 +1,145 @@ +/* + * 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.core.deployer.federation; + +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.core.component.ComponentManager; +import org.apache.tuscany.core.marshaller.PhysicalChangeSetMarshaller; +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.builder.Connector; +import org.apache.tuscany.spi.builder.physical.PhysicalComponentBuilderRegistry; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.RegistrationException; +import org.apache.tuscany.spi.marshaller.MarshallException; +import org.apache.tuscany.spi.marshaller.ModelMarshallerRegistry; +import org.apache.tuscany.spi.model.physical.PhysicalChangeSet; +import org.apache.tuscany.spi.model.physical.PhysicalComponentDefinition; +import org.apache.tuscany.spi.model.physical.PhysicalWireDefinition; +import org.apache.tuscany.spi.services.discovery.DiscoveryService; +import org.apache.tuscany.spi.services.discovery.RequestListener; +import org.osoa.sca.annotations.Reference; + +/** + * Federated deployer that deploys components in response to asynchronous messages from the federated domain. + * + * @version $Revision$ $Date$ + */ +public class FederatedDeployer implements RequestListener { + + /** + * Marshaller registry. + */ + private ModelMarshallerRegistry marshallerRegistry; + + /** + * Physical component builder registry. + */ + private PhysicalComponentBuilderRegistry builderRegistry; + + /** + * Component manager. + */ + private ComponentManager componentManager; + + /** + * Connector. + */ + private Connector connector; + + /** + * Deploys the component. + * + * @param content SCDL content. + * @return Response to the request message. + * <p/> + * TODO Handle response messages. + */ + public XMLStreamReader onRequest(XMLStreamReader content) { + + try { + + final PhysicalChangeSet changeSet = (PhysicalChangeSet) marshallerRegistry.unmarshall(content); + + for (PhysicalComponentDefinition pcd : changeSet.getComponentDefinitions()) { + final Component component = builderRegistry.build(pcd); + componentManager.register(component); + component.start(); + } + for (PhysicalWireDefinition pwd : changeSet.getWireDefinitions()) { + connector.connect(pwd); + } + + } catch (MarshallException ex) { + return null; + } catch (BuilderException ex) { + return null; + } catch (RegistrationException ex) { + return null; + } + + return null; + } + + /** + * Injects the discovery service. + * @param discoveryService Discovery service to be injected. + */ + @Reference + public void setDiscoveryService(DiscoveryService discoveryService) { + discoveryService.registerRequestListener(PhysicalChangeSetMarshaller.QNAME, this); + } + + /** + * Injects the model marshaller registry. + * @param marshallerRegistry Marshaller registry. + */ + @Reference + public void setMarshallerRegistry(ModelMarshallerRegistry marshallerRegistry) { + this.marshallerRegistry = marshallerRegistry; + } + + /** + * Injects the builder registry. + * @param builderRegistry Builder registry. + */ + @Reference + public void setBuilderRegistry(PhysicalComponentBuilderRegistry builderRegistry) { + this.builderRegistry = builderRegistry; + } + + /** + * Injects the component manager. + * @param componentManager Component manager. + */ + @Reference + public void setComponentManager(ComponentManager componentManager) { + this.componentManager = componentManager; + } + + /** + * Injects the connector. + * @param connector Connector. + */ + @Reference + public void setConnector(Connector connector) { + this.connector = connector; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/idl/java/IllegalCallbackException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/idl/java/IllegalCallbackException.java new file mode 100644 index 0000000000..f52bd4cfb1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/idl/java/IllegalCallbackException.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.core.idl.java; + +import org.apache.tuscany.spi.idl.InvalidServiceContractException; + +/** + * Denotes an illegal callback interface + * + * @version $Rev$ $Date$ + */ + +public class IllegalCallbackException extends InvalidServiceContractException { + + public IllegalCallbackException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/idl/java/InterfaceJavaLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/idl/java/InterfaceJavaLoader.java new file mode 100644 index 0000000000..e2169d8978 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/idl/java/InterfaceJavaLoader.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.core.idl.java; + +import java.util.HashMap; +import java.util.Map; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import static org.osoa.sca.Constants.SCA_NS; +import org.osoa.sca.annotations.Constructor; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.LoaderExtension; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.loader.InvalidValueException; +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.model.DataType; +import org.apache.tuscany.spi.model.ModelObject; + +/** + * Loads a Java interface definition from an XML-based assembly file + * + * @version $Rev$ $Date$ + */ +public class InterfaceJavaLoader extends LoaderExtension<JavaServiceContract> { + public static final QName INTERFACE_JAVA = new QName(SCA_NS, "interface.java"); + + private final JavaInterfaceProcessorRegistry interfaceRegsitry; + + @Constructor({"registry", "interfaceRegsitry"}) + public InterfaceJavaLoader(@Reference LoaderRegistry registry, + @Reference JavaInterfaceProcessorRegistry interfaceRegistry) { + super(registry); + this.interfaceRegsitry = interfaceRegistry; + } + + public QName getXMLType() { + return INTERFACE_JAVA; + } + + public JavaServiceContract load( + ModelObject object, XMLStreamReader reader, + DeploymentContext deploymentContext) + throws XMLStreamException, LoaderException { + + assert INTERFACE_JAVA.equals(reader.getName()); + String conversationalAttr = reader.getAttributeValue(null, "conversational"); + boolean conversational = Boolean.parseBoolean(conversationalAttr); + String name = reader.getAttributeValue(null, "interface"); + if (name == null) { + // allow "class" as well as seems to be a common mistake + name = reader.getAttributeValue(null, "class"); + } + if (name == null) { + throw new InvalidValueException("interface name not supplied"); + } + Class<?> interfaceClass = LoaderUtil.loadClass(name, deploymentContext.getClassLoader()); + + name = reader.getAttributeValue(null, "callbackInterface"); + Class<?> callbackClass = (name != null) ? LoaderUtil.loadClass(name, deploymentContext.getClassLoader()) : null; + + Map<Class<?>, ModelObject> extensions = new HashMap<Class<?>, ModelObject>(); + while (true) { + int event = reader.next(); + if (event == XMLStreamConstants.START_ELEMENT) { + ModelObject mo = registry.load(null, reader, deploymentContext); + if (mo != null) { + extensions.put(mo.getClass(), mo); + } + } else if (event == XMLStreamConstants.END_ELEMENT && reader.getName().equals(INTERFACE_JAVA)) { + break; + } + } + JavaServiceContract serviceContract; + try { + serviceContract = interfaceRegsitry.introspect(interfaceClass, callbackClass); + } catch (InvalidServiceContractException e) { + throw new LoaderException(interfaceClass.getName(), e); + } + + // Set databinding from the SCDL extension <databinding> + DataType<?> dataType = (DataType<?>) extensions.get(DataType.class); + if (dataType != null) { + serviceContract.setDataBinding(dataType.getDataBinding()); + } + serviceContract.getExtensions().putAll(extensions); + serviceContract.setConversational(conversational); + return serviceContract; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/idl/java/JavaInterfaceProcessorRegistryImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/idl/java/JavaInterfaceProcessorRegistryImpl.java new file mode 100644 index 0000000000..ea64af75b6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/idl/java/JavaInterfaceProcessorRegistryImpl.java @@ -0,0 +1,156 @@ +/* + * 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.core.idl.java; + +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.osoa.sca.annotations.Callback; +import org.osoa.sca.annotations.Conversational; +import org.osoa.sca.annotations.EndsConversation; +import org.osoa.sca.annotations.OneWay; +import org.osoa.sca.annotations.Remotable; + +import org.apache.tuscany.spi.idl.InvalidConversationalOperationException; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.idl.OverloadedOperationException; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessor; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.model.DataType; +import org.apache.tuscany.spi.model.Operation; +import static org.apache.tuscany.spi.model.Operation.CONVERSATION_END; +import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION; + +import static org.apache.tuscany.core.util.JavaIntrospectionHelper.getBaseName; + +/** + * Default implementation of an InterfaceJavaIntrospector. + * + * @version $Rev$ $Date$ + */ +public class JavaInterfaceProcessorRegistryImpl implements JavaInterfaceProcessorRegistry { + public static final String IDL_INPUT = "idl:input"; + + private static final String UNKNOWN_DATABINDING = null; + + private List<JavaInterfaceProcessor> processors = new ArrayList<JavaInterfaceProcessor>(); + + public JavaInterfaceProcessorRegistryImpl() { + } + + public void registerProcessor(JavaInterfaceProcessor processor) { + processors.add(processor); + } + + public void unregisterProcessor(JavaInterfaceProcessor processor) { + processors.remove(processor); + } + + public <T> JavaServiceContract introspect(Class<T> type) throws InvalidServiceContractException { + Class<?> callbackClass = null; + Callback callback = type.getAnnotation(Callback.class); + if (callback != null && !Void.class.equals(callback.value())) { + callbackClass = callback.value(); + } else if (callback != null && Void.class.equals(callback.value())) { + throw new IllegalCallbackException("No callback interface specified on annotation", type.getName()); + } + return introspect(type, callbackClass); + } + + public <I, C> JavaServiceContract introspect(Class<I> type, Class<C> callback) + throws InvalidServiceContractException { + JavaServiceContract contract = new JavaServiceContract(); + contract.setInterfaceName(getBaseName(type)); + contract.setInterfaceClass(type); + boolean remotable = type.isAnnotationPresent(Remotable.class); + contract.setRemotable(remotable); + //Scope interactionScope = type.getAnnotation(Scope.class); + boolean conversational = type.isAnnotationPresent(Conversational.class); + contract.setConversational(conversational); + contract.setOperations(getOperations(type, remotable, conversational)); + + if (callback != null) { + contract.setCallbackName(getBaseName(callback)); + contract.setCallbackClass(callback); + contract.setCallbackOperations(getOperations(callback, remotable, conversational)); + } + + for (JavaInterfaceProcessor processor : processors) { + processor.visitInterface(type, callback, contract); + } + return contract; + } + + private <T> Map<String, Operation<Type>> getOperations(Class<T> type, boolean remotable, boolean conversational) + throws InvalidServiceContractException { + Method[] methods = type.getMethods(); + Map<String, Operation<Type>> operations = new HashMap<String, Operation<Type>>(methods.length); + for (Method method : methods) { + String name = method.getName(); + if (remotable && operations.containsKey(name)) { + throw new OverloadedOperationException(method); + } + + Type returnType = method.getGenericReturnType(); + Type[] paramTypes = method.getGenericParameterTypes(); + Type[] faultTypes = method.getGenericExceptionTypes(); + boolean nonBlocking = method.isAnnotationPresent(OneWay.class); + int conversationSequence = NO_CONVERSATION; + if (method.isAnnotationPresent(EndsConversation.class)) { + if (!conversational) { + throw new InvalidConversationalOperationException( + "Method is marked as end conversation but contract is not conversational", + method.getDeclaringClass().getName(), + method); + } + conversationSequence = CONVERSATION_END; + } else if (conversational) { + conversationSequence = Operation.CONVERSATION_CONTINUE; + } + + DataType<Type> returnDataType = new DataType<Type>(UNKNOWN_DATABINDING, returnType, returnType); + List<DataType<Type>> paramDataTypes = new ArrayList<DataType<Type>>(paramTypes.length); + for (Type paramType : paramTypes) { + paramDataTypes.add(new DataType<Type>(UNKNOWN_DATABINDING, paramType, paramType)); + } + List<DataType<Type>> faultDataTypes = new ArrayList<DataType<Type>>(faultTypes.length); + for (Type faultType : faultTypes) { + faultDataTypes.add(new DataType<Type>(UNKNOWN_DATABINDING, faultType, faultType)); + } + + DataType<List<DataType<Type>>> inputType = + new DataType<List<DataType<Type>>>(IDL_INPUT, Object[].class, paramDataTypes); + Operation<Type> operation = new Operation<Type>(name, + inputType, + returnDataType, + faultDataTypes, + nonBlocking, + UNKNOWN_DATABINDING, + conversationSequence); + operations.put(name, operation); + } + return operations; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/IntrospectionRegistryImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/IntrospectionRegistryImpl.java new file mode 100644 index 0000000000..3c0986a83e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/IntrospectionRegistryImpl.java @@ -0,0 +1,133 @@ +/* + * 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.core.implementation; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessor; +import org.apache.tuscany.spi.implementation.java.IntrospectionRegistry; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +import org.apache.tuscany.core.util.JavaIntrospectionHelper; + +/** + * Default implementation of the <code>IntrospectionRegistry</code> + * + * @version $Rev$ $Date$ + */ +public class IntrospectionRegistryImpl implements IntrospectionRegistry { + + private Monitor monitor; + private List<ImplementationProcessor> cache = new ArrayList<ImplementationProcessor>(); + + public IntrospectionRegistryImpl() { + } + + public IntrospectionRegistryImpl(Monitor monitor) { + this.monitor = monitor; + } + + @org.apache.tuscany.api.annotation.Monitor + public void setMonitor(Monitor monitor) { + this.monitor = monitor; + } + + public void registerProcessor(ImplementationProcessor processor) { + monitor.register(processor); + cache.add(processor); + } + + public void unregisterProcessor(ImplementationProcessor processor) { + monitor.unregister(processor); + cache.remove(processor); + } + + public PojoComponentType introspect(Class<?> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, + JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException { + for (ImplementationProcessor processor : cache) { + processor.visitClass(clazz, type, context); + } + + for (Constructor<?> constructor : clazz.getConstructors()) { + for (ImplementationProcessor processor : cache) { + processor.visitConstructor(constructor, type, context); + } + } + + Set<Method> methods = JavaIntrospectionHelper.getAllUniquePublicProtectedMethods(clazz); + for (Method method : methods) { + for (ImplementationProcessor processor : cache) { + processor.visitMethod(method, type, context); + } + } + + Set<Field> fields = JavaIntrospectionHelper.getAllPublicAndProtectedFields(clazz); + for (Field field : fields) { + for (ImplementationProcessor processor : cache) { + processor.visitField(field, type, context); + } + } + + Class superClass = clazz.getSuperclass(); + if (superClass != null) { + visitSuperClass(superClass, type, context); + } + + for (ImplementationProcessor processor : cache) { + processor.visitEnd(clazz, type, context); + } + return type; + } + + private void visitSuperClass(Class<?> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException { + if (!Object.class.equals(clazz)) { + for (ImplementationProcessor processor : cache) { + processor.visitSuperClass(clazz, type, context); + } + clazz = clazz.getSuperclass(); + if (clazz != null) { + visitSuperClass(clazz, type, context); + } + } + } + + public static interface Monitor { + void register(ImplementationProcessor processor); + + void unregister(ImplementationProcessor processor); + + void processing(ImplementationProcessor processor); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/PhysicalComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/PhysicalComponent.java new file mode 100644 index 0000000000..0037a2ca38 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/PhysicalComponent.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.core.implementation; + +import java.net.URI; + +import org.apache.tuscany.spi.extension.AbstractComponentExtension; +import org.apache.tuscany.core.component.scope.InstanceWrapper; +import org.apache.tuscany.core.component.InstanceFactory; + +/** + * Base class for implementations of physical components. + * + * @version $Rev$ $Date$ + * @param <T> the type of the physical instance + */ +public abstract class PhysicalComponent<T> extends AbstractComponentExtension { + private final InstanceFactory<T> factory; + + /** + * Constructor specifying the component id. + * + * @param id the component id + * @param factory a factory for physical instances + */ + protected PhysicalComponent(URI id, InstanceFactory<T> factory) { + super(id); + this.factory = factory; + } + + public InstanceWrapper<T> createInstance() { + return factory.newInstance(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/PojoAtomicComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/PojoAtomicComponent.java new file mode 100644 index 0000000000..e34a8b96c9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/PojoAtomicComponent.java @@ -0,0 +1,399 @@ +/* + * 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.core.implementation; + +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.osoa.sca.ComponentContext; +import org.osoa.sca.ServiceReference; +import org.osoa.sca.CallableReference; + +import org.apache.tuscany.spi.CoreRuntimeException; +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.component.TargetDestructionException; +import org.apache.tuscany.spi.component.TargetInitializationException; +import org.apache.tuscany.spi.component.TargetResolutionException; +import org.apache.tuscany.spi.extension.AtomicComponentExtension; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.wire.Wire; + +import org.apache.tuscany.core.component.ComponentContextImpl; +import org.apache.tuscany.core.component.ComponentContextProvider; +import org.apache.tuscany.core.component.ServiceReferenceImpl; +import org.apache.tuscany.core.injection.ArrayMultiplicityObjectFactory; +import org.apache.tuscany.core.injection.CallbackWireObjectFactory; +import org.apache.tuscany.core.injection.ConversationIDObjectFactory; +import org.apache.tuscany.core.injection.EventInvoker; +import org.apache.tuscany.core.injection.FieldInjector; +import org.apache.tuscany.core.injection.Injector; +import org.apache.tuscany.core.injection.InvalidAccessorException; +import org.apache.tuscany.core.injection.ListMultiplicityObjectFactory; +import org.apache.tuscany.core.injection.MethodInjector; +import org.apache.tuscany.core.injection.NoAccessorException; +import org.apache.tuscany.core.injection.NoMultiplicityTypeException; +import org.apache.tuscany.core.injection.ObjectCallbackException; +import org.apache.tuscany.core.injection.PojoObjectFactory; + +/** + * Base implementation of an {@link org.apache.tuscany.spi.component.AtomicComponent} whose type is a Java class + * + * @version $$Rev$$ $$Date$$ + */ +public abstract class PojoAtomicComponent extends AtomicComponentExtension implements ComponentContextProvider { + protected EventInvoker<Object> initInvoker; + protected EventInvoker<Object> destroyInvoker; + protected PojoObjectFactory<?> instanceFactory; + protected List<String> constructorParamNames; + protected Map<String, Member> referenceSites; + protected Map<String, Member> resourceSites; + protected Map<String, Member> propertySites; + protected Map<String, Member> callbackSites; + protected List<Injector<Object>> injectors; + protected Class implementationClass; + protected Map<String, List<Wire>> wires = new HashMap<String, List<Wire>>(); + protected Map<String, List<Wire>> callBackwires = new HashMap<String, List<Wire>>(); + + private final ComponentContext componentContext; + private final Map<String, ObjectFactory<?>> propertyFactories = new ConcurrentHashMap<String, ObjectFactory<?>>(); + private List<Class<?>> constructorParamTypes = new ArrayList<Class<?>>(); + + public PojoAtomicComponent(PojoConfiguration configuration) { + super(configuration.getName(), + configuration.getProxyService(), + configuration.getWorkContext(), + configuration.getInitLevel(), + configuration.getMaxIdleTime(), + configuration.getMaxAge()); + assert configuration.getInstanceFactory() != null : "Object factory was null"; + initInvoker = configuration.getInitInvoker(); + destroyInvoker = configuration.getDestroyInvoker(); + instanceFactory = configuration.getInstanceFactory(); + constructorParamNames = configuration.getConstructorParamNames(); + constructorParamTypes = configuration.getConstructorParamTypes(); + injectors = new ArrayList<Injector<Object>>(); + referenceSites = configuration.getReferenceSite() != null ? configuration.getReferenceSite() + : new HashMap<String, Member>(); + propertySites = configuration.getPropertySites() != null ? configuration.getPropertySites() + : new HashMap<String, Member>(); + resourceSites = configuration.getResourceSites() != null ? configuration.getResourceSites() + : new HashMap<String, Member>(); + callbackSites = configuration.getCallbackSites() != null ? configuration.getCallbackSites() + : new HashMap<String, Member>(); + implementationClass = configuration.getImplementationClass(); + + componentContext = new ComponentContextImpl(this); + } + + public boolean isDestroyable() { + return destroyInvoker != null; + } + + public void init(Object instance) throws TargetInitializationException { + if (initInvoker != null) { + try { + initInvoker.invokeEvent(instance); + } catch (ObjectCallbackException e) { + String uri = getUri().toString(); + throw new TargetInitializationException("Error initializing component instance", uri, e); + } + } + } + + public void destroy(Object instance) throws TargetDestructionException { + if (destroyInvoker != null) { + try { + destroyInvoker.invokeEvent(instance); + } catch (ObjectCallbackException e) { + throw new TargetDestructionException("Error destroying component instance", getUri().toString(), e); + } + } + } + + public boolean isOptimizable() { + // stateless implementations that require a destroy callback cannot be optimized since the callback is + // performed by the JavaTargetInvoker + return !(getScope() == Scope.STATELESS && isDestroyable()); + } + + public Object getTargetInstance() throws TargetResolutionException { + return scopeContainer.getInstance(this); + } + + public Object getAssociatedTargetInstance() throws TargetResolutionException { + return scopeContainer.getAssociatedInstance(this); + } + + public Object createInstance() throws ObjectCreationException { + Object instance = instanceFactory.getInstance(); + // inject the instance with properties and references + for (Injector<Object> injector : injectors) { + injector.inject(instance); + } + return instance; + } + + public List<Wire> getWires(String name) { + return wires.get(name); + } + + public void attachWire(Wire wire) { + assert wire.getSourceUri().getFragment() != null; + String referenceName = wire.getSourceUri().getFragment(); + List<Wire> wireList = wires.get(referenceName); + if (wireList == null) { + wireList = new ArrayList<Wire>(); + wires.put(referenceName, wireList); + } + wireList.add(wire); + Member member = referenceSites.get(referenceName); + if (member != null) { + injectors.add(createInjector(member, wire)); + } + // cycle through constructor param names as well + for (int i = 0; i < constructorParamNames.size(); i++) { + if (referenceName.equals(constructorParamNames.get(i))) { + ObjectFactory[] initializerFactories = instanceFactory.getInitializerFactories(); + initializerFactories[i] = createWireFactory(constructorParamTypes.get(i), wire); + break; + } + } + //TODO error if ref not set on constructor or ref site + + } + + public void attachWires(List<Wire> attachWires) { + assert attachWires.size() > 0; + assert attachWires.get(0).getSourceUri().getFragment() != null; + String referenceName = attachWires.get(0).getSourceUri().getFragment(); + List<Wire> wireList = wires.get(referenceName); + if (wireList == null) { + wireList = new ArrayList<Wire>(); + wires.put(referenceName, wireList); + } + wireList.addAll(attachWires); + Member member = referenceSites.get(referenceName); + if (member == null) { + if (constructorParamNames.contains(referenceName)) { + // injected on the constructor + throw new UnsupportedOperationException(); + } else { + throw new NoAccessorException(referenceName); + } + } + + Class<?> type = attachWires.get(0).getSourceContract().getInterfaceClass(); + if (type == null) { + throw new NoMultiplicityTypeException("Java interface must be specified for multiplicity", referenceName); + } + injectors.add(createMultiplicityInjector(member, type, wireList)); + + } + + public void attachCallbackWire(Wire wire) { + assert wire.getSourceUri().getFragment() != null; + String callbackName = wire.getSourceContract().getCallbackName(); + assert callbackSites.get(callbackName) != null; + List<Wire> wireList = callBackwires.get(callbackName); + if (wireList == null) { + wireList = new ArrayList<Wire>(); + callBackwires.put(callbackName, wireList); + } + wireList.add(wire); + } + + public void start() throws CoreRuntimeException { + if (!callbackSites.isEmpty()) { + for (Map.Entry<String, Member> entry : callbackSites.entrySet()) { + List<Wire> wires = callBackwires.get(entry.getKey()); + if (wires == null) { + // this can happen when there are no client wires to a component that has a callback + continue; + } + Member member = entry.getValue(); + if (member instanceof Field) { + Field field = (Field) member; + ObjectFactory<?> factory = new CallbackWireObjectFactory(field.getType(), proxyService, wires); + injectors.add(new FieldInjector<Object>(field, factory)); + } else if (member instanceof Method) { + Method method = (Method) member; + Class<?> type = method.getParameterTypes()[0]; + ObjectFactory<?> factory = new CallbackWireObjectFactory(type, proxyService, wires); + injectors.add(new MethodInjector<Object>(method, factory)); + } else { + throw new InvalidAccessorException("Member must be a field or method", member.getName()); + } + } + } + super.start(); + + } + + public void addPropertyFactory(String name, ObjectFactory<?> factory) { + Member member = propertySites.get(name); + if (member instanceof Field) { + injectors.add(new FieldInjector<Object>((Field) member, factory)); + } else if (member instanceof Method) { + injectors.add(new MethodInjector<Object>((Method) member, factory)); + } + // cycle through constructor param names as well + for (int i = 0; i < constructorParamNames.size(); i++) { + if (name.equals(constructorParamNames.get(i))) { + ObjectFactory[] initializerFactories = instanceFactory.getInitializerFactories(); + initializerFactories[i] = factory; + break; + } + } + //FIXME throw an error if no injection site found + + propertyFactories.put(name, factory); + } + + public void addResourceFactory(String name, ObjectFactory<?> factory) { + Member member = resourceSites.get(name); + if (member instanceof Field) { + injectors.add(new FieldInjector<Object>((Field) member, factory)); + } else if (member instanceof Method) { + injectors.add(new MethodInjector<Object>((Method) member, factory)); + } + // cycle through constructor param names as well + for (int i = 0; i < constructorParamNames.size(); i++) { + if (name.equals(constructorParamNames.get(i))) { + ObjectFactory[] initializerFactories = instanceFactory.getInitializerFactories(); + initializerFactories[i] = factory; + break; + } + } + //FIXME throw an error if no injection site found + } + + public void addConversationIDFactory(Member member) { + ObjectFactory<String> convIDObjectFactory = new ConversationIDObjectFactory(workContext); + if (member instanceof Field) { + injectors.add(new FieldInjector<Object>((Field) member, convIDObjectFactory)); + } else if (member instanceof Method) { + injectors.add(new MethodInjector<Object>((Method) member, convIDObjectFactory)); + } else { + throw new InvalidAccessorException("Member must be a field or method", member.getName()); + } + } + + public boolean implementsCallback(Class callbackClass) { + Class<?>[] implementedInterfaces = implementationClass.getInterfaces(); + for (Class<?> implementedInterface : implementedInterfaces) { + if (implementedInterface.isAssignableFrom(callbackClass)) { + return true; + } + } + + return false; + } + + protected Injector<Object> createInjector(Member member, Wire wire) { + if (member instanceof Field) { + Class<?> type = ((Field) member).getType(); + ObjectFactory<?> factory = createWireFactory(type, wire); + return new FieldInjector<Object>((Field) member, factory); + } else if (member instanceof Method) { + Class<?> type = ((Method) member).getParameterTypes()[0]; + ObjectFactory<?> factory = createWireFactory(type, wire); + return new MethodInjector<Object>((Method) member, factory); + } else { + throw new InvalidAccessorException("Member must be a field or method", member.getName()); + } + } + + protected Injector<Object> createMultiplicityInjector(Member member, + Class<?> interfaceType, + List<Wire> wireFactories) { + List<ObjectFactory<?>> factories = new ArrayList<ObjectFactory<?>>(); + for (Wire wire : wireFactories) { + factories.add(createWireFactory(interfaceType, wire)); + } + if (member instanceof Field) { + Field field = (Field) member; + if (field.getType().isArray()) { + return new FieldInjector<Object>(field, new ArrayMultiplicityObjectFactory(interfaceType, factories)); + } else { + return new FieldInjector<Object>(field, new ListMultiplicityObjectFactory(factories)); + } + } else if (member instanceof Method) { + Method method = (Method) member; + if (method.getParameterTypes()[0].isArray()) { + return new MethodInjector<Object>(method, new ArrayMultiplicityObjectFactory(interfaceType, factories)); + } else { + return new MethodInjector<Object>(method, new ListMultiplicityObjectFactory(factories)); + } + } else { + throw new InvalidAccessorException("Member must be a field or method", member.getName()); + } + } + + public ComponentContext getComponentContext() { + return componentContext; + } + + public <B> B getProperty(Class<B> type, String propertyName) { + ObjectFactory<?> factory = propertyFactories.get(propertyName); + if (factory != null) { + return type.cast(factory.getInstance()); + } else { + return null; + } + + } + + public <B> B getService(Class<B> type, String name) { + List<Wire> referenceWires = wires.get(name); + if (referenceWires == null || referenceWires.size() < 1) { + return null; + } else { + // TODO support multiplicity + Wire wire = referenceWires.get(0); + ObjectFactory<B> factory = createWireFactory(type, wire); + return factory.getInstance(); + } + } + + public <B> ServiceReference<B> getServiceReference(Class<B> type, String name) { + List<Wire> referenceWires = wires.get(name); + if (referenceWires == null || referenceWires.size() < 1) { + return null; + } else { + // TODO support multiplicity + Wire wire = referenceWires.get(0); + ObjectFactory<B> factory = createWireFactory(type, wire); + return new ServiceReferenceImpl<B>(type, factory); + } + } + + public <B, R extends CallableReference<B>> R cast(B target) { + return (R) proxyService.cast(target); + } + + protected abstract <B> ObjectFactory<B> createWireFactory(Class<B> interfaze, Wire wire); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/PojoComponentContextFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/PojoComponentContextFactory.java new file mode 100644 index 0000000000..880802e086 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/PojoComponentContextFactory.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.core.implementation; + +import org.osoa.sca.ComponentContext; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.ObjectCreationException; + +/** + * @version $Rev$ $Date$ + */ +public class PojoComponentContextFactory implements ObjectFactory<ComponentContext> { + private final PojoAtomicComponent component; + + + public PojoComponentContextFactory(PojoAtomicComponent component) { + this.component = component; + } + + + public ComponentContext getInstance() throws ObjectCreationException { + return component.getComponentContext(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/PojoConfiguration.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/PojoConfiguration.java new file mode 100644 index 0000000000..20676145c8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/PojoConfiguration.java @@ -0,0 +1,203 @@ +/* + * 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.core.implementation; + +import java.lang.reflect.Member; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.wire.ProxyService; + +import org.apache.tuscany.core.injection.EventInvoker; +import org.apache.tuscany.core.injection.Injector; +import org.apache.tuscany.core.injection.PojoObjectFactory; + +/** + * Encapsulates confuration for a Java-based atomic component + * + * @version $Rev$ $Date$ + */ +public class PojoConfiguration { + private URI name; + //private ScopeContainer scopeContainer; + private PojoObjectFactory<?> instanceFactory; + private List<String> constructorParamNames = new ArrayList<String>(); + private List<Class<?>> constructorParamTypes = new ArrayList<Class<?>>(); + private int initLevel; + private EventInvoker<Object> initInvoker; + private EventInvoker<Object> destroyInvoker; + private List<Injector> propertyInjectors = new ArrayList<Injector>(); + private Map<String, Member> referenceSites = new HashMap<String, Member>(); + private Map<String, Member> propertySites = new HashMap<String, Member>(); + private Map<String, Member> resourceSites = new HashMap<String, Member>(); + private Map<String, Member> callbackSites = new HashMap<String, Member>(); + private ProxyService proxyService; + private WorkContext workContext; + private long maxIdleTime = -1; + private long maxAge = -1; + private Class implementationClass; + + public URI getName() { + return name; + } + + public void setName(URI name) { + this.name = name; + } + + public PojoObjectFactory<?> getInstanceFactory() { + return instanceFactory; + } + + public void setInstanceFactory(PojoObjectFactory<?> objectFactory) { + this.instanceFactory = objectFactory; + } + + public List<String> getConstructorParamNames() { + return constructorParamNames; + } + + public void setConstructorParamNames(List<String> names) { + constructorParamNames = names; + } + + public void addConstructorParamName(String name) { + constructorParamNames.add(name); + } + + public List<Class<?>> getConstructorParamTypes() { + return constructorParamTypes; + } + + public void setConstructorParamTypes(List<Class<?>> constructorParamTypes) { + this.constructorParamTypes = constructorParamTypes; + } + + public void addConstructorParamType(Class<?> type) { + constructorParamTypes.add(type); + } + + public int getInitLevel() { + return initLevel; + } + + public void setInitLevel(int initLevel) { + this.initLevel = initLevel; + } + + public long getMaxIdleTime() { + return maxIdleTime; + } + + public void setMaxIdleTime(long maxIdleTime) { + this.maxIdleTime = maxIdleTime; + } + + public long getMaxAge() { + return maxAge; + } + + public void setMaxAge(long maxAge) { + this.maxAge = maxAge; + } + + public EventInvoker<Object> getInitInvoker() { + return initInvoker; + } + + public void setInitInvoker(EventInvoker<Object> initInvoker) { + this.initInvoker = initInvoker; + } + + public EventInvoker<Object> getDestroyInvoker() { + return destroyInvoker; + } + + public void setDestroyInvoker(EventInvoker<Object> destroyInvoker) { + this.destroyInvoker = destroyInvoker; + } + + public List<Injector> getPropertyInjectors() { + return propertyInjectors; + } + + public void addPropertyInjector(Injector injector) { + propertyInjectors.add(injector); + } + + public Map<String, Member> getReferenceSite() { + return referenceSites; + } + + public void addReferenceSite(String name, Member member) { + referenceSites.put(name, member); + } + + public Map<String, Member> getResourceSites() { + return resourceSites; + } + + public void addResourceSite(String name, Member member) { + resourceSites.put(name, member); + } + + public Map<String, Member> getCallbackSites() { + 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 ProxyService getProxyService() { + return proxyService; + } + + public void setProxyService(ProxyService proxyService) { + this.proxyService = proxyService; + } + + public WorkContext getWorkContext() { + return workContext; + } + + public void setWorkContext(WorkContext workContext) { + this.workContext = workContext; + } + + public Class getImplementationClass() { + return implementationClass; + } + + public void setImplementationClass(Class implementationClass) { + this.implementationClass = implementationClass; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/AbstractCompositeBuilder.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/AbstractCompositeBuilder.java new file mode 100644 index 0000000000..d12b407ea7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/AbstractCompositeBuilder.java @@ -0,0 +1,69 @@ +/* + * 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.core.implementation.composite; + +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.builder.BuilderInstantiationException; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.RegistrationException; +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.ComponentDefinition; +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceDefinition; + +/** + * Abstract builder for composites + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractCompositeBuilder<T extends Implementation<CompositeComponentType>> + extends ComponentBuilderExtension<T> { + + public Component build( + Component component, + CompositeComponentType<?, ?, ?> componentType, + DeploymentContext deploymentContext) throws BuilderException { + for (ComponentDefinition<? extends Implementation<?>> definition : componentType.getComponents().values()) { + builderRegistry.build(definition, deploymentContext); + } + for (ServiceDefinition definition : componentType.getServices().values()) { + try { + Service service = builderRegistry.build(definition, deploymentContext); + component.register(service); + } catch (RegistrationException e) { + throw new BuilderInstantiationException("Error registering service", e); + } + } + for (ReferenceDefinition definition : componentType.getReferences().values()) { + try { + Reference reference = builderRegistry.build(definition, deploymentContext); + component.register(reference); + } catch (RegistrationException e) { + throw new BuilderInstantiationException("Error registering reference", e); + } + } + return component; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/ComponentTimeoutException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/ComponentTimeoutException.java new file mode 100644 index 0000000000..ed64cb1236 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/ComponentTimeoutException.java @@ -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. + */ +package org.apache.tuscany.core.implementation.composite; + +import org.apache.tuscany.spi.component.ComponentRuntimeException; + +/** + * Denotes a condition where a component times out waiting to perform an operation + * + * @version $Rev$ $Date$ + */ +public class ComponentTimeoutException extends ComponentRuntimeException { + + public ComponentTimeoutException(String message) { + super(message); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeBuilder.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeBuilder.java new file mode 100644 index 0000000000..51d360ec39 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeBuilder.java @@ -0,0 +1,51 @@ +/* + * 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.core.implementation.composite; + +import java.net.URI; + +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.CompositeImplementation; + +/** + * Instantiates a composite component from an assembly definition + * + * @version $Rev$ $Date$ + */ +public class CompositeBuilder extends AbstractCompositeBuilder<CompositeImplementation> { + + public Component build(ComponentDefinition<CompositeImplementation> componentDefinition, + DeploymentContext deploymentContext) throws BuilderException { + + CompositeImplementation implementation = componentDefinition.getImplementation(); + CompositeComponentType<?, ?, ?> componentType = implementation.getComponentType(); + URI name = componentDefinition.getUri(); + CompositeComponentImpl component = new CompositeComponentImpl(name); + + return build(component, componentType, deploymentContext); + } + + protected Class<CompositeImplementation> getImplementationType() { + return CompositeImplementation.class; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImpl.java new file mode 100644 index 0000000000..8df05048c8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImpl.java @@ -0,0 +1,121 @@ +/* + * 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.core.implementation.composite; + +import java.net.URI; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.apache.tuscany.spi.event.Event; +import org.apache.tuscany.spi.extension.CompositeComponentExtension; +import org.apache.tuscany.spi.wire.Wire; + +import org.apache.tuscany.core.component.event.ComponentStop; + +/** + * The standard implementation of a composite component. Autowiring is performed by delegating to the parent composite. + * + * @version $Rev$ $Date$ + */ +public class CompositeComponentImpl extends CompositeComponentExtension { + public static final int DEFAULT_WAIT = 1000 * 60; + // Blocking latch to ensure the composite is initialized exactly once prior to servicing requests + protected CountDownLatch initializeLatch = new CountDownLatch(1); + protected final Object lock = new Object(); + // Indicates whether the composite context has been initialized + protected boolean initialized; + + /** + * Constructor + * + * @param name the name of this Component + */ + public CompositeComponentImpl(URI name) { + super(name); + } + + public void attachWire(Wire wire) { + throw new UnsupportedOperationException(); + } + + public void attachWires(List<Wire> wires) { + throw new UnsupportedOperationException(); + } + + public List<Wire> getWires(String name) { + throw new UnsupportedOperationException(); + } + + public void attachCallbackWire(Wire wire) { + throw new UnsupportedOperationException(); + } + + public void start() { + synchronized (lock) { + if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) { + throw new IllegalStateException("Composite not in UNINITIALIZED state"); + } + initializeLatch.countDown(); + initialized = true; + lifecycleState = INITIALIZED; + } + } + + public void stop() { + if (lifecycleState == STOPPED) { + return; + } + + publish(new ComponentStop(this, getUri())); + // need to block a start until reset is complete + initializeLatch = new CountDownLatch(2); + lifecycleState = STOPPING; + initialized = false; + // allow initialized to be called + initializeLatch.countDown(); + lifecycleState = STOPPED; + } + + public void publish(Event event) { + if (lifecycleState == STOPPED) { + return; + } + checkInit(); + super.publish(event); + } + + /** + * Blocks until the composite context has been initialized + */ + protected void checkInit() throws ComponentTimeoutException { + if (!initialized) { + try { + /* block until the composite has initialized */ + boolean success = initializeLatch.await(DEFAULT_WAIT, TimeUnit.MILLISECONDS); + if (!success) { + throw new ComponentTimeoutException("Timeout waiting for context to initialize"); + } + } catch (InterruptedException e) { // should not happen + } + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeComponentTypeLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeComponentTypeLoader.java new file mode 100644 index 0000000000..61942fc66f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeComponentTypeLoader.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.core.implementation.composite; + +import java.net.URI; +import java.net.URL; + +import org.apache.tuscany.spi.deployer.CompositeClassLoader; +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.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.CompositeImplementation; + +import org.apache.tuscany.core.deployer.ChildDeploymentContext; + +/** + * Loads a composite component type + * + * @version $Rev$ $Date$ + */ +public class CompositeComponentTypeLoader extends ComponentTypeLoaderExtension<CompositeImplementation> { + public CompositeComponentTypeLoader() { + } + + public CompositeComponentTypeLoader(LoaderRegistry loaderRegistry) { + super(loaderRegistry); + } + + protected Class<CompositeImplementation> getImplementationClass() { + return CompositeImplementation.class; + } + + public void load(CompositeImplementation implementation, DeploymentContext context) throws LoaderException { + URL scdlLocation = implementation.getScdlLocation(); + ClassLoader cl = new CompositeClassLoader(implementation.getClassLoader()); + URI componentId = URI.create(context.getComponentId().toString() + '/'); + DeploymentContext childContext = + new ChildDeploymentContext(context, cl, scdlLocation, componentId, context.isAutowire()); + CompositeComponentType componentType = loadFromSidefile(scdlLocation, childContext); + implementation.setComponentType(componentType); + } + + protected CompositeComponentType loadFromSidefile(URL url, DeploymentContext deploymentContext) + throws LoaderException { + return loaderRegistry.load(null, url, CompositeComponentType.class, deploymentContext); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeLoader.java new file mode 100644 index 0000000000..af0a5a7a56 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeLoader.java @@ -0,0 +1,251 @@ +/* + * 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.core.implementation.composite; + +import java.net.URI; +import java.net.URL; +import java.util.List; +import java.util.Map; +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.Constants.SCA_NS; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.deployer.CompositeClassLoader; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.LoaderExtension; +import org.apache.tuscany.spi.loader.InvalidServiceException; +import org.apache.tuscany.spi.loader.InvalidWireException; +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.ComponentDefinition; +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.Include; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ReferenceTarget; +import org.apache.tuscany.spi.model.ServiceDefinition; +import org.apache.tuscany.spi.model.WireDefinition; +import org.apache.tuscany.spi.services.artifact.Artifact; +import org.apache.tuscany.spi.services.artifact.ArtifactRepository; + +import org.apache.tuscany.core.property.PropertyHelper; + +/** + * Loads a composite component definition from an XML-based assembly file + * + * @version $Rev$ $Date$ + */ +public class CompositeLoader extends LoaderExtension<CompositeComponentType> { + public static final QName COMPOSITE = new QName(SCA_NS, "composite"); + public static final String URI_DELIMITER = "/"; + + private final ArtifactRepository artifactRepository; + + public CompositeLoader(@Reference LoaderRegistry registry, @Reference ArtifactRepository artifactRepository) { + super(registry); + this.artifactRepository = artifactRepository; + } + + public QName getXMLType() { + return COMPOSITE; + } + + public CompositeComponentType load( + ModelObject object, + XMLStreamReader reader, + DeploymentContext deploymentContext) throws XMLStreamException, LoaderException { + + String name = reader.getAttributeValue(null, "name"); + String targetNamespace = reader.getAttributeValue(null, "targetNamespace"); + boolean autowire = Boolean.parseBoolean(reader.getAttributeValue(null, "autowire")); + + CompositeComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new CompositeComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>( + new QName(targetNamespace, name) + ); + type.setAutowire(autowire); + boolean done = false; + while (!done) { + switch (reader.next()) { + case START_ELEMENT: + boolean oldAutowire = deploymentContext.isAutowire(); + deploymentContext.setAutowire(autowire); + ModelObject o = registry.load(type, reader, deploymentContext); + deploymentContext.setAutowire(oldAutowire); + if (o instanceof ServiceDefinition) { + type.add((ServiceDefinition) o); + } else if (o instanceof ReferenceDefinition) { + type.add((ReferenceDefinition) o); + } else if (o instanceof Property<?>) { + type.add((Property<?>) o); + } else if (o instanceof ComponentDefinition<?>) { + type.add((ComponentDefinition<?>) o); + } else if (o instanceof Include) { + type.add((Include) o); + } else if (o instanceof Dependency) { + Artifact artifact = ((Dependency) o).getArtifact(); + if (artifactRepository == null) { + throw new MissingResourceException("No ArtifactRepository configured for this system", + artifact.toString() + ); + } + + // default to jar type if not specified + if (artifact.getType() == null) { + artifact.setType("jar"); + } + artifactRepository.resolve(artifact); + if (artifact.getUrl() == null) { + throw new MissingResourceException("Dependency not found", artifact.toString()); + } + + ClassLoader classLoader = deploymentContext.getClassLoader(); + if (classLoader instanceof CompositeClassLoader) { + CompositeClassLoader ccl = (CompositeClassLoader) classLoader; + for (URL dep : artifact.getUrls()) { + ccl.addURL(dep); + } + } + } else if (o instanceof WireDefinition) { + type.add((WireDefinition) o); + } else { + // add as an unknown model extension + if (o != null) { + type.getExtensions().put(o.getClass(), o); + } + } + reader.next(); + break; + case END_ELEMENT: + if (COMPOSITE.equals(reader.getName())) { + // if there are wire defintions then link them up to the relevant components + resolveWires(type); + verifyCompositeCompleteness(type); + done = true; + break; + } + } + } + for (ComponentDefinition<? extends Implementation<?>> c : type.getComponents().values()) { + PropertyHelper.processProperties(type, c, deploymentContext); + } + return type; + } + + protected void resolveWires(CompositeComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> composite) + throws InvalidWireException { + ComponentDefinition componentDefinition; + ServiceDefinition serviceDefinition; + List<WireDefinition> wireDefns = composite.getDeclaredWires(); + for (WireDefinition wire : wireDefns) { + URI targetUri = wire.getTarget(); + // validate the target before finding the source + validateTarget(targetUri, composite); + + String sourceName = wire.getSource().getPath(); //new QualifiedName(wire.getSource().getPath()); + serviceDefinition = composite.getDeclaredServices().get(sourceName); + if (serviceDefinition != null) { + serviceDefinition.setTarget(wire.getTarget()); + } else { + componentDefinition = composite.getDeclaredComponents().get(sourceName); + if (componentDefinition != null) { + if (wire.getSource().getFragment() == null) { + throw new InvalidWireException("Source reference not specified", sourceName); + } + URI referenceName = URI.create(wire.getSource().getFragment()); + ReferenceTarget referenceTarget = createReferenceTarget(referenceName, + targetUri, + componentDefinition); + componentDefinition.add(referenceTarget); + } else { + throw new InvalidWireException("Source not found", sourceName); + } + } + } + } + + private ReferenceTarget createReferenceTarget(URI componentReferenceName, + URI target, + ComponentDefinition componentDefn) throws InvalidWireException { + ComponentType componentType = componentDefn.getImplementation().getComponentType(); + if (componentReferenceName == null) { + // if there is ambiguity in determining the source of the wire or there is no reference to be wired + if (componentType.getReferences().size() > 1 || componentType.getReferences().isEmpty()) { + throw new InvalidWireException("Unable to determine unique source reference"); + } else { + Map references = componentType.getReferences(); + ReferenceDefinition definition = (ReferenceDefinition) references.values().iterator().next(); + componentReferenceName = definition.getUri(); + } + } + + ReferenceTarget referenceTarget = new ReferenceTarget(); + referenceTarget.setReferenceName(componentReferenceName); + referenceTarget.addTarget(target); + return referenceTarget; + } + + protected void verifyCompositeCompleteness( + CompositeComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> composite) + throws InvalidServiceException { + // check if all of the composite services have been wired + for (ServiceDefinition svcDefn : composite.getDeclaredServices().values()) { + if (svcDefn.getTarget() == null) { + String identifier = svcDefn.getUri().toString(); + throw new InvalidServiceException("Composite service not wired to a target", identifier); + } + } + } + + private void validateTarget(URI target, + CompositeComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> composite) + throws InvalidWireException { + // if target is not a reference of the composite + String targetName = target.getPath(); + if (composite.getReferences().get(targetName) == null) { + ComponentDefinition<?> targetDefinition = composite.getDeclaredComponents().get(targetName); + // if a target component exists in this composite + if (targetDefinition != null) { + Implementation<?> implementation = targetDefinition.getImplementation(); + ComponentType<?, ?, ?> componentType = implementation.getComponentType(); + Map<String, ? extends ServiceDefinition> services = componentType.getServices(); + if (target.getFragment() == null) { + if (services.size() > 1 || services.isEmpty()) { + throw new InvalidWireException("Ambiguous target", target.toString()); + } + } else { + if (services.get(target.getFragment()) == null) { + throw new InvalidWireException("Invalid target service", target.toString()); + } + } + } else { + throw new InvalidWireException("Target not found", target.toString()); + } + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/Dependency.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/Dependency.java new file mode 100644 index 0000000000..808f36072f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/Dependency.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.implementation.composite; + +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.services.artifact.Artifact; + +/** + * A model object that represents a dependency on an external artifact. + * + * @version $Rev$ $Date$ + */ +public class Dependency extends ModelObject { + private Artifact artifact; + + public Artifact getArtifact() { + return artifact; + } + + public void setArtifact(Artifact artifact) { + this.artifact = artifact; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/ImplementationCompositeLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/ImplementationCompositeLoader.java new file mode 100644 index 0000000000..48836cd62f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/ImplementationCompositeLoader.java @@ -0,0 +1,125 @@ +/* + * 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.core.implementation.composite; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Set; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.osoa.sca.Constants; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.deployer.CompositeClassLoader; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.LoaderExtension; +import org.apache.tuscany.spi.loader.InvalidValueException; +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.apache.tuscany.spi.model.CompositeImplementation; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.services.artifact.Artifact; +import org.apache.tuscany.spi.services.artifact.ArtifactRepository; + +/** + * Loader that handles an <implementation.composite> element. + * + * @version $Rev$ $Date$ + */ +public class ImplementationCompositeLoader extends LoaderExtension<CompositeImplementation> { + private static final QName IMPLEMENTATION_COMPOSITE = + new QName(Constants.SCA_NS, "implementation.composite"); + + private final ArtifactRepository artifactRepository; + + public ImplementationCompositeLoader(@Reference LoaderRegistry registry, + @Reference ArtifactRepository artifactRepository) { + super(registry); + this.artifactRepository = artifactRepository; + } + + public QName getXMLType() { + return IMPLEMENTATION_COMPOSITE; + } + + public CompositeImplementation load( + ModelObject object, XMLStreamReader reader, + DeploymentContext deploymentContext) + throws XMLStreamException, LoaderException { + + assert IMPLEMENTATION_COMPOSITE.equals(reader.getName()); + String name = reader.getAttributeValue(null, "name"); + String group = reader.getAttributeValue(null, "group"); + String version = reader.getAttributeValue(null, "version"); + String scdlLocation = reader.getAttributeValue(null, "scdlLocation"); + String jarLocation = reader.getAttributeValue(null, "jarLocation"); + LoaderUtil.skipToEndElement(reader); + + CompositeImplementation impl = new CompositeImplementation(); + impl.setName(name); + if (scdlLocation != null) { + try { + impl.setScdlLocation(new URL(deploymentContext.getScdlLocation(), scdlLocation)); + } catch (MalformedURLException e) { + throw new InvalidValueException(scdlLocation, name, e); + } + impl.setClassLoader(deploymentContext.getClassLoader()); + } else if (jarLocation != null) { + URL jarUrl; + try { + jarUrl = new URL(deploymentContext.getScdlLocation(), jarLocation); + } catch (MalformedURLException e) { + throw new InvalidValueException(jarLocation, name, e); + } + try { + impl.setScdlLocation(new URL("jar:" + jarUrl.toExternalForm() + "!/META-INF/sca/default.scdl")); + } catch (MalformedURLException e) { + throw new AssertionError("Could not convert URL to a jar: url"); + } + impl.setClassLoader(new CompositeClassLoader(new URL[]{jarUrl}, deploymentContext.getClassLoader())); + } else if (artifactRepository != null && group != null && version != null) { + Artifact artifact = new Artifact(); + artifact.setGroup(group); + artifact.setName(name); + artifact.setVersion(version); + artifact.setType("jar"); + artifactRepository.resolve(artifact); + if (artifact.getUrl() == null) { + throw new MissingResourceException(artifact.toString(), name); + } + try { + impl.setScdlLocation(new URL("jar:" + artifact.getUrl() + "!/META-INF/sca/default.scdl")); + } catch (MalformedURLException e) { + throw new AssertionError(e); + } + Set<URL> artifactURLs = artifact.getUrls(); + URL[] urls = new URL[artifactURLs.size()]; + int i = 0; + for (URL artifactURL : artifactURLs) { + urls[i++] = artifactURL; + } + impl.setClassLoader(new CompositeClassLoader(urls, deploymentContext.getClassLoader())); + } + return impl; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/ManagedRequestContext.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/ManagedRequestContext.java new file mode 100644 index 0000000000..f2a8109ee3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/ManagedRequestContext.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.core.implementation.composite; + +import javax.security.auth.Subject; + +import org.osoa.sca.RequestContext; +import org.osoa.sca.ServiceReference; +import org.osoa.sca.CallableReference; + +import org.apache.tuscany.spi.component.WorkContext; + +/** + * @version $Rev$ $Date$ + */ +public class ManagedRequestContext implements RequestContext { + private WorkContext workContext; + + public ManagedRequestContext(WorkContext workContext) { + this.workContext = workContext; + } + + public Subject getSecuritySubject() { + throw new UnsupportedOperationException(); + } + + public String getServiceName() { + return workContext.getCurrentServiceName(); + } + + public <B> ServiceReference<B> getServiceReference() { + throw new UnsupportedOperationException(); + } + + public <CB> CB getCallback() { + throw new UnsupportedOperationException(); + } + + public <CB> CallableReference<CB> getCallbackReference() { + throw new UnsupportedOperationException(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/ReferenceImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/ReferenceImpl.java new file mode 100644 index 0000000000..f824980f29 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/ReferenceImpl.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.core.implementation.composite; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.tuscany.spi.component.AbstractSCAObject; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.ReferenceBinding; +import org.apache.tuscany.spi.model.ServiceContract; + +/** + * The default implementation of a {@link org.apache.tuscany.spi.component.Reference} + * + * @version $Rev$ $Date$ + */ +public class ReferenceImpl extends AbstractSCAObject implements Reference { + private ServiceContract<?> serviceContract; + private List<ReferenceBinding> bindings = new ArrayList<ReferenceBinding>(); + + public ReferenceImpl(URI name, ServiceContract<?> contract) { + super(name); + this.serviceContract = contract; + } + + public ServiceContract<?> getServiceContract() { + return serviceContract; + } + + public List<ReferenceBinding> getReferenceBindings() { + return Collections.unmodifiableList(bindings); + } + + public void addReferenceBinding(ReferenceBinding binding) { + bindings.add(binding); + } + + public void start() { + super.start(); + for (ReferenceBinding binding : bindings) { + binding.start(); + } + } + + public void stop() { + super.stop(); + for (ReferenceBinding binding : bindings) { + binding.stop(); + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/ServiceImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/ServiceImpl.java new file mode 100644 index 0000000000..b8b9b00b49 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/ServiceImpl.java @@ -0,0 +1,81 @@ +/* + * 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.core.implementation.composite; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.tuscany.spi.component.AbstractSCAObject; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.component.ServiceBinding; +import org.apache.tuscany.spi.model.ServiceContract; + +/** + * The default implementation of a {@link Service} + * + * @version $Rev$ $Date$ + */ +public class ServiceImpl extends AbstractSCAObject implements Service { + private ServiceContract<?> serviceContract; + private List<ServiceBinding> bindings = new ArrayList<ServiceBinding>(); + private URI targetUri; + + public ServiceImpl(URI name, ServiceContract<?> contract) { + this(name, contract, null); + } + + public ServiceImpl(URI name, ServiceContract<?> contract, URI targetUri) { + super(name); + this.serviceContract = contract; + this.targetUri = targetUri; + } + + public ServiceContract<?> getServiceContract() { + return serviceContract; + } + + public URI getTargetUri() { + return targetUri; + } + + public List<ServiceBinding> getServiceBindings() { + return Collections.unmodifiableList(bindings); + } + + public void addServiceBinding(ServiceBinding binding) { + bindings.add(binding); + } + + public void start() { + super.start(); + for (ServiceBinding binding : bindings) { + binding.start(); + } + } + + public void stop() { + super.stop(); + for (ServiceBinding binding : bindings) { + binding.stop(); + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/SystemCompositeBuilder.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/SystemCompositeBuilder.java new file mode 100644 index 0000000000..531f610bf9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/composite/SystemCompositeBuilder.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.core.implementation.composite; + +import java.net.URI; + +import org.osoa.sca.annotations.Constructor; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.builder.BuilderRegistry; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.CompositeComponentType; + +import org.apache.tuscany.core.implementation.system.model.SystemCompositeImplementation; + +/** + * Produces system composite components by evaluating an assembly. + * + * @version $Rev$ $Date$ + */ +public class SystemCompositeBuilder extends AbstractCompositeBuilder<SystemCompositeImplementation> { + + @Constructor + public SystemCompositeBuilder(@Reference BuilderRegistry builderRegistry) { + this.builderRegistry = builderRegistry; + } + + public Component build(ComponentDefinition<SystemCompositeImplementation> componentDefinition, + DeploymentContext context) throws BuilderException { + SystemCompositeImplementation impl = componentDefinition.getImplementation(); + CompositeComponentType<?, ?, ?> componentType = impl.getComponentType(); + URI name = componentDefinition.getUri(); + Component component = new CompositeComponentImpl(name); + build(component, componentType, context); + return component; + } + + protected Class<SystemCompositeImplementation> getImplementationType() { + return SystemCompositeImplementation.class; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponent.java new file mode 100644 index 0000000000..3ecae61a46 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponent.java @@ -0,0 +1,66 @@ +/* + * 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.core.implementation.java; + +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.component.TargetInvokerCreationException; +import static org.apache.tuscany.spi.idl.java.JavaIDLUtils.findMethod; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; + +import org.apache.tuscany.core.implementation.PojoAtomicComponent; +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.wire.WireObjectFactory; + +/** + * The runtime instantiation of Java component implementations + * + * @version $Rev$ $Date$ + */ +public class JavaAtomicComponent extends PojoAtomicComponent { + + public JavaAtomicComponent(PojoConfiguration configuration) { + super(configuration); + } + + public TargetInvoker createTargetInvoker(String targetName, Operation operation) + throws TargetInvokerCreationException { + Method[] methods; + Class callbackClass = null; + if (operation.isCallback()) { + callbackClass = operation.getServiceContract().getCallbackClass(); + methods = callbackClass.getMethods(); + + } else { + methods = implementationClass.getMethods(); + } + Method method = findMethod(operation, methods); + if (method == null) { + throw new TargetMethodNotFoundException(operation); + } + return new JavaTargetInvoker(method, this, callbackClass, workContext); + } + + protected <B> ObjectFactory<B> createWireFactory(Class<B> interfaze, Wire wire) { + return new WireObjectFactory<B>(interfaze, wire, proxyService); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaComponent.java new file mode 100644 index 0000000000..4ab2cfd9ce --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaComponent.java @@ -0,0 +1,163 @@ +/* + * 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.core.implementation.java; + +import java.net.URI; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.core.component.InstanceFactory; +import org.apache.tuscany.spi.CoreRuntimeException; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.RegistrationException; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.component.TargetInvokerCreationException; +import org.apache.tuscany.spi.event.Event; +import org.apache.tuscany.spi.event.EventFilter; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.PropertyValue; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; +import org.osoa.sca.ComponentContext; + +/** + * + * @version $Revision$ $Date$ + * + */ +public class JavaComponent implements Component { + + // Instance factory class + private Class<InstanceFactory<?>> instanceFactoryClass; //NOPMD + + // Scope container + private ScopeContainer scopeContainer; //NOPMD + + /** + * Injects the instance factory class. + * @param instanceFactoryClass Instance factory class. + */ + public void setInstanceFactoryClass(Class<InstanceFactory<?>> instanceFactoryClass) { + this.instanceFactoryClass = instanceFactoryClass; + } + + /** + * Injects the scope container. + * @param scopeContainer Scope container. + */ + public void setScopeContainer(ScopeContainer scopeContainer) { + throw new UnsupportedOperationException(); + } + + + + public void attachCallbackWire(Wire wire) { + throw new UnsupportedOperationException(); + } + + public void attachWire(Wire wire) { + throw new UnsupportedOperationException(); + } + + public void attachWires(List<Wire> wires) { + throw new UnsupportedOperationException(); + } + + public ComponentContext getComponentContext() { + throw new UnsupportedOperationException(); + } + + public Map<String, PropertyValue<?>> getDefaultPropertyValues() { + throw new UnsupportedOperationException(); + } + + public Reference getReference(String name) { + throw new UnsupportedOperationException(); + } + + public Scope getScope() { + throw new UnsupportedOperationException(); + } + + public Service getService(String name) { + throw new UnsupportedOperationException(); + } + + public List<Wire> getWires(String name) { + throw new UnsupportedOperationException(); + } + + public boolean isOptimizable() { + throw new UnsupportedOperationException(); + } + + public void register(Service service) throws RegistrationException { + throw new UnsupportedOperationException(); + } + + public void register(Reference reference) throws RegistrationException { + throw new UnsupportedOperationException(); + } + + public void setDefaultPropertyValues(Map<String, PropertyValue<?>> defaultPropertyValues) { + throw new UnsupportedOperationException(); + } + + public TargetInvoker createTargetInvoker(String targetName, Operation operation) + throws TargetInvokerCreationException { + throw new UnsupportedOperationException(); + } + + public URI getUri() { + throw new UnsupportedOperationException(); + } + + public void addListener(RuntimeEventListener listener) { + throw new UnsupportedOperationException(); + } + + public void addListener(EventFilter filter, RuntimeEventListener listener) { + throw new UnsupportedOperationException(); + } + + public void publish(Event object) { + throw new UnsupportedOperationException(); + } + + public void removeListener(RuntimeEventListener listener) { + throw new UnsupportedOperationException(); + } + + public int getLifecycleState() { + throw new UnsupportedOperationException(); + } + + public void start() throws CoreRuntimeException { + throw new UnsupportedOperationException(); + } + + public void stop() throws CoreRuntimeException { + throw new UnsupportedOperationException(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilder.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilder.java new file mode 100644 index 0000000000..7f2fdd7627 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilder.java @@ -0,0 +1,195 @@ +/* + * 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.core.implementation.java; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Member; +import java.lang.reflect.Method; + +import org.osoa.sca.ComponentContext; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.builder.BuilderConfigException; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.ComponentBuilderExtension; +import org.apache.tuscany.spi.host.ResourceHost; +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.Resource; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.PropertyValue; + +import org.apache.tuscany.core.implementation.PojoComponentContextFactory; +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.injection.MethodEventInvoker; +import org.apache.tuscany.core.injection.PojoObjectFactory; +import org.apache.tuscany.core.injection.ResourceObjectFactory; + +/** + * Builds a Java-based atomic context from a component definition + * + * @version $$Rev$$ $$Date$$ + */ +public class JavaComponentBuilder extends ComponentBuilderExtension<JavaImplementation> { + + private ResourceHost host; + + @Reference + public void setHost(ResourceHost host) { + this.host = host; + } + + @SuppressWarnings("unchecked") + public AtomicComponent build(ComponentDefinition<JavaImplementation> definition, DeploymentContext context) + throws BuilderConfigException { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> componentType = + definition.getImplementation().getComponentType(); + + PojoConfiguration configuration = new PojoConfiguration(); + if (definition.getInitLevel() != null) { + configuration.setInitLevel(definition.getInitLevel()); + } else { + configuration.setInitLevel(componentType.getInitLevel()); + } + if (componentType.getMaxAge() > 0) { + configuration.setMaxAge(componentType.getMaxAge()); + } else if (componentType.getMaxIdleTime() > 0) { + configuration.setMaxIdleTime(componentType.getMaxIdleTime()); + } + Method initMethod = componentType.getInitMethod(); + if (initMethod != null) { + configuration.setInitInvoker(new MethodEventInvoker(initMethod)); + } + Method destroyMethod = componentType.getDestroyMethod(); + if (destroyMethod != null) { + configuration.setDestroyInvoker(new MethodEventInvoker(destroyMethod)); + } + + configuration.setProxyService(proxyService); + configuration.setWorkContext(workContext); + configuration.setImplementationClass(definition.getImplementation().getImplementationClass()); + + // setup property injection sites + for (JavaMappedProperty<?> property : componentType.getProperties().values()) { + configuration.addPropertySite(property.getName(), property.getMember()); + } + + // setup reference injection sites + for (JavaMappedReference reference : componentType.getReferences().values()) { + Member member = reference.getMember(); + if (member != null) { + // could be null if the reference is mapped to a constructor + configuration.addReferenceSite(reference.getUri().getFragment(), member); + } + } + + for (Resource resource : componentType.getResources().values()) { + Member member = resource.getMember(); + if (member != null) { + // could be null if the resource is mapped to a constructor + configuration.addResourceSite(resource.getName(), member); + } + } + + // setup constructor injection + ConstructorDefinition<?> ctorDef = componentType.getConstructorDefinition(); + Constructor<?> constr = ctorDef.getConstructor(); + PojoObjectFactory<?> instanceFactory = new PojoObjectFactory(constr); + configuration.setInstanceFactory(instanceFactory); + configuration.getConstructorParamNames().addAll(ctorDef.getInjectionNames()); + for (Class<?> clazz : constr.getParameterTypes()) { + configuration.addConstructorParamType(clazz); + } + configuration.setName(definition.getUri()); + handleCallbackSites(componentType, configuration); + + JavaAtomicComponent component = new JavaAtomicComponent(configuration); + + // handle properties + handleProperties(definition, component); + + // handle resources + handleResources(componentType, component); + + if (componentType.getConversationIDMember() != null) { + component.addConversationIDFactory(componentType.getConversationIDMember()); + } + + return component; + } + + private void handleCallbackSites( + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> componentType, + PojoConfiguration configuration) { + for (JavaMappedService service : componentType.getServices().values()) { + // setup callback injection sites + String name = service.getServiceContract().getCallbackName(); + if (name != null) { + // Only if there is a callback reference in the service + configuration.addCallbackSite(name, service.getCallbackMember()); + } + } + } + + private void handleResources( + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> componentType, + JavaAtomicComponent component) { + for (Resource<?> resource : componentType.getResources().values()) { + String name = resource.getName(); + ObjectFactory<?> objectFactory = resource.getObjectFactory(); + if (objectFactory == null) { + Class<?> type = resource.getType(); + if (ComponentContext.class.equals(type)) { + objectFactory = new PojoComponentContextFactory(component); + } else { + boolean optional = resource.isOptional(); + String mappedName = resource.getMappedName(); + objectFactory = createResourceObjectFactory(type, mappedName, optional, host); + } + } + component.addResourceFactory(name, objectFactory); + } + } + + private <T> ResourceObjectFactory<T> createResourceObjectFactory(Class<T> type, + String mappedName, + boolean optional, + ResourceHost host) { + return new ResourceObjectFactory<T>(type, mappedName, optional, host); + } + + private void handleProperties(ComponentDefinition<JavaImplementation> definition, JavaAtomicComponent component) { + for (PropertyValue<?> property : definition.getPropertyValues().values()) { + ObjectFactory<?> factory = property.getValueFactory(); + if (factory != null) { + component.addPropertyFactory(property.getName(), factory); + } + } + } + + protected Class<JavaImplementation> getImplementationType() { + return JavaImplementation.class; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaComponentTypeLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaComponentTypeLoader.java new file mode 100644 index 0000000000..c4234596f8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaComponentTypeLoader.java @@ -0,0 +1,86 @@ +/* + * 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.core.implementation.java; + +import java.net.URL; + +import org.osoa.sca.annotations.Constructor; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.ComponentTypeLoaderExtension; +import org.apache.tuscany.spi.implementation.java.IntrospectionRegistry; +import org.apache.tuscany.spi.implementation.java.Introspector; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; + +import org.apache.tuscany.core.util.JavaIntrospectionHelper; + +/** + * @version $Rev$ $Date$ + */ +public class JavaComponentTypeLoader extends ComponentTypeLoaderExtension<JavaImplementation> { + private Introspector introspector; + + @Constructor({"registry", "introspector"}) + public JavaComponentTypeLoader(@Reference LoaderRegistry loaderRegistry, + @Reference IntrospectionRegistry introspector) { + super(loaderRegistry); + this.introspector = introspector; + } + + @Override + protected Class<JavaImplementation> getImplementationClass() { + return JavaImplementation.class; + } + + public void load( + JavaImplementation implementation, + DeploymentContext deploymentContext) throws LoaderException { + Class<?> implClass = implementation.getImplementationClass(); + URL resource = implClass.getResource(JavaIntrospectionHelper.getBaseName(implClass) + ".componentType"); + PojoComponentType componentType; + if (resource == null) { + componentType = loadByIntrospection(implementation, deploymentContext); + } else { + componentType = loadFromSidefile(resource, deploymentContext); + } + implementation.setComponentType(componentType); + } + + protected PojoComponentType loadByIntrospection(JavaImplementation implementation, DeploymentContext context) + throws ProcessingException { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> componentType = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Class<?> implClass = implementation.getImplementationClass(); + introspector.introspect(implClass, componentType, context); + return componentType; + } + + protected PojoComponentType loadFromSidefile(URL url, DeploymentContext deploymentContext) throws LoaderException { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> componentType = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + return loaderRegistry.load(componentType, url, PojoComponentType.class, deploymentContext); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaImplementation.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaImplementation.java new file mode 100644 index 0000000000..432bf31d63 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaImplementation.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.core.implementation.java; + +import org.apache.tuscany.spi.model.AtomicImplementation; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class JavaImplementation extends AtomicImplementation<PojoComponentType> { + private String className; + private Class<?> implementationClass; + + public JavaImplementation() { + } + + public JavaImplementation(Class<?> implementationClass) { + this.implementationClass = implementationClass; + this.className = implementationClass.getName(); + } + + public JavaImplementation(Class<?> implementationClass, PojoComponentType componentType) { + super(componentType); + this.implementationClass = implementationClass; + this.className = implementationClass == null ? null : implementationClass.getName(); + } + + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + this.implementationClass = null; + } + + public Class<?> getImplementationClass() { + return implementationClass; + } + + public void setImplementationClass(Class<?> implementationClass) { + this.implementationClass = implementationClass; + this.className = implementationClass.getName(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaImplementationLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaImplementationLoader.java new file mode 100644 index 0000000000..91f3852c0e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaImplementationLoader.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.core.implementation.java; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import static org.osoa.sca.Constants.SCA_NS; +import org.osoa.sca.annotations.Constructor; +import org.osoa.sca.annotations.Reference; + +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.model.ModelObject; + +public class JavaImplementationLoader extends LoaderExtension { + public static final QName IMPLEMENTATION_JAVA = new QName(SCA_NS, "implementation.java"); + + @Constructor + public JavaImplementationLoader(@Reference LoaderRegistry registry) { + super(registry); + } + + @Override + public QName getXMLType() { + return IMPLEMENTATION_JAVA; + } + + public ModelObject load(ModelObject object, XMLStreamReader reader, + DeploymentContext deploymentContext) + throws XMLStreamException, LoaderException { + assert IMPLEMENTATION_JAVA.equals(reader.getName()); + String implClass = reader.getAttributeValue(null, "class"); + Class<?> implementationClass = LoaderUtil.loadClass(implClass, deploymentContext.getClassLoader()); + + JavaImplementation implementation = new JavaImplementation(); + implementation.setClassName(implClass); + implementation.setImplementationClass(implementationClass); + registry.loadComponentType(implementation, deploymentContext); + LoaderUtil.skipToEndElement(reader); + return implementation; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaPhysicalComponentBuilder.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaPhysicalComponentBuilder.java new file mode 100644 index 0000000000..7758aa69d3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaPhysicalComponentBuilder.java @@ -0,0 +1,108 @@ +/* + * 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.core.implementation.java; + +import java.net.URI; + +import org.apache.tuscany.core.component.InstanceFactory; +import org.apache.tuscany.core.model.physical.java.JavaPhysicalComponentDefinition; +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.builder.physical.PhysicalComponentBuilder; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.ScopeRegistry; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.services.classloading.ClassLoaderRegistry; +import org.osoa.sca.annotations.Reference; + +/** + * Java physical component builder. + * + * @version $Rev$ $Date$ + * + */ +public class JavaPhysicalComponentBuilder implements + PhysicalComponentBuilder<JavaPhysicalComponentDefinition, JavaComponent> { + + // Classloader registry + private ClassLoaderRegistry classLoaderRegistry; + + // SCope registry + private ScopeRegistry scopeRegistry; + + /** + * Builds a component from its physical component definition. + * + * @param componentDefinition Physical component definition of the component + * to be built. + * @return A component instance that is ready to go live. + * @throws BuilderException If unable to build the component. + */ + public JavaComponent build(JavaPhysicalComponentDefinition componentDefinition) throws BuilderException { + + JavaComponent component = new JavaComponent(); + + setScopeContainer(componentDefinition, component); + + setInstanceFactoryClass(componentDefinition, component); + + return component; + } + + /** + * Injects classloader registry. + * @param classLoaderRegistry Class loader registry. + */ + @Reference + public void setClassLoaderRegistry(ClassLoaderRegistry classLoaderRegistry) { + this.classLoaderRegistry = classLoaderRegistry; + } + + /** + * Injects scope registry. + * @param scopeRegistry Scope registry. + */ + @Reference + public void setScopeRegistry(ScopeRegistry scopeRegistry) { + this.scopeRegistry = scopeRegistry; + } + + /* + * Sets the instance factory class. + */ + private void setInstanceFactoryClass(JavaPhysicalComponentDefinition componentDefinition, JavaComponent component) { + // TODO use MPCL to load IF class + URI classLoaderId = componentDefinition.getClassLoaderId(); + byte[] instanceFactoryByteCode = componentDefinition.getInstanceFactoryByteCode(); //NOPMD + ClassLoader appCl = classLoaderRegistry.getClassLoader(classLoaderId); //NOPMD + ClassLoader systemCl = getClass().getClassLoader(); //NOPMD + ClassLoader mpcl = null; //NOPMD + Class<InstanceFactory<?>> instanceFactoryClass = null; + component.setInstanceFactoryClass(instanceFactoryClass); + } + + /* + * Set the scope container. + */ + private void setScopeContainer(JavaPhysicalComponentDefinition componentDefinition, JavaComponent component) { + Scope scope = componentDefinition.getScope(); + ScopeContainer scopeContainer = scopeRegistry.getScopeContainer(scope); + component.setScopeContainer(scopeContainer); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaTargetInvoker.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaTargetInvoker.java new file mode 100644 index 0000000000..2bf602732d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaTargetInvoker.java @@ -0,0 +1,133 @@ +/* + * 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.core.implementation.java; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Set; + +import org.osoa.sca.NoRegisteredCallbackException; + +import org.apache.tuscany.spi.component.ComponentException; +import org.apache.tuscany.spi.component.InvalidConversationSequenceException; +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.extension.TargetInvokerExtension; +import org.apache.tuscany.spi.model.Scope; + +import static org.apache.tuscany.core.util.JavaIntrospectionHelper.findClosestMatchingMethod; +import static org.apache.tuscany.core.util.JavaIntrospectionHelper.getAllUniquePublicProtectedMethods; + +/** + * Responsible for synchronously dispatching an invocation to a Java component implementation instance + * + * @version $Rev$ $Date$ + */ +public class JavaTargetInvoker extends TargetInvokerExtension { + protected Method operation; + protected JavaAtomicComponent component; + protected Object target; + protected Class callbackClass; + protected boolean stateless; + + public JavaTargetInvoker(Method operation, JavaAtomicComponent component, Class clazz, WorkContext context) { + super(context); + assert operation != null : "Operation method cannot be null"; + this.operation = operation; + this.component = component; + stateless = Scope.STATELESS == component.getScope(); + this.callbackClass = clazz; + } + + public JavaTargetInvoker(Method operation, JavaAtomicComponent component, WorkContext context) { + this(operation, component, null, context); + } + + public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException { + try { + Object instance = getInstance(sequence); + if (callbackClass != null && !callbackClass.isInstance(instance)) { + throw new InvocationTargetException( + new NoRegisteredCallbackException("Instance is does not implement callback [" + + callbackClass.toString() + "]")); + } + if (!operation.getDeclaringClass().isInstance(instance)) { + Set<Method> methods = getAllUniquePublicProtectedMethods(instance.getClass()); + Method newOperation = findClosestMatchingMethod(operation.getName(), + operation.getParameterTypes(), methods); + if (newOperation != null) { + operation = newOperation; + } + } + Object ret; + if (payload != null && !payload.getClass().isArray()) { + ret = operation.invoke(instance, payload); + } else { + ret = operation.invoke(instance, (Object[]) payload); + } + if (stateless) { + // notify a stateless instance of a destruction event after the invoke + component.destroy(instance); + } else if (sequence == END) { + component.destroy(instance); + // if end conversation, remove resource + component.removeInstance(); + } + return ret; + } catch (IllegalAccessException e) { + throw new InvocationTargetException(e); + } catch (ComponentException e) { + throw new InvocationTargetException(e); + } + } + + @Override + public JavaTargetInvoker clone() throws CloneNotSupportedException { + try { + JavaTargetInvoker invoker = (JavaTargetInvoker) super.clone(); + invoker.target = null; + return invoker; + } catch (CloneNotSupportedException e) { + return null; // will not happen + } + } + + /** + * Resolves the target service instance or returns a cached one + */ + protected Object getInstance(short sequence) throws TargetException { + if (!cacheable) { + if (sequence == START || sequence == NONE) { + return component.getTargetInstance(); + } else if (sequence == CONTINUE || sequence == END) { + return component.getAssociatedTargetInstance(); + } else { + throw new InvalidConversationSequenceException("Unknown sequence type", String.valueOf(sequence)); + } + } else { + assert sequence == NONE; // conversations are not cacheable + if (target == null) { + target = component.getTargetInstance(); + } + return target; + } + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/TargetMethodNotFoundException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/TargetMethodNotFoundException.java new file mode 100644 index 0000000000..e98f4b3329 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/java/TargetMethodNotFoundException.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.core.implementation.java; + +import org.apache.tuscany.spi.component.TargetInvokerCreationException; +import org.apache.tuscany.spi.model.Operation; + +/** + * @version $Rev$ $Date$ + */ +public class TargetMethodNotFoundException extends TargetInvokerCreationException { + private Operation operation; + + public TargetMethodNotFoundException(Operation operation) { + super("Target method not found for operation"); + this.operation = operation; + } + + public Operation getOperation() { + return operation; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/AllowsPassByReferenceProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/AllowsPassByReferenceProcessor.java new file mode 100644 index 0000000000..5d90b49362 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/AllowsPassByReferenceProcessor.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.core.implementation.processor;
+
+import org.osoa.sca.annotations.AllowsPassByReference;
+
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Processes {@link AllowsPassByReference} on an implementation
+ *
+ * @version $Rev: 479093 $ $Date: 2006-11-25 12:34:41 +0530 (Sat, 25 Nov 2006) $
+ */
+public class AllowsPassByReferenceProcessor extends ImplementationProcessorExtension {
+
+ public <T> void visitClass(Class<T> clazz,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context)
+ throws ProcessingException {
+ AllowsPassByReference annotation = clazz.getAnnotation(AllowsPassByReference.class);
+ if (annotation == null) {
+ return;
+ } else {
+ // TODO implement
+ }
+
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/AmbiguousConstructorException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/AmbiguousConstructorException.java new file mode 100644 index 0000000000..03d092880d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/AmbiguousConstructorException.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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Thrown when constructor parameters cannot be unambiguously resolved to a property or reference + * + * @version $Rev$ $Date$ + */ +public class AmbiguousConstructorException extends ProcessingException { + + public AmbiguousConstructorException(String message) { + super(message); + } + + public AmbiguousConstructorException(String message, String identifier) { + super(message, identifier); + } + + public AmbiguousConstructorException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessor.java new file mode 100644 index 0000000000..04598199c5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessor.java @@ -0,0 +1,112 @@ +/* + * 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.core.implementation.processor; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.util.List; + +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; + + +/** + * Handles processing of a constructor decorated with {@link org.osoa.sca.annotations.Constructor} + * + * @version $Rev$ $Date$ + */ +@SuppressWarnings("unchecked") +public class ConstructorProcessor extends ImplementationProcessorExtension { + + private ImplementationProcessorService service; + + public ConstructorProcessor(@Reference ImplementationProcessorService service) { + this.service = service; + } + + public <T> void visitClass(Class<T> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + Constructor[] ctors = clazz.getConstructors(); + boolean found = false; + for (Constructor constructor : ctors) { + if (constructor.getAnnotation(org.osoa.sca.annotations.Constructor.class) != null) { + if (found) { + String name = constructor.getDeclaringClass().getName(); + throw new DuplicateConstructorException("Multiple constructors marked with @Constructor", name); + } + found = true; + } + } + } + + public <T> void visitConstructor(Constructor<T> constructor, + PojoComponentType<JavaMappedService, JavaMappedReference, + JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + org.osoa.sca.annotations.Constructor annotation = + constructor.getAnnotation(org.osoa.sca.annotations.Constructor.class); + if (annotation == null) { + return; + } + ConstructorDefinition<?> definition = type.getConstructorDefinition(); + if (definition != null && !definition.getConstructor().equals(constructor)) { + String name = constructor.getDeclaringClass().getName(); + throw new DuplicateConstructorException("Multiple constructor definitions found", name); + } else if (definition == null) { + definition = new ConstructorDefinition(constructor); + } + Class<?>[] params = constructor.getParameterTypes(); + String[] names = annotation.value(); + Annotation[][] annotations = constructor.getParameterAnnotations(); + List<String> injectionNames = definition.getInjectionNames(); + for (int i = 0; i < params.length; i++) { + Class<?> param = params[i]; + Annotation[] paramAnnotations = annotations[i]; + try { + if (!service.processParam(param, + constructor.getGenericParameterTypes()[i], + paramAnnotations, + names, + i, + type, + injectionNames)) { + String name = (i < names.length) ? names[i] : ""; + service.addName(injectionNames, i, name); + } + } catch (ProcessingException e) { + e.setMember(constructor); + throw e; + } + } + if (names.length != 0 && names[0].length() != 0 && names.length != params.length) { + throw new InvalidConstructorException("Names in @Constructor do not match number of parameters"); + } + type.setConstructorDefinition(definition); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ContextProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ContextProcessor.java new file mode 100644 index 0000000000..a0d462b660 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ContextProcessor.java @@ -0,0 +1,103 @@ +/* + * 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.core.implementation.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.osoa.sca.ComponentContext; +import org.osoa.sca.RequestContext; +import org.osoa.sca.annotations.Context; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; +import org.apache.tuscany.spi.implementation.java.Resource; + +import org.apache.tuscany.core.injection.RequestContextObjectFactory; +import org.apache.tuscany.core.util.JavaIntrospectionHelper; + +/** + * Processes {@link @Context} annotations on a component implementation and adds a {@link JavaMappedProperty} to the + * component type which will be used to inject the appropriate context + * + * @version $Rev$ $Date$ + */ +public class ContextProcessor extends ImplementationProcessorExtension { + private WorkContext workContext; + + @Reference + public void setWorkContext(WorkContext workContext) { + this.workContext = workContext; + } + + public void visitMethod( + Method method, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException { + if (method.getAnnotation(Context.class) == null) { + return; + } + if (method.getParameterTypes().length != 1) { + throw new IllegalContextException("Context setter must have one parameter", method.toString()); + } + Class<?> paramType = method.getParameterTypes()[0]; + if (ComponentContext.class.equals(paramType)) { + String name = JavaIntrospectionHelper.toPropertyName(method.getName()); + Resource<ComponentContext> resource = new Resource<ComponentContext>(name, ComponentContext.class, method); + type.getResources().put(name, resource); + } else if (RequestContext.class.equals(paramType)) { + String name = JavaIntrospectionHelper.toPropertyName(method.getName()); + Resource<RequestContext> resource = new Resource<RequestContext>(name, RequestContext.class, method); + resource.setObjectFactory(new RequestContextObjectFactory(workContext)); + type.getResources().put(name, resource); + } else { + throw new UnknownContextTypeException(paramType.getName()); + } + } + + public void visitField(Field field, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + if (field.getAnnotation(Context.class) == null) { + return; + } + Class<?> paramType = field.getType(); + if (ComponentContext.class.equals(paramType)) { + String name = field.getName(); + Resource<ComponentContext> resource = new Resource<ComponentContext>(name, ComponentContext.class, field); + type.getResources().put(name, resource); + } else if (RequestContext.class.equals(paramType)) { + String name = field.getName(); + name = JavaIntrospectionHelper.toPropertyName(name); + Resource<RequestContext> resource = new Resource<RequestContext>(name, RequestContext.class, field); + resource.setObjectFactory(new RequestContextObjectFactory(workContext)); + type.getResources().put(name, resource); + } else { + throw new UnknownContextTypeException(paramType.getName()); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ConversationProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ConversationProcessor.java new file mode 100644 index 0000000000..9d81e15ba1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ConversationProcessor.java @@ -0,0 +1,141 @@ +/* + * 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.core.implementation.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.osoa.sca.annotations.ConversationAttributes; +import org.osoa.sca.annotations.ConversationID; +import org.osoa.sca.annotations.Scope; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * @version $Rev$ $Date$ + */ +public class ConversationProcessor extends ImplementationProcessorExtension { + private static final String SECONDS = " SECONDS"; + private static final String MINUTES = " MINUTES"; + private static final String HOURS = " HOURS"; + private static final String DAYS = " DAYS"; + private static final String YEARS = " YEARS"; + + public <T> void visitClass(Class<T> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + + ConversationAttributes conversation = clazz.getAnnotation(ConversationAttributes.class); + if (conversation == null) { + return; + } + Scope scope = clazz.getAnnotation(Scope.class); + if (scope == null) { + // implicitly assume conversation + type.setImplementationScope(org.apache.tuscany.spi.model.Scope.CONVERSATION); + } else if (scope != null && !"CONVERSATION".equals(scope.value().toUpperCase())) { + throw new InvalidConversationalImplementation( + "Service is marked with @ConversationAttributes but the scope is not @Scope(\"CONVERSATION\")", + clazz.getName()); + } else if (conversation != null) { + long maxAge; + long maxIdleTime; + String maxAgeVal = conversation.maxAge(); + String maxIdleTimeVal = conversation.maxIdleTime(); + if (maxAgeVal.length() > 0 && maxIdleTimeVal.length() > 0) { + throw new InvalidConversationalImplementation("Max idle time and age both specified", clazz.getName()); + } + try { + if (maxAgeVal.length() > 0) { + maxAge = convertTimeMillis(maxAgeVal); + type.setMaxAge(maxAge); + } + } catch (NumberFormatException e) { + throw new InvalidConversationalImplementation("Invalid maximum age", clazz.getName(), e); + } + try { + if (maxIdleTimeVal.length() > 0) { + maxIdleTime = convertTimeMillis(maxIdleTimeVal); + type.setMaxIdleTime(maxIdleTime); + } + } catch (NumberFormatException e) { + throw new InvalidConversationalImplementation("Invalid maximum idle time", clazz.getName(), e); + } + } + + } + + public void visitMethod(Method method, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException { + ConversationID conversationID = method.getAnnotation(ConversationID.class); + if (conversationID == null) { + return; + } + type.setConversationIDMember(method); + } + + public void visitField(Field field, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + ConversationID conversationID = field.getAnnotation(ConversationID.class); + if (conversationID == null) { + return; + } + type.setConversationIDMember(field); + } + + protected long convertTimeMillis(String expr) throws NumberFormatException { + expr = expr.trim().toUpperCase(); + int i = expr.lastIndexOf(SECONDS); + if (i >= 0) { + String units = expr.substring(0, i); + return Long.parseLong(units) * 1000; + } + i = expr.lastIndexOf(MINUTES); + if (i >= 0) { + String units = expr.substring(0, i); + return Long.parseLong(units) * 60000; + } + + i = expr.lastIndexOf(HOURS); + if (i >= 0) { + String units = expr.substring(0, i); + return Long.parseLong(units) * 3600000; + } + i = expr.lastIndexOf(DAYS); + if (i >= 0) { + String units = expr.substring(0, i); + return Long.parseLong(units) * 86400000; + } + i = expr.lastIndexOf(YEARS); + if (i >= 0) { + String units = expr.substring(0, i); + return Long.parseLong(units) * 31556926000L; + } + return Long.parseLong(expr) * 1000; // assume seconds if no suffix specified + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DestroyProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DestroyProcessor.java new file mode 100644 index 0000000000..0b4e8eff76 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DestroyProcessor.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.core.implementation.processor; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.osoa.sca.annotations.Destroy; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Processes the {@link @Destroy} annotation on a component implementation and updates the component type with the + * decorated destructor method + * + * @version $Rev$ $Date$ + */ +public class DestroyProcessor extends ImplementationProcessorExtension { + + public void visitMethod(Method method, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException { + Destroy annotation = method.getAnnotation(Destroy.class); + if (annotation == null) { + return; + } + if (method.getParameterTypes().length != 0) { + throw new IllegalDestructorException("Destructor must not have argments", method.toString()); + } + if (type.getDestroyMethod() != null) { + throw new DuplicateDestructorException("More than one destructor found on implementation"); + } + if (Modifier.isProtected(method.getModifiers())) { + method.setAccessible(true); + } + type.setDestroyMethod(method); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateConstructorException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateConstructorException.java new file mode 100644 index 0000000000..88db7ebb79 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateConstructorException.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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Thrown when more than one component implementation constructor is annotated with {@link + * org.osoa.sca.annotations.Constructor} + * + * @version $Rev$ $Date$ + */ +public class DuplicateConstructorException extends ProcessingException { + + public DuplicateConstructorException(String message) { + super(message); + } + + public DuplicateConstructorException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateDestructorException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateDestructorException.java new file mode 100644 index 0000000000..6225bd6219 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateDestructorException.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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Thrown when an implementation is annotated multiple times with {@link org.osoa.sca.annotations.Destroy} + * + * @version $Rev$ $Date$ + */ +public class DuplicateDestructorException extends ProcessingException { + + public DuplicateDestructorException(String message) { + super(message); + } + + public DuplicateDestructorException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateInitException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateInitException.java new file mode 100644 index 0000000000..105edee1a2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateInitException.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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Thrown when an implementation is annotated multiple times with {@link @org.osoa.sca.annotations.Init} + * + * @version $Rev$ $Date$ + */ +public class DuplicateInitException extends ProcessingException { + + public DuplicateInitException(String message) { + super(message); + } + + public DuplicateInitException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateReferenceException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateReferenceException.java new file mode 100644 index 0000000000..5eae1461c2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateReferenceException.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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Thrown when an implementation has more than one reference injection site with the same name + * + * @version $Rev$ $Date$ + */ +public class DuplicateReferenceException extends ProcessingException { + + public DuplicateReferenceException(String message) { + super(message); + } + + + public DuplicateReferenceException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateResourceException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateResourceException.java new file mode 100644 index 0000000000..9dd718c03e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateResourceException.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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Thrown when an implementation has more than one resource injection site with the same name + * + * @version $Rev$ $Date$ + */ +public class DuplicateResourceException extends ProcessingException { + + public DuplicateResourceException(String message) { + super(message); + } + + public DuplicateResourceException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/EagerInitProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/EagerInitProcessor.java new file mode 100644 index 0000000000..cdf39013a1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/EagerInitProcessor.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.core.implementation.processor; + +import org.osoa.sca.annotations.EagerInit; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Handles processing of {@link org.osoa.sca.annotations.EagerInit} + * + * @version $Rev$ $Date$ + */ +public class EagerInitProcessor extends ImplementationProcessorExtension { + + public <T> void visitClass(Class<T> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + super.visitClass(clazz, type, context); + EagerInit annotation = clazz.getAnnotation(EagerInit.class); + if (annotation == null) { + Class<?> superClass = clazz.getSuperclass(); + while (!Object.class.equals(superClass)) { + annotation = superClass.getAnnotation(EagerInit.class); + if (annotation != null) { + break; + } + superClass = superClass.getSuperclass(); + } + if (annotation == null) { + return; + } + } + type.setInitLevel(50); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/HeuristicPojoProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/HeuristicPojoProcessor.java new file mode 100644 index 0000000000..ab125d5ca1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/HeuristicPojoProcessor.java @@ -0,0 +1,548 @@ +/* + * 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.core.implementation.processor; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Remotable; +import org.osoa.sca.annotations.Service; + +import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.model.TypeInfo; +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +import static org.apache.tuscany.core.util.JavaIntrospectionHelper.getAllInterfaces; +import static org.apache.tuscany.core.util.JavaIntrospectionHelper.getAllPublicAndProtectedFields; +import static org.apache.tuscany.core.util.JavaIntrospectionHelper.getAllUniquePublicProtectedMethods; +import static org.apache.tuscany.core.util.JavaIntrospectionHelper.getBaseName; +import static org.apache.tuscany.core.util.JavaIntrospectionHelper.toPropertyName; + +/** + * Heuristically evaluates an un-annotated Java implementation type to determine services, references, and properties + * according to the algorithm described in the SCA Java Client and Implementation Model Specification <p/> TODO + * Implement: + * <p/> + * When no service inteface is annotated, need to calculate a single service comprising all public methods that are not + * reference or property injection sites. If that service can be exactly mapped to an interface implemented by the class + * then the service interface will be defined in terms of that interface. + * + * @version $Rev$ $Date$ + */ +public class HeuristicPojoProcessor extends ImplementationProcessorExtension { + private SimpleTypeMapperExtension typeMapper = new SimpleTypeMapperExtension(); + private ImplementationProcessorService implService; + + public HeuristicPojoProcessor(@Reference ImplementationProcessorService service) { + this.implService = service; + } + + public <T> void visitEnd( + Class<T> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + Map<String, JavaMappedService> services = type.getServices(); + if (services.isEmpty()) { + // heuristically determine the service + // TODO finish algorithm + Set<Class> interfaces = getAllInterfaces(clazz); + if (interfaces.size() == 0) { + // class is the interface + JavaMappedService service; + try { + service = implService.createService(clazz); + } catch (InvalidServiceContractException e) { + throw new ProcessingException(e); + } + type.getServices().put(service.getUri().getFragment(), service); + } else if (interfaces.size() == 1) { + JavaMappedService service; + try { + service = implService.createService(interfaces.iterator().next()); + } catch (InvalidServiceContractException e) { + throw new ProcessingException(e); + } + type.getServices().put(service.getUri().getFragment(), service); + } + } + Set<Method> methods = getAllUniquePublicProtectedMethods(clazz); + if (!type.getReferences().isEmpty() || !type.getProperties().isEmpty()) { + // references and properties have been explicitly defined + if (type.getServices().isEmpty()) { + calculateServiceInterface(clazz, type, methods); + if (type.getServices().isEmpty()) { + throw new ServiceTypeNotFoundException(clazz.getName()); + } + } + evaluateConstructor(type, clazz); + return; + } + calcPropRefs(methods, services, type, clazz); + evaluateConstructor(type, clazz); + } + + private <T> void calcPropRefs(Set<Method> methods, + Map<String, JavaMappedService> services, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + Class<T> clazz) throws ProcessingException { + // heuristically determine the properties references + // make a first pass through all public methods with one param + for (Method method : methods) { + if (method.getParameterTypes().length != 1 || !Modifier.isPublic(method.getModifiers()) + || !method.getName().startsWith("set") + || method.getReturnType() != void.class) { + continue; + } + if (!isInServiceInterface(method, services)) { + String name = toPropertyName(method.getName()); + // avoid duplicate property or ref names + if (!type.getProperties().containsKey(name) && !type.getReferences().containsKey(name)) { + Class<?> param = method.getParameterTypes()[0]; + Type genericType = method.getGenericParameterTypes()[0]; + if (isReferenceType(genericType)) { + type.add(createReference(name, method, param)); + } else { + type.add(createProperty(name, method, param)); + } + } + } + } + // second pass for protected methods with one param + for (Method method : methods) { + if (method.getParameterTypes().length != 1 || !Modifier.isProtected(method.getModifiers()) + || !method.getName().startsWith("set") + || method.getReturnType() != void.class) { + continue; + } + Class<?> param = method.getParameterTypes()[0]; + String name = toPropertyName(method.getName()); + // avoid duplicate property or ref names + if (!type.getProperties().containsKey(name) && !type.getReferences().containsKey(name)) { + if (isReferenceType(param)) { + type.add(createReference(name, method, param)); + } else { + type.add(createProperty(name, method, param)); + } + } + } + Set<Field> fields = getAllPublicAndProtectedFields(clazz); + for (Field field : fields) { + Class<?> paramType = field.getType(); + if (isReferenceType(paramType)) { + type.add(createReference(field.getName(), field, paramType)); + } else { + type.add(createProperty(field.getName(), field, paramType)); + } + } + } + + /** + * Determines the constructor to use based on the component type's references and properties + * + * @param type the component type + * @param clazz the implementation class corresponding to the component type + * @throws NoConstructorException if no suitable constructor is found + * @throws AmbiguousConstructorException if the parameters of a constructor cannot be unambiguously mapped to + * references and properties + */ + @SuppressWarnings("unchecked") + private <T> void evaluateConstructor( + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + Class<T> clazz) throws ProcessingException { + // determine constructor if one is not annotated + ConstructorDefinition<?> definition = type.getConstructorDefinition(); + Constructor constructor; + boolean explict = false; + if (definition != null + && definition.getConstructor().getAnnotation(org.osoa.sca.annotations.Constructor.class) != null) { + // the constructor was already defined explicitly + return; + } else if (definition != null) { + explict = true; + constructor = definition.getConstructor(); + } else { + // no definition, heuristically determine constructor + Constructor[] constructors = clazz.getConstructors(); + if (constructors.length == 0) { + throw new NoConstructorException("No public constructor for class", clazz.getName()); + } else if (constructors.length == 1) { + constructor = constructors[0]; + } else { + // FIXME multiple constructors, none yet done + Constructor<T> selected = null; + int sites = type.getProperties().size() + type.getReferences().size(); + for (Constructor<T> ctor : constructors) { + if (ctor.getParameterTypes().length == 0) { + selected = ctor; + } + if (ctor.getParameterTypes().length == sites) { + // TODO finish + // selected = constructor; + // select constructor + // break; + } + } + if (selected == null) { + throw new NoConstructorException(); + } + constructor = selected; + definition = new ConstructorDefinition<T>(selected); + type.setConstructorDefinition(definition); + // return; + } + definition = new ConstructorDefinition<T>(constructor); + type.setConstructorDefinition(definition); + } + Class[] params = constructor.getParameterTypes(); + if (params.length == 0) { + return; + } + List<String> paramNames = definition.getInjectionNames(); + Map<String, JavaMappedProperty<?>> props = type.getProperties(); + Map<String, JavaMappedReference> refs = type.getReferences(); + Annotation[][] annotations = constructor.getParameterAnnotations(); + if (!explict) { + // the constructor wasn't defined by an annotation, so check to see if any of the params have an annotation + // which we can impute as explicitly defining the constructor, e.g. @Property, @Reference, or @Autowire + explict = implService.injectionAnnotationsPresent(annotations); + } + if (explict) { + for (int i = 0; i < params.length; i++) { + Class param = params[i]; + implService.processParam(param, + constructor.getGenericParameterTypes()[i], + annotations[i], + new String[0], + i, + type, + paramNames); + } + } else { + if (!implService.areUnique(params)) { + throw new AmbiguousConstructorException("Cannot resolve non-unique parameter types, use @Constructor"); + } + if (!calcPropRefUniqueness(props.values(), refs.values())) { + throw new AmbiguousConstructorException("Cannot resolve non-unique parameter types, use @Constructor"); + } + boolean empty = props.size() + refs.size() == 0; + if (!empty) { + calcParamNames(params, props, refs, paramNames); + } else { + heuristicParamNames(params, refs, props, paramNames); + + } + } + } + + private void calcParamNames(Class[] params, + Map<String, JavaMappedProperty<?>> props, + Map<String, JavaMappedReference> refs, + List<String> paramNames) + throws AmbiguousConstructorException { + // the constructor param types must unambiguously match defined reference or property types + for (Class param : params) { + String name = findReferenceOrProperty(param, props, refs); + if (name == null) { + throw new AmbiguousConstructorException(param.getName()); + } + paramNames.add(name); + } + } + + private void heuristicParamNames(Class[] params, + Map<String, JavaMappedReference> refs, + Map<String, JavaMappedProperty<?>> props, + List<String> paramNames) + throws ProcessingException { + // heuristically determine refs and props from the parameter types + for (Class<?> param : params) { + String name = getBaseName(param).toLowerCase(); + if (isReferenceType(param)) { + refs.put(name, createReference(name, null, param)); + } else { + props.put(name, createProperty(name, null, param)); + } + paramNames.add(name); + } + } + + /** + * Returns true if the union of the given collections of properties and references have unique Java types + */ + private boolean calcPropRefUniqueness( + Collection<JavaMappedProperty<?>> props, + Collection<JavaMappedReference> refs) { + + Class[] classes = new Class[props.size() + refs.size()]; + int i = 0; + for (JavaMappedProperty<?> property : props) { + classes[i] = property.getJavaType(); + i++; + } + for (JavaMappedReference reference : refs) { + classes[i] = reference.getServiceContract().getInterfaceClass(); + i++; + } + return implService.areUnique(classes); + } + + /** + * Unambiguously finds the reference or property associated with the given type + * + * @return the name of the reference or property if found, null if not + * @throws AmbiguousConstructorException if the constructor parameter cannot be resolved to a property or reference + */ + private String findReferenceOrProperty( + Class<?> type, + Map<String, JavaMappedProperty<?>> props, + Map<String, JavaMappedReference> refs) throws AmbiguousConstructorException { + + String name = null; + for (JavaMappedProperty<?> property : props.values()) { + if (property.getJavaType().equals(type)) { + if (name != null) { + throw new AmbiguousConstructorException("Ambiguous property or reference for constructor type", + type.getName()); + } + name = property.getName(); + // do not break since ambiguities must be checked, i.e. more than one prop or ref of the same type + } + } + for (JavaMappedReference reference : refs.values()) { + if (reference.getServiceContract().getInterfaceClass().equals(type)) { + if (name != null) { + throw new AmbiguousConstructorException("Ambiguous property or reference for constructor type", + type.getName()); + } + name = reference.getUri().getFragment(); + // do not break since ambiguities must be checked, i.e. more than one prop or ref of the same type + } + } + return name; + } + + /** + * Returns true if a given type is reference according to the SCA specification rules for determining reference + * types + */ + private boolean isReferenceType(Type operationType) { + Class<?> rawType; + Class<?> referenceType = null; + if (operationType instanceof ParameterizedType) { + ParameterizedType parameterizedType = (ParameterizedType) operationType; + rawType = (Class<?>) parameterizedType.getRawType(); + Type[] typeArgs = parameterizedType.getActualTypeArguments(); + if (typeArgs.length == 1) { + referenceType = (Class<?>) typeArgs[0]; + } + } else { + rawType = (Class<?>) operationType; + } + if (rawType.isArray()) { + referenceType = rawType.getComponentType(); + } else if (Collection.class.isAssignableFrom(rawType) && referenceType == null) { + return true; + } + if (referenceType != null) { + return referenceType.getAnnotation(Remotable.class) != null + || referenceType.getAnnotation(Service.class) != null; + } else { + return rawType.getAnnotation(Remotable.class) != null || rawType.getAnnotation(Service.class) != null; + } + } + + /** + * Returns true if the given operation is defined in the collection of service interfaces + */ + private boolean isInServiceInterface(Method operation, Map<String, JavaMappedService> services) { + for (JavaMappedService service : services.values()) { + Class<?> clazz = service.getServiceContract().getInterfaceClass(); + if (operation.getDeclaringClass().equals(clazz)) { + return true; + } + Method[] methods = service.getServiceContract().getInterfaceClass().getMethods(); + for (Method method : methods) { + if (operation.getName().equals(method.getName()) + && operation.getParameterTypes().length == method.getParameterTypes().length) { + Class<?>[] methodTypes = method.getParameterTypes(); + for (int i = 0; i < operation.getParameterTypes().length; i++) { + Class<?> paramType = operation.getParameterTypes()[i]; + if (!paramType.equals(methodTypes[i])) { + break; + } else if (i == operation.getParameterTypes().length - 1) { + return true; + } + } + } + } + } + return false; + } + + /** + * Creates a mapped reference + * + * @param name the reference name + * @param member the injection site the reference maps to + * @param paramType the service interface of the reference + */ + private JavaMappedReference createReference(String name, Member member, Class<?> paramType) + throws ProcessingException { + return implService.createReference(name, member, paramType); + } + + /** + * Creates a mapped property + * + * @param name the property name + * @param member the injection site the reference maps to + * @param paramType the property type + */ + private <T> JavaMappedProperty<T> createProperty(String name, Member member, Class<T> paramType) { + JavaMappedProperty<T> property = new JavaMappedProperty<T>(); + property.setName(name); + property.setMember(member); + property.setJavaType(paramType); + TypeInfo xmlType = typeMapper.getXMLType(paramType); + if (xmlType != null) { + property.setXmlType(xmlType.getQName()); + } + + return property; + } + + /** + * Populates a component type with a service whose interface type is determined by examining all implemented + * interfaces of the given class and chosing one whose operations match all of the class's non-property and + * non-reference methods + * + * @param clazz the class to examine + * @param type the component type + * @param methods all methods in the class to examine + */ + private void calculateServiceInterface( + Class<?> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + Set<Method> methods) throws ProcessingException { + List<Method> nonPropRefMethods = new ArrayList<Method>(); + // Map<String, JavaMappedService> services = type.getServices(); + Map<String, JavaMappedReference> references = type.getReferences(); + Map<String, JavaMappedProperty<?>> properties = type.getProperties(); + // calculate methods that are not properties or references + for (Method method : methods) { + String name = toPropertyName(method.getName()); + if (!references.containsKey(name) && !properties.containsKey(name)) { + nonPropRefMethods.add(method); + } + } + // determine if an implemented interface matches all of the non-property and non-reference methods + Class[] interfaces = clazz.getInterfaces(); + if (interfaces.length == 0) { + return; + } + for (Class interfaze : interfaces) { + if (analyzeInterface(interfaze, nonPropRefMethods)) { + JavaMappedService service; + try { + service = implService.createService(interfaze); + } catch (InvalidServiceContractException e) { + throw new ProcessingException(e); + } + type.getServices().put(service.getUri().getFragment(), service); + } + } + } + + /** + * Determines if the methods of a given interface match the given list of methods + * + * @param interfaze the interface to examine + * @param nonPropRefMethods the list of methods to match against + * @return true if the interface matches + */ + private boolean analyzeInterface(Class<?> interfaze, List<Method> nonPropRefMethods) { + Method[] interfaceMethods = interfaze.getMethods(); + if (nonPropRefMethods.size() != interfaceMethods.length) { + return false; + } + for (Method method : nonPropRefMethods) { + boolean found = false; + for (Method interfaceMethod : interfaceMethods) { + if (interfaceMethod.getName().equals(method.getName())) { + Class<?>[] interfaceParamTypes = interfaceMethod.getParameterTypes(); + Class<?>[] methodParamTypes = method.getParameterTypes(); + if (interfaceParamTypes.length == methodParamTypes.length) { + if (interfaceParamTypes.length == 0) { + found = true; + } else { + for (int i = 0; i < methodParamTypes.length; i++) { + Class<?> param = methodParamTypes[i]; + if (!param.equals(interfaceParamTypes[i])) { + break; + } + if (i == methodParamTypes.length - 1) { + found = true; + } + } + } + } + if (found) { + break; + } + } + } + if (!found) { + return false; + } + } + return true; + } + +} + +/* + * 1) public setter methods that are not included in any service interface 2) protected setter methods 3) public or + * protected fields unless there is a setter method for the same name If the type associated with the member is an array + * or a java.util.Collection, then the basetype will be the element type of the array or the parameterized type of the + * Collection, otherwise the basetype will be the member type. If the basetype is an interface with an @Remotable or + * @Service annotation then the member will be defined as a reference, otherwise it will be defined as a property. + * + * + */ diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalCallbackReferenceException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalCallbackReferenceException.java new file mode 100644 index 0000000000..4581faa872 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalCallbackReferenceException.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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Denotes an illegcal use of {@link org.osoa.sca.annotations.Callback} on a reference + * + * @version $Rev$ $Date$ + */ +public class IllegalCallbackReferenceException extends ProcessingException { + + public IllegalCallbackReferenceException(String message) { + super(message); + } + + public IllegalCallbackReferenceException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalContextException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalContextException.java new file mode 100644 index 0000000000..8c56cade83 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalContextException.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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Denotes an illegal signature for a method decorated with {@link org.osoa.sca.annotations.Context} + * + * @version $Rev$ $Date$ + */ +public class IllegalContextException extends ProcessingException { + + public IllegalContextException(String message) { + super(message); + } + + public IllegalContextException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalDestructorException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalDestructorException.java new file mode 100644 index 0000000000..fee42ea5c8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalDestructorException.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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Denotes an illegal signature for a method decorated with {@link org.osoa.sca.annotations.Destroy} + * + * @version $Rev$ $Date$ + */ +public class IllegalDestructorException extends ProcessingException { + + public IllegalDestructorException(String message) { + super(message); + } + + public IllegalDestructorException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalInitException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalInitException.java new file mode 100644 index 0000000000..219074b785 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalInitException.java @@ -0,0 +1,36 @@ +/* + * 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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Denotes an illegal signature for a method decorated with {@link @org.osoa.sca.annotations.Init} + * + * @version $Rev$ $Date$ + */ +public class IllegalInitException extends ProcessingException { + public IllegalInitException(String message) { + super(message); + } + + public IllegalInitException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalReferenceException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalReferenceException.java new file mode 100644 index 0000000000..11137bcaba --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalReferenceException.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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Denotes an illegal reference definition in a component type + * + * @version $Rev$ $Date$ + */ +public class IllegalReferenceException extends ProcessingException { + + public IllegalReferenceException(String message) { + super(message); + } + + public IllegalReferenceException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalResourceException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalResourceException.java new file mode 100644 index 0000000000..e25c1174e2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalResourceException.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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Denotes an illegal resource definition in a component type + * + * @version $Rev$ $Date$ + */ +public class IllegalResourceException extends ProcessingException { + + public IllegalResourceException(String message) { + super(message); + } + + public IllegalResourceException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalServiceDefinitionException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalServiceDefinitionException.java new file mode 100644 index 0000000000..1d9079636a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalServiceDefinitionException.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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Denotes an illegal use of the {@link @org.osoa.sca.annotations.Service} annotation + * + * @version $Rev$ $Date$ + */ +public class IllegalServiceDefinitionException extends ProcessingException { + + public IllegalServiceDefinitionException(String message) { + super(message); + } + + public IllegalServiceDefinitionException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceImpl.java new file mode 100644 index 0000000000..ccc947f58a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceImpl.java @@ -0,0 +1,384 @@ +/* + * 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.core.implementation.processor; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Member; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.net.URI; +import java.util.Collection; +import java.util.List; + +import org.osoa.sca.annotations.Callback; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Remotable; + +import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.model.TypeInfo; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.implementation.java.DuplicatePropertyException; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; +import org.apache.tuscany.spi.model.Multiplicity; +import org.apache.tuscany.spi.model.ServiceContract; + +import org.apache.tuscany.api.annotation.Resource; +import org.apache.tuscany.core.idl.java.IllegalCallbackException; +import static org.apache.tuscany.core.util.JavaIntrospectionHelper.getBaseName; + +/** + * The default implementation of an <code>ImplementationProcessorService</code> + * + * @version $Rev$ $Date$ + */ +public class ImplementationProcessorServiceImpl implements ImplementationProcessorService { + private JavaInterfaceProcessorRegistry registry; + private SimpleTypeMapperExtension typeMapper = new SimpleTypeMapperExtension(); + + public ImplementationProcessorServiceImpl(@Reference JavaInterfaceProcessorRegistry registry) { + this.registry = registry; + } + + public JavaMappedService createService(Class<?> interfaze) throws InvalidServiceContractException { + JavaMappedService service = new JavaMappedService(); + // create a relative URI + service.setUri(URI.create("#" + interfaze.getSimpleName())); + service.setRemotable(interfaze.getAnnotation(Remotable.class) != null); + ServiceContract<?> contract = registry.introspect(interfaze); + service.setServiceContract(contract); + return service; + } + + public void processCallback(Class<?> interfaze, ServiceContract<?> contract) throws IllegalCallbackException { + Callback callback = interfaze.getAnnotation(Callback.class); + if (callback != null && !Void.class.equals(callback.value())) { + Class<?> callbackClass = callback.value(); + contract.setCallbackClass(callbackClass); + contract.setCallbackName(getBaseName(callbackClass)); + } else if (callback != null && Void.class.equals(callback.value())) { + throw new IllegalCallbackException("No callback interface specified on annotation", interfaze.getName()); + } + } + + public boolean areUnique(Class[] collection) { + if (collection.length == 0) { + return true; + } + return areUnique(collection, 0); + } + + public void addName(List<String> names, int pos, String name) { + if (names.size() < pos) { + for (int i = 0; i < pos; i++) { + names.add(i, ""); + } + names.add(name); + } else if (names.size() > pos) { + names.remove(pos); + names.add(pos, name); + } else { + names.add(pos, name); + } + } + + public boolean processParam( + Class<?> param, + Type genericParam, + Annotation[] paramAnnotations, + String[] constructorNames, + int pos, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + List<String> injectionNames) throws ProcessingException { + boolean processed = false; + for (Annotation annot : paramAnnotations) { + if (Property.class.equals(annot.annotationType())) { + processed = true; + processProperty(annot, constructorNames, pos, type, param, genericParam, injectionNames); + } else if (Reference.class.equals(annot.annotationType())) { + processed = true; + processReference(annot, constructorNames, pos, type, param, genericParam, injectionNames); + } else if (Resource.class.equals(annot.annotationType())) { + processed = true; + processResource((Resource) annot, constructorNames, pos, type, param, injectionNames); + } + } + return processed; + } + + public boolean injectionAnnotationsPresent(Annotation[][] annots) { + for (Annotation[] annotations : annots) { + for (Annotation annotation : annotations) { + Class<? extends Annotation> annotType = annotation.annotationType(); + if (annotType.equals(Property.class) + || annotType.equals(Reference.class) + || annotType.equals(Resource.class)) { + return true; + } + } + } + return false; + } + + public JavaMappedReference createReference(String name, Member member, Class<?> paramType) + throws ProcessingException { + JavaMappedReference reference = new JavaMappedReference(); + reference.setUri(URI.create("#" + name)); + reference.setMember(member); + reference.setRequired(false); + ServiceContract contract; + try { + contract = registry.introspect(paramType); + } catch (InvalidServiceContractException e1) { + throw new ProcessingException(e1); + } + try { + processCallback(paramType, contract); + } catch (IllegalCallbackException e) { + throw new ProcessingException(e); + } + reference.setServiceContract(contract); + return reference; + } + + /** + * Determines if all the members of a collection have unique types + * + * @param collection the collection to analyze + * @param start the position in the collection to start + * @return true if the types are unique + */ + private boolean areUnique(Class[] collection, int start) { + Object compare = collection[start]; + for (int i = start + 1; i < collection.length; i++) { + if (compare.equals(collection[i])) { + return false; + } + } + if (start + 1 < collection.length) { + return areUnique(collection, start + 1); + } else { + return true; + } + } + + /** + * Processes parameter metadata for a constructor parameter + * + * @param annot the parameter annotation + * @param constructorNames the parameter names as specified in an {@link org.osoa.sca.annotations.Constructor} + * annotation + * @param pos the position of the parameter in the constructor's parameter list + * @param type the component type associated with the implementation being processed + * @param param the parameter type + * @param explicitNames the collection of injection names to update + * @throws ProcessingException + */ + @SuppressWarnings("unchecked") + private void processProperty( + Annotation annot, + String[] constructorNames, + int pos, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + Class<?> param, + Type genericParam, + List<String> explicitNames) throws ProcessingException { + // the param is marked as a property + Property propAnnot = (Property) annot; + JavaMappedProperty property = new JavaMappedProperty(); + Class<?> baseType = getBaseType(param, genericParam); + if (param.isArray() || Collection.class.isAssignableFrom(param)) { + property.setMany(true); + } + property.setJavaType(baseType); + String name = propAnnot.name(); + if (name == null || name.length() == 0) { + if (constructorNames.length < pos + 1 || constructorNames[pos] == null + || constructorNames[pos].length() == 0) { + throw new InvalidPropertyException("No name specified for property parameter " + (pos + 1)); + } + name = constructorNames[pos]; + } else if (pos < constructorNames.length && constructorNames[pos] != null + && constructorNames[pos].length() != 0 && !name.equals(constructorNames[pos])) { + String paramNum = String.valueOf(pos + 1); + throw new InvalidConstructorException("Name specified by @Constructor does not match property name", + paramNum); + } + if (type.getProperties().get(name) != null) { + throw new DuplicatePropertyException(name); + } + property.setName(name); + property.setRequired(propAnnot.required()); + + TypeInfo typeInfo = typeMapper.getXMLType(property.getJavaType()); + if (typeInfo != null) { + property.setXmlType(typeInfo.getQName()); + } + type.getProperties().put(name, property); + addName(explicitNames, pos, name); + } + + /** + * Processes reference metadata for a constructor parameter + * + * @param annot the parameter annotation + * @param constructorNames the parameter names as specified in an {@link org.osoa.sca.annotations.Constructor} + * annotation + * @param pos the position of the parameter in the constructor's parameter list + * @param type the component type associated with the implementation being processed + * @param param the parameter type + * @param explicitNames the collection of injection names to update + * @throws ProcessingException + */ + private void processReference( + Annotation annot, + String[] constructorNames, + int pos, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + Class<?> param, + Type genericParam, + List<String> explicitNames) throws ProcessingException { + + // TODO multiplicity + // the param is marked as a reference + Reference refAnnotation = (Reference) annot; + JavaMappedReference reference = new JavaMappedReference(); + String name = refAnnotation.name(); + if (name == null || name.length() == 0) { + if (constructorNames.length == 0 || constructorNames[0].length() == 0) { + name = "_ref" + pos; + } else if (constructorNames.length < pos + 1 || constructorNames[pos] == null + || constructorNames[pos].length() == 0) { + throw new InvalidReferenceException("No name specified for reference parameter " + (pos + 1)); + } else { + name = constructorNames[pos]; + } + } else if (pos < constructorNames.length && constructorNames[pos] != null + && constructorNames[pos].length() != 0 && !name.equals(constructorNames[pos])) { + String paramNum = String.valueOf(pos + 1); + throw new InvalidConstructorException("Name specified by @Constructor does not match reference name", + paramNum); + } + if (type.getReferences().get(name) != null) { + throw new DuplicateReferenceException(name); + } + reference.setUri(URI.create("#" + name)); + boolean required = refAnnotation.required(); + reference.setRequired(required); + try { + Class<?> rawType = param; + if (rawType.isArray() || Collection.class.isAssignableFrom(rawType)) { + if (required) { + reference.setMultiplicity(Multiplicity.ONE_N); + } else { + reference.setMultiplicity(Multiplicity.ZERO_N); + } + } else { + if (required) { + reference.setMultiplicity(Multiplicity.ONE_ONE); + } else { + reference.setMultiplicity(Multiplicity.ZERO_ONE); + } + } + Class<?> baseType = getBaseType(rawType, genericParam); + ServiceContract<?> contract = registry.introspect(baseType); + reference.setServiceContract(contract); + } catch (InvalidServiceContractException e) { + throw new ProcessingException(e); + } + type.getReferences().put(name, reference); + addName(explicitNames, pos, name); + } + + /** + * Processes resource metadata for a constructor parameter + * + * @param resourceAnnot the resource annotation + * @param constructorNames the parameter names as specified in an {@link org.osoa.sca.annotations.Constructor} + * annotation + * @param pos the position of the parameter in the constructor's parameter list + * @param type the component type associated with the implementation being processed + * @param param the parameter type + * @param explicitNames the collection of injection names to update + * @throws ProcessingException + */ + private <T> void processResource( + Resource resourceAnnot, + String[] constructorNames, + int pos, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + Class<T> param, + List<String> explicitNames) throws ProcessingException { + + String name = resourceAnnot.name(); + if (name == null || name.length() == 0) { + if (constructorNames.length < pos + 1 || constructorNames[pos] == null + || constructorNames[pos].length() == 0) { + String paramNum = String.valueOf(pos + 1); + throw new InvalidResourceException("No name specified for resource parameter", paramNum); + } + name = constructorNames[pos]; + } else if (pos < constructorNames.length && constructorNames[pos] != null + && constructorNames[pos].length() != 0 && !name.equals(constructorNames[pos])) { + String paramNum = String.valueOf(pos + 1); + throw new InvalidConstructorException("Name specified by @Constructor does not match resource name", + paramNum); + } + if (type.getResources().get(name) != null) { + throw new DuplicateResourceException(name); + } + org.apache.tuscany.spi.implementation.java.Resource<T> resource = + new org.apache.tuscany.spi.implementation.java.Resource<T>(name, param, null); + resource.setOptional(resourceAnnot.optional()); + String mappedName = resourceAnnot.mappedName(); + if (mappedName.length() > 0) { + resource.setMappedName(mappedName); + } + type.add(resource); + addName(explicitNames, pos, name); + } + + protected static Class<?> getBaseType(Class<?> cls, Type genericType) { + if (cls.isArray()) { + return cls.getComponentType(); + } else if (Collection.class.isAssignableFrom(cls)) { + if (genericType == cls) { + return Object.class; + } else { + ParameterizedType parameterizedType = (ParameterizedType) genericType; + Type baseType = parameterizedType.getActualTypeArguments()[0]; + if (baseType instanceof Class) { + return (Class<?>) baseType; + } else if (baseType instanceof ParameterizedType) { + return (Class<?>) ((ParameterizedType) baseType).getRawType(); + } else { + return null; + } + } + } else { + return cls; + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InitProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InitProcessor.java new file mode 100644 index 0000000000..d78632d496 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InitProcessor.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.core.implementation.processor; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.osoa.sca.annotations.Init; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Processes the {@link @Init} annotation on a component implementation and updates the component type with the + * decorated initializer method + * + * @version $Rev$ $Date$ + */ +public class InitProcessor extends ImplementationProcessorExtension { + + public void visitMethod(Method method, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException { + Init annotation = method.getAnnotation(Init.class); + if (annotation == null) { + return; + } + if (method.getParameterTypes().length != 0) { + throw new IllegalInitException("Initializer must not have argments", method.toString()); + } + if (type.getInitMethod() != null) { + throw new DuplicateInitException("More than one initializer found on implementaton"); + } + if (Modifier.isProtected(method.getModifiers())) { + method.setAccessible(true); + } + type.setInitMethod(method); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidConstructorException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidConstructorException.java new file mode 100644 index 0000000000..a2dd3f09c4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidConstructorException.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Denotes an invalid constructor definition, e.g. when the number of injection names specified in {@link + * org.osoa.sca.annotations.Constructor} do not match the number of actual constructor parameters + * + * @version $Rev$ $Date$ + */ +public class InvalidConstructorException extends ProcessingException { + + public InvalidConstructorException(String message) { + super(message); + } + + public InvalidConstructorException(String message, String identifier) { + super(message, identifier); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidConversationalImplementation.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidConversationalImplementation.java new file mode 100644 index 0000000000..28bd65200e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidConversationalImplementation.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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Raised when an implementation specifies improper conversational metadata + * + * @version $Rev$ $Date$ + */ +public class InvalidConversationalImplementation extends ProcessingException { + + public InvalidConversationalImplementation(String message) { + super(message); + } + + public InvalidConversationalImplementation(String message, String identifier) { + super(message, identifier); + } + + public InvalidConversationalImplementation(String message, Throwable cause) { + super(message, cause); + } + + public InvalidConversationalImplementation(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidPropertyException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidPropertyException.java new file mode 100644 index 0000000000..5d4c245764 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidPropertyException.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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Denotes an invalid usage of {@link org.osoa.sca.annotations.Property} + * + * @version $Rev$ $Date$ + */ +public class InvalidPropertyException extends ProcessingException { + + public InvalidPropertyException(String message) { + super(message); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidReferenceException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidReferenceException.java new file mode 100644 index 0000000000..8fbc07aa1c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidReferenceException.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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Denotes an invalid usage of {@link org.osoa.sca.annotations.Reference} + * + * @version $Rev$ $Date$ + */ +public class InvalidReferenceException extends ProcessingException { + + public InvalidReferenceException(String message) { + super(message); + } + + public InvalidReferenceException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidReferenceException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidResourceException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidResourceException.java new file mode 100644 index 0000000000..4ed6d93994 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidResourceException.java @@ -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. + */ +package org.apache.tuscany.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Denotes an invalid usage of {@link @org.apache.tuscany.api.annotation.Resource} + * + * @version $Rev$ $Date$ + */ +public class InvalidResourceException extends ProcessingException { + + public InvalidResourceException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidServiceType.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidServiceType.java new file mode 100644 index 0000000000..f3d0367661 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidServiceType.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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Thrown when a service type specified by an {@link org.osoa.sca.annotations.Service} annotation is invalid, e.g. it is + * not an interface + * + * @version $Rev$ $Date$ + */ +public class InvalidServiceType extends ProcessingException { + + public InvalidServiceType(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/MonitorProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/MonitorProcessor.java new file mode 100644 index 0000000000..f8d560504b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/MonitorProcessor.java @@ -0,0 +1,56 @@ +/* + * 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.core.implementation.processor; + +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.AbstractPropertyProcessor; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; + +import org.apache.tuscany.api.annotation.Monitor; +import org.apache.tuscany.core.injection.SingletonObjectFactory; +import org.apache.tuscany.host.MonitorFactory; + +/** + * Processes an {@link @Monitor} annotation, updating the component type with corresponding {@link + * org.apache.tuscany.spi.implementation.java.JavaMappedProperty} + * + * @version $Rev$ $Date$ + */ +public class MonitorProcessor extends AbstractPropertyProcessor<Monitor> { + private MonitorFactory monitorFactory; + + public MonitorProcessor(@Reference MonitorFactory factory, @Reference ImplementationProcessorService service) { + super(Monitor.class, service); + this.monitorFactory = factory; + } + + protected String getName(Monitor annotation) { + return null; + } + + protected <T> void initProperty(JavaMappedProperty<T> property, + Monitor annotation, + DeploymentContext context) { + Class<T> javaType = property.getJavaType(); + property.setDefaultValueFactory(new SingletonObjectFactory<T>(monitorFactory.getMonitor(javaType))); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/NoConstructorException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/NoConstructorException.java new file mode 100644 index 0000000000..f36b7900a4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/NoConstructorException.java @@ -0,0 +1,36 @@ +/* + * 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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Thrown when a suitable constructor for a component implementation cannot be found + * + * @version $Rev$ $Date$ + */ +public class NoConstructorException extends ProcessingException { + + public NoConstructorException() { + } + + public NoConstructorException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/PropertyProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/PropertyProcessor.java new file mode 100644 index 0000000000..206c937b05 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/PropertyProcessor.java @@ -0,0 +1,69 @@ +/* + * 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.core.implementation.processor; + +import java.lang.reflect.Constructor; + +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.TypeInfo; +import org.apache.tuscany.spi.implementation.java.AbstractPropertyProcessor; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Processes an {@link @Property} annotation, updating the component type with corresponding {@link JavaMappedProperty} + * + * @version $Rev$ $Date$ + */ +public class PropertyProcessor extends AbstractPropertyProcessor<Property> { + private SimpleTypeMapperExtension typeMapper = new SimpleTypeMapperExtension(); + + public PropertyProcessor(@Reference ImplementationProcessorService service) { + super(Property.class, service); + } + + protected String getName(Property annotation) { + return annotation.name(); + } + + protected <T> void initProperty(JavaMappedProperty<T> property, + Property annotation, + DeploymentContext context) { + property.setRequired(annotation.required()); + TypeInfo type = typeMapper.getXMLType(property.getJavaType()); + if (type != null) { + property.setXmlType(type.getQName()); + } + } + + public <T> void visitConstructor(Constructor<T> constructor, + PojoComponentType<JavaMappedService, JavaMappedReference, + JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + // override since heuristic pojo processor evalautes properties + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ReferenceProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ReferenceProcessor.java new file mode 100644 index 0000000000..9ecc1c768e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ReferenceProcessor.java @@ -0,0 +1,164 @@ +/* + * 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.core.implementation.processor; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.URI; +import java.util.Collection; + +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; +import org.apache.tuscany.spi.model.Multiplicity; +import org.apache.tuscany.spi.model.ServiceContract; + +import static org.apache.tuscany.core.util.JavaIntrospectionHelper.toPropertyName; + +/** + * Processes an {@link @Reference} annotation, updating the component type with corresponding {@link + * org.apache.tuscany.spi.implementation.java.JavaMappedReference} + * + * @version $Rev$ $Date$ + */ +public class ReferenceProcessor extends ImplementationProcessorExtension { + + private JavaInterfaceProcessorRegistry regsitry; + + public ReferenceProcessor(@Reference JavaInterfaceProcessorRegistry registry) { + this.regsitry = registry; + } + + public void visitMethod( + Method method, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + Reference annotation = method.getAnnotation(Reference.class); + if (annotation == null) { + return; // Not a reference annotation. + } + if (method.getParameterTypes().length != 1) { + throw new IllegalReferenceException("Setter must have one parameter", method.toString()); + } + String name = null; + if (annotation.name() != null && annotation.name().length() > 0) { + name = annotation.name(); + } + boolean required = annotation.required(); + if (name == null) { + name = toPropertyName(method.getName()); + } + if (type.getReferences().get(name) != null) { + throw new DuplicateReferenceException(name); + } + + JavaMappedReference reference = new JavaMappedReference(); + reference.setMember(method); + reference.setRequired(required); + reference.setUri(URI.create("#" + name)); + ServiceContract contract; + try { + Class<?> rawType = method.getParameterTypes()[0]; + if (rawType.isArray() || Collection.class.isAssignableFrom(rawType)) { + if (required) { + reference.setMultiplicity(Multiplicity.ONE_N); + } else { + reference.setMultiplicity(Multiplicity.ZERO_N); + } + } else { + if (required) { + reference.setMultiplicity(Multiplicity.ONE_ONE); + } else { + reference.setMultiplicity(Multiplicity.ZERO_ONE); + } + } + Class<?> baseType = getBaseType(rawType, method.getGenericParameterTypes()[0]); + contract = regsitry.introspect(baseType); + } catch (InvalidServiceContractException e) { + throw new ProcessingException(e); + } + reference.setServiceContract(contract); + type.getReferences().put(name, reference); + } + + public void visitField( + Field field, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + Reference annotation = field.getAnnotation(Reference.class); + if (annotation == null) { + return; + } + String name = field.getName(); + if (annotation.name() != null) { + name = annotation.name(); + } + boolean required = annotation.required(); + if (name.length() == 0) { + name = field.getName(); + } + if (type.getReferences().get(name) != null) { + throw new DuplicateReferenceException(name); + } + JavaMappedReference reference = new JavaMappedReference(); + reference.setMember(field); + reference.setRequired(required); + reference.setUri(URI.create("#" + name)); + ServiceContract contract; + try { + Class<?> rawType = field.getType(); + if (rawType.isArray() || Collection.class.isAssignableFrom(rawType)) { + if (required) { + reference.setMultiplicity(Multiplicity.ONE_N); + } else { + reference.setMultiplicity(Multiplicity.ZERO_N); + } + } else { + if (required) { + reference.setMultiplicity(Multiplicity.ONE_ONE); + } else { + reference.setMultiplicity(Multiplicity.ZERO_ONE); + } + } + Class<?> baseType = getBaseType(rawType, field.getGenericType()); + contract = regsitry.introspect(baseType); + } catch (InvalidServiceContractException e) { + throw new ProcessingException(e); + } + reference.setServiceContract(contract); + type.getReferences().put(name, reference); + } + + public <T> void visitConstructor( + Constructor<T> constructor, + PojoComponentType<JavaMappedService, + JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ResourceProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ResourceProcessor.java new file mode 100644 index 0000000000..2db36652d0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ResourceProcessor.java @@ -0,0 +1,122 @@ +/* + * 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.core.implementation.processor; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; +import org.apache.tuscany.spi.implementation.java.Resource; + +import static org.apache.tuscany.core.util.JavaIntrospectionHelper.toPropertyName; + +/** + * Processes an {@link @Resource} annotation, updating the component type with corresponding {@link + * org.apache.tuscany.spi.implementation.java.Resource} + * + * @version $Rev$ $Date$ + */ +public class ResourceProcessor extends ImplementationProcessorExtension { + + public ResourceProcessor() { + } + + public void visitMethod( + Method method, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException { + org.apache.tuscany.api.annotation.Resource annotation = + method.getAnnotation(org.apache.tuscany.api.annotation.Resource.class); + if (annotation == null) { + return; + } + if (method.getParameterTypes().length != 1) { + throw new IllegalResourceException("Resource setter must have one parameter", method.toString()); + } + Class<?> resourceType = method.getParameterTypes()[0]; + + String name = annotation.name(); + if (name.length() < 1) { + name = toPropertyName(method.getName()); + } + if (type.getResources().get(name) != null) { + throw new DuplicateResourceException(name); + } + + String mappedName = annotation.mappedName(); + Resource<?> resource = createResource(name, resourceType, method); + resource.setOptional(annotation.optional()); + if (mappedName.length() > 0) { + resource.setMappedName(mappedName); + } + type.add(resource); + } + + public void visitField( + Field field, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + + org.apache.tuscany.api.annotation.Resource annotation = + field.getAnnotation(org.apache.tuscany.api.annotation.Resource.class); + if (annotation == null) { + return; + } + String name = annotation.name(); + if (name.length() < 1) { + name = field.getName(); + } + if (type.getResources().get(name) != null) { + throw new DuplicateResourceException(name); + } + + Class<?> fieldType = field.getType(); + String mappedName = annotation.mappedName(); + + Resource<?> resource = createResource(name, fieldType, field); + resource.setOptional(annotation.optional()); + if (mappedName.length() > 0) { + resource.setMappedName(mappedName); + } + type.add(resource); + } + + public <T> Resource<T> createResource(String name, Class<T> type, Member member) { + return new Resource<T>(name, type, member); + } + + public <T> void visitConstructor( + Constructor<T> constructor, + PojoComponentType<JavaMappedService, JavaMappedReference, + JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ScopeProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ScopeProcessor.java new file mode 100644 index 0000000000..efd0e25cd3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ScopeProcessor.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.core.implementation.processor; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; +import org.apache.tuscany.spi.model.Scope; + +/** + * Processes the {@link Scope} annotation and updates the component type with the corresponding implmentation scope + * + * @version $Rev$ $Date$ + */ +public class ScopeProcessor extends ImplementationProcessorExtension { + + public <T> void visitClass(Class<T> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException { + org.osoa.sca.annotations.Scope annotation = clazz.getAnnotation(org.osoa.sca.annotations.Scope.class); + if (annotation == null) { + type.setImplementationScope(Scope.STATELESS); + return; + } + String name = annotation.value(); + Scope scope; + if ("COMPOSITE".equals(name)) { + scope = Scope.COMPOSITE; + } else if ("SESSION".equals(name)) { + scope = Scope.SESSION; + } else if ("CONVERSATION".equals(name)) { + scope = Scope.CONVERSATION; + } else if ("REQUEST".equals(name)) { + scope = Scope.REQUEST; + } else if ("SYSTEM".equals(name)) { + scope = Scope.SYSTEM; + } else { + scope = new Scope(name); + } + type.setImplementationScope(scope); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ServiceProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ServiceProcessor.java new file mode 100644 index 0000000000..8d6e72cae3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ServiceProcessor.java @@ -0,0 +1,155 @@ +/* + * 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.core.implementation.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Set; + +import org.osoa.sca.annotations.Callback; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Remotable; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; +import org.apache.tuscany.spi.model.ServiceContract; + +import static org.apache.tuscany.core.util.JavaIntrospectionHelper.getAllInterfaces; +import static org.apache.tuscany.core.util.JavaIntrospectionHelper.toPropertyName; + +/** + * Processes an {@link org.osoa.sca.annotations.Service} annotation and updates the component type with corresponding + * {@link JavaMappedService}s. Also processes related {@link org.osoa.sca.annotations.Callback} annotations. + * + * @version $Rev$ $Date$ + */ +public class ServiceProcessor extends ImplementationProcessorExtension { + + private ImplementationProcessorService implService; + + public ServiceProcessor(@Reference ImplementationProcessorService implService) { + this.implService = implService; + } + + public <T> void visitClass(Class<T> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + org.osoa.sca.annotations.Service annotation = clazz.getAnnotation(org.osoa.sca.annotations.Service.class); + if (annotation == null) { + // scan intefaces for remotable + Set<Class> interfaces = getAllInterfaces(clazz); + for (Class<?> interfaze : interfaces) { + if (interfaze.isAnnotationPresent(Remotable.class) || interfaze.isAnnotationPresent(Callback.class)) { + JavaMappedService service; + try { + service = implService.createService(interfaze); + } catch (InvalidServiceContractException e) { + throw new ProcessingException(e); + } + type.getServices().put(service.getUri().getFragment(), service); + } + } + return; + } + Class<?>[] interfaces = annotation.interfaces(); + if (interfaces.length == 0) { + Class<?> interfaze = annotation.value(); + if (Void.class.equals(interfaze)) { + throw new IllegalServiceDefinitionException("No interfaces specified"); + } else { + interfaces = new Class<?>[1]; + interfaces[0] = interfaze; + } + } + for (Class<?> interfaze : interfaces) { + if (!interfaze.isInterface()) { + throw new InvalidServiceType("Service must be an interface", interfaze.getName()); + } + JavaMappedService service; + try { + service = implService.createService(interfaze); + } catch (InvalidServiceContractException e) { + throw new ProcessingException(e); + } + type.getServices().put(service.getUri().getFragment(), service); + } + } + + + public void visitMethod( + Method method, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + + Callback annotation = method.getAnnotation(Callback.class); + if (annotation == null) { + return; + } + if (method.getParameterTypes().length != 1) { + throw new IllegalCallbackReferenceException("Setter must have one parameter", method.toString()); + } + String name = toPropertyName(method.getName()); + JavaMappedService callbackService = null; + Class<?> callbackClass = method.getParameterTypes()[0]; + for (JavaMappedService service : type.getServices().values()) { + ServiceContract serviceContract = service.getServiceContract(); + if (serviceContract.getCallbackClass().equals(callbackClass)) { + callbackService = service; + } + } + if (callbackService == null) { + throw new IllegalCallbackReferenceException("Callback type does not match a service callback interface"); + } + callbackService.setCallbackReferenceName(name); + callbackService.setCallbackMember(method); + } + + public void visitField(Field field, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + + Callback annotation = field.getAnnotation(Callback.class); + if (annotation == null) { + return; + } + String name = field.getName(); + JavaMappedService callbacksService = null; + Class<?> callbackClass = field.getType(); + for (JavaMappedService service : type.getServices().values()) { + ServiceContract serviceContract = service.getServiceContract(); + if (serviceContract.getCallbackClass().equals(callbackClass)) { + callbacksService = service; + } + } + if (callbacksService == null) { + throw new IllegalCallbackReferenceException("Callback type does not match a service callback interface"); + } + callbacksService.setCallbackReferenceName(name); + callbacksService.setCallbackMember(field); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ServiceTypeNotFoundException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ServiceTypeNotFoundException.java new file mode 100644 index 0000000000..8a0d4afc3d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/ServiceTypeNotFoundException.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.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +/** + * Thrown when a service interface cannot be determined based on a heuristic evaluation of an implementation + * + * @version $Rev$ $Date$ + */ +public class ServiceTypeNotFoundException extends ProcessingException { + + public ServiceTypeNotFoundException(String message) { + super(message); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/UnknownContextTypeException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/UnknownContextTypeException.java new file mode 100644 index 0000000000..a7868349a6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/processor/UnknownContextTypeException.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.implementation.processor; + +/** + * Thrown when a method or field marked with {@link org.osoa.sca.annotations.Context} takes an unknown type + * + * @version $Rev$ $Date$ + */ +public class UnknownContextTypeException extends IllegalContextException { + + public UnknownContextTypeException(String message) { + super(message); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/builder/SystemComponentBuilder.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/builder/SystemComponentBuilder.java new file mode 100644 index 0000000000..369ac13ca4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/builder/SystemComponentBuilder.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.core.implementation.system.builder; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Map; + +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.builder.BuilderConfigException; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.ComponentBuilderExtension; +import org.apache.tuscany.spi.host.ResourceHost; +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.Resource; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.PropertyValue; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl; +import org.apache.tuscany.core.implementation.system.model.SystemImplementation; +import org.apache.tuscany.core.injection.MethodEventInvoker; +import org.apache.tuscany.core.injection.PojoObjectFactory; +import org.apache.tuscany.core.injection.ResourceObjectFactory; + +/** + * Produces system atomic components from a component definition + * + * @version $$Rev$$ $$Date$$ + */ +public class SystemComponentBuilder extends ComponentBuilderExtension<SystemImplementation> { + private ResourceHost host; + + protected Class<SystemImplementation> getImplementationType() { + return SystemImplementation.class; + } + + @Reference + public void setHost(ResourceHost host) { + this.host = host; + } + + @SuppressWarnings("unchecked") + public AtomicComponent build(ComponentDefinition<SystemImplementation> definition, DeploymentContext context) + throws BuilderConfigException { + + PojoComponentType<ServiceDefinition, JavaMappedReference, JavaMappedProperty<?>> componentType = + definition.getImplementation().getComponentType(); + + PojoConfiguration configuration = new PojoConfiguration(); + if (definition.getInitLevel() != null) { + configuration.setInitLevel(definition.getInitLevel()); + } else { + configuration.setInitLevel(componentType.getInitLevel()); + } + Method initMethod = componentType.getInitMethod(); + if (initMethod != null) { + configuration.setInitInvoker(new MethodEventInvoker<Object>(initMethod)); + } + Method destroyMethod = componentType.getDestroyMethod(); + if (destroyMethod != null) { + configuration.setDestroyInvoker(new MethodEventInvoker<Object>(destroyMethod)); + } + // setup property injection sites + for (JavaMappedProperty<?> property : componentType.getProperties().values()) { + configuration.addPropertySite(property.getName(), property.getMember()); + } + // setup reference injection sites + for (JavaMappedReference reference : componentType.getReferences().values()) { + Member member = reference.getMember(); + if (member != null) { + // could be null if the reference is mapped to a constructor + configuration.addReferenceSite(reference.getUri().getFragment(), member); + } + } + + for (Resource resource : componentType.getResources().values()) { + Member member = resource.getMember(); + if (member != null) { + // could be null if the resource is mapped to a constructor + configuration.addResourceSite(resource.getName(), member); + } + } + + // setup constructor injection + ConstructorDefinition<?> ctorDef = componentType.getConstructorDefinition(); + Constructor<?> constr = ctorDef.getConstructor(); + PojoObjectFactory<?> instanceFactory = new PojoObjectFactory(constr); + configuration.setInstanceFactory(instanceFactory); + configuration.getConstructorParamNames().addAll(ctorDef.getInjectionNames()); + for (Class<?> clazz : constr.getParameterTypes()) { + configuration.addConstructorParamType(clazz); + } + configuration.setName(definition.getUri()); + SystemAtomicComponentImpl component = new SystemAtomicComponentImpl(configuration); + // handle properties + Map<String, PropertyValue<?>> propertyValues = definition.getPropertyValues(); + processProperties(propertyValues, componentType.getProperties().values(), component); + + // handle resources + for (Resource resource : componentType.getResources().values()) { + String name = resource.getName(); + boolean optional = resource.isOptional(); + Class<Object> type = (Class<Object>) resource.getType(); + ResourceObjectFactory<Object> factory; + String mappedName = resource.getMappedName(); + if (mappedName == null) { + // by type + factory = new ResourceObjectFactory<Object>(type, optional, host); + } else { + factory = new ResourceObjectFactory<Object>(type, mappedName, optional, host); + } + component.addResourceFactory(name, factory); + + } + return component; + } + + private void processProperties(Map<String, PropertyValue<?>> propertyValues, + Collection<JavaMappedProperty<?>> properties, + SystemAtomicComponentImpl component) { + for (JavaMappedProperty<?> property : properties) { + PropertyValue value = propertyValues.get(property.getName()); + ObjectFactory<?> factory; + if (value != null) { + factory = value.getValueFactory(); + } else { + factory = property.getDefaultValueFactory(); + } + if (factory != null) { + component.addPropertyFactory(property.getName(), factory); + } + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentImpl.java new file mode 100644 index 0000000000..f15dd2aa9d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentImpl.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.core.implementation.system.component; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; + +import org.apache.tuscany.core.implementation.PojoAtomicComponent; +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.wire.OptimizedWireObjectFactory; + +/** + * Default implementation of a system atomic context + * + * @version $$Rev$$ $$Date$$ + */ +public class SystemAtomicComponentImpl extends PojoAtomicComponent { + + public SystemAtomicComponentImpl(PojoConfiguration configuration) { + super(configuration); + scope = Scope.COMPOSITE; + } + + public TargetInvoker createTargetInvoker(String targetName, Operation operation) { + return null; + } + + protected <B> ObjectFactory<B> createWireFactory(Class<B> interfaze, Wire wire) { + return new OptimizedWireObjectFactory<B>(interfaze, wire); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemComponentTypeLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemComponentTypeLoader.java new file mode 100644 index 0000000000..05fbd42e22 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemComponentTypeLoader.java @@ -0,0 +1,99 @@ +/* + * 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.core.implementation.system.loader; + +import java.net.URL; + +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.ComponentTypeLoaderExtension; +import org.apache.tuscany.spi.implementation.java.IntrospectionRegistry; +import org.apache.tuscany.spi.implementation.java.Introspector; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.model.Scope; + +import org.apache.tuscany.core.implementation.system.model.SystemImplementation; +import org.apache.tuscany.core.util.JavaIntrospectionHelper; + +/** + * Loads a system component type + * + * @version $Rev$ $Date$ + */ +public class SystemComponentTypeLoader extends ComponentTypeLoaderExtension<SystemImplementation> { + private Introspector introspector; + + public SystemComponentTypeLoader() { + } + + public SystemComponentTypeLoader(Introspector introspector) { + this.introspector = introspector; + } + + public SystemComponentTypeLoader(LoaderRegistry loaderRegistry, Introspector introspector) { + super(loaderRegistry); + this.introspector = introspector; + } + + @Reference + public void setIntrospector(IntrospectionRegistry introspector) { + this.introspector = introspector; + } + + public void load( + SystemImplementation implementation, + DeploymentContext deploymentContext) throws LoaderException { + Class<?> implClass = implementation.getImplementationClass(); + URL sidefile = implClass.getResource(JavaIntrospectionHelper.getBaseName(implClass) + ".componentType"); + PojoComponentType componentType; + if (sidefile == null) { + componentType = loadByIntrospection(implementation, deploymentContext); + } else { + componentType = loadFromSidefile(sidefile, deploymentContext); + } + // this means system components are always composite scoped + componentType.setImplementationScope(Scope.COMPOSITE); + implementation.setComponentType(componentType); + } + + protected Class<SystemImplementation> getImplementationClass() { + return SystemImplementation.class; + } + + protected PojoComponentType loadByIntrospection(SystemImplementation implementation, DeploymentContext context) + throws ProcessingException { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> componentType = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Class<?> implClass = implementation.getImplementationClass(); + introspector.introspect(implClass, componentType, context); + return componentType; + } + + + protected PojoComponentType loadFromSidefile(URL url, DeploymentContext deploymentContext) throws LoaderException { + return loaderRegistry.load(null, url, PojoComponentType.class, deploymentContext); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemCompositeComponentTypeLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemCompositeComponentTypeLoader.java new file mode 100644 index 0000000000..7a6e1b5c83 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemCompositeComponentTypeLoader.java @@ -0,0 +1,73 @@ +/* + * 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.core.implementation.system.loader; + +import java.net.URI; +import java.net.URL; + +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.spi.model.CompositeComponentType; + +import org.apache.tuscany.core.deployer.ChildDeploymentContext; +import org.apache.tuscany.core.implementation.system.model.SystemCompositeImplementation; + +/** + * Loads a system composite component type + * + * @version $Rev$ $Date$ + */ +public class SystemCompositeComponentTypeLoader extends ComponentTypeLoaderExtension<SystemCompositeImplementation> { + public SystemCompositeComponentTypeLoader() { + } + + public SystemCompositeComponentTypeLoader(LoaderRegistry loaderRegistry) { + super(loaderRegistry); + } + + protected Class<SystemCompositeImplementation> getImplementationClass() { + return SystemCompositeImplementation.class; + } + + public void load( + SystemCompositeImplementation implementation, + DeploymentContext deploymentContext) + throws LoaderException { + URL scdlLocation = implementation.getScdlLocation(); + if (scdlLocation == null) { + throw new LoaderException("SCDL location not found"); + } + ClassLoader cl = implementation.getClassLoader(); + URI componentId = deploymentContext.getComponentId(); + DeploymentContext childContext = new ChildDeploymentContext(deploymentContext, + cl, + scdlLocation, + componentId, + deploymentContext.isAutowire()); + CompositeComponentType componentType = loadFromSidefile(scdlLocation, childContext); + implementation.setComponentType(componentType); + } + + + protected CompositeComponentType loadFromSidefile(URL url, DeploymentContext context) throws LoaderException { + return loaderRegistry.load(null, url, CompositeComponentType.class, context); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemImplementationLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemImplementationLoader.java new file mode 100644 index 0000000000..f2dd88bfcc --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemImplementationLoader.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.core.implementation.system.loader; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.osoa.sca.annotations.Reference; + +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.UnrecognizedElementException; +import org.apache.tuscany.spi.model.ModelObject; + +import org.apache.tuscany.core.implementation.system.model.SystemImplementation; + +/** + * Loads information for a system implementation + * + * @version $Rev$ $Date$ + */ +public class SystemImplementationLoader extends LoaderExtension<SystemImplementation> { + public static final QName SYSTEM_IMPLEMENTATION = + new QName("http://tuscany.apache.org/xmlns/sca/system/2.0-alpha", "implementation.system"); + + public SystemImplementationLoader(@Reference LoaderRegistry registry) { + super(registry); + } + + public SystemImplementation load( + ModelObject object, XMLStreamReader reader, + DeploymentContext deploymentContext) + throws XMLStreamException, LoaderException { + assert SYSTEM_IMPLEMENTATION.equals(reader.getName()); + SystemImplementation implementation = new SystemImplementation(); + String implClass = reader.getAttributeValue(null, "class"); + Class<?> implementationClass = LoaderUtil.loadClass(implClass, deploymentContext.getClassLoader()); + implementation.setImplementationClass(implementationClass); + registry.loadComponentType(implementation, deploymentContext); + while (true) { + int code = reader.next(); + if (code == XMLStreamConstants.START_ELEMENT) { + throw new UnrecognizedElementException(reader.getName()); + } else if (code == XMLStreamConstants.END_ELEMENT) { + return implementation; + } + } + } + + public QName getXMLType() { + return SYSTEM_IMPLEMENTATION; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/model/SystemCompositeImplementation.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/model/SystemCompositeImplementation.java new file mode 100644 index 0000000000..e634609c5b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/model/SystemCompositeImplementation.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.core.implementation.system.model; + +import java.net.URL; + +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.Implementation; + +/** + * Represents a system composite type + * + * @version $Rev$ $Date$ + */ +public class SystemCompositeImplementation extends Implementation<CompositeComponentType> { + private URL scdlLocation; + private ClassLoader classLoader; + + public SystemCompositeImplementation() { + } + + public SystemCompositeImplementation(CompositeComponentType componentType) { + super(componentType); + } + + public URL getScdlLocation() { + return scdlLocation; + } + + public void setScdlLocation(URL scdlLocation) { + this.scdlLocation = scdlLocation; + } + + public ClassLoader getClassLoader() { + return classLoader; + } + + public void setClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/model/SystemImplementation.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/model/SystemImplementation.java new file mode 100644 index 0000000000..ce48ed3fe5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/implementation/system/model/SystemImplementation.java @@ -0,0 +1,51 @@ +/* + * 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.core.implementation.system.model; + +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.model.AtomicImplementation; + +/** + * Represents the system composite implementation + * + * @version $Rev$ $Date$ + */ +public class SystemImplementation extends AtomicImplementation<PojoComponentType> { + private Class<?> implementationClass; + + public SystemImplementation(PojoComponentType componentType, Class<?> implementationClass) { + super(componentType); + this.implementationClass = implementationClass; + } + + public SystemImplementation() { + } + + public SystemImplementation(Class<?> implementationClass) { + this.implementationClass = implementationClass; + } + + public Class<?> getImplementationClass() { + return implementationClass; + } + + public void setImplementationClass(Class<?> implementationClass) { + this.implementationClass = implementationClass; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ArrayMultiplicityObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ArrayMultiplicityObjectFactory.java new file mode 100644 index 0000000000..1a441dcf87 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ArrayMultiplicityObjectFactory.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.core.injection; + +import java.lang.reflect.Array; +import java.util.List; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; + +/** + * Resolves targets configured in a multiplicity by delegating to object factories and returning an <code>Array</code> + * containing object instances + * + * @version $Rev$ $Date$ + */ +public class ArrayMultiplicityObjectFactory implements ObjectFactory<Object> { + + private ObjectFactory[] factories; + + private Class interfaceType; + + public ArrayMultiplicityObjectFactory(Class interfaceType, List<ObjectFactory<?>> factories) { + assert interfaceType != null : "Interface type was null"; + assert factories != null : "Object factories were null"; + this.interfaceType = interfaceType; + this.factories = factories.toArray(new ObjectFactory[factories.size()]); + } + + public Object getInstance() throws ObjectCreationException { + Object array = Array.newInstance(interfaceType, factories.length); + for (int i = 0; i < factories.length; i++) { + Array.set(array, i, factories[i].getInstance()); + } + return array; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/CallbackWireObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/CallbackWireObjectFactory.java new file mode 100644 index 0000000000..519397e9ff --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/CallbackWireObjectFactory.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.core.injection; + +import java.util.List; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.wire.Wire; +import org.apache.tuscany.spi.wire.ProxyService; + +/** + * Returns proxy instance for a wire callback + * + * @version $Rev$ $Date$ + */ +public class CallbackWireObjectFactory implements ObjectFactory { + private ProxyService proxyService; + private Class<?> interfaze; + private List<Wire> wires; + + public CallbackWireObjectFactory(Class<?> interfaze, ProxyService proxyService, List<Wire> wires) { + this.interfaze = interfaze; + this.proxyService = proxyService; + this.wires = wires; + } + + public Object getInstance() throws ObjectCreationException { + return proxyService.createCallbackProxy(interfaze, wires); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ContextInjector.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ContextInjector.java new file mode 100644 index 0000000000..a422500f3c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ContextInjector.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.injection; + +import org.apache.tuscany.spi.ObjectCreationException; + +/** + * Implementations inject a pre-configured context type (interface) on an instance. + * + * @version $Rev$ $Date$ + */ +public interface ContextInjector<S, T> extends Injector<T> { + + void setContext(S context) throws ObjectCreationException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ConversationIDObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ConversationIDObjectFactory.java new file mode 100644 index 0000000000..8dbc0a3a83 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ConversationIDObjectFactory.java @@ -0,0 +1,36 @@ +/*
+ * 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.core.injection;
+
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+
+public class ConversationIDObjectFactory implements ObjectFactory<String> {
+
+ private WorkContext workContext;
+
+ public ConversationIDObjectFactory(WorkContext workContext) {
+ this.workContext = workContext;
+ }
+
+ public String getInstance() {
+ return (String)workContext.getIdentifier(Scope.CONVERSATION);
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/EventInvoker.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/EventInvoker.java new file mode 100644 index 0000000000..af2382b36a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/EventInvoker.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.core.injection; + +/** + * Performs an invocation on an instance + * + * @version $Rev$ $Date$ + */ +public interface EventInvoker<T> { + + /** + * Performs the invocation on a given instance + * + * @throws ObjectCallbackException + */ + void invokeEvent(T instance) throws ObjectCallbackException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/FieldInjector.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/FieldInjector.java new file mode 100644 index 0000000000..e9f8f42aa1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/FieldInjector.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.core.injection; + +import java.lang.reflect.Field; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; + +/** + * Injects a value created by an {@link org.apache.tuscany.spi.ObjectFactory} on a given field + * + * @version $Rev$ $Date$ + */ +public class FieldInjector<T> implements Injector<T> { + + private final Field field; + + private final ObjectFactory<?> objectFactory; + + /** + * Create an injector and have it use the given <code>ObjectFactory</code> to inject a value on the instance using + * the reflected <code>Field</code> + */ + public FieldInjector(Field field, ObjectFactory<?> objectFactory) { + this.field = field; + this.field.setAccessible(true); + this.objectFactory = objectFactory; + } + + /** + * Inject a new value on the given isntance + */ + public void inject(T instance) throws ObjectCreationException { + try { + field.set(instance, objectFactory.getInstance()); + } catch (IllegalAccessException e) { + throw new AssertionError("Field is not accessible [" + field + "]"); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/InjectionRuntimeException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/InjectionRuntimeException.java new file mode 100644 index 0000000000..c5f037d931 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/InjectionRuntimeException.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.core.injection; + +import org.apache.tuscany.api.TuscanyRuntimeException; + +/** + * Root unchecked exception for the injection package + * + * @version $Rev$ $Date$ + */ +public abstract class InjectionRuntimeException extends TuscanyRuntimeException { + + public InjectionRuntimeException() { + super(); + } + + public InjectionRuntimeException(String message) { + super(message); + } + + + protected InjectionRuntimeException(String message, String identifier) { + super(message, identifier); + } + + public InjectionRuntimeException(String message, Throwable cause) { + super(message, cause); + } + + protected InjectionRuntimeException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + public InjectionRuntimeException(Throwable cause) { + super(cause); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/Injector.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/Injector.java new file mode 100644 index 0000000000..c2125d8212 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/Injector.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.injection; + +import org.apache.tuscany.spi.ObjectCreationException; + +/** + * Implementations inject a pre-configured value on an instance + * + * @version $Rev$ $Date$ + */ +public interface Injector<T> { + + /** + * Inject a value on the given instance + */ + void inject(T instance) throws ObjectCreationException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/InvalidAccessorException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/InvalidAccessorException.java new file mode 100644 index 0000000000..2e7ff0e754 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/InvalidAccessorException.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.core.injection; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class InvalidAccessorException extends InjectionRuntimeException { + + public InvalidAccessorException(String message) { + super(message); + } + + public InvalidAccessorException(String message, String identifier) { + super(message, identifier); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/InvalidResourceTypeException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/InvalidResourceTypeException.java new file mode 100644 index 0000000000..1a3eaf4d1a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/InvalidResourceTypeException.java @@ -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. + */ +package org.apache.tuscany.core.injection; + +import org.apache.tuscany.spi.ObjectCreationException; + +/** + * Denotes an invalid resource type, i.e. that is not a component + * + * @version $Rev$ $Date$ + */ +public class InvalidResourceTypeException extends ObjectCreationException { + + public InvalidResourceTypeException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/JNDIObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/JNDIObjectFactory.java new file mode 100644 index 0000000000..0189d8245b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/JNDIObjectFactory.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.core.injection; + +import javax.naming.Context; +import javax.naming.NamingException; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; + +/** + * An implementation of ObjectFactory that creates instances by looking them up in a JNDI context. + * + * @version $Rev$ $Date$ + */ +public class JNDIObjectFactory<T> implements ObjectFactory<T> { + private final Context context; + private final String name; + + public JNDIObjectFactory(Context context, String name) { + this.context = context; + this.name = name; + } + + + @SuppressWarnings("unchecked") + public T getInstance() throws ObjectCreationException { + try { + return (T) context.lookup(name); + } catch (NamingException e) { + throw new ObjectCreationException(e); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ListMultiplicityObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ListMultiplicityObjectFactory.java new file mode 100644 index 0000000000..b261bcda53 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ListMultiplicityObjectFactory.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.core.injection; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; + +/** + * Resolves targets configured in a multiplicity by delegating to object factories and returning an <code>List</code> + * containing object instances + * + * @version $Rev$ $Date$ + */ +public class ListMultiplicityObjectFactory implements ObjectFactory<List> { + + private ObjectFactory[] factories; + + public ListMultiplicityObjectFactory(List<ObjectFactory<?>> factories) { + assert factories != null : "Object factories were null"; + this.factories = factories.toArray(new ObjectFactory[factories.size()]); + } + + public List getInstance() throws ObjectCreationException { + List<Object> list = new ArrayList<Object>(); + for (ObjectFactory factory : factories) { + list.add(factory.getInstance()); + } + return list; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/MethodEventInvoker.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/MethodEventInvoker.java new file mode 100644 index 0000000000..e43a1e1fa6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/MethodEventInvoker.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.core.injection; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Performs an wire on a method of a given instance + * + * @version $Rev$ $Date$ + */ +public class MethodEventInvoker<T> implements EventInvoker<T> { + private final Method method; + + /** + * Intantiates an invoker for the given method + */ + public MethodEventInvoker(Method method) { + assert method != null; + this.method = method; + } + + public void invokeEvent(T instance) throws ObjectCallbackException { + try { + method.invoke(instance, (Object[]) null); + } catch (IllegalArgumentException e) { + String name = method.getName(); + throw new ObjectCallbackException("Exception thrown by callback method [" + name + "]", e.getCause()); + } catch (IllegalAccessException e) { + String name = method.getName(); + throw new AssertionError("Method is not accessible [" + name + "]"); + } catch (InvocationTargetException e) { + String name = method.getName(); + throw new ObjectCallbackException("Exception thrown by callback method [" + name + "]", e.getCause()); + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/MethodInjector.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/MethodInjector.java new file mode 100644 index 0000000000..258f0817dd --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/MethodInjector.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.core.injection; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; + +/** + * Injects a value created by an {@link org.apache.tuscany.spi.ObjectFactory} using a given method + * + * @version $Rev$ $Date$ + */ +public class MethodInjector<T> implements Injector<T> { + private final Method method; + private final ObjectFactory<?> objectFactory; + + public MethodInjector(Method method, ObjectFactory<?> objectFactory) { + assert method != null; + assert objectFactory != null; + this.method = method; + this.method.setAccessible(true); + this.objectFactory = objectFactory; + } + + public void inject(T instance) throws ObjectCreationException { + try { + method.invoke(instance, objectFactory.getInstance()); + } catch (IllegalAccessException e) { + throw new AssertionError("Method is not accessible [" + method + "]"); + } catch (IllegalArgumentException e) { + throw new ObjectCreationException("Exception thrown by setter", method.getName(), e); + } catch (InvocationTargetException e) { + throw new ObjectCreationException("Exception thrown by setter", method.getName(), e); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/NoAccessorException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/NoAccessorException.java new file mode 100644 index 0000000000..b3109074e3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/NoAccessorException.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.injection; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class NoAccessorException extends InjectionRuntimeException { + public NoAccessorException() { + } + + public NoAccessorException(String message) { + super(message); + } + + public NoAccessorException(String message, Throwable cause) { + super(message, cause); + } + + public NoAccessorException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/NoMultiplicityTypeException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/NoMultiplicityTypeException.java new file mode 100644 index 0000000000..a86451525b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/NoMultiplicityTypeException.java @@ -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. + */ +package org.apache.tuscany.core.injection; + +/** + * @version $Rev$ $Date$ + */ +public class NoMultiplicityTypeException extends InjectionRuntimeException { + + public NoMultiplicityTypeException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ObjectCallbackException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ObjectCallbackException.java new file mode 100644 index 0000000000..ff830aab4b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ObjectCallbackException.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.core.injection; + +/** + * Denotes an error when invoking on an object + * + * @version $Rev$ $Date$ + */ +public class ObjectCallbackException extends InjectionRuntimeException { + + public ObjectCallbackException() { + super(); + } + + public ObjectCallbackException(String message) { + super(message); + } + + public ObjectCallbackException(String message, String identifier) { + super(message, identifier); + } + + public ObjectCallbackException(String message, Throwable cause) { + super(message, cause); + } + + public ObjectCallbackException(Throwable cause) { + super(cause); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/PojoObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/PojoObjectFactory.java new file mode 100644 index 0000000000..d36af74de5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/PojoObjectFactory.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.core.injection; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.List; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; + +/** + * Creates new instances of a Java class + * + * @version $Rev$ $Date$ + * @see org.apache.tuscany.core.injection.Injector + */ +public class PojoObjectFactory<T> implements ObjectFactory<T> { + + private final Constructor<T> ctr; + private ObjectFactory[] initializerFactories; + + /** + * Creates the object factory + * + * @param ctr the constructor to use when instantiating a new object + */ + public PojoObjectFactory(Constructor<T> ctr) { + assert ctr != null; + this.ctr = ctr; + initializerFactories = new ObjectFactory[ctr.getParameterTypes().length]; + } + + /** + * Creates the object factory + * + * @param ctr the constructor to use when instantiating a new object + * @param factories an ordered list of <code>ObjectFactory</code>s to use for returning constructor parameters + */ + public PojoObjectFactory(Constructor<T> ctr, List<ObjectFactory> factories) { + assert ctr != null; + int params = ctr.getParameterTypes().length; + assert params == factories.size(); + this.ctr = ctr; + initializerFactories = new ObjectFactory[params]; + int i = 0; + for (ObjectFactory factory : factories) { + initializerFactories[i] = factory; + i++; + } + } + + /** + * Returns the ordered array of <code>ObjectFactory</code>s use in creating constructor parameters + */ + public ObjectFactory[] getInitializerFactories() { + return initializerFactories; + } + + /** + * Sets an <code>ObjectFactory</code>s to use in creating constructor parameter + * + * @param pos the constructor parameter position + * @param factory the object factory + */ + public void setInitializerFactory(int pos, ObjectFactory factory) { + assert pos < initializerFactories.length; + initializerFactories[pos] = factory; + } + + /** + * Creates a new instance of an object + */ + public T getInstance() throws ObjectCreationException { + int size = initializerFactories.length; + Object[] initargs = new Object[size]; + // create the constructor arg array + for (int i = 0; i < size; i++) { + ObjectFactory<?> objectFactory = initializerFactories[i]; + if (objectFactory == null) { + // this can happen if a reference is optional + initargs[i] = null; + } else { + initargs[i] = objectFactory.getInstance(); + } + } + try { + ctr.setAccessible(true); + return ctr.newInstance(initargs); + } catch (IllegalArgumentException e) { + String name = ctr.getName(); + throw new ObjectCreationException("Exception thrown by constructor", name, e); + } catch (InstantiationException e) { + String name = ctr.getDeclaringClass().getName(); + throw new AssertionError("Class is not instantiable [" + name + "]"); + } catch (IllegalAccessException e) { + String name = ctr.getName(); + throw new AssertionError("Constructor is not accessible [" + name + "]"); + } catch (InvocationTargetException e) { + String name = ctr.getName(); + throw new ObjectCreationException("Exception thrown by constructor", name, e); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/RequestContextObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/RequestContextObjectFactory.java new file mode 100644 index 0000000000..92a422a968 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/RequestContextObjectFactory.java @@ -0,0 +1,46 @@ +/* + * 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.core.injection; + +import org.osoa.sca.RequestContext; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.component.WorkContext; + +import org.apache.tuscany.core.implementation.composite.ManagedRequestContext; + +/** + * Creates instances of {@link org.apache.tuscany.core.implementation.composite.ManagedRequestContext} for injection on + * component implementation instances + * + * @version $Rev$ $Date$ + */ +public class RequestContextObjectFactory implements ObjectFactory<RequestContext> { + private WorkContext workContext; + + public RequestContextObjectFactory(WorkContext workContext) { + assert workContext != null; + this.workContext = workContext; + } + + public ManagedRequestContext getInstance() throws ObjectCreationException { + return new ManagedRequestContext(workContext); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ResourceNotFoundException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ResourceNotFoundException.java new file mode 100644 index 0000000000..ed3ac20631 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ResourceNotFoundException.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.core.injection; + +import org.apache.tuscany.spi.ObjectCreationException; + +/** + * Denotes an exception thrown when a runtime resource is not found + * + * @version $Rev$ $Date$ + */ +public class ResourceNotFoundException extends ObjectCreationException { + + public ResourceNotFoundException(String message, String identifier) { + super(message, identifier); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ResourceObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ResourceObjectFactory.java new file mode 100644 index 0000000000..bb2f335506 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/ResourceObjectFactory.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.injection; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.host.ResourceHost; +import org.apache.tuscany.spi.host.ResourceResolutionException; + +/** + * Resolves a runtime resource to be injected on a field or method of a Java component type marked with {@link + * org.apache.tuscany.api.annotation.Resource}. If the mapped name of the resource is an absolute URI such as + * <code>sca://localhost</code> or <code>jndi://localhost</code> the host container namespace is searched; otherwise the + * URI is assumed to be relative and the parent composite is searched. If a mapped name is not provided, i.e. resolution + * is by type, the parent composite is first searched followed by the host namespace. + * + * @version $Rev$ $Date$ + */ +public class ResourceObjectFactory<T> implements ObjectFactory<T> { + + private Class<T> type; + private String mappedName; + private ResourceHost host; + private boolean optional; + + /** + * Instantiates a factory that resolves resources by type + * + * @param type the type of the resource to inject + * @param optional true if an error should be thrown if the resource is not found + * @param host the runtime resource provider + */ + public ResourceObjectFactory(Class<T> type, boolean optional, ResourceHost host) { + this(type, null, optional, host); + } + + /** + * Instantiates a factory that resolves resources by mapped name + * + * @param type the type of the resource to inject + * @param mappedName the resource name + * @param optional true if an error should be thrown if the resource is not found + * @param host the runtime resource provider + */ + public ResourceObjectFactory(Class<T> type, String mappedName, boolean optional, ResourceHost host) { + this.type = type; + this.host = host; + this.mappedName = mappedName; + this.optional = optional; + } + + @SuppressWarnings({"unchecked"}) + public T getInstance() throws ObjectCreationException { + try { + T resource; + if (mappedName == null) { + resource = host.resolveResource(type); + if (!optional && resource == null) { + throw new ResourceNotFoundException("Resource not found", type.getName()); + } + } else { + resource = host.resolveResource(type, mappedName); + if (!optional && resource == null) { + throw new ResourceNotFoundException("Resource not found", mappedName); + } + } + return resource; + } catch (ResourceResolutionException e) { + throw new ObjectCreationException(e); + } + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/SingletonObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/SingletonObjectFactory.java new file mode 100644 index 0000000000..713c1ae54f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/injection/SingletonObjectFactory.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.injection; + +import org.apache.tuscany.spi.ObjectFactory; + +/** + * Implementation of ObjectFactory that returns a single instance, typically an immutable type. + * + * @version $Rev$ $Date$ + */ +public class SingletonObjectFactory<T> implements ObjectFactory<T> { + private final T instance; + + public SingletonObjectFactory(T instance) { + this.instance = instance; + } + + public T getInstance() { + return instance; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/ComponentLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/ComponentLoader.java new file mode 100644 index 0000000000..8656890ad9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/ComponentLoader.java @@ -0,0 +1,348 @@ +/* + * 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.core.loader; + +import java.lang.reflect.Type; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; +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 org.w3c.dom.Document; +import static org.osoa.sca.Constants.SCA_NS; +import org.osoa.sca.annotations.Constructor; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.QualifiedName; +import org.apache.tuscany.spi.databinding.extension.DOMHelper; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.LoaderExtension; +import org.apache.tuscany.spi.loader.InvalidReferenceException; +import org.apache.tuscany.spi.loader.InvalidValueException; +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.MissingImplementationException; +import org.apache.tuscany.spi.loader.MissingReferenceException; +import org.apache.tuscany.spi.loader.MissingRequiredPropertyException; +import org.apache.tuscany.spi.loader.PropertyObjectFactory; +import org.apache.tuscany.spi.loader.ReferenceMultiplicityViolationException; +import org.apache.tuscany.spi.loader.UndefinedPropertyException; +import org.apache.tuscany.spi.loader.UndefinedReferenceException; +import org.apache.tuscany.spi.loader.UnrecognizedElementException; +import org.apache.tuscany.spi.model.BindingDefinition; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.model.Multiplicity; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.PropertyValue; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ReferenceTarget; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import org.apache.tuscany.core.binding.local.LocalBindingDefinition; +import org.apache.tuscany.core.deployer.ChildDeploymentContext; +import org.apache.tuscany.core.property.SimplePropertyObjectFactory; + +/** + * Loads a component definition from an XML-based assembly file + * + * @version $Rev$ $Date$ + */ +public class ComponentLoader extends LoaderExtension<ComponentDefinition<?>> { + private static final QName COMPONENT = new QName(SCA_NS, "component"); + private static final QName PROPERTY = new QName(SCA_NS, "property"); + private static final QName REFERENCE = new QName(SCA_NS, "reference"); + + private static final String PROPERTY_FILE_ATTR = "file"; + private static final String PROPERTY_NAME_ATTR = "name"; + private static final String PROPERTY_SOURCE_ATTR = "source"; + + private PropertyObjectFactory propertyFactory; + + @Constructor + public ComponentLoader(@Reference LoaderRegistry registry, @Reference PropertyObjectFactory propertyFactory) { + super(registry); + this.propertyFactory = propertyFactory; + } + + public QName getXMLType() { + return COMPONENT; + } + + @SuppressWarnings("unchecked") + public ComponentDefinition<?> load(ModelObject object, XMLStreamReader reader, DeploymentContext context) + throws XMLStreamException, LoaderException { + assert COMPONENT.equals(reader.getName()); + String name = reader.getAttributeValue(null, "name"); + String initLevel = reader.getAttributeValue(null, "initLevel"); + String autowireAttr = reader.getAttributeValue(null, "autowire"); + boolean autowire; + if (autowireAttr == null) { + autowire = context.isAutowire(); + } else { + autowire = Boolean.parseBoolean(autowireAttr); + } + + URI componentId = URI.create(context.getComponentId() + "/").resolve(name); + ClassLoader loader = context.getClassLoader(); + URL location = context.getScdlLocation(); + // xcv test + DeploymentContext childContext = new ChildDeploymentContext(context, loader, location, componentId, autowire); + Implementation<?> impl = loadImplementation(reader, childContext); + registry.loadComponentType(impl, childContext); + + ComponentDefinition<Implementation<?>> componentDefinition = + new ComponentDefinition<Implementation<?>>(componentId, impl); + componentDefinition.setAutowire(autowire); + if (initLevel != null) { + if (initLevel.length() == 0) { + componentDefinition.setInitLevel(0); + } else { + try { + componentDefinition.setInitLevel(Integer.valueOf(initLevel)); + } catch (NumberFormatException e) { + throw new InvalidValueException(initLevel, "initValue", e); + } + } + } + + while (true) { + switch (reader.next()) { + case START_ELEMENT: + QName qname = reader.getName(); + if (PROPERTY.equals(qname)) { + loadProperty(reader, componentDefinition, childContext); + } else if (REFERENCE.equals(qname)) { + loadReference(reader, componentDefinition, childContext); + } else { + throw new UnrecognizedElementException(qname); + } + reader.next(); + break; + case END_ELEMENT: + if (reader.getName().equals(COMPONENT)) { + populatePropertyValues(componentDefinition); + ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + (ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>) componentDefinition + .getImplementation().getComponentType(); + + for (ReferenceDefinition ref : type.getReferences().values()) { + // add reference target definitions if autowire is enabled for references that are not + // explicitly configured with autowire by the component + if (!componentDefinition.getReferenceTargets().containsKey(ref.getUri().getFragment())) { + if (autowire) { + ReferenceTarget referenceTarget = new ReferenceTarget(); + String compName = componentDefinition.getUri().toString(); + URI refName = URI.create(compName + ref.getUri().toString()); + referenceTarget.setReferenceName(refName); + referenceTarget.setAutowire(autowire); + componentDefinition.add(referenceTarget); + } + } + } + validate(componentDefinition); + return componentDefinition; + } + break; + } + } + } + + protected Implementation<?> loadImplementation(XMLStreamReader reader, DeploymentContext context) + throws XMLStreamException, LoaderException { + reader.nextTag(); + ModelObject o = registry.load(null, reader, context); + if (!(o instanceof Implementation)) { + throw new MissingImplementationException(); + } + return (Implementation<?>) o; + } + + @SuppressWarnings("unchecked") + protected void loadProperty(XMLStreamReader reader, ComponentDefinition<?> definition, DeploymentContext context) + throws XMLStreamException, LoaderException { + String name = reader.getAttributeValue(null, PROPERTY_NAME_ATTR); + Implementation<?> implementation = definition.getImplementation(); + ComponentType<?, ?, ?> componentType = implementation.getComponentType(); + Property<Type> property = (Property<Type>) componentType.getProperties().get(name); + if (property == null) { + throw new UndefinedPropertyException(name); + } + PropertyValue<Type> propertyValue; + String source = reader.getAttributeValue(null, PROPERTY_SOURCE_ATTR); + String file = reader.getAttributeValue(null, PROPERTY_FILE_ATTR); + if (source != null || file != null) { + propertyValue = new PropertyValue<Type>(name, source, file); + propertyValue.setValue(property.getDefaultValue()); + LoaderUtil.skipToEndElement(reader); + } else { + try { + DocumentBuilder documentBuilder = DOMHelper.newDocumentBuilder(); + Document value = PropertyUtils.createPropertyValue(reader, property.getXmlType(), documentBuilder); + propertyValue = new PropertyValue<Type>(name, value); + } catch (ParserConfigurationException e) { + throw new LoaderException(e); + } + } + ObjectFactory<Type> objectFactory = propertyFactory.createObjectFactory(property, propertyValue); + propertyValue.setValueFactory(objectFactory); + definition.add(propertyValue); + } + + protected void loadReference(XMLStreamReader reader, + ComponentDefinition<?> componentDefinition, + DeploymentContext context) throws XMLStreamException, LoaderException { + String name = reader.getAttributeValue(null, "name"); + if (name == null) { + throw new InvalidReferenceException("No name specified"); + } + String target = reader.getAttributeValue(null, "target"); + boolean autowire = Boolean.parseBoolean(reader.getAttributeValue(null, "autowire")); + URI componentId = context.getComponentId(); + List<URI> uris = new ArrayList<URI>(); + if (target != null) { + StringTokenizer tokenizer = new StringTokenizer(target); + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken(); + QualifiedName qName = new QualifiedName(token); + uris.add(componentId.resolve(qName.getFragment())); + } + } + + Implementation<?> impl = componentDefinition.getImplementation(); + ComponentType<?, ?, ?> componentType = impl.getComponentType(); + if (!componentType.getReferences().containsKey(name)) { + throw new UndefinedReferenceException(name); + } + if (componentType instanceof CompositeComponentType) { + if (uris.size() != 1) { + // FIXME not yet implemented + throw new UnsupportedOperationException(); + } + ReferenceDefinition definition = componentType.getReferences().get(name); + if (definition.getBindings().isEmpty()) { + // TODO JFM allow selection of a default binding + LocalBindingDefinition binding = new LocalBindingDefinition(uris.get(0)); + definition.addBinding(binding); + } else { + for (BindingDefinition binding : definition.getBindings()) { + binding.setTargetUri(uris.get(0)); + } + } + } else { + ReferenceTarget referenceTarget = componentDefinition.getReferenceTargets().get(name); + if (referenceTarget == null) { + referenceTarget = new ReferenceTarget(); + referenceTarget.setReferenceName(componentId.resolve('#' + name)); + referenceTarget.setAutowire(autowire); + componentDefinition.add(referenceTarget); + } + for (URI uri : uris) { + referenceTarget.addTarget(uri); + } + } + } + + @SuppressWarnings("unchecked") + protected void populatePropertyValues(ComponentDefinition<Implementation<?>> componentDefinition) + throws MissingRequiredPropertyException { + ComponentType componentType = componentDefinition.getImplementation().getComponentType(); + if (componentType != null) { + Map<String, Property<?>> properties = componentType.getProperties(); + Map<String, PropertyValue<?>> propertyValues = componentDefinition.getPropertyValues(); + + for (Property<?> aProperty : properties.values()) { + if (propertyValues.get(aProperty.getName()) == null) { + if (aProperty.isRequired()) { + throw new MissingRequiredPropertyException(aProperty.getName()); + } else if (aProperty.getDefaultValue() != null) { + PropertyValue propertyValue = new PropertyValue(); + propertyValue.setName(aProperty.getName()); + propertyValue.setValue(aProperty.getDefaultValue()); + propertyValue.setValueFactory(new SimplePropertyObjectFactory(aProperty, + propertyValue.getValue())); + propertyValues.put(aProperty.getName(), propertyValue); + } + } + } + } + } + + /** + * Validates a component definition, ensuring all component type configuration elements are satisfied + */ + protected void validate(ComponentDefinition<Implementation<?>> definition) throws LoaderException { + // validate refererences + Implementation<?> implementation = definition.getImplementation(); + ComponentType<?, ?, ?> type = implementation.getComponentType(); + if (type == null) { + return; + } + for (ReferenceDefinition referenceDef : type.getReferences().values()) { + if (!referenceDef.isRequired()) { + continue; + } + String name = referenceDef.getUri().getFragment(); + ReferenceTarget target = definition.getReferenceTargets().get(name); + if (target == null) { + throw new MissingReferenceException(name); + } + if (target.isAutowire()) { + // autowire targets are not set yet + continue; + } + int count = target.getTargets().size(); + Multiplicity multiplicity = referenceDef.getMultiplicity(); + switch (multiplicity) { + case ZERO_N: + break; + case ZERO_ONE: + if (count > 1) { + throw new ReferenceMultiplicityViolationException(name, multiplicity, count); + } + break; + case ONE_ONE: + if (count != 1) { + throw new ReferenceMultiplicityViolationException(name, multiplicity, count); + } + break; + case ONE_N: + if (count < 1) { + throw new ReferenceMultiplicityViolationException(name, multiplicity, count); + } + break; + } + + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/ComponentTypeElementLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/ComponentTypeElementLoader.java new file mode 100644 index 0000000000..beb0bc2731 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/ComponentTypeElementLoader.java @@ -0,0 +1,86 @@ +/* + * 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.core.loader; + +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.Constants.SCA_NS; +import org.osoa.sca.annotations.Constructor; +import org.osoa.sca.annotations.Reference; + +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.model.ComponentType; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceDefinition; + +/** + * @version $Rev$ $Date$ + */ +public class ComponentTypeElementLoader extends LoaderExtension<ComponentType> { + public static final QName COMPONENT_TYPE = new QName(SCA_NS, "componentType"); + + @Constructor + public ComponentTypeElementLoader(@Reference LoaderRegistry registry) { + super(registry); + } + + public QName getXMLType() { + return COMPONENT_TYPE; + } + + @SuppressWarnings("unchecked") + public ComponentType load(ModelObject object, XMLStreamReader reader, DeploymentContext context) + throws XMLStreamException, LoaderException { + assert COMPONENT_TYPE.equals(reader.getName()); + ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> componentType; + if (object != null) { + assert object instanceof ComponentType; + // a specialized component type was passed in + componentType = (ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>) object; + } else { + componentType = new ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + } + + while (true) { + switch (reader.next()) { + case START_ELEMENT: + ModelObject o = registry.load(componentType, reader, context); + if (o instanceof ServiceDefinition) { + componentType.add((ServiceDefinition) o); + } else if (o instanceof ReferenceDefinition) { + componentType.add((ReferenceDefinition) o); + } else if (o instanceof Property) { + componentType.add((Property<?>) o); + } + break; + case END_ELEMENT: + return componentType; + } + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/DependencyLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/DependencyLoader.java new file mode 100644 index 0000000000..a4d1cd1440 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/DependencyLoader.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.core.loader; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.osoa.sca.annotations.Reference; + +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.UnrecognizedElementException; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.services.artifact.Artifact; + +import org.apache.tuscany.core.implementation.composite.Dependency; + +/** + * Loader for handling <dependency> elements. + * + * @version $Rev$ $Date$ + */ +public class DependencyLoader extends LoaderExtension<Dependency> { + private static final String NS = "http://tuscany.apache.org/xmlns/sca/2.0-alpha"; + private static final QName DEPENDENCY = new QName(NS, "dependency"); + private static final QName GROUP = new QName(NS, "group"); + private static final QName NAME = new QName(NS, "name"); + private static final QName VERSION = new QName(NS, "version"); + private static final QName CLASSIFIER = new QName(NS, "classifier"); + private static final QName TYPE = new QName(NS, "type"); + + public DependencyLoader(@Reference LoaderRegistry registry) { + super(registry); + } + + public QName getXMLType() { + return DEPENDENCY; + } + + public Dependency load( + ModelObject object, + XMLStreamReader reader, + DeploymentContext deploymentContext) + throws XMLStreamException, LoaderException { + + Artifact artifact = new Artifact(); + while (reader.nextTag() == XMLStreamConstants.START_ELEMENT) { + QName name = reader.getName(); + String text = reader.getElementText(); + if (GROUP.equals(name)) { + artifact.setGroup(text); + } else if (NAME.equals(name)) { + artifact.setName(text); + } else if (VERSION.equals(name)) { + artifact.setVersion(text); + } else if (CLASSIFIER.equals(name)) { + artifact.setClassifier(text); + } else if (TYPE.equals(name)) { + artifact.setType(text); + } else { + throw new UnrecognizedElementException(name); + } + } + Dependency dependency = new Dependency(); + dependency.setArtifact(artifact); + return dependency; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/IncludeLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/IncludeLoader.java new file mode 100644 index 0000000000..e10a93bbc0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/IncludeLoader.java @@ -0,0 +1,105 @@ +/* + * 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.core.loader; + +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import static org.osoa.sca.Constants.SCA_NS; +import org.osoa.sca.annotations.Constructor; +import org.osoa.sca.annotations.Reference; + +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.MissingIncludeException; +import org.apache.tuscany.spi.loader.MissingResourceException; +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.Include; +import org.apache.tuscany.spi.model.ModelObject; + +import org.apache.tuscany.core.deployer.ChildDeploymentContext; + +/** + * Loader that handles <include> elements. + * + * @version $Rev$ $Date$ + */ +public class IncludeLoader extends LoaderExtension<Include> { + private static final QName INCLUDE = new QName(SCA_NS, "include"); + + @Constructor + public IncludeLoader(@Reference LoaderRegistry registry) { + super(registry); + } + + public QName getXMLType() { + return INCLUDE; + } + + public Include load(ModelObject object, XMLStreamReader reader, DeploymentContext deploymentContext) + throws XMLStreamException, LoaderException { + + assert INCLUDE.equals(reader.getName()); + String name = reader.getAttributeValue(null, "name"); + String scdlLocation = reader.getAttributeValue(null, "scdlLocation"); + String scdlResource = reader.getAttributeValue(null, "scdlResource"); + LoaderUtil.skipToEndElement(reader); + + ClassLoader cl = deploymentContext.getClassLoader(); + URL url; + if (scdlLocation != null) { + try { + url = new URL(deploymentContext.getScdlLocation(), scdlLocation); + } catch (MalformedURLException e) { + throw new MissingResourceException(scdlLocation, name, e); + } + } else if (scdlResource != null) { + url = cl.getResource(scdlResource); + if (url == null) { + throw new MissingResourceException(scdlResource, name); + } + } else { + throw new MissingIncludeException("No SCDL location or resource specified", name); + } + + // when we include, the componentId remains that of the parent + URI componentId = deploymentContext.getComponentId(); + boolean autowire = deploymentContext.isAutowire(); + DeploymentContext childContext = new ChildDeploymentContext(deploymentContext, cl, url, componentId, autowire); + CompositeComponentType composite; + composite = loadFromSidefile(url, childContext); + + Include include = new Include(); + include.setName(name); + include.setScdlLocation(url); + include.setIncluded(composite); + return include; + } + + protected CompositeComponentType loadFromSidefile(URL url, DeploymentContext context) throws LoaderException { + return registry.load(null, url, CompositeComponentType.class, context); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/JNDIPropertyFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/JNDIPropertyFactory.java new file mode 100644 index 0000000000..8759377840 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/JNDIPropertyFactory.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.core.loader; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.PropertyObjectFactory; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.PropertyValue; + +import org.apache.tuscany.core.injection.JNDIObjectFactory; + +/** + * A StAXPropertyFactory that creates property values by looking them up in the default JNDI InitialContext. <p/> This + * can be used to locate resources in a J2EE environment and inject them as configuration properties. For example, to + * access a database a component could write: <code> &at;Property DataSource myDB; </code> and configure with <code> + * <properties> <v:myDb>java:comp/env/jdbc/MyDatabase</v:myDB> </properties> </code> + * + * @version $Rev$ $Date$ + */ +public class JNDIPropertyFactory implements PropertyObjectFactory { + public <T> ObjectFactory<T> createObjectFactory(Property<T> property, PropertyValue<T> value) + throws LoaderException { + String text = value.getValue().getDocumentElement().getTextContent(); + try { + Context context = new InitialContext(); + return new JNDIObjectFactory<T>(context, text); + } catch (NamingException e) { + throw new LoaderException(e); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/LoaderExceptionFormatter.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/LoaderExceptionFormatter.java new file mode 100644 index 0000000000..26ec72ecb6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/LoaderExceptionFormatter.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.loader; + +import java.io.PrintWriter; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.loader.LoaderException; + +import org.apache.tuscany.host.monitor.ExceptionFormatter; +import org.apache.tuscany.host.monitor.FormatterRegistry; + +/** + * Formats {@link org.apache.tuscany.spi.loader.LoaderException} events + * + * @version $Rev$ $Date$ + */ +@EagerInit +public class LoaderExceptionFormatter implements ExceptionFormatter { + private FormatterRegistry factory; + + public LoaderExceptionFormatter(@Reference FormatterRegistry factory) { + this.factory = factory; + factory.register(this); + } + + public boolean canFormat(Class<?> type) { + return LoaderException.class.isAssignableFrom(type); + } + + @Destroy + public void destroy() { + factory.unregister(this); + } + + public PrintWriter write(PrintWriter writer, Throwable exception) { + assert exception instanceof LoaderException; + LoaderException e = (LoaderException) exception; + e.appendBaseMessage(writer); + if (e.getLine() != LoaderException.UNDEFINED) { + writer.write("\nLine: " + e.getLine() + "\n"); + writer.write("Column: " + e.getColumn() + "\n"); + } else { + writer.write("\n"); + } + return writer; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/LoaderRegistryImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/LoaderRegistryImpl.java new file mode 100644 index 0000000000..57fd1da870 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/LoaderRegistryImpl.java @@ -0,0 +1,179 @@ +/* + * 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.core.loader; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.osoa.sca.annotations.EagerInit; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.loader.ComponentTypeLoader; +import org.apache.tuscany.spi.loader.InvalidConfigurationException; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.StAXElementLoader; +import org.apache.tuscany.spi.loader.UnrecognizedComponentTypeException; +import org.apache.tuscany.spi.loader.UnrecognizedElementException; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.ModelObject; + +/** + * The default implementation of a loader registry + * + * @version $Rev$ $Date$ + */ +@EagerInit +public class LoaderRegistryImpl implements LoaderRegistry { + private Monitor monitor; + private final Map<QName, StAXElementLoader<? extends ModelObject>> loaders = + new HashMap<QName, StAXElementLoader<? extends ModelObject>>(); + private final Map<Class<? extends Implementation<?>>, + ComponentTypeLoader<? extends Implementation<?>>> componentTypeLoaders = + new HashMap<Class<? extends Implementation<?>>, ComponentTypeLoader<? extends Implementation<?>>>(); + + public LoaderRegistryImpl(@org.apache.tuscany.api.annotation.Monitor Monitor monitor) { + this.monitor = monitor; + } + + public <T extends ModelObject> void registerLoader(QName element, StAXElementLoader<T> loader) { + monitor.registeringLoader(element); + loaders.put(element, loader); + } + + public <T extends ModelObject> void unregisterLoader(QName element, StAXElementLoader<T> loader) { + monitor.unregisteringLoader(element); + loaders.remove(element); + } + + public ModelObject load( + ModelObject object, + XMLStreamReader reader, + DeploymentContext deploymentContext) throws XMLStreamException, LoaderException { + QName name = reader.getName(); + monitor.elementLoad(name); + StAXElementLoader<? extends ModelObject> loader = loaders.get(name); + if (loader == null) { + throw new UnrecognizedElementException(name); + } + return loader.load(object, reader, deploymentContext); + } + + public <MO extends ModelObject> MO load( + ModelObject object, + URL url, + Class<MO> type, + DeploymentContext ctx) throws LoaderException { + try { + XMLStreamReader reader; + InputStream is; + is = url.openStream(); + try { + XMLInputFactory factory = ctx.getXmlFactory(); + reader = factory.createXMLStreamReader(is); + try { + reader.nextTag(); + QName name = reader.getName(); + ModelObject mo = load(object, reader, ctx); + if (type.isInstance(mo)) { + return type.cast(mo); + } else { + UnrecognizedElementException e = new UnrecognizedElementException(name); + e.setResourceURI(url.toString()); + throw e; + } + } catch (LoaderException e) { + Location location = reader.getLocation(); + e.setLine(location.getLineNumber()); + e.setColumn(location.getColumnNumber()); + throw e; + } finally { + try { + reader.close(); + } catch (XMLStreamException e) { + // ignore + } + } + } finally { + try { + is.close(); + } catch (IOException e) { + // ignore + } + } + } catch (IOException e) { + LoaderException sfe = new LoaderException(e); + sfe.setResourceURI(url.toString()); + throw sfe; + } catch (XMLStreamException e) { + throw new InvalidConfigurationException("Invalid or missing resource", url.toString(), e); + } + } + + public <I extends Implementation<?>> void registerLoader(Class<I> key, ComponentTypeLoader<I> loader) { + componentTypeLoaders.put(key, loader); + } + + public <I extends Implementation<?>> void unregisterLoader(Class<I> key) { + componentTypeLoaders.remove(key); + } + + @SuppressWarnings("unchecked") + public <I extends Implementation<?>> void loadComponentType(I implementation, + DeploymentContext deploymentContext) + throws LoaderException { + Class<I> key = (Class<I>) implementation.getClass(); + ComponentTypeLoader<I> loader = (ComponentTypeLoader<I>) componentTypeLoaders.get(key); + if (loader == null) { + throw new UnrecognizedComponentTypeException(key); + } + loader.load(implementation, deploymentContext); + } + + public static interface Monitor { + /** + * Event emitted when a StAX element loader is registered. + * + * @param xmlType the QName of the element the loader will handle + */ + void registeringLoader(QName xmlType); + + /** + * Event emitted when a StAX element loader is unregistered. + * + * @param xmlType the QName of the element the loader will handle + */ + void unregisteringLoader(QName xmlType); + + /** + * Event emitted when a request is made to load an element. + * + * @param xmlType the QName of the element that should be loaded + */ + void elementLoad(QName xmlType); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/PolicySetLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/PolicySetLoader.java new file mode 100644 index 0000000000..66d2a87593 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/PolicySetLoader.java @@ -0,0 +1,195 @@ +/* + * 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.core.loader; + +import java.util.ArrayList; +import java.util.List; +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.Constants.SCA_NS; +import org.osoa.sca.annotations.Constructor; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.LoaderExtension; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.LoaderUtil; +import org.apache.tuscany.spi.model.IntentMap; +import org.apache.tuscany.spi.model.IntentName; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.model.PolicySet; +import org.apache.tuscany.spi.model.PolicySetReference; +import org.apache.tuscany.spi.model.Qualifier; +import org.apache.tuscany.spi.model.WSPolicyAttachment; + +/** + * Loads a PolicySet definition from an SCDL file. + * + * @version $Rev$ $Date$ + */ +public class PolicySetLoader extends LoaderExtension<PolicySet> { + + private static final String WSPOLICY_NAMESPACE = "http://schemas.xmlsoap.org/ws/2004/09/policy"; + + private static final QName POLICYSET = new QName(SCA_NS, "policySet"); + + private static final QName INTENTMAP = new QName(SCA_NS, "intentMap"); + + private static final QName QUALIFIER = new QName(SCA_NS, "qualifier"); + + private static final QName POLICYSETREFERENCE = new QName(SCA_NS, "policySetReference"); + + private static final QName WSPOLICYATTACHMENT = new QName(WSPOLICY_NAMESPACE, "PolicyAttachment"); + + @Constructor + public PolicySetLoader(@Reference LoaderRegistry registry) { + super(registry); + + } + + @Override + public QName getXMLType() { + return POLICYSET; + } + + public PolicySet load(ModelObject object, XMLStreamReader reader, + DeploymentContext deploymentContext) + throws XMLStreamException { + assert POLICYSET.equals(reader.getName()); + String name = reader.getAttributeValue(null, "name"); + String provides = reader.getAttributeValue(null, "provides"); + String appliesTo = reader.getAttributeValue(null, "appliesTo"); + PolicySet policySet = new PolicySet(new QName(SCA_NS, name), parseIntentName(provides)); + String[] appliesToArtifact = split(appliesTo); + for (String artifact : appliesToArtifact) { + policySet.addAppliedArtifacts(new QName(SCA_NS, artifact)); + } + while (true) { + switch (reader.next()) { + case START_ELEMENT: + QName qname = reader.getName(); + if (INTENTMAP.equals(qname)) { + policySet.addIntentMap(loadIntentMap(reader, deploymentContext)); + } else if (POLICYSETREFERENCE.equals(qname)) { + policySet.addPolicySetReference(loadPolicyReference(reader, deploymentContext)); + } else if (WSPOLICYATTACHMENT.equals(qname)) { + policySet.addWsPolicyAttachment(loadWSPolicyAttachment(reader, deploymentContext)); + } + + reader.next(); + break; + case END_ELEMENT: + if (reader.getName().equals(POLICYSET)) { + return policySet; + } + break; + } + } + + } + + private PolicySetReference loadPolicyReference(XMLStreamReader reader, DeploymentContext deploymentContext) + throws XMLStreamException { + assert POLICYSETREFERENCE.equals(reader.getName()); + String name = reader.getAttributeValue(null, "name"); + LoaderUtil.skipToEndElement(reader); + return new PolicySetReference(new QName(SCA_NS, name)); + } + + private IntentMap loadIntentMap(XMLStreamReader reader, DeploymentContext deploymentContext) + throws XMLStreamException { + assert INTENTMAP.equals(reader.getName()); + String defaultIntentAttr = reader.getAttributeValue(null, "default"); + String provides = reader.getAttributeValue(null, "provides"); + IntentMap intentMap = new IntentMap(defaultIntentAttr, java.util.Arrays.asList(split(provides))); + //parentPolicySet.addIntentMap(intentMap); + + while (true) { + switch (reader.next()) { + case START_ELEMENT: + QName qname = reader.getName(); + if (QUALIFIER.equals(qname)) { + intentMap.addQualifier(loadQualifier(reader, deploymentContext)); + } + reader.next(); + break; + case END_ELEMENT: + if (reader.getName().equals(INTENTMAP)) { + return intentMap; + } + } + } + + } + + private Qualifier loadQualifier(XMLStreamReader reader, DeploymentContext deploymentContext) + throws XMLStreamException { + assert QUALIFIER.equals(reader.getName()); + String name = reader.getAttributeValue(null, "name"); + Qualifier qualifier = new Qualifier(name); + while (true) { + switch (reader.next()) { + case START_ELEMENT: + QName qname = reader.getName(); + if (INTENTMAP.equals(qname)) { + qualifier.setIntentMap(loadIntentMap(reader, deploymentContext)); + } else if (WSPOLICYATTACHMENT.equals(qname)) { + qualifier.addWsPolicyAttachment(loadWSPolicyAttachment(reader, deploymentContext)); + } + reader.next(); + break; + case END_ELEMENT: + if (reader.getName().equals(QUALIFIER)) { + return qualifier; + } + } + } + + } + + private WSPolicyAttachment loadWSPolicyAttachment(XMLStreamReader reader, DeploymentContext deploymentContext) + throws XMLStreamException { + return new WSPolicyAttachment(); + } + + /** + * Split a string to string array separated by " " + */ + private static String[] split(String string) { + if (string == null) { + return new String[0]; + } + String[] intents = string.split("[ ]+"); + return intents; + } + + private static List<IntentName> parseIntentName(String attributes) { + String[] intents = split(attributes); + List<IntentName> result = new ArrayList<IntentName>(intents.length); + for (String intent : intents) { + result.add(new IntentName(intent)); + } + return result; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/PropertyLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/PropertyLoader.java new file mode 100644 index 0000000000..ac39c135d9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/PropertyLoader.java @@ -0,0 +1,98 @@ +/* + * 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.core.loader; + +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.w3c.dom.Document; +import static org.osoa.sca.Constants.SCA_NS; +import org.osoa.sca.annotations.Constructor; +import org.osoa.sca.annotations.Reference; + +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.model.ModelObject; +import org.apache.tuscany.spi.model.Property; + +/** + * Loads a property from an XML-based assembly file + * + * @version $Rev$ $Date$ + */ +public class PropertyLoader extends LoaderExtension<Property> { + public static final String PROPERTY_NAME_ATTR = "name"; + public static final String PROPERTY_TYPE_ATTR = "type"; + public static final String PROPERTY_MANY_ATTR = "many"; + public static final String REQUIRED_ATTR = "override"; + + public static final QName PROPERTY = new QName(SCA_NS, "property"); + private final DocumentBuilder documentBuilder; + + @Constructor + public PropertyLoader(@Reference LoaderRegistry registry) { + super(registry); + try { + documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + } catch (ParserConfigurationException e) { + // we should be able to construct the default DocumentBuilder + throw new AssertionError(e); + } + } + + public QName getXMLType() { + return PROPERTY; + } + + public Property<?> load(ModelObject object, XMLStreamReader reader, + DeploymentContext ctx) + throws XMLStreamException, LoaderException { + assert PROPERTY.equals(reader.getName()); + String name = reader.getAttributeValue(null, PROPERTY_NAME_ATTR); + String typeName = reader.getAttributeValue(null, PROPERTY_TYPE_ATTR); + QName xmlType = null; + if (typeName != null) { + int index = typeName.indexOf(':'); + if (index != -1) { + String prefix = typeName.substring(0, index); + String localName = typeName.substring(index + 1); + String ns = reader.getNamespaceURI(prefix); + xmlType = new QName(ns, localName, prefix); + } + } + boolean many = Boolean.parseBoolean(reader.getAttributeValue(null, PROPERTY_MANY_ATTR)); + String required = reader.getAttributeValue(null, REQUIRED_ATTR); + Document value = PropertyUtils.createPropertyValue(reader, xmlType, documentBuilder); + + Property<?> property = new Property(); + property.setRequired(Boolean.parseBoolean(required)); + property.setName(name); + property.setXmlType(xmlType); + property.setMany(many); + + property.setDefaultValue(value); + return property; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/PropertyUtils.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/PropertyUtils.java new file mode 100644 index 0000000000..57c1e1b5f4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/PropertyUtils.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.core.loader; + +import javax.xml.XMLConstants; +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * @version $Rev$ $Date$ + */ +public final class PropertyUtils { + + private PropertyUtils() { + } + + public static Document createPropertyValue(XMLStreamReader reader, QName type, DocumentBuilder builder) + throws XMLStreamException { + Document doc = builder.newDocument(); + + // root element has no namespace and local name "value" + Element root = doc.createElementNS(null, "value"); + if (type != null) { + Attr xsi = doc.createAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:xsi"); + xsi.setValue(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI); + root.setAttributeNodeNS(xsi); + + String prefix = type.getPrefix(); + if (prefix == null || prefix.length() == 0) { + prefix = "ns"; + } + Attr typeXmlns = doc.createAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:" + prefix); + typeXmlns.setValue(type.getNamespaceURI()); + root.setAttributeNodeNS(typeXmlns); + + Attr xsiType = doc.createAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi:type"); + xsiType.setValue(prefix + ":" + type.getLocalPart()); + root.setAttributeNodeNS(xsiType); + } + doc.appendChild(root); + + loadPropertyValue(reader, root); + return doc; + } + + /** + * Load a property value specification from an StAX stream into a DOM Document. Only elements, text and attributes + * are processed; all comments and other whitespace are ignored. + * + * @param reader the stream to read from + * @param root the DOM node to load + * @throws javax.xml.stream.XMLStreamException + * + */ + public static void loadPropertyValue(XMLStreamReader reader, Node root) throws XMLStreamException { + Document document = root.getOwnerDocument(); + Node current = root; + while (true) { + switch (reader.next()) { + case XMLStreamConstants.START_ELEMENT: + QName name = reader.getName(); + Element child = document.createElementNS(name.getNamespaceURI(), name.getLocalPart()); + + // add the attributes for this element + int count = reader.getAttributeCount(); + for (int i = 0; i < count; i++) { + String ns = reader.getAttributeNamespace(i); + String localPart = reader.getAttributeLocalName(i); + String value = reader.getAttributeValue(i); + child.setAttributeNS(ns, localPart, value); + } + + // push the new element and make it the current one + current.appendChild(child); + current = child; + break; + case XMLStreamConstants.CDATA: + current.appendChild(document.createCDATASection(reader.getText())); + break; + case XMLStreamConstants.CHARACTERS: + current.appendChild(document.createTextNode(reader.getText())); + break; + case XMLStreamConstants.END_ELEMENT: + // if we are back at the root then we are done + if (current == root) { + return; + } + + // pop the element off the stack + current = current.getParentNode(); + } + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/ReferenceLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/ReferenceLoader.java new file mode 100644 index 0000000000..54183d1c72 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/ReferenceLoader.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.core.loader; + +import java.util.HashMap; +import java.util.Map; +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.Constants.SCA_NS; +import org.osoa.sca.annotations.Constructor; +import org.osoa.sca.annotations.Reference; + +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.UnrecognizedElementException; +import org.apache.tuscany.spi.model.BindingDefinition; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.model.Multiplicity; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceContract; + +/** + * Loads a reference from an XML-based assembly file + * + * @version $Rev$ $Date$ + */ +public class ReferenceLoader extends LoaderExtension<ReferenceDefinition> { + public static final QName REFERENCE = new QName(SCA_NS, "reference"); + private static final Map<String, Multiplicity> MULTIPLICITY = new HashMap<String, Multiplicity>(4); + + static { + MULTIPLICITY.put("0..1", Multiplicity.ZERO_ONE); + MULTIPLICITY.put("1..1", Multiplicity.ONE_ONE); + MULTIPLICITY.put("0..n", Multiplicity.ZERO_N); + MULTIPLICITY.put("1..n", Multiplicity.ONE_N); + } + + @Constructor + public ReferenceLoader(@Reference LoaderRegistry registry) { + super(registry); + } + + public QName getXMLType() { + return REFERENCE; + } + + public ReferenceDefinition load(ModelObject object, XMLStreamReader reader, DeploymentContext context) + throws XMLStreamException, LoaderException { + assert REFERENCE.equals(reader.getName()); + String name = reader.getAttributeValue(null, "name"); + String multiplicityVal = reader.getAttributeValue(null, "multiplicity"); + Multiplicity multiplicity = multiplicity(multiplicityVal, Multiplicity.ONE_ONE); + ReferenceDefinition referenceDefinition = new ReferenceDefinition(); + referenceDefinition.setMultiplicity(multiplicity); + referenceDefinition.setUri(context.getComponentId().resolve('#' + name)); + while (true) { + switch (reader.next()) { + case START_ELEMENT: + ModelObject o = registry.load(null, reader, context); + if (o instanceof ServiceContract) { + referenceDefinition.setServiceContract((ServiceContract) o); + } else if (o instanceof BindingDefinition) { + referenceDefinition.addBinding((BindingDefinition) o); + } else { + throw new UnrecognizedElementException(reader.getName()); + } + break; + case END_ELEMENT: + return referenceDefinition; + } + } + } + + /** + * Convert a "multiplicity" attribute to the equivalent enum value. + * + * @param multiplicity the attribute to convert + * @param def the default value + * @return the enum equivalent + */ + private static Multiplicity multiplicity(String multiplicity, Multiplicity def) { + return multiplicity == null ? def : MULTIPLICITY.get(multiplicity); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/ServiceLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/ServiceLoader.java new file mode 100644 index 0000000000..c5be797cda --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/ServiceLoader.java @@ -0,0 +1,99 @@ +/* + * 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.core.loader; + +import java.net.URI; +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.Constants.SCA_NS; +import org.osoa.sca.annotations.Constructor; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.QualifiedName; +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.UnrecognizedElementException; +import org.apache.tuscany.spi.model.BindingDefinition; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.model.ServiceDefinition; + +/** + * Loads a service definition from an XML-based assembly file + * + * @version $Rev$ $Date$ + */ +public class ServiceLoader extends LoaderExtension<ServiceDefinition> { + private static final QName SERVICE = new QName(SCA_NS, "service"); + + @Constructor + public ServiceLoader(@Reference LoaderRegistry registry) { + super(registry); + } + + public QName getXMLType() { + return SERVICE; + } + + public ServiceDefinition load(ModelObject object, XMLStreamReader reader, DeploymentContext context) + throws XMLStreamException, LoaderException { + assert SERVICE.equals(reader.getName()); + String name = reader.getAttributeValue(null, "name"); + URI compositeId = context.getComponentId(); + URI componentBase = URI.create(compositeId + "/"); + ServiceDefinition def = new ServiceDefinition(); + def.setUri(compositeId.resolve('#' + name)); + + URI targetUri = null; + String promote = reader.getAttributeValue(null, "promote"); + if (promote != null) { + QualifiedName qName = new QualifiedName(promote); + targetUri = componentBase.resolve(qName.getFragment()); + } + while (true) { + int i = reader.next(); + switch (i) { + case START_ELEMENT: + ModelObject o = registry.load(null, reader, context); + if (o instanceof ServiceContract) { + def.setServiceContract((ServiceContract) o); + } else if (o instanceof BindingDefinition) { + def.addBinding((BindingDefinition) o); + } else { + throw new UnrecognizedElementException(reader.getName()); + } + break; + case END_ELEMENT: + if (SERVICE.equals(reader.getName())) { + if (targetUri != null) { + def.setTarget(targetUri); + } + return def; + } + break; + } + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/StringParserPropertyFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/StringParserPropertyFactory.java new file mode 100644 index 0000000000..eda09d6f11 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/StringParserPropertyFactory.java @@ -0,0 +1,191 @@ +/* + * 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.core.loader; + +import java.beans.PropertyEditor; +import java.beans.PropertyEditorManager; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import javax.xml.stream.XMLStreamException; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.PropertyObjectFactory; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.PropertyValue; + +import org.apache.tuscany.core.injection.SingletonObjectFactory; + +/** + * Implementation of StAXPropertyFactory that interprets the XML as + * + * @version $Rev$ $Date$ + */ +public class StringParserPropertyFactory implements PropertyObjectFactory { + + public <T> ObjectFactory<T> createObjectFactory(Property<T> property, PropertyValue<T> value) + throws LoaderException { + String text = value.getValue().getDocumentElement().getTextContent(); + return new SingletonObjectFactory<T>(createInstance(text, property.getJavaType())); + } + + @SuppressWarnings("unchecked") + public <T> T createInstance(String text, Class<T> type) throws LoaderException { + // Class<T> type = property.getJavaType(); + assert type != null : "property type is null"; + + // degenerate case where property type is a String + if (String.class.equals(type)) { + return type.cast(text); + } + + // special handler to convert hexBinary to a byte[] + if (byte[].class.equals(type)) { + byte[] instance = new byte[text.length() >> 1]; + for (int i = 0; i < instance.length; i++) { + instance[i] = + (byte) (Character.digit(text.charAt(i << 1), 16) << 4 | Character.digit(text + .charAt((i << 1) + 1), 16)); + } + return type.cast(instance); + } + + // does this type have a static valueOf(String) method? + try { + Method valueOf = type.getMethod("valueOf", String.class); + if (Modifier.isStatic(valueOf.getModifiers())) { + try { + return type.cast(valueOf.invoke(null, text)); + } catch (IllegalAccessException e) { + throw new AssertionError("getMethod returned an inaccessible method"); + } catch (InvocationTargetException e) { + // FIXME we should throw something better + throw new LoaderException(e.getCause()); + } + } + } catch (NoSuchMethodException e) { + // try something else + } + + // does this type have a constructor that takes a String? + try { + Constructor<T> ctr = type.getConstructor(String.class); + return ctr.newInstance(text); + } catch (NoSuchMethodException e) { + // try something else + } catch (IllegalAccessException e) { + throw new AssertionError("getConstructor returned an inaccessible method"); + } catch (InstantiationException e) { + throw new LoaderException("Property type cannot be instantiated: " + type.getName()); + } catch (InvocationTargetException e) { + // FIXME we should throw something better + throw new LoaderException(e.getCause()); + } + + // do we have a property editor for it? + PropertyEditor editor = PropertyEditorManager.findEditor(type); + if (editor != null) { + try { + editor.setAsText(text); + return (T) editor.getValue(); + } catch (IllegalArgumentException e) { + // FIXME we should throw something better + throw new LoaderException(e); + + } + } + + // FIXME we should throw something better + throw new LoaderException("Do not have a way to parse a String into a " + type.getName()); + + } + + @SuppressWarnings("unchecked") + public <T> ObjectFactory<T> createObjectFactory(String text, Property<T> property) + throws XMLStreamException, LoaderException { + Class<T> type = property.getJavaType(); + assert type != null : "property type is null"; + + // degenerate case where property type is a String + if (String.class.equals(type)) { + return new SingletonObjectFactory<T>(type.cast(text)); + } + + // special handler to convert hexBinary to a byte[] + if (byte[].class.equals(type)) { + byte[] instance = new byte[text.length() >> 1]; + for (int i = 0; i < instance.length; i++) { + instance[i] = + (byte) (Character.digit(text.charAt(i << 1), 16) << 4 | Character.digit(text + .charAt((i << 1) + 1), 16)); + } + return new SingletonObjectFactory<T>(type.cast(instance)); + } + + // does this type have a static valueOf(String) method? + try { + Method valueOf = type.getMethod("valueOf", String.class); + if (Modifier.isStatic(valueOf.getModifiers())) { + try { + return new SingletonObjectFactory<T>(type.cast(valueOf.invoke(null, text))); + } catch (IllegalAccessException e) { + throw new AssertionError("getMethod returned an inaccessible method"); + } catch (InvocationTargetException e) { + // FIXME we should throw something better + throw new LoaderException(e.getCause()); + } + } + } catch (NoSuchMethodException e) { + // try something else + } + + // does this type have a constructor that takes a String? + try { + Constructor<T> ctr = type.getConstructor(String.class); + return new SingletonObjectFactory<T>(ctr.newInstance(text)); + } catch (NoSuchMethodException e) { + // try something else + } catch (IllegalAccessException e) { + throw new AssertionError("getConstructor returned an inaccessible method"); + } catch (InstantiationException e) { + throw new LoaderException("Property type cannot be instantiated: " + type.getName()); + } catch (InvocationTargetException e) { + // FIXME we should throw something better + throw new LoaderException(e.getCause()); + } + + // do we have a property editor for it? + PropertyEditor editor = PropertyEditorManager.findEditor(type); + if (editor != null) { + try { + editor.setAsText(text); + return new SingletonObjectFactory<T>((T) editor.getValue()); + } catch (IllegalArgumentException e) { + // FIXME we should throw something better + throw new LoaderException(e); + + } + } + + // FIXME we should throw something better + throw new LoaderException("Do not have a way to parse a String into a " + type.getName()); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/WireLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/WireLoader.java new file mode 100644 index 0000000000..9c60790111 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/loader/WireLoader.java @@ -0,0 +1,122 @@ +/*
+ * 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.core.loader;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+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.Constants.SCA_NS;
+import org.osoa.sca.annotations.Constructor;
+import org.osoa.sca.annotations.Reference;
+
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.InvalidWireException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.model.WireDefinition;
+
+/**
+ * Loads a wire from an XML-based assembly file
+ *
+ * @version $Rev: 465084 $ $Date: 2006-10-18 04:00:49 +0530 (Wed, 18 Oct 2006) $
+ */
+public class WireLoader extends LoaderExtension<WireDefinition> {
+ private static final QName WIRE = new QName(SCA_NS, "wire");
+ private static final QName SOURCE_URI = new QName(SCA_NS, "source.uri");
+ private static final QName TARGET_URI = new QName(SCA_NS, "target.uri");
+
+ @Constructor
+ public WireLoader(@Reference LoaderRegistry registry) {
+ super(registry);
+ }
+
+ public QName getXMLType() {
+ return WIRE;
+ }
+
+ public WireDefinition load(
+ ModelObject object,
+ XMLStreamReader reader,
+ DeploymentContext deploymentContext) throws XMLStreamException, LoaderException {
+ assert WIRE.equals(reader.getName());
+ WireDefinition wireDefn;
+ URI sourceURI = null;
+ URI targetURI = null;
+ String uriString;
+ while (true) {
+ switch (reader.next()) {
+ case START_ELEMENT:
+ try {
+ if (reader.getName().equals(SOURCE_URI)) {
+ uriString = reader.getElementText();
+ if (uriString != null && uriString.trim().length() > 0) {
+ QualifiedName name = new QualifiedName(uriString);
+ if (name.getPortName() == null) {
+ sourceURI = new URI(uriString);
+ } else {
+ sourceURI = new URI(name.getPartName() + "#" + name.getPortName());
+ }
+ } else {
+ throw new InvalidWireException("Wire source not defined");
+ }
+ } else if (reader.getName().equals(TARGET_URI)) {
+ uriString = reader.getElementText();
+ if (uriString != null && uriString.trim().length() > 0) {
+ QualifiedName name = new QualifiedName(uriString);
+ if (name.getPortName() == null) {
+ targetURI = new URI(uriString);
+ } else {
+ targetURI = new URI(name.getPartName() + "#" + name.getPortName());
+ }
+ } else {
+ throw new InvalidWireException("Wire target not defined");
+ }
+ } else {
+ QName name = reader.getName();
+ throw new InvalidWireException("Unrecognized element in wire ", name.toString());
+ }
+ } catch (URISyntaxException e) {
+ throw new InvalidWireException("Invalid wire uri", e);
+ }
+
+ reader.next();
+ break;
+ case END_ELEMENT:
+ if (reader.getName().equals(WIRE)) {
+ if (sourceURI != null && targetURI != null) {
+ wireDefn = new WireDefinition();
+ wireDefn.setSource(sourceURI);
+ wireDefn.setTarget(targetURI);
+ } else {
+ throw new InvalidWireException("Incomplete wire definition");
+ }
+ return wireDefn;
+ }
+ }
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/AbstractMarshallerExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/AbstractMarshallerExtension.java new file mode 100644 index 0000000000..16bf6ea178 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/AbstractMarshallerExtension.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.marshaller; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.marshaller.ModelMarshaller; +import org.apache.tuscany.spi.marshaller.ModelMarshallerRegistry; +import org.apache.tuscany.spi.model.ModelObject; +import org.osoa.sca.annotations.Reference; + +/** + * Abstract marshaller that supports marshaller registry. + * + * @version $Revision$ $Date: 2007-03-03 12:17:30 +0000 (Sat, 03 Mar + * 2007) $ + * @param <MD> + */ +public abstract class AbstractMarshallerExtension<MD extends ModelObject> implements ModelMarshaller<MD> { + + // Private Model marshaller registry + protected ModelMarshallerRegistry registry; + + /** + * Injects the model marshaller registry. + * + * @param registry Model marshaller registry. + */ + @Reference + public final void setRegistry(ModelMarshallerRegistry registry) { + + this.registry = registry; + + Class<MD> marshallerType = getModelObjectType(); + QName marshallerQName = getModelObjectQName(); + + registry.registerMarshaller(marshallerType, marshallerQName, this); + + } + + /** + * Gets the qualified name of the XML fragment for the marshalled model + * object. + * + * @return Qualified name of the XML fragment. + */ + protected abstract QName getModelObjectQName(); + + /** + * Retursn the type of the model object. + * + * @return Model object type. + */ + protected abstract Class<MD> getModelObjectType(); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/DefaultModelMarshallerRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/DefaultModelMarshallerRegistry.java new file mode 100644 index 0000000000..6b502eac59 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/DefaultModelMarshallerRegistry.java @@ -0,0 +1,97 @@ +/* + * 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.core.marshaller; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.spi.marshaller.MarshallException; +import org.apache.tuscany.spi.marshaller.ModelMarshaller; +import org.apache.tuscany.spi.marshaller.ModelMarshallerRegistry; +import org.apache.tuscany.spi.model.ModelObject; + +/** + * Default map-based implementation of the model marshaller registry. + * + * @version $Rev$ $Date$ + */ +public class DefaultModelMarshallerRegistry implements ModelMarshallerRegistry { + + // Marshaller registry + private final Map<Class<? extends ModelObject>, ModelMarshaller> marshallerRegistry = + new ConcurrentHashMap<Class<? extends ModelObject>, ModelMarshaller>(); + + // Unmarshaller registry + private final Map<QName, ModelMarshaller> unmarshallerRegistry = new ConcurrentHashMap<QName, ModelMarshaller>(); + + /** + * Registers a model object marshaller. + * + * @param <MD> Model object type. + * @param modelClass Model obejct class. + * @param qname Qualified name of the root element of the marshalled XML. + * @param marshaller Model object marshaller. + */ + public <MD extends ModelObject> void registerMarshaller(Class<MD> modelClass, + QName qname, + ModelMarshaller<MD> marshaller) { + marshallerRegistry.put(modelClass, marshaller); + unmarshallerRegistry.put(qname, marshaller); + } + + /** + * Marshalls a model object. + * + * @param modelObject Model object to be marshalled. + * @param writer Writer to which marshalled information is written. + */ + @SuppressWarnings("unchecked") + public void marshall(ModelObject modelObject, XMLStreamWriter writer) throws MarshallException { + + ModelMarshaller marshaller = marshallerRegistry.get(modelObject.getClass()); + if (marshaller == null) { + throw new MarshallException("No marshaller defined for " + modelObject.getClass()); + } + marshaller.marshall(modelObject, writer); + + } + + /** + * Unmarshalls an XML stream to a model object. + * + * @param reader Reader from which marshalled information is read. + * @return Model object from the marshalled stream. + */ + public ModelObject unmarshall(XMLStreamReader reader) throws MarshallException { + + QName qname = reader.getName(); + + ModelMarshaller marshaller = unmarshallerRegistry.get(qname); + if (marshaller == null) { + throw new MarshallException("No marshaller defined for " + qname); + } + return marshaller.unmarshall(reader); + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/PhysicalChangeSetMarshaller.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/PhysicalChangeSetMarshaller.java new file mode 100644 index 0000000000..e10a06b004 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/PhysicalChangeSetMarshaller.java @@ -0,0 +1,97 @@ +/* + * 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.core.marshaller; + +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.END_DOCUMENT; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.spi.marshaller.MarshallException; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.model.physical.PhysicalChangeSet; +import org.apache.tuscany.spi.model.physical.PhysicalComponentDefinition; +import org.apache.tuscany.spi.model.physical.PhysicalWireDefinition; + +/** + * Marshaller for physical changeset. + * + * @version $Revision$ $Date$ + * + */ +public class PhysicalChangeSetMarshaller extends AbstractMarshallerExtension<PhysicalChangeSet> { + + // QName for the root element + public static final QName QNAME = new QName("http://tuscany.apache.org/xmlns/marshaller/1.0-SNAPSHOT", "changeSet"); + + // Local part for wire + private static final String WIRE = "wire"; + + // Local part for component + private static final String COMPONENT = "component"; + + /** + * Marshalls a physical change set to the xml writer. + */ + public void marshall(PhysicalChangeSet modelObject, XMLStreamWriter writer) throws MarshallException { + throw new UnsupportedOperationException(); + } + + /** + * Unmarshalls a physical change set from the xml reader. + */ + public PhysicalChangeSet unmarshall(XMLStreamReader reader) throws MarshallException { + + try { + PhysicalChangeSet changeSet = new PhysicalChangeSet(); + while (true) { + switch (reader.next()) { + case START_ELEMENT: + String name = reader.getName().getLocalPart(); + ModelObject modelObject = registry.unmarshall(reader); + if (COMPONENT.equals(name)) { + changeSet.addComponentDefinition((PhysicalComponentDefinition)modelObject); + } else if (WIRE.equals(name)) { + changeSet.addWireDefinition((PhysicalWireDefinition)modelObject); + } + break; + case END_DOCUMENT: + return changeSet; + } + } + } catch (XMLStreamException ex) { + throw new MarshallException(ex); + } + + } + + @Override + protected QName getModelObjectQName() { + return QNAME; + } + + @Override + protected Class<PhysicalChangeSet> getModelObjectType() { + return PhysicalChangeSet.class; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/PhysicalOperationDefinitionMarshaller.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/PhysicalOperationDefinitionMarshaller.java new file mode 100644 index 0000000000..4fe35e11ee --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/PhysicalOperationDefinitionMarshaller.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.marshaller; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.spi.marshaller.MarshallException; +import org.apache.tuscany.spi.model.physical.PhysicalOperationDefinition; + +/** + * Marshaller for physical operation definition. + * + * @version $Revision$ $Date: 2007-03-03 11:36:03 +0000 (Sat, 03 Mar + * 2007) $ + */ +public class PhysicalOperationDefinitionMarshaller extends AbstractMarshallerExtension<PhysicalOperationDefinition> { + + // Source name attribute + private static final String NAME = "name"; + + // QName for the root element + private static final QName QNAME = + new QName("http://tuscany.apache.org/xmlns/marshaller/1.0-SNAPSHOT", "operation"); + + /** + * Marshalls a physical operation to the xml writer. + */ + public void marshall(PhysicalOperationDefinition modelObject, XMLStreamWriter writer) throws MarshallException { + throw new UnsupportedOperationException(); + } + + /** + * Unmarshalls a physical operation from the xml reader. + */ + public PhysicalOperationDefinition unmarshall(XMLStreamReader reader) throws MarshallException { + + PhysicalOperationDefinition operation = new PhysicalOperationDefinition(); + operation.setName(reader.getAttributeValue(null, NAME)); + operation.setCallback(Boolean.valueOf(reader.getAttributeValue(null, NAME))); + return operation; + + } + + @Override + protected QName getModelObjectQName() { + return QNAME; + } + + @Override + protected Class<PhysicalOperationDefinition> getModelObjectType() { + return PhysicalOperationDefinition.class; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/PhysicalWireDefinitionMarshaller.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/PhysicalWireDefinitionMarshaller.java new file mode 100644 index 0000000000..c8dfd37fac --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/PhysicalWireDefinitionMarshaller.java @@ -0,0 +1,99 @@ +/* + * 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.core.marshaller; + +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; + +import java.net.URI; +import java.net.URISyntaxException; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.spi.marshaller.MarshallException; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.model.physical.PhysicalOperationDefinition; +import org.apache.tuscany.spi.model.physical.PhysicalWireDefinition; + +/** + * Marshaller for physical wire definition. + * + * @version $Revision$ $Date: 2007-03-03 11:36:03 +0000 (Sat, 03 Mar + * 2007) $ + */ +public class PhysicalWireDefinitionMarshaller extends AbstractMarshallerExtension<PhysicalWireDefinition> { + + // Source URI attribute + private static final String SOURCE_URI = "sourceUri"; + + // Source URI attribute + private static final String TARGET_URI = "targetUri"; + + // QName for the root element + private static final QName QNAME = new QName("http://tuscany.apache.org/xmlns/marshaller/1.0-SNAPSHOT", "wire"); + + /** + * Marshalls a physical wire to the xml writer. + */ + public void marshall(PhysicalWireDefinition modelObject, XMLStreamWriter writer) throws MarshallException { + throw new UnsupportedOperationException(); + } + + /** + * Unmarshalls a physical wire from the xml reader. + */ + public PhysicalWireDefinition unmarshall(XMLStreamReader reader) throws MarshallException { + + try { + PhysicalWireDefinition wireDefinition = new PhysicalWireDefinition(); + wireDefinition.setSourceUri(new URI(reader.getAttributeValue(null, SOURCE_URI))); + wireDefinition.setTargetUri(new URI(reader.getAttributeValue(null, TARGET_URI))); + while (true) { + switch (reader.next()) { + case START_ELEMENT: + ModelObject modelObject = registry.unmarshall(reader); + wireDefinition.addOperation((PhysicalOperationDefinition)modelObject); + break; + case END_ELEMENT: + return wireDefinition; + + } + } + } catch (XMLStreamException ex) { + throw new MarshallException(ex); + } catch (URISyntaxException ex) { + throw new MarshallException(ex); + } + + } + + @Override + protected QName getModelObjectQName() { + return QNAME; + } + + @Override + protected Class<PhysicalWireDefinition> getModelObjectType() { + return PhysicalWireDefinition.class; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/AbstractExtensibleMarshallerExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/AbstractExtensibleMarshallerExtension.java new file mode 100644 index 0000000000..090797e349 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/AbstractExtensibleMarshallerExtension.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.core.marshaller.extensions; + +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.core.marshaller.AbstractMarshallerExtension; +import org.apache.tuscany.spi.marshaller.MarshallException; +import org.apache.tuscany.spi.model.ModelObject; + +/** + * Abstract marshaller that supports extensible model objects. + * + * @version $Revision$ $Date: 2007-03-04 18:23:24 +0000 (Sun, 04 Mar + * 2007) $ + * @param <MD> + */ +public abstract class AbstractExtensibleMarshallerExtension<MD extends ModelObject> extends + AbstractMarshallerExtension<MD> { + + /** + * Create the concrete model object. + * + * @return Concrete model object. + */ + protected abstract MD getConcreteModelObject(); + + /** + * Handles extensions for unmarshalling. + * + * @param modelObject Concrete model object. + * @param reader Reader from which marshalled data is read. + */ + protected abstract void handleExtension(MD modelObject, XMLStreamReader reader) throws MarshallException; + + /** + * Handles extensions for marshalling. + * + * @param modelObject Concrete model object. + * @param reader Writer to which marshalled data is written. + */ + protected abstract void handleExtension(MD modelObject, XMLStreamWriter writer) throws MarshallException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/AbstractPhysicalComponentDefinitionMarshaller.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/AbstractPhysicalComponentDefinitionMarshaller.java new file mode 100644 index 0000000000..bcf868ad1e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/AbstractPhysicalComponentDefinitionMarshaller.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.core.marshaller.extensions; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; + +import java.net.URI; +import java.net.URISyntaxException; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.spi.marshaller.MarshallException; +import org.apache.tuscany.spi.model.physical.PhysicalComponentDefinition; + +/** + * Abstract super class for all PCD marshallers. + * + * @version $Revision$ $Date: 2007-03-03 16:41:22 +0000 (Sat, 03 Mar + * 2007) $ + */ +public abstract class AbstractPhysicalComponentDefinitionMarshaller<PCD extends PhysicalComponentDefinition<?, ?>> + extends AbstractExtensibleMarshallerExtension<PCD> { + + // Component id attribute + private static final String COMPONENT_ID = "componentId"; + + // Reference + private static final String REFERENCE = "reference"; + + // Service + private static final String SERVICE = "service"; + + /** + * Marshalls a physical change set to the xml writer. + */ + public final void marshall(PCD modelObject, XMLStreamWriter writer) throws MarshallException { + throw new UnsupportedOperationException(); + } + + /** + * Unmarshalls a physical change set from the xml reader. + */ + public final PCD unmarshall(XMLStreamReader reader) throws MarshallException { + + try { + PCD componentDefinition = getConcreteModelObject(); + componentDefinition.setComponentId(new URI(reader.getAttributeValue(null, COMPONENT_ID))); + while (true) { + switch (reader.next()) { + case START_ELEMENT: + String name = reader.getName().getLocalPart(); + if (REFERENCE.equals(name)) { + handleReference(componentDefinition, reader); + } else if (SERVICE.equals(name)) { + handleService(componentDefinition, reader); + } else { + handleExtension(componentDefinition, reader); + } + break; + case END_ELEMENT: + if (getModelObjectQName().equals(reader.getName())) { + return componentDefinition; + } + + } + } + } catch (XMLStreamException ex) { + throw new MarshallException(ex); + } catch (URISyntaxException ex) { + throw new MarshallException(ex); + } + + } + + /** + * Handles a reference. + * + * @param componentDefinition Component definition. + * @param reader XML stream. + */ + protected abstract void handleReference(PCD componentDefinition, XMLStreamReader reader) throws MarshallException; + + /** + * Handles a reference. + * + * @param componentDefinition Component definition. + * @param reader XML stream. + */ + protected abstract void handleService(PCD componentDefinition, XMLStreamReader reader) throws MarshallException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/AbstractPhysicalReferenceDefinitionMarshaller.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/AbstractPhysicalReferenceDefinitionMarshaller.java new file mode 100644 index 0000000000..f8b7d9e9e7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/AbstractPhysicalReferenceDefinitionMarshaller.java @@ -0,0 +1,84 @@ +/* + * 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.core.marshaller.extensions; + +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 javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.spi.marshaller.MarshallException; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.model.physical.PhysicalOperationDefinition; +import org.apache.tuscany.spi.model.physical.PhysicalReferenceDefinition; + +/** + * Marshaller for java physical reference definition. + * + * @version $Revision$ $Date$ + */ +public abstract class AbstractPhysicalReferenceDefinitionMarshaller<PRD extends PhysicalReferenceDefinition> extends + AbstractExtensibleMarshallerExtension<PRD> { + + // Local part for operation + private static final String OPERATION = "operation"; + + // Source name attribute + private static final String NAME = "name"; + + /** + * Marshalls a physical java reference definition to the xml writer. + */ + public void marshall(PRD modelObject, XMLStreamWriter writer) throws MarshallException { + throw new UnsupportedOperationException(); + } + + /** + * Unmarshalls a java physical reference definition from the xml reader. + */ + public PRD unmarshall(XMLStreamReader reader) throws MarshallException { + + try { + PRD referenceDefinition = getConcreteModelObject(); + referenceDefinition.setName(reader.getAttributeValue(null, NAME)); + while (true) { + switch (reader.next()) { + case START_ELEMENT: + ModelObject modelObject = registry.unmarshall(reader); + String name = reader.getName().getLocalPart(); + if (OPERATION.equals(name)) { + referenceDefinition.addOperation((PhysicalOperationDefinition)modelObject); + } else { + handleExtension(referenceDefinition, reader); + } + break; + case END_ELEMENT: + return referenceDefinition; + + } + } + } catch (XMLStreamException ex) { + throw new MarshallException(ex); + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/AbstractPhysicalServiceDefinitionMarshaller.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/AbstractPhysicalServiceDefinitionMarshaller.java new file mode 100644 index 0000000000..7adb3f7ae2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/AbstractPhysicalServiceDefinitionMarshaller.java @@ -0,0 +1,84 @@ +/* + * 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.core.marshaller.extensions; + +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 javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.spi.marshaller.MarshallException; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.model.physical.PhysicalOperationDefinition; +import org.apache.tuscany.spi.model.physical.PhysicalServiceDefinition; + +/** + * Marshaller for java physical service definition. + * + * @version $Revision$ $Date$ + */ +public abstract class AbstractPhysicalServiceDefinitionMarshaller<PSD extends PhysicalServiceDefinition> extends + AbstractExtensibleMarshallerExtension<PSD> { + + // Local part for operation + private static final String OPERATION = "operation"; + + // Source name attribute + private static final String NAME = "name"; + + /** + * Marshalls a physical java reference definition to the xml writer. + */ + public void marshall(PSD modelObject, XMLStreamWriter writer) throws MarshallException { + throw new UnsupportedOperationException(); + } + + /** + * Unmarshalls a java physical reference definition from the xml reader. + */ + public PSD unmarshall(XMLStreamReader reader) throws MarshallException { + + try { + PSD serviceDefinition = getConcreteModelObject(); + serviceDefinition.setName(reader.getAttributeValue(null, NAME)); + while (true) { + switch (reader.next()) { + case START_ELEMENT: + ModelObject modelObject = registry.unmarshall(reader); + String name = reader.getName().getLocalPart(); + if (OPERATION.equals(name)) { + serviceDefinition.addOperation((PhysicalOperationDefinition)modelObject); + } else { + handleExtension(serviceDefinition, reader); + } + break; + case END_ELEMENT: + return serviceDefinition; + + } + } + } catch (XMLStreamException ex) { + throw new MarshallException(ex); + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/java/JavaPhysicalComponentDefinitionMarshaller.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/java/JavaPhysicalComponentDefinitionMarshaller.java new file mode 100644 index 0000000000..08ed890da7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/java/JavaPhysicalComponentDefinitionMarshaller.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.core.marshaller.extensions.java; + +import java.net.URI; +import java.net.URISyntaxException; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.commons.codec.binary.Base64; +import org.apache.tuscany.core.marshaller.extensions.AbstractPhysicalComponentDefinitionMarshaller; +import org.apache.tuscany.core.model.physical.java.JavaPhysicalComponentDefinition; +import org.apache.tuscany.core.model.physical.java.JavaPhysicalReferenceDefinition; +import org.apache.tuscany.core.model.physical.java.JavaPhysicalServiceDefinition; +import org.apache.tuscany.spi.marshaller.MarshallException; +import org.apache.tuscany.spi.model.Scope; + +/** + * Marshaller for Java physical component definitions. + * + * @version $Revision$ $Date: 2007-03-03 16:41:22 +0000 (Sat, 03 Mar + * 2007) $ + */ +public class JavaPhysicalComponentDefinitionMarshaller extends + AbstractPhysicalComponentDefinitionMarshaller<JavaPhysicalComponentDefinition> { + + // Instance factory + private static final String INSTANCE_FACTORY = "instanceFactory"; + + // Scope + private static final String SCOPE = "scope"; + + // Classloader id + private static final String CLASSLOADER_ID = "classLoaderId"; + + // QName for the root element + private static final QName QNAME = + new QName("http://tuscany.apache.org/xmlns/marshaller/java/1.0-SNAPSHOT", "component"); + + /** + * Gets the qualified name of the XML fragment for the marshalled model + * object. + * + * @return {"http://tuscany.apache.org/xmlns/marshaller/component/java/1.0-SNAPSHOT", + * "component"} + */ + @Override + protected QName getModelObjectQName() { + return QNAME; + } + + /** + * Retursn the type of the model object. + * + * @return <code>JavaPhysicalComponentDefinition.class</code>. + */ + @Override + protected Class<JavaPhysicalComponentDefinition> getModelObjectType() { + return JavaPhysicalComponentDefinition.class; + } + + /** + * Create the concrete PCD. + * + * @return An instance of<code>JavaPhysicalComponentDefinition</code>. + */ + @Override + protected JavaPhysicalComponentDefinition getConcreteModelObject() { + return new JavaPhysicalComponentDefinition(); + } + + /** + * Handles extensions for unmarshalling Java physical component definitions + * including the marshalling of base64 encoded instance factory byte code. + * + * @param componentDefinition Physical component definition. + * @param reader Reader from which marshalled data is read. + */ + @Override + protected void handleExtension(JavaPhysicalComponentDefinition componentDefinition, XMLStreamReader reader) + throws MarshallException { + + try { + String name = reader.getName().getLocalPart(); + reader.next(); + if (INSTANCE_FACTORY.equals(name)) { + byte[] base64ByteCode = reader.getText().getBytes(); + byte[] byteCode = Base64.decodeBase64(base64ByteCode); + componentDefinition.setInstanceFactoryByteCode(byteCode); + } else if (SCOPE.equals(name)) { + componentDefinition.setScope(new Scope(reader.getText())); + } else if (CLASSLOADER_ID.equals(name)) { + componentDefinition.setClassLoaderId(new URI(reader.getText())); + } + } catch (XMLStreamException ex) { + throw new MarshallException(ex); + } catch (URISyntaxException ex) { + throw new MarshallException(ex); + } + + } + + /** + * Handles a reference. + * + * @param componentDefinition Component definition. + * @param reader XML stream. + */ + protected void handleReference(JavaPhysicalComponentDefinition componentDefinition, XMLStreamReader reader) + throws MarshallException { + JavaPhysicalReferenceDefinition reference = (JavaPhysicalReferenceDefinition)registry.unmarshall(reader); + componentDefinition.addReference(reference); + } + + /** + * Handles a reference. + * + * @param componentDefinition Component definition. + * @param reader XML stream. + */ + protected void handleService(JavaPhysicalComponentDefinition componentDefinition, XMLStreamReader reader) + throws MarshallException { + JavaPhysicalServiceDefinition service = (JavaPhysicalServiceDefinition)registry.unmarshall(reader); + componentDefinition.addService(service); + } + + /** + * Handles extensions for marshalling Java physical component definitions + * including the marshalling of base64 encoded instance factory byte code. + * + * @param componentDefinition Physical component definition. + * @param reader Writer to which marshalled data is written. + */ + @Override + protected void handleExtension(JavaPhysicalComponentDefinition componentDefinition, XMLStreamWriter writer) { + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/java/JavaPhysicalReferenceDefinitionMarshaller.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/java/JavaPhysicalReferenceDefinitionMarshaller.java new file mode 100644 index 0000000000..3b4a37e903 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/java/JavaPhysicalReferenceDefinitionMarshaller.java @@ -0,0 +1,93 @@ +/* + * 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.core.marshaller.extensions.java; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.core.marshaller.extensions.AbstractPhysicalReferenceDefinitionMarshaller; +import org.apache.tuscany.core.model.physical.java.JavaPhysicalReferenceDefinition; + +/** + * Marshaller for java physical reference definition. + * + * @version $Revision$ $Date: 2007-03-03 16:41:22 +0000 (Sat, 03 Mar + * 2007) $ + */ +public class JavaPhysicalReferenceDefinitionMarshaller extends + AbstractPhysicalReferenceDefinitionMarshaller<JavaPhysicalReferenceDefinition> { + + // QName for the root element + private static final QName QNAME = + new QName("http://tuscany.apache.org/xmlns/marshaller/java/1.0-SNAPSHOT", "reference"); + + /** + * Gets the qualified name of the XML fragment for the marshalled model + * object. + * + * @return {"http://tuscany.apache.org/xmlns/marshaller/reference/java/1.0-SNAPSHOT", + * "service"}. + */ + @Override + protected QName getModelObjectQName() { + return QNAME; + } + + /** + * Retursn the type of the model object. + * + * @return <code>JavaPhysicalReferenceDefinition.class</code>. + */ + @Override + protected Class<JavaPhysicalReferenceDefinition> getModelObjectType() { + return JavaPhysicalReferenceDefinition.class; + } + + /** + * Create the concrete model object. + * + * @return An instance of <code>JavaPhysicalReferenceDefinition</code>. + */ + @Override + protected JavaPhysicalReferenceDefinition getConcreteModelObject() { + return new JavaPhysicalReferenceDefinition(); + } + + /** + * Handles extensions for unmarshalling Java physical references. + * + * @param modelObject Concrete model object. + * @param reader Reader from which marshalled data is read. + */ + @Override + protected void handleExtension(JavaPhysicalReferenceDefinition modelObject, XMLStreamReader reader) { + } + + /** + * Handles extensions for marshalling Java physical references. + * + * @param modelObject Concrete model object. + * @param reader Writer to which marshalled data is written. + */ + @Override + protected void handleExtension(JavaPhysicalReferenceDefinition modelObject, XMLStreamWriter writer) { + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/java/JavaPhysicalServiceDefinitionMarshaller.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/java/JavaPhysicalServiceDefinitionMarshaller.java new file mode 100644 index 0000000000..ade4d3fd5e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/marshaller/extensions/java/JavaPhysicalServiceDefinitionMarshaller.java @@ -0,0 +1,93 @@ +/* + * 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.core.marshaller.extensions.java; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.core.marshaller.extensions.AbstractPhysicalServiceDefinitionMarshaller; +import org.apache.tuscany.core.model.physical.java.JavaPhysicalServiceDefinition; + +/** + * Marshaller for java physical service definition. + * + * @version $Revision$ $Date: 2007-03-03 16:41:22 +0000 (Sat, 03 Mar + * 2007) $ + */ +public class JavaPhysicalServiceDefinitionMarshaller extends + AbstractPhysicalServiceDefinitionMarshaller<JavaPhysicalServiceDefinition> { + + // QName for the root element + private static final QName QNAME = + new QName("http://tuscany.apache.org/xmlns/marshaller/java/1.0-SNAPSHOT", "service"); + + /** + * Gets the qualified name of the XML fragment for the marshalled model + * object. + * + * @return {"http://tuscany.apache.org/xmlns/marshaller/reference/java/1.0-SNAPSHOT", + * "service"}. + */ + @Override + protected QName getModelObjectQName() { + return QNAME; + } + + /** + * Returns the type of the model object. + * + * @return <code>JavaPhysicalServiceDefinition.class</code>. + */ + @Override + protected Class<JavaPhysicalServiceDefinition> getModelObjectType() { + return JavaPhysicalServiceDefinition.class; + } + + /** + * Create the concrete model object. + * + * @return An instance of <code>JavaPhysicalServiceDefinition</code>. + */ + @Override + protected JavaPhysicalServiceDefinition getConcreteModelObject() { + return new JavaPhysicalServiceDefinition(); + } + + /** + * Handles extensions for unmarshalling Java service definitions. + * + * @param modelObject Concrete model object. + * @param reader Reader from which marshalled data is read. + */ + @Override + protected void handleExtension(JavaPhysicalServiceDefinition modelObject, XMLStreamReader reader) { + } + + /** + * Handles extensions for marshalling Java service definitions. + * + * @param modelObject Concrete model object. + * @param reader Writer to which marshalled data is written. + */ + @Override + protected void handleExtension(JavaPhysicalServiceDefinition modelObject, XMLStreamWriter writer) { + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/model/physical/java/JavaPhysicalComponentDefinition.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/model/physical/java/JavaPhysicalComponentDefinition.java new file mode 100644 index 0000000000..b0e06f23d9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/model/physical/java/JavaPhysicalComponentDefinition.java @@ -0,0 +1,93 @@ +/* + * 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.core.model.physical.java; + +import java.net.URI; + +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.physical.PhysicalComponentDefinition; + +/** + * Represents the physical component definition for a Java implementation. + * + * @version $Rev$ $Date$ + */ +public class JavaPhysicalComponentDefinition extends + PhysicalComponentDefinition<JavaPhysicalServiceDefinition, JavaPhysicalReferenceDefinition> { + + // The byte code for the instance factory + private byte[] instanceFactoryByteCode; + + // Scope + private Scope scope; + + // Class loader id + private URI classLoaderId; + + /** + * Gets the classloader id. + * @return Classloader id. + */ + public URI getClassLoaderId() { + return classLoaderId; + } + + /** + * Set the classloader id. + * @param classLoaderId Classloader id. + */ + public void setClassLoaderId(URI classLoaderId) { + this.classLoaderId = classLoaderId; + } + + /** + * Gets the scope for the component. + * @return The scope for the component. + */ + public Scope getScope() { + return scope; + } + + /** + * Sets the scope for the component. + * @param scope The scope for the component. + */ + public void setScope(Scope scope) { + this.scope = scope; + } + + /** + * Gets the byte code for the instance factory. + * + * @return Byte code for the instance factory. + */ + public byte[] getInstanceFactoryByteCode() { + return instanceFactoryByteCode; + } + + /** + * Sets the byte code for the instance factory. + * + * @param instanceFactoryByteCode Byte code for the instance factory. + */ + public void setInstanceFactoryByteCode(byte[] instanceFactoryByteCode) { + this.instanceFactoryByteCode = instanceFactoryByteCode; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/model/physical/java/JavaPhysicalReferenceDefinition.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/model/physical/java/JavaPhysicalReferenceDefinition.java new file mode 100644 index 0000000000..51919c6000 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/model/physical/java/JavaPhysicalReferenceDefinition.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.core.model.physical.java; + +import org.apache.tuscany.spi.model.physical.PhysicalReferenceDefinition; + +/** + * Models a Java physical reference definition. + * + * @version $Revision$ $Date: 2007-02-28 06:29:37 +0000 (Wed, 28 Feb + * 2007) $ + */ +public class JavaPhysicalReferenceDefinition extends PhysicalReferenceDefinition { + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/model/physical/java/JavaPhysicalServiceDefinition.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/model/physical/java/JavaPhysicalServiceDefinition.java new file mode 100644 index 0000000000..06885dfdce --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/model/physical/java/JavaPhysicalServiceDefinition.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.core.model.physical.java; + +import org.apache.tuscany.spi.model.physical.PhysicalServiceDefinition; + +/** + * Models a Java physical service definition. + * + * @version $Revision$ $Date: 2007-02-28 06:29:37 +0000 (Wed, 28 Feb + * 2007) $ + */ +public class JavaPhysicalServiceDefinition extends PhysicalServiceDefinition { + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/DefaultExceptionFormatter.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/DefaultExceptionFormatter.java new file mode 100644 index 0000000000..14468061e3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/DefaultExceptionFormatter.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.core.monitor; + +import java.io.PrintWriter; + +import org.apache.tuscany.api.TuscanyException; +import org.apache.tuscany.api.TuscanyRuntimeException; +import org.apache.tuscany.host.monitor.ExceptionFormatter; + +/** + * Performs basics formatting of exceptions for JDK logging + * + * @version $Rev$ $Date$ + */ +public class DefaultExceptionFormatter implements ExceptionFormatter { + + public DefaultExceptionFormatter() { + } + + public boolean canFormat(Class<?> type) { + return Throwable.class.isAssignableFrom(type); + } + + public PrintWriter write(PrintWriter writer, Throwable exception) { + if (exception instanceof TuscanyException) { + TuscanyException e = (TuscanyException) exception; + e.appendBaseMessage(writer); + } else if (exception instanceof TuscanyRuntimeException) { + TuscanyRuntimeException e = (TuscanyRuntimeException) exception; + e.appendBaseMessage(writer); + } + writer.append("\n"); + return writer; + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/InvalidLevelException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/InvalidLevelException.java new file mode 100644 index 0000000000..cf07b0f914 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/InvalidLevelException.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.core.monitor; + +/** + * Exception indicating an invalid log level has been passed. + * + * @version $Rev$ $Date$ + */ +public class InvalidLevelException extends IllegalArgumentException { + private static final long serialVersionUID = 7767234706427841915L; + private final String method; + private final String level; + + /** + * Constructor specifying the method name and the level affected. + * + * @param method the name of the method being monitored + * @param level the invalid log level value + */ + public InvalidLevelException(String method, String level) { + super(); + this.method = method; + this.level = level; + } + + /** + * Returns the name of the method being monitored. + * + * @return the name of the method being monitored + */ + public String getMethod() { + return method; + } + + /** + * Returns the invalid log level specified. + * + * @return the invalid log level that was specified + */ + public String getLevel() { + return level; + } + + public String getMessage() { + return "Invalid level for method " + method + " : " + level; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/JavaLoggingMonitorFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/JavaLoggingMonitorFactory.java new file mode 100644 index 0000000000..4adff1b0db --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/JavaLoggingMonitorFactory.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.core.monitor; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.ResourceBundle; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +import org.osoa.sca.annotations.Service; + +import org.apache.tuscany.host.MonitorFactory; +import org.apache.tuscany.host.monitor.FormatterRegistry; + +/** + * A factory for monitors that forwards events to a {@link java.util.logging.Logger Java Logging (JSR47) Logger}. + * + * @version $Rev$ $Date$ + * @see java.util.logging + */ +@Service(interfaces = {MonitorFactory.class, FormatterRegistry.class}) +public class JavaLoggingMonitorFactory extends ProxyMonitorFactory { + + /** + * Construct a MonitorFactory that will monitor the specified methods at the specified levels and generate messages + * using java.util.logging. + * <p/> + * The supplied Properties can be used to specify custom log levels for specific monitor methods. The key should be + * the method name in form returned by <code>Class.getName() + '#' + Method.getName()</code> and the value the log + * level to use as defined by {@link java.util.logging.Level}. + * + * @param levels definition of custom levels for specific monitored methods, may be null or empty. + * @param defaultLevel the default log level to use + * @param bundleName the name of a resource bundle that will be passed to the logger + * @see java.util.logging.Logger + */ + public JavaLoggingMonitorFactory(Properties levels, Level defaultLevel, String bundleName) { + Map<String, Object> configProperties = new HashMap<String, Object>(); + configProperties.put("levels", levels); + configProperties.put("defaultLevel", defaultLevel); + configProperties.put("bundleName", bundleName); + initInternal(configProperties); + } + + /** + * Constructs a MonitorFactory that needs to be subsequently configured via a call to {@link #initialize}. + */ + public JavaLoggingMonitorFactory() { + } + + protected <T> InvocationHandler createInvocationHandler(Class<T> monitorInterface, + Map<String, Level> levels) { + ResourceBundle bundle = locateBundle(monitorInterface, bundleName); + Logger logger = Logger.getLogger(monitorInterface.getName()); + return new LoggingHandler(logger, levels, bundle); + } + + private class LoggingHandler implements InvocationHandler { + private final Logger logger; + private final Map<String, Level> methodLevels; + private final ResourceBundle bundle; + + public LoggingHandler(Logger logger, + Map<String, Level> methodLevels, + ResourceBundle bundle + ) { + this.logger = logger; + this.methodLevels = methodLevels; + this.bundle = bundle; + } + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + String sourceMethod = method.getName(); + Level level = methodLevels.get(sourceMethod); + if (level != null && logger.isLoggable(level)) { + // construct the key for the resource bundle + String className = logger.getName(); + String key = className + '#' + sourceMethod; + + LogRecord logRecord = new LogRecord(level, key); + logRecord.setLoggerName(className); + logRecord.setSourceClassName(className); + logRecord.setSourceMethodName(sourceMethod); + logRecord.setParameters(args); + if (args != null) { + for (Object o : args) { + if (o instanceof Throwable) { + logRecord.setMessage(formatException((Throwable) o)); + break; + } + } + } + logRecord.setResourceBundle(bundle); + logger.log(logRecord); + } + return null; + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/MonitorFactoryUtil.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/MonitorFactoryUtil.java new file mode 100644 index 0000000000..92224d469f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/MonitorFactoryUtil.java @@ -0,0 +1,78 @@ +/* + * 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.core.monitor; + +import org.apache.tuscany.host.MonitorFactory; + +import java.util.Map; + +/** + * Helper for creating MonitorFactory instances. + * + * @version $$Rev$$ $$Date$$ + */ + +public final class MonitorFactoryUtil { + /** + * Hide the constructor + */ + private MonitorFactoryUtil() { + } + + /** + * Creates a MonitorFactory instance of the specified type. + * @param name fully qualified classname of the desired MonitorFactory type + * @param props collection of initialization properties + * @return a configured MonitorFactory instance, or null if the factory could not be instantiated. + */ + @SuppressWarnings("unchecked") + public static MonitorFactory createMonitorFactory(String name, Map<String, Object> props) { + Class<? extends MonitorFactory> clazz; + try { + clazz = (Class<? extends MonitorFactory>) Class.forName(name); + } catch (ClassNotFoundException cnfe) { + return null; + } catch (ClassCastException cce) { + return null; + } + + return createMonitorFactory(clazz, props); + } + + /** + * Creates a MonitorFactory instance of the specified type. + * @param mfc class of the desired MonitorFactory type + * @param props collection of initialization properties + * @return a configured MonitorFactory instance, or null if the factory could not be instantiated. + */ + public static MonitorFactory createMonitorFactory(Class<? extends MonitorFactory> mfc, Map<String, Object> props) { + MonitorFactory mf; + try { + mf = mfc.newInstance(); + mf.initialize(props); + } catch (InstantiationException e) { + throw new AssertionError(e); + } catch (IllegalAccessException e) { + throw new AssertionError(e); + } + // allow IllegalArgumentException to propogate out + + return mf; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/NullMonitorFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/NullMonitorFactory.java new file mode 100644 index 0000000000..46c52e38f6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/NullMonitorFactory.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.core.monitor; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Map; + +import org.osoa.sca.annotations.EagerInit; + +import org.apache.tuscany.host.MonitorFactory; +import org.apache.tuscany.host.monitor.ExceptionFormatter; + +/** + * Implementation of a {@link MonitorFactory} that produces implementations that simply return. + * + * @version $Rev$ $Date$ + */ +@EagerInit +public class NullMonitorFactory implements MonitorFactory { + + /** + * Singleton hander that does nothing. + */ + private static final InvocationHandler NULL_MONITOR = new InvocationHandler() { + public Object invoke(Object proxy, Method method, Object[] args) { + return null; + } + }; + + public void initialize(Map<String, Object> configProperties) { + } + + public <T> T getMonitor(Class<T> monitorInterface) { + /* + * This uses a reflection proxy to implement the monitor interface which + * is a simple but perhaps not very performant solution. Performance + * might be improved by code generating an implementation with empty methods. + */ + return monitorInterface.cast( + Proxy.newProxyInstance(monitorInterface.getClassLoader(), new Class<?>[]{monitorInterface}, NULL_MONITOR)); + } + + public void register(ExceptionFormatter formatter) { + + } + + public void unregister(ExceptionFormatter formatter) { + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/ProxyMonitorFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/ProxyMonitorFactory.java new file mode 100644 index 0000000000..d9ca9e6cfc --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/monitor/ProxyMonitorFactory.java @@ -0,0 +1,234 @@ +/* + * 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.core.monitor; + +import java.util.Map; +import java.util.Properties; +import java.util.HashMap; +import java.util.ResourceBundle; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.List; +import java.util.ArrayList; +import java.util.WeakHashMap; +import java.util.logging.Level; +import java.lang.ref.WeakReference; +import java.lang.reflect.Method; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; +import java.io.PrintWriter; +import java.io.StringWriter; + +import org.apache.tuscany.host.MonitorFactory; +import org.apache.tuscany.host.monitor.FormatterRegistry; +import org.apache.tuscany.host.monitor.ExceptionFormatter; +import org.apache.tuscany.api.annotation.LogLevel; + +/** + * @version $Rev$ $Date$ + */ +public abstract class ProxyMonitorFactory implements MonitorFactory, FormatterRegistry { + protected String bundleName; + protected final List<ExceptionFormatter> formatters = new ArrayList<ExceptionFormatter>(); + protected final ExceptionFormatter defaultFormatter = new DefaultExceptionFormatter(); + protected Level defaultLevel; + protected Map<String, Level> levels; + private final Map<Class<?>, WeakReference<?>> proxies = new WeakHashMap<Class<?>, WeakReference<?>>(); + + public void initialize(Map<String, Object> configProperties) { + if (configProperties == null) { + return; + } + initInternal(configProperties); + } + + protected void initInternal(Map<String, Object> configProperties) { + try { + this.defaultLevel = (Level) configProperties.get("defaultLevel"); + this.bundleName = (String) configProperties.get("bundleName"); + Properties levels = (Properties) configProperties.get("levels"); + + this.levels = new HashMap<String, Level>(); + if (levels != null) { + for (Map.Entry<Object, Object> entry : levels.entrySet()) { + String method = (String) entry.getKey(); + String level = (String) entry.getValue(); + try { + this.levels.put(method, Level.parse(level)); + } catch (IllegalArgumentException e) { + throw new InvalidLevelException(method, level); + } + } + } + } catch (ClassCastException cce) { + throw new IllegalArgumentException(cce.getLocalizedMessage()); + } + } + + public synchronized <T> T getMonitor(Class<T> monitorInterface) { + T proxy = getCachedMonitor(monitorInterface); + if (proxy == null) { + proxy = createMonitor(monitorInterface); + proxies.put(monitorInterface, new WeakReference<T>(proxy)); + } + return proxy; + } + + protected <T> T getCachedMonitor(Class<T> monitorInterface) { + WeakReference<?> ref = proxies.get(monitorInterface); + return (ref != null) ? monitorInterface.cast(ref.get()) : null; + } + + protected <T> T createMonitor(Class<T> monitorInterface) { + String className = monitorInterface.getName(); + Method[] methods = monitorInterface.getMethods(); + Map<String, Level> levels = new HashMap<String, Level>(methods.length); + for (Method method : methods) { + String key = className + '#' + method.getName(); + Level level = null; + if (this.levels != null) { + this.levels.get(key); + } + // if not specified the in config properties, look for an annotation on the method + if (level == null) { + LogLevel annotation = method.getAnnotation(LogLevel.class); + if (annotation != null && annotation.value() != null) { + try { + level = Level.parse(annotation.value()); + } catch (IllegalArgumentException e) { + // bad value, just use the default + level = defaultLevel; + } + } + } + if (level == null) { + level = defaultLevel; + } + levels.put(method.getName(), level); + } + + InvocationHandler handler = createInvocationHandler(monitorInterface, levels); + Object proxy = Proxy.newProxyInstance(monitorInterface.getClassLoader(), + new Class<?>[]{monitorInterface}, + handler); + return monitorInterface.cast(proxy); + } + + protected <T> ResourceBundle locateBundle(Class<T> monitorInterface, String bundleName) { + Locale locale = Locale.getDefault(); + ClassLoader cl = monitorInterface.getClassLoader(); + String packageName = monitorInterface.getPackage().getName(); + while (true) { + try { + return ResourceBundle.getBundle(packageName + '.' + bundleName, locale, cl); + } catch (MissingResourceException e) { + //ok + } + int index = packageName.lastIndexOf('.'); + if (index == -1) { + break; + } + packageName = packageName.substring(0, index); + } + try { + return ResourceBundle.getBundle(bundleName, locale, cl); + } catch (Exception e) { + return null; + } + } + + public void register(ExceptionFormatter formatter) { + formatters.add(formatter); + } + + public void unregister(ExceptionFormatter formatter) { + formatters.remove(formatter); + } + + protected abstract <T> InvocationHandler createInvocationHandler(Class<T> monitorInterface, + Map<String, Level> levels); + + protected String formatException(Throwable e) { + ExceptionFormatter formatter = defaultFormatter; + for (ExceptionFormatter candidate : formatters) { + if (candidate.canFormat(e.getClass())) { + formatter = candidate; + break; + } + } + StringWriter writer = new StringWriter(); + PrintWriter pw = new PrintWriter(writer); + formatter.write(pw, e); + format(pw, e); + pw.close(); + return writer.toString(); + } + + protected void format(PrintWriter writer, Throwable throwable) { + writer.println(throwable.getClass().getName()); + StackTraceElement[] trace = throwable.getStackTrace(); + for (StackTraceElement aTrace : trace) { + writer.println("\tat " + aTrace); + } + Throwable ourCause = throwable.getCause(); + + if (ourCause != null) { + printStackTraceAsCause(writer, ourCause, trace); + } + } + + protected void printStackTraceAsCause(PrintWriter pw, + Throwable throwable, + StackTraceElement[] causedTrace) { + + // Compute number of frames in common between this and caused + StackTraceElement[] trace = throwable.getStackTrace(); + int m = trace.length - 1; + int n = causedTrace.length - 1; + while (m >= 0 && n >= 0 && trace[m].equals(causedTrace[n])) { + m--; + n--; + } + int framesInCommon = trace.length - 1 - m; + + pw.println("Caused by: " + throwable.getClass().getName()); + + ExceptionFormatter formatter = defaultFormatter; + for (ExceptionFormatter candidate : formatters) { + if (candidate.canFormat(throwable.getClass())) { + formatter = candidate; + break; + } + } + formatter.write(pw, throwable); + + for (int i = 0; i <= m; i++) { + pw.println("\tat " + trace[i]); + } + if (framesInCommon != 0) { + pw.println("\t... " + framesInCommon + " more"); + } + + // Recurse if we have a cause + Throwable ourCause = throwable.getCause(); + if (ourCause != null) { + printStackTraceAsCause(pw, ourCause, trace); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/policy/IntentRegistryImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/policy/IntentRegistryImpl.java new file mode 100644 index 0000000000..5ea24e4c9b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/policy/IntentRegistryImpl.java @@ -0,0 +1,167 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.model.Intent; +import org.apache.tuscany.spi.model.IntentName; +import org.apache.tuscany.spi.policy.IntentRegistry; + +/** + * The default implementation of a data intent registry + */ +public class IntentRegistryImpl implements IntentRegistry { + private final Map<IntentName, IntentEntry> intentRepo = new HashMap<IntentName, IntentEntry>(); + + public Collection<IntentName> getQualifiedIntents(final IntentName qualifiable, final QName artifact) { + List<IntentName> result = new ArrayList<IntentName>(); + for (IntentName intentName : intentRepo.keySet()) { + if (intentRepo.get(intentName).getAppliedArtifacts().contains(artifact) + && PolicyHelper.isQualifiedIntentFor(intentName, qualifiable, true)) { + result.add(intentName); + } + } + return result; + } + + public Collection<IntentName> inlineProfileIntent(final Collection<IntentName> intentNameList, + final QName artifact) { + + return getConcretIntentsInternal(intentNameList, artifact); + } + + private Collection<IntentName> getConcretIntentsInternal(final Collection<IntentName> intentNameList, + QName artifact) { + List<IntentName> result = new ArrayList<IntentName>(); + for (IntentName intentName : intentNameList) { + IntentEntry intentEntry = intentRepo.get(intentName); + if (!intentEntry.isProfileIntent()) { + if (intentEntry.getAppliedArtifacts().contains(artifact)) { + result.add(intentEntry.getName()); + } + } else { + result.addAll(getConcretIntentsInternal(intentEntry.getRequriedIntents(), artifact)); + } + } + return result; + } + + public boolean isApplicable(IntentName intentName, QName artifact) { + if (intentRepo.containsKey(intentName)) { + return intentRepo.get(intentName).getAppliedArtifacts().contains(artifact); + } + return false; + } + + public void register(Intent intent) { + + IntentEntry entry = new IntentEntry(intent); + // if the qualified intents have been registered, make the intent qualifiable(unqualified) + if (!getQualifiedIntents(intent.getName()).isEmpty()) { + entry.setQualified(false); + } + intentRepo.put(intent.getName(), entry); + List<IntentName> qualifiables = getAllQualifiableIntent(intent.getName()); + // set qualifiable intent of this intent unqualified + for (IntentName qualifiable : qualifiables) { + IntentEntry qualifiableEntry = intentRepo.get(qualifiable); + qualifiableEntry.setQualified(false); + for (QName artifact : intent.getAppliedArtifacts()) { + qualifiableEntry.addAppliedArtifacts(artifact); + } + } + } + + public void unRegister(Intent intent) { + if (intentRepo.containsKey(intent.getName())) { + IntentEntry intentEntry = intentRepo.get(intent.getName()); + List<QName> appliedArtifacts = intent.getAppliedArtifacts(); + for (QName artifact : appliedArtifacts) { + if (intentEntry.getAppliedArtifacts().contains(artifact)) { + intentEntry.removeappliedArtifact(artifact); + } + } + if (intentEntry.getAppliedArtifacts().isEmpty()) { + intentRepo.remove(intent.getName()); + } + } + } + + public boolean isQualifiedIntent(IntentName name) { + IntentEntry intentEntry = intentRepo.get(name); + return intentEntry.isQualified(); + } + + private List<IntentName> getQualifiedIntents(final IntentName qualifiable) { + List<IntentName> result = new ArrayList<IntentName>(); + for (IntentName intentName : intentRepo.keySet()) { + if (PolicyHelper.isQualifiedIntentFor(intentName, qualifiable, true)) { + result.add(intentName); + } + } + return result; + } + + private List<IntentName> getAllQualifiableIntent(final IntentName qualified) { + + List<IntentName> result = new ArrayList<IntentName>(); + for (IntentName intentName : intentRepo.keySet()) { + if (PolicyHelper.isQualifiedIntentFor(qualified, intentName, false)) { + result.add(intentName); + } + } + return result; + } + + /** + * Wrapper class for intent used internally + */ + private static final class IntentEntry extends Intent { + + /** + * Whether this intent is qualified, defaults to true + */ + private boolean isQualified = true; + + private IntentEntry(Intent intent) { + super(intent.getName(), intent.getDescription()); + appliedArtifacts.addAll(intent.getAppliedArtifacts()); + requriedIntents.addAll(intent.getRequriedIntents()); + } + + public boolean isQualified() { + return isQualified; + } + + public void setQualified(boolean isQualified) { + this.isQualified = isQualified; + } + + public void removeappliedArtifact(QName artifact) { + appliedArtifacts.remove(artifact); + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/policy/PolicyBuilderRegistryImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/policy/PolicyBuilderRegistryImpl.java new file mode 100644 index 0000000000..9c874b5610 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/policy/PolicyBuilderRegistryImpl.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.core.policy; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.spi.policy.PolicyBuilderRegistry; +import org.apache.tuscany.spi.policy.SourcePolicyBuilder; +import org.apache.tuscany.spi.policy.TargetPolicyBuilder; + +/** + * The default policy builder + * + * @version $Rev$ $Date$ + * @deprecated + */ +public class PolicyBuilderRegistryImpl implements PolicyBuilderRegistry { + + private final List<List<SourcePolicyBuilder>> sourceBuilders; + private final List<List<TargetPolicyBuilder>> targetBuilders; + + public PolicyBuilderRegistryImpl() { + sourceBuilders = new ArrayList<List<SourcePolicyBuilder>>(); + targetBuilders = new ArrayList<List<TargetPolicyBuilder>>(); + for (int i = 0; i <= FINAL; i++) { + sourceBuilders.add(new ArrayList<SourcePolicyBuilder>()); + targetBuilders.add(new ArrayList<TargetPolicyBuilder>()); + } + } + + public void registerTargetBuilder(int phase, TargetPolicyBuilder builder) { + assert INITIAL <= phase && phase <= FINAL : "Illegal phase"; + targetBuilders.get(phase).add(builder); + } + + public void registerSourceBuilder(int phase, SourcePolicyBuilder builder) { + assert INITIAL <= phase && phase <= FINAL : "Illegal phase"; + sourceBuilders.get(phase).add(builder); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/policy/PolicyEngineImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/policy/PolicyEngineImpl.java new file mode 100644 index 0000000000..308e43c038 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/policy/PolicyEngineImpl.java @@ -0,0 +1,297 @@ +/* + * 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.core.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.model.IntentMap; +import org.apache.tuscany.spi.model.IntentName; +import org.apache.tuscany.spi.model.PolicyContentModel; +import org.apache.tuscany.spi.model.PolicyModel; +import org.apache.tuscany.spi.model.PolicySet; +import org.apache.tuscany.spi.model.PolicySetReference; +import org.apache.tuscany.spi.model.Qualifier; +import org.apache.tuscany.spi.policy.IntentRegistry; +import org.apache.tuscany.spi.policy.PolicyEngine; +import org.apache.tuscany.spi.policy.PolicySetContainer; +import org.apache.tuscany.spi.policy.SCATypeManager; + +/** + * Default implementation of a polciy engine + */ +public class PolicyEngineImpl implements PolicyEngine { + private final IntentRegistry intentRegistry; + private final PolicySetContainer policySetContainer; + private final SCATypeManager scaTypeManager; + + public PolicyEngineImpl(IntentRegistry intentRegistry, + PolicySetContainer policySetContainer, + SCATypeManager scaTypeManager) { + this.intentRegistry = intentRegistry; + this.policySetContainer = policySetContainer; + this.scaTypeManager = scaTypeManager; + } + + @SuppressWarnings("unchecked") + public Collection<PolicyModel> getPolicy(final IntentName[] requires, + final QName[] policySetNames, + final QName artifactType) { + if (requires == null || requires.length == 0) { + return Collections.EMPTY_LIST; + } + Collection<PolicyModel> result = new ArrayList<PolicyModel>(); + Collection<IntentName> requiredIntents = java.util.Arrays.asList(requires); + Collection<IntentName> matchings; + + //handle profile intents + requiredIntents = intentRegistry.inlineProfileIntent(requiredIntents, artifactType); + // + if (policySetNames != null && policySetNames.length != 0) { + Collection<PolicySet> explicitPolicySet = getExplicitPolicySet(policySetNames); + matchings = calculateExplicitPolicySet(requiredIntents, explicitPolicySet, artifactType, result); + //remove satisfied intent + requiredIntents.removeAll(matchings); + } + // + if (requiredIntents.size() > 0) { + matchings = findingAdditionalMatching(requiredIntents, artifactType, result); + requiredIntents.removeAll(matchings); + } + //If no collection of policySets covers all required intents, the configuration is not valid. + if (requiredIntents.size() > 0) { + //TODO + } + return result; + } + + + private boolean introspectPolicySet(PolicySet policySet, IntentName intent, QName artifactType, + Collection<PolicyModel> matchings) { + Collection<QName> appliedArtifacts = policySet.getAppliedArtifacts(); + boolean provide = false; + for (QName name : appliedArtifacts) { + if (this.scaTypeManager.isTypeOf(artifactType, name)) { + provide = true; + break; + } + } + if (!provide) { + return false; + } + //1. The required intent matches a provides intent in a policySet exactly. + if (policySet.getProvideIntents().contains(intent)) { + if (intentRegistry.isQualifiedIntent(intent)) { + addMatching(matchings, policySet); + } else { + Collection<IntentMap> intentMaps = policySet.getIntentMaps(); + provide = searchIntentMaps(intent, intent, matchings, intentMaps); + if (provide) { + return true; + } + } + } else if (provideAbstract(intent, policySet.getProvideIntents())) { + // 2. The provides intent is a parent (e.g. prefix) of the required intent (in this case the policySet must + // have an intentMap entry for the requested qualifier) + Collection<IntentMap> intentMaps = policySet.getIntentMaps(); + IntentName satisfiedIntent = getSatisfiedIntent(intent, policySet.getProvideIntents()); + provide = searchIntentMaps(intent, satisfiedIntent, matchings, intentMaps); + if (provide) { + return true; + } + } else if (provideQualifier(intent, policySet.getProvideIntents())) { + //3. The provides intent is more qualified than the required intent + if (intentRegistry.isQualifiedIntent(intent)) { + addMatching(matchings, policySet); + } else { + //TODO + } + } + + //handle PolicySetReference + Collection<PolicySetReference> policySetReferences = policySet.getPolicySetReferences(); + for (PolicySetReference reference : policySetReferences) { + PolicySet referencedPolicySet = policySetContainer.getPolicySet(reference.getReference()); + if (introspectPolicySet(referencedPolicySet, intent, artifactType, matchings)) { + return true; + } + } + + return false; + } + + private void addMatching(Collection<PolicyModel> matching, PolicyContentModel policy) { + if (!policy.getWsPolicyAttachments().isEmpty()) { + matching.addAll(policy.getWsPolicyAttachments()); + } + if (!policy.getPolicyExtensions().isEmpty()) { + matching.addAll(policy.getPolicyExtensions()); + } + } + + private boolean searchIntentMaps(IntentName require, + IntentName satisfiedIntent, + Collection<PolicyModel> matchings, + Collection<IntentMap> intentMaps) { + String qualifierName = getQualifierName(require, satisfiedIntent, intentMaps); + for (IntentMap intentMap : intentMaps) { + if (intentMap.getProvideIntents().contains(qualifierName)) { + Collection<Qualifier> qualifiers = intentMap.getQualifiers(); + for (Qualifier qualifier : qualifiers) { + String nextQualifier = getNextQualifier(require, satisfiedIntent, intentMap); + if (qualifier.getName().equals(nextQualifier)) { + if (intentRegistry + .isQualifiedIntent(new IntentName(satisfiedIntent.toString() + "/" + nextQualifier))) { + addMatching(matchings, qualifier); + return true; + } else { + require = new IntentName(require.toString() + "/" + intentMap.getDefaultProvideIntent()); + satisfiedIntent = new IntentName(satisfiedIntent.toString() + "/" + qualifierName); + intentMaps = new ArrayList<IntentMap>(0); + intentMaps.add(qualifier.getIntentMap()); + searchIntentMaps(require, satisfiedIntent, matchings, intentMaps); + } + break; + } + } + } + } + return false; + } + + private String getQualifierName(IntentName require, IntentName satisfiedIntent, Collection<IntentMap> intentMaps) { + String[] requrieQualifiers = require.getQualifiedNames(); + String[] satisfiedQualifiers = satisfiedIntent.getQualifiedNames(); + if (requrieQualifiers.length == satisfiedQualifiers.length) { + return requrieQualifiers[requrieQualifiers.length - 1]; + } else if (requrieQualifiers.length > satisfiedQualifiers.length) { + return satisfiedQualifiers[satisfiedQualifiers.length - 1]; + } + //TODO raise exception + return null; + } + + private String getNextQualifier(IntentName require, IntentName satisfiedIntent, IntentMap intentMap) { + String[] requrieQualifiers = require.getQualifiedNames(); + String[] satisfiedQualifiers = satisfiedIntent.getQualifiedNames(); + if (requrieQualifiers.length > satisfiedQualifiers.length) { + return requrieQualifiers[satisfiedQualifiers.length]; + } else { + return intentMap.getDefaultProvideIntent(); + } + } + + private IntentName getSatisfiedIntent(IntentName require, Collection<IntentName> provides) { + for (IntentName name : provides) { + if (PolicyHelper.isQualifiedIntentFor(require, name, true)) { + return name; + } + } + //TODO raise exception + return null; + } + + private boolean provideAbstract(IntentName require, Collection<IntentName> provides) { + for (IntentName name : provides) { + if (PolicyHelper.isQualifiedIntentFor(require, name, true)) { + return true; + } + } + return false; + } + + private boolean provideQualifier(IntentName require, Collection<IntentName> provides) { + for (IntentName name : provides) { + if (PolicyHelper.isQualifiedIntentFor(name, require, true)) { + return true; + } + } + return false; + } + + private Collection<PolicySet> getExplicitPolicySet(QName[] policySetNames) { + Collection<PolicySet> result = new ArrayList<PolicySet>(); + for (QName policySetName : policySetNames) { + PolicySet set = policySetContainer.getPolicySet(policySetName); + if (set != null) { + result.add(set); + } + } + return result; + } + + /** + * Step C. Calculate the list of explicitly specified policySets that apply to the target element as follows: 1. + * Start with the list of policySets specified in the element's policySet attribute. 2. If any of these explicitly + * listed policySets has an XPath expression in its appliesTo attribute that does not match the target element + * (binding or implementation) then the composite is invalid. It does not match if the XPath returns a result set + * that corresponds to XPath false. For example, a policySet could have appliesTo=”binding.ws/soaphttp”. This would + * return false if the target element is a <binding.jms…/> element. 3. Include the values of policySet attributes + * from ancestor elements. 4. Remove any policySet where the XPath expression in that policySet’s appliesTo + * attribute does not match the target element. + * <p/> + * + * @param requires + * @param policies + * @return intent names was satisfied by this step. + */ + private Collection<IntentName> calculateExplicitPolicySet(Collection<IntentName> requires, + Collection<PolicySet> policies, + QName artifactType, + Collection<PolicyModel> matchings) { + Collection<IntentName> satisfied = new ArrayList<IntentName>(); + for (IntentName intent : requires) { + for (PolicySet policySet : policies) { + if (introspectPolicySet(policySet, intent, artifactType, matchings)) { + satisfied.add(intent); + } + } + } + return satisfied; + } + + /** + * * The remaining required intents, if any, are provided by finding additional matching policySets within the SCA + * system. E. Choose the smallest collection of these policySets that match all remaining required intents. A + * policySet matches a required intent if any of the following are true: 1. The required intent matches a provides + * intent in a policySet exactly. 2. The provides intent is a parent (e.g. prefix) of the required intent (in this + * case the policySet must have an intentMap entry for the requested qualifier) 3. The provides intent is more + * qualified than the required intent All intents should now be satisfied. + * + * @param remainings + * @param artifactType + * @param matchings + */ + private Collection<IntentName> findingAdditionalMatching(final Collection<IntentName> remainings, + QName artifactType, + Collection<PolicyModel> matchings) { + Collection<IntentName> satisfied = new ArrayList<IntentName>(); + Collection<PolicySet> policies = this.policySetContainer.getAllPolicySet(); + for (IntentName intent : remainings) { + for (PolicySet policySet : policies) { + if (introspectPolicySet(policySet, intent, artifactType, matchings)) { + satisfied.add(intent); + } + } + } + return satisfied; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/policy/PolicyHelper.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/policy/PolicyHelper.java new file mode 100644 index 0000000000..50c94aaf13 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/policy/PolicyHelper.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.core.policy; + +import org.apache.tuscany.spi.model.IntentName; + +/** + * Contains utility methods for dealing with policies + */ +public final class PolicyHelper { + + private PolicyHelper() { + } + + /** + * Whether <code>qualified</code> is qualified intent for <code>qualifiable</code> + * <p/> + * For example: sec.confidentiality/message is direct qualifier for sec.confidentiality. + * sec.confidentiality/message/body is qualifier for sec.confidentiality, but not a direct qualifier + * + * @param qualified qualified intent name + * @param qualifiable qualifiable intent name + * @param direct indicate whether to expect <code>qualified</code> is direct qualified intent for + * <code>qualifiable</code> + * @return whether <code>qualified</code> is qualified intent for <code>qualifiable</code> + */ + public static boolean isQualifiedIntentFor(final IntentName qualified, + final IntentName qualifiable, + boolean direct) { + if (qualified.equals(qualifiable) || !qualified.getDomain().equals(qualifiable.getDomain())) { + return false; + } + boolean result = true; + String[] shortArray = qualifiable.getQualifiedNames(); + String[] longArray = qualified.getQualifiedNames(); + if (longArray.length - shortArray.length < 1 && !direct) { + return false; + } else if (direct && longArray.length - shortArray.length != 1) { + return false; + } + for (int i = 0; i < shortArray.length; i++) { + if (!shortArray[i].equals(longArray[i])) { + result = false; + break; + } + } + return result; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/property/PropertyHelper.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/property/PropertyHelper.java new file mode 100644 index 0000000000..8ed7e8adf6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/property/PropertyHelper.java @@ -0,0 +1,194 @@ +/* + * 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.core.property; + +import java.io.InputStream; +import java.net.URI; +import java.net.URL; +import java.util.Iterator; +import java.util.Map; +import javax.xml.namespace.NamespaceContext; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +import org.apache.tuscany.spi.databinding.extension.DOMHelper; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.loader.InvalidValueException; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.PropertyValue; + +import org.apache.tuscany.core.databinding.xml.InputStream2Node; + +/** + * The property factory backed by the DataBindingframework + */ +public final class PropertyHelper { + + private static final XPathFactory FACTORY = XPathFactory.newInstance(); + + private PropertyHelper() { + } + + public static Document evaluate(NamespaceContext nsContext, Node node, String xPathExpression) + throws XPathExpressionException, ParserConfigurationException { + XPath path = FACTORY.newXPath(); + if (nsContext != null) { + path.setNamespaceContext(nsContext); + } else { + path.setNamespaceContext(new DOMNamespeceContext(node)); + } + XPathExpression expression = path.compile(xPathExpression); + Node result = (Node) expression.evaluate(node, XPathConstants.NODE); + if (result == null) { + return null; + } + + // TODO: How to wrap the result into a Document? + Document document = DOMHelper.newDocument(); + if (result instanceof Document) { + return document; + } else { + document.appendChild(document.importNode(result, true)); + return document; + } + } + + public static Document loadFromFile(String file, DeploymentContext deploymentContext) + throws LoaderException { + try { + URI uri = URI.create(file); + URL url = null; + if (!uri.isAbsolute()) { + url = deploymentContext.getClassLoader().getResource(file); + } else { + url = uri.toURL(); + } + InputStream is = url.openStream(); + try { + InputStream2Node transformer = new InputStream2Node(); + return (Document) transformer.transform(is, null); + } finally { + is.close(); + } + } catch (Exception e) { + throw new LoaderException(e); + } + } + + @SuppressWarnings("unchecked") + public static void processProperties(CompositeComponentType<?, ?, Property<?>> parent, + ComponentDefinition<? extends Implementation<?>> componentDefinition, + DeploymentContext deploymentContext) throws LoaderException { + Map<String, PropertyValue<?>> propertyValues = componentDefinition.getPropertyValues(); + + for (PropertyValue propValue : propertyValues.values()) { + Document node = propValue.getValue(); + String source = propValue.getSource(); + String file = propValue.getFile(); + if (source != null) { + try { + // $<name>/... + int index = source.indexOf('/'); + if (index == -1) { + // Tolerating $prop + source = source + "/"; + index = source.length() - 1; + } + if (source.charAt(0) == '$') { + String name = source.substring(1, index); + Property<?> compositeProp = parent.getProperties().get(name); + if (compositeProp == null) { + throw new InvalidValueException("Source cannot be resolved to a composite property"); + } + Document document = compositeProp.getDefaultValue(); + // Adding /value because the document root is "value" + String path = source.substring(index); + String xpath = null; + if ("/".equals(path)) { + // trailing / is not legal for xpath + xpath = "/value"; + } else { + xpath = "/value" + path; + } + + // FIXME: How to deal with namespaces? + node = evaluate(null, document, xpath); + if (node != null) { + propValue.setValue(node); + } + /*Property<?> prop = + (Property<?>)componentDefinition.getImplementation().getComponentType() + .getProperties().get(propValue.getName()); + propValue + .setValueFactory(new SimplePropertyObjectFactory(prop, propValue.getValue()));*/ + } else { + throw new InvalidValueException("Source has an invalid value"); + } + } catch (Exception e) { + throw new LoaderException(e); + } + } else if (file != null) { + node = loadFromFile(propValue.getFile(), deploymentContext); + propValue.setValue(node); + Property<?> prop = + (Property<?>) componentDefinition.getImplementation().getComponentType().getProperties() + .get(propValue.getName()); + propValue.setValueFactory(new SimplePropertyObjectFactory(prop, propValue.getValue())); + } + } + } + + private static class DOMNamespeceContext implements NamespaceContext { + private Node node; + + /** + * @param node + */ + public DOMNamespeceContext(Node node) { + super(); + this.node = node; + } + + public String getNamespaceURI(String prefix) { + return node.lookupNamespaceURI(prefix); + } + + public String getPrefix(String namespaceURI) { + return node.lookupPrefix(namespaceURI); + } + + public Iterator getPrefixes(String namespaceURI) { + return null; + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/property/PropertyObjectFactoryImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/property/PropertyObjectFactoryImpl.java new file mode 100644 index 0000000000..8419bc1eba --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/property/PropertyObjectFactoryImpl.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.core.property; + +import javax.xml.namespace.QName; + +import org.w3c.dom.Node; +import org.osoa.sca.annotations.Constructor; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.databinding.DataBinding; +import org.apache.tuscany.spi.databinding.DataBindingRegistry; +import org.apache.tuscany.spi.databinding.Mediator; +import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension; +import org.apache.tuscany.spi.model.ElementInfo; +import org.apache.tuscany.spi.model.TypeInfo; +import org.apache.tuscany.spi.loader.PropertyObjectFactory; +import org.apache.tuscany.spi.model.DataType; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.PropertyValue; + +import org.apache.tuscany.core.databinding.xml.DOMDataBinding; + +@Service(PropertyObjectFactory.class) +@Scope("COMPOSITE") +public class PropertyObjectFactoryImpl implements PropertyObjectFactory { + private DataBindingRegistry registry; + private Mediator mediator; + + public PropertyObjectFactoryImpl() { + } + + @Constructor + public PropertyObjectFactoryImpl(@Reference DataBindingRegistry registry, @Reference Mediator mediator) { + super(); + this.registry = registry; + this.mediator = mediator; + } + + public <T> ObjectFactory<T> createObjectFactory(Property<T> property, PropertyValue<T> value) { + if (mediator == null) { + return new SimplePropertyObjectFactory<T>(property, value.getValue()); + } + return new ObjectFactoryImpl<T>(property, value); + } + + public class ObjectFactoryImpl<P> implements ObjectFactory<P> { + private Property<P> property; + private PropertyValue<P> propertyValue; + private DataType<QName> sourceDataType; + private DataType<?> targetDataType; + + public ObjectFactoryImpl(Property<P> property, PropertyValue<P> propertyValue) { + this.property = property; + this.propertyValue = propertyValue; + sourceDataType = new DataType<QName>(DOMDataBinding.NAME, Node.class, this.property.getXmlType()); + TypeInfo typeInfo = null; + if (this.property.getXmlType() != null) { + if (SimpleTypeMapperExtension.isSimpleXSDType(this.property.getXmlType())) { + typeInfo = new TypeInfo(property.getXmlType(), true, null); + } else { + typeInfo = new TypeInfo(property.getXmlType(), false, null); + } + } else { + typeInfo = new TypeInfo(property.getXmlType(), false, null); + } + + ElementInfo elementInfo = new ElementInfo(null, typeInfo); + sourceDataType.setMetadata(ElementInfo.class.getName(), elementInfo); + Class javaType = this.property.getJavaType(); + String dataBinding = (String) property.getExtensions().get(DataBinding.class.getName()); + if (dataBinding != null) { + targetDataType = new DataType<Class>(dataBinding, javaType, javaType); + } else { + targetDataType = registry.introspectType(javaType); + if (targetDataType == null) { + targetDataType = new DataType<Class>("java.lang.Object", javaType, javaType); + } + } + } + + @SuppressWarnings("unchecked") + public P getInstance() throws ObjectCreationException { + return (P) mediator.mediate(propertyValue.getValue(), sourceDataType, targetDataType, null); + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/property/SimplePropertyObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/property/SimplePropertyObjectFactory.java new file mode 100644 index 0000000000..7e9c685bc7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/property/SimplePropertyObjectFactory.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.core.property; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension; +import org.apache.tuscany.spi.model.TypeInfo; +import org.apache.tuscany.spi.model.Property; + +import org.w3c.dom.Document; + +public class SimplePropertyObjectFactory<P> implements ObjectFactory<P> { + private SimpleTypeMapperExtension typeMapper; + private Property<P> property; + private Document value; + private P instance; + + public SimplePropertyObjectFactory(Property<P> property, Document value) { + super(); + + this.property = property; + this.value = (value == null) ? property.getDefaultValue() : value; + this.typeMapper = new SimpleTypeMapperExtension(); + } + + @SuppressWarnings("unchecked") + public P getInstance() throws ObjectCreationException { + if (value == null) { + return null; + } + if (instance == null) { + String text = value.getDocumentElement().getTextContent(); + TypeInfo xmlType = null; + if (property.getJavaType() == null) { + xmlType = new TypeInfo(property.getXmlType(), true, null); + } else { + xmlType = typeMapper.getXMLType(property.getJavaType()); + } + if (xmlType == null) { + throw new IllegalArgumentException("Complex property is not supported."); + } + instance = (P)typeMapper.toJavaObject(xmlType, text, null); + } + return instance; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/resolver/AutowireResolver.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/resolver/AutowireResolver.java new file mode 100644 index 0000000000..06322f9c0f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/resolver/AutowireResolver.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.core.resolver; + +import java.net.URI; + +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.resolver.ResolutionException; + +/** + * Implementations are responsible for resolving autowire targets in an SCA Domain. It is assumed that autowire + * resolution occurs after resource resolution as service interface classes may be laoded + * + * @version $Rev$ $Date$ + */ +public interface AutowireResolver { + + /** + * Resolves autowires for a component definition and its decendents + * + * @param parentDefinition the parent + * @param definition the component definition to resolve autowires for + * @throws ResolutionException + */ + void resolve(ComponentDefinition<Implementation<CompositeComponentType<?, ?, ?>>> parentDefinition, + ComponentDefinition<? extends Implementation<?>> definition) throws ResolutionException; + + /** + * Adds the uri of a host system service that can be an autowire target + * + * @param contract the service contract of the system service + * @param uri the component uri + */ + void addHostUri(ServiceContract contract, URI uri); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/resolver/AutowireTargetNotFoundException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/resolver/AutowireTargetNotFoundException.java new file mode 100644 index 0000000000..1526724ca9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/resolver/AutowireTargetNotFoundException.java @@ -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. + */ +package org.apache.tuscany.core.resolver; + +import org.apache.tuscany.spi.resolver.ResolutionException; + +/** + * @version $Rev$ $Date$ + */ +public class AutowireTargetNotFoundException extends ResolutionException { + public AutowireTargetNotFoundException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/resolver/DefaultAutowireResolver.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/resolver/DefaultAutowireResolver.java new file mode 100644 index 0000000000..f83ec33241 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/resolver/DefaultAutowireResolver.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.core.resolver; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ReferenceTarget; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.model.ServiceDefinition; +import org.apache.tuscany.spi.resolver.ResolutionException; + +/** + * Default implementation of an autowire resolver + * + * @version $Rev$ $Date$ + */ +public class DefaultAutowireResolver implements AutowireResolver { + private Map<ServiceContract, URI> hostAutowire = new HashMap<ServiceContract, URI>(); + + + @SuppressWarnings({"unchecked"}) + public void resolve(ComponentDefinition<Implementation<CompositeComponentType<?, ?, ?>>> parentDefinition, + ComponentDefinition<? extends Implementation<?>> definition) + throws ResolutionException { + ComponentType<?, ?, ?> type = definition.getImplementation().getComponentType(); + // resolve autowires + if (type instanceof CompositeComponentType) { + CompositeComponentType<?, ?, ?> compositeType = (CompositeComponentType<?, ?, ?>) type; + for (ComponentDefinition<? extends Implementation<?>> child : compositeType.getComponents().values()) { + Implementation<?> implementation = child.getImplementation(); + ComponentType<?, ?, ?> childType = implementation.getComponentType(); + if (childType instanceof CompositeComponentType) { + // recurse decendents for composites + resolve((ComponentDefinition<Implementation<CompositeComponentType<?, ?, ?>>>) definition, child); + } + Map<String, ReferenceTarget> targets = child.getReferenceTargets(); + for (ReferenceDefinition reference : childType.getReferences().values()) { + ReferenceTarget target = targets.get(reference.getUri().getFragment()); + if (target == null) { + continue; + } + if (target.isAutowire()) { + ServiceContract requiredContract = reference.getServiceContract(); + resolve(compositeType, requiredContract, target, reference.isRequired()); + } + } + } + } else { + // a leaf level component + ComponentType<?, ?, ?> componentType = definition.getImplementation().getComponentType(); + Map<String, ReferenceTarget> targets = definition.getReferenceTargets(); + for (ReferenceDefinition reference : componentType.getReferences().values()) { + ReferenceTarget target = targets.get(reference.getUri().getFragment()); + if (target == null) { + continue; + } + if (target.isAutowire()) { + ServiceContract requiredContract = reference.getServiceContract(); + CompositeComponentType<?, ?, ?> ctype = parentDefinition.getImplementation().getComponentType(); + resolve(ctype, requiredContract, target, reference.isRequired()); + } + } + } + } + + public void addHostUri(ServiceContract contract, URI uri) { + hostAutowire.put(contract, uri); + } + + /** + * Performs the actual resolution against a composite TODO this should be extensible allowing for path + * optimizations + * + * @param compositeType the composite component type to resolve against + * @param requiredContract the required target contract + * @param target the reference target + * @param required true if the autowire is required + * @throws AutowireTargetNotFoundException + * + */ + private void resolve(CompositeComponentType<?, ?, ?> compositeType, + ServiceContract requiredContract, + ReferenceTarget target, + boolean required) throws AutowireTargetNotFoundException { + // for now, attempt to match on interface, assume the class can be loaded + Class<?> requiredInterface = requiredContract.getInterfaceClass(); + if (requiredInterface == null) { + throw new UnsupportedOperationException("Only interfaces support for autowire"); + } + // autowire to a target in the parent + URI targetUri = null; + URI candidateUri = null; + // find a suitable target, starting with components first + for (ComponentDefinition<? extends Implementation<?>> candidate : compositeType.getComponents().values()) { + Implementation<?> candidateImpl = candidate.getImplementation(); + ComponentType<?, ?, ?> candidateType = candidateImpl.getComponentType(); + for (ServiceDefinition service : candidateType.getServices().values()) { + Class<?> serviceInterface = service.getServiceContract().getInterfaceClass(); + if (serviceInterface == null) { + continue; + } + if (requiredInterface.equals(serviceInterface)) { + targetUri = URI.create(candidate.getUri().toString() + service.getUri()); + break; + } else if (candidateUri == null && requiredInterface.isAssignableFrom(serviceInterface)) { + candidateUri = URI.create(candidate.getUri().toString() + service.getUri()); + } + } + if (targetUri != null) { + break; + } + } + if (targetUri == null) { + targetUri = resolvePrimordial(requiredContract); + } + if (candidateUri != null) { + targetUri = candidateUri; + } + if (targetUri != null) { + target.addTarget(targetUri); + } + if (targetUri == null && required) { + String uri = target.getReferenceName().toString(); + throw new AutowireTargetNotFoundException("No suitable target found for", uri); + } + } + + private URI resolvePrimordial(ServiceContract contract) { + Class<?> requiredClass = contract.getInterfaceClass(); + for (Map.Entry<ServiceContract, URI> entry : hostAutowire.entrySet()) { + if (requiredClass.isAssignableFrom(entry.getKey().getInterfaceClass())) { + return entry.getValue(); + } + } + return null; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/runtime/AbstractRuntime.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/runtime/AbstractRuntime.java new file mode 100644 index 0000000000..e2d92711f6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/runtime/AbstractRuntime.java @@ -0,0 +1,301 @@ +/* + * 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.core.runtime; + +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import javax.xml.stream.XMLInputFactory; + +import org.osoa.sca.ComponentContext; + +import org.apache.tuscany.spi.bootstrap.ComponentNames; +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.builder.Connector; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.ComponentException; +import org.apache.tuscany.spi.component.RegistrationException; +import org.apache.tuscany.spi.component.TargetResolutionException; +import org.apache.tuscany.spi.deployer.Deployer; +import org.apache.tuscany.spi.event.RuntimeEventListener; +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.model.ComponentDefinition; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.resolver.ResolutionException; +import org.apache.tuscany.spi.services.management.TuscanyManagementService; + +import org.apache.tuscany.core.bootstrap.Bootstrapper; +import org.apache.tuscany.core.bootstrap.DefaultBootstrapper; +import org.apache.tuscany.core.builder.ConnectorImpl; +import org.apache.tuscany.core.component.ComponentManager; +import org.apache.tuscany.core.component.ComponentManagerImpl; +import org.apache.tuscany.core.component.event.ComponentStart; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.implementation.system.model.SystemCompositeImplementation; +import org.apache.tuscany.core.monitor.NullMonitorFactory; +import org.apache.tuscany.core.resolver.AutowireResolver; +import org.apache.tuscany.core.resolver.DefaultAutowireResolver; +import org.apache.tuscany.host.MonitorFactory; +import org.apache.tuscany.host.RuntimeInfo; +import org.apache.tuscany.host.management.ManagementService; +import org.apache.tuscany.host.monitor.FormatterRegistry; +import org.apache.tuscany.host.runtime.InitializationException; +import org.apache.tuscany.host.runtime.TuscanyRuntime; + +/** + * @version $Rev$ $Date$ + */ +public abstract class AbstractRuntime<I extends RuntimeInfo> implements TuscanyRuntime<I> { + private static final URI MONITOR_URI = ComponentNames.TUSCANY_SYSTEM_ROOT.resolve("MonitorFactory"); + + private static final URI COMPONENT_MGR_URI = ComponentNames.TUSCANY_SYSTEM_ROOT.resolve("ComponentManager"); + + private static final URI AUTOWIRE_RESOLVER_URI = ComponentNames.TUSCANY_SYSTEM_ROOT.resolve("AutowireResolver"); + + private static final URI RUNTIME_INFO_URI = ComponentNames.TUSCANY_SYSTEM_ROOT.resolve("RuntimeInfo"); + + private final XMLInputFactory xmlFactory; + private URL systemScdl; + private String applicationName; + private URL applicationScdl; + private ClassLoader hostClassLoader; + private ClassLoader applicationClassLoader; + private Class<I> runtimeInfoType; + private I runtimeInfo; + private MonitorFactory monitorFactory; + private ManagementService<?> managementService; + private ComponentManager componentManager; + + private Component systemComponent; + private Component tuscanySystem; + private AutowireResolver resolver; + private JavaInterfaceProcessorRegistry interfaceProcessorRegistry; + + protected AbstractRuntime(Class<I> runtimeInfoType) { + this(runtimeInfoType, new NullMonitorFactory()); + } + + protected AbstractRuntime(Class<I> runtimeInfoType, MonitorFactory monitorFactory) { + this.runtimeInfoType = runtimeInfoType; + this.monitorFactory = monitorFactory; + xmlFactory = XMLInputFactory.newInstance("javax.xml.stream.XMLInputFactory", getClass().getClassLoader()); + this.interfaceProcessorRegistry = new JavaInterfaceProcessorRegistryImpl(); + } + + public URL getSystemScdl() { + return systemScdl; + } + + public void setSystemScdl(URL systemScdl) { + this.systemScdl = systemScdl; + } + + public String getApplicationName() { + return applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + public URL getApplicationScdl() { + return applicationScdl; + } + + public void setApplicationScdl(URL applicationScdl) { + this.applicationScdl = applicationScdl; + } + + public ClassLoader getApplicationClassLoader() { + return applicationClassLoader; + } + + public void setApplicationClassLoader(ClassLoader applicationClassLoader) { + this.applicationClassLoader = applicationClassLoader; + } + + public ClassLoader getHostClassLoader() { + return hostClassLoader; + } + + public void setHostClassLoader(ClassLoader hostClassLoader) { + this.hostClassLoader = hostClassLoader; + } + + public I getRuntimeInfo() { + return runtimeInfo; + } + + public void setRuntimeInfo(I runtimeInfo) { + this.runtimeInfo = runtimeInfo; + } + + public MonitorFactory getMonitorFactory() { + return monitorFactory; + } + + public void setMonitorFactory(MonitorFactory monitorFactory) { + this.monitorFactory = monitorFactory; + } + + public ManagementService<?> getManagementService() { + return managementService; + } + + public void setManagementService(ManagementService<?> managementService) { + this.managementService = managementService; + } + + public void initialize() throws InitializationException { + URI name = ComponentNames.TUSCANY_SYSTEM_ROOT.resolve("main"); + Bootstrapper bootstrapper = createBootstrapper(); + + registerBaselineSystemComponents(); + + // deploy the system scdl + Collection<Component> components; + try { + components = deploySystemScdl(bootstrapper.createDeployer(), + systemComponent, + name, + getSystemScdl(), + getClass().getClassLoader()); + } catch (LoaderException e) { + throw new InitializationException(e); + } catch (BuilderException e) { + throw new InitializationException(e); + } catch (ComponentException e) { + throw new InitializationException(e); + } catch (ResolutionException e) { + throw new InitializationException(e); + } + for (Component component : components) { + component.start(); + } + Component composite = componentManager.getComponent(name); + if (composite instanceof RuntimeEventListener) { + ((RuntimeEventListener) composite).onEvent(new ComponentStart(this, name)); + } + } + + public void destroy() { + if (tuscanySystem != null) { + tuscanySystem.stop(); + tuscanySystem = null; + } + if (systemComponent != null) { + systemComponent.stop(); + systemComponent = null; + } + } + + + public ComponentContext getComponentContext(URI componentId) { + Component component = componentManager.getComponent(componentId); + if (component == null) { + return null; + } + return component.getComponentContext(); + } + + protected Bootstrapper createBootstrapper() { + TuscanyManagementService tms = (TuscanyManagementService) getManagementService(); + resolver = new DefaultAutowireResolver(); + componentManager = new ComponentManagerImpl(tms, resolver); + Connector connector = new ConnectorImpl(componentManager); + return new DefaultBootstrapper(getMonitorFactory(), xmlFactory, componentManager, resolver, connector); + } + + protected void registerBaselineSystemComponents() throws InitializationException { + registerSystemComponent(RUNTIME_INFO_URI, runtimeInfoType, runtimeInfo); + List<Class<?>> monitorServices = new ArrayList<Class<?>>(); + monitorServices.add(MonitorFactory.class); + monitorServices.add(FormatterRegistry.class); + registerSystemComponent(MONITOR_URI, monitorServices, getMonitorFactory()); + // register the component manager with itself so it can be autowired + registerSystemComponent(COMPONENT_MGR_URI, ComponentManager.class, componentManager); + registerSystemComponent(AUTOWIRE_RESOLVER_URI, AutowireResolver.class, resolver); + } + + @SuppressWarnings({"unchecked"}) + protected <S, I extends S> void registerSystemComponent(URI uri, Class<S> type, I component) + throws InitializationException { + try { + ServiceContract contract = interfaceProcessorRegistry.introspect(type); + componentManager.registerJavaObject(uri, contract, component); + } catch (RegistrationException e) { + throw new InitializationException(e); + } catch (InvalidServiceContractException e) { + throw new InitializationException(e); + } + } + + protected <I> void registerSystemComponent(URI uri, List<Class<?>> types, I component) + throws InitializationException { + try { + List<ServiceContract<?>> contracts = new ArrayList<ServiceContract<?>>(); + for (Class<?> type : types) { + contracts.add(this.interfaceProcessorRegistry.introspect(type)); + + } + componentManager.registerJavaObject(uri, contracts, component); + } catch (RegistrationException e) { + throw new InitializationException(e); + } catch (InvalidServiceContractException e) { + throw new InitializationException(e); + } + } + + protected Collection<Component> deploySystemScdl(Deployer deployer, + Component parent, + URI name, + URL systemScdl, + ClassLoader systemClassLoader) + throws LoaderException, BuilderException, ComponentException, ResolutionException { + + SystemCompositeImplementation impl = new SystemCompositeImplementation(); + impl.setScdlLocation(systemScdl); + impl.setClassLoader(systemClassLoader); + ComponentDefinition<SystemCompositeImplementation> definition = + new ComponentDefinition<SystemCompositeImplementation>(name, impl); + + return deployer.deploy(parent, definition); + } + + + protected ComponentManager getComponentManager() { + return componentManager; + } + + + protected Deployer getDeployer() { + try { + AtomicComponent component = + (AtomicComponent) getComponentManager().getComponent(ComponentNames.TUSCANY_DEPLOYER); + return (Deployer) component.getTargetInstance(); + } catch (TargetResolutionException e) { + throw new AssertionError(e); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/artifact/LocalMavenRepository.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/artifact/LocalMavenRepository.java new file mode 100644 index 0000000000..f50e8544a3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/artifact/LocalMavenRepository.java @@ -0,0 +1,100 @@ +/* + * 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.core.services.artifact; + +import java.io.File; +import java.net.MalformedURLException; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.Collection; + +import org.osoa.sca.annotations.Property; + +import org.apache.tuscany.spi.services.artifact.Artifact; +import org.apache.tuscany.spi.services.artifact.ArtifactRepository; + +/** + * An implementation of ArtifactRepository that uses a local Maven2 repository. + * + * @version $Rev$ $Date$ + */ +public class LocalMavenRepository implements ArtifactRepository { + private File localRepo; + + /** + * Constructor specifying the location of the local repo. Relative paths are resolved against the user's home + * directory. + * + * @param repoPath the path to the local repo + */ + public LocalMavenRepository(@Property(name = "repository") String repoPath) { + String home = AccessController.doPrivileged(new PrivilegedAction<String>() { + public String run() { + return System.getProperty("user.home"); + } + }); + this.localRepo = new File(home, repoPath); + } + + public void resolve(Artifact artifact) { + if (artifact.getUrl() != null) { + return; + } + + String path = getPath(artifact); + File artifactFile = new File(localRepo, path); + if (artifactFile.exists()) { + try { + artifact.setUrl(artifactFile.toURI().toURL()); + } catch (MalformedURLException e) { + // toURI should have escaped the filename to allow it to be converted to a URL + throw new AssertionError(); + } + } + } + + /** + * Return the path into the repo for an artifact. The path for an artifact is ${group.replace('.', + * '/')}/$[name}/${version}/${name}-${version}[-${classifier}].${type} + * + * @param artifact the artifact to resolve + * @return the path into the repo for the artifact + */ + protected String getPath(Artifact artifact) { + StringBuilder builder = new StringBuilder(); + if (artifact.getGroup() != null) { + builder.append(artifact.getGroup().replace('.', '/')).append('/'); + } + builder.append(artifact.getName()).append('/'); + builder.append(artifact.getVersion()).append('/'); + + builder.append(artifact.getName()).append('-').append(artifact.getVersion()); + if (artifact.getClassifier() != null) { + builder.append('-').append(artifact.getClassifier()); + } + builder.append('.').append(artifact.getType()); + return builder.toString(); + } + + public void resolve(Collection<? extends Artifact> artifacts) { + for (Artifact artifact : artifacts) { + resolve(artifact); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/classloading/ClassLoaderRegistryImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/classloading/ClassLoaderRegistryImpl.java new file mode 100644 index 0000000000..afa7f64246 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/classloading/ClassLoaderRegistryImpl.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.core.services.classloading; + +import java.net.URI; +import java.util.concurrent.ConcurrentHashMap; +import java.util.Map; + +import org.apache.tuscany.spi.services.classloading.ClassLoaderRegistry; +import org.apache.tuscany.spi.services.classloading.DuplicateClassLoaderException; + +/** + * Implementation of a registry for classloaders. + * + * @version $Rev$ $Date$ + */ +public class ClassLoaderRegistryImpl implements ClassLoaderRegistry { + private final Map<URI, ClassLoader> registry = new ConcurrentHashMap<URI, ClassLoader>(); + + public synchronized void register(URI id, ClassLoader classLoader) throws DuplicateClassLoaderException { + if (registry.containsKey(id)) { + throw new DuplicateClassLoaderException("Duplicate class loader", id.toString()); + } + registry.put(id, classLoader); + } + + public ClassLoader getClassLoader(URI id) { + return registry.get(id); + } + + public ClassLoader unregister(URI id) { + return registry.remove(id); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/classloading/MultiParentClassLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/classloading/MultiParentClassLoader.java new file mode 100644 index 0000000000..0a255ede9e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/classloading/MultiParentClassLoader.java @@ -0,0 +1,402 @@ +/* + * 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.core.services.classloading; + +import java.beans.Introspector; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLStreamHandlerFactory; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import java.util.Set; + +/** + * A MultiParentClassLoader is a simple extension of the URLClassLoader that + * simply changes the single parent class loader model to support a list of + * parent class loaders. Each operation that accesses a parent, has been + * replaced with a operation that checks each parent in order. This getParent + * method of this class will always return null, which may be interpreted by the + * calling code to mean that this class loader is a direct child of the system + * class loader. + * + * @version $Rev$ $Date$ + */ +public class MultiParentClassLoader extends URLClassLoader { + private boolean destroyed; + private final String[] hiddenClasses; + private final String[] hiddenResources; + private final boolean inverseClassLoading; + private final String[] nonOverridableClasses; + private final String[] nonOverridableResources; + + private final ClassLoader[] parents; + + /** + * Creates a named class loader with no parents. + * + * @param urls the urls from which this class loader will classes and + * resources + */ + public MultiParentClassLoader(URL[] urls) { + super(urls); + parents = new ClassLoader[] {ClassLoader.getSystemClassLoader()}; + inverseClassLoading = false; + hiddenClasses = new String[0]; + nonOverridableClasses = new String[0]; + hiddenResources = new String[0]; + nonOverridableResources = new String[0]; + } + + /** + * Creates a named class loader as a child of the specified parent. + * + * @param urls the urls from which this class loader will classes and + * resources + * @param parent the parent of this class loader + */ + public MultiParentClassLoader(URL[] urls, ClassLoader parent) { + this(urls, new ClassLoader[] {parent}); + } + + public MultiParentClassLoader(URL[] urls, + ClassLoader parent, + boolean inverseClassLoading, + String[] hiddenClasses, + String[] nonOverridableClasses) { + this(urls, new ClassLoader[] {parent}, inverseClassLoading, hiddenClasses, nonOverridableClasses); + } + + /** + * Creates a named class loader as a child of the specified parent and using + * the specified URLStreamHandlerFactory for accessing the urls.. + * + * @param urls the urls from which this class loader will classes and + * resources + * @param parent the parent of this class loader + * @param factory the URLStreamHandlerFactory used to access the urls + */ + public MultiParentClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) { + this(urls, new ClassLoader[] {parent}, factory); + } + + /** + * Creates a named class loader as a child of the specified parents. + * + * @param urls the urls from which this class loader will classes and + * resources + * @param parents the parents of this class loader + */ + public MultiParentClassLoader(URL[] urls, ClassLoader[] parents) { + super(urls); + this.parents = copyParents(parents); + inverseClassLoading = false; + hiddenClasses = new String[0]; + nonOverridableClasses = new String[0]; + hiddenResources = new String[0]; + nonOverridableResources = new String[0]; + } + + public MultiParentClassLoader(URL[] urls, + ClassLoader[] parents, + boolean inverseClassLoading, + Collection<String> hiddenClasses, + Collection<String> nonOverridableClasses) { + this(urls, parents, inverseClassLoading, (String[])hiddenClasses.toArray(new String[hiddenClasses.size()]), + (String[])nonOverridableClasses.toArray(new String[nonOverridableClasses.size()])); + } + + public MultiParentClassLoader(URL[] urls, + ClassLoader[] parents, + boolean inverseClassLoading, + String[] hiddenClasses, + String[] nonOverridableClasses) { + super(urls); + this.parents = copyParents(parents); + this.inverseClassLoading = inverseClassLoading; + this.hiddenClasses = hiddenClasses; + this.nonOverridableClasses = nonOverridableClasses; + hiddenResources = toResources(hiddenClasses); + nonOverridableResources = toResources(nonOverridableClasses); + } + + /** + * Creates a named class loader as a child of the specified parents and + * using the specified URLStreamHandlerFactory for accessing the urls.. + * + * @param urls the urls from which this class loader will classes and + * resources + * @param parents the parents of this class loader + * @param factory the URLStreamHandlerFactory used to access the urls + */ + public MultiParentClassLoader(URL[] urls, ClassLoader[] parents, URLStreamHandlerFactory factory) { + super(urls, null, factory); + this.parents = copyParents(parents); + inverseClassLoading = false; + hiddenClasses = new String[0]; + nonOverridableClasses = new String[0]; + hiddenResources = new String[0]; + nonOverridableResources = new String[0]; + } + + private static ClassLoader[] copyParents(ClassLoader[] parents) { + ClassLoader[] newParentsArray = new ClassLoader[parents.length]; + for (int i = 0; i < parents.length; i++) { + ClassLoader parent = parents[i]; + if (parent == null) { + throw new RuntimeException("parent[" + i + "] is null"); + } + newParentsArray[i] = parent; + } + return newParentsArray; + } + + public void addURL(URL url) { + // todo this needs a security check + super.addURL(url); + } + + public void destroy() { + synchronized (this) { + if (destroyed) { + return; + } + destroyed = true; + } + + // clearSoftCache(ObjectInputStream.class, "subclassAudits"); + // clearSoftCache(ObjectOutputStream.class, "subclassAudits"); + // clearSoftCache(ObjectStreamClass.class, "localDescs"); + // clearSoftCache(ObjectStreamClass.class, "reflectors"); + + // The beanInfoCache in java.beans.Introspector will hold on to Classes + // which + // it has introspected. If we don't flush the cache, we may run out of + // Permanent Generation space. + Introspector.flushCaches(); + } + + public Enumeration<URL> findResources(String name) throws IOException { + if (isDestroyed()) { + Set<URL> emptySet = Collections.emptySet(); + return Collections.enumeration(emptySet); + } + + List<URL> resources = new ArrayList<URL>(); + + // + // if we are using inverse class loading, add the resources from local + // urls first + // + if (inverseClassLoading && !isDestroyed()) { + List<URL> myResources = Collections.list(super.findResources(name)); + resources.addAll(myResources); + } + + // + // Add parent resources + // + for (int i = 0; i < parents.length; i++) { + ClassLoader parent = parents[i]; + List<URL> parentResources = Collections.list(parent.getResources(name)); + resources.addAll(parentResources); + } + + // + // if we are not using inverse class loading, add the resources from + // local urls now + // + if (!inverseClassLoading && !isDestroyed()) { + List<URL> myResources = Collections.list(super.findResources(name)); + resources.addAll(myResources); + } + + return Collections.enumeration(resources); + } + + /** + * Gets the parents of this class loader. + * + * @return the parents of this class loader + */ + public ClassLoader[] getParents() { + return parents; + } + + public URL getResource(String name) { + if (isDestroyed()) { + return null; + } + + // + // if we are using inverse class loading, check local urls first + // + if (inverseClassLoading && !isDestroyed() && !isNonOverridableResource(name)) { + URL url = findResource(name); + if (url != null) { + return url; + } + } + + // + // Check parent class loaders + // + if (!isHiddenResource(name)) { + for (int i = 0; i < parents.length; i++) { + ClassLoader parent = parents[i]; + URL url = parent.getResource(name); + if (url != null) { + return url; + } + } + } + + // + // if we are not using inverse class loading, check local urls now + // + // don't worry about excluding non-overridable resources here... we + // have alredy checked he parent and the parent didn't have the + // resource, so we can override now + if (!isDestroyed()) { + // parents didn't have the resource; attempt to load it from my urls + return findResource(name); + } + + return null; + } + + public synchronized boolean isDestroyed() { + return destroyed; + } + + private boolean isHiddenClass(String name) { + for (int i = 0; i < hiddenClasses.length; i++) { + if (name.startsWith(hiddenClasses[i])) { + return true; + } + } + return false; + } + + private boolean isHiddenResource(String name) { + for (int i = 0; i < hiddenResources.length; i++) { + if (name.startsWith(hiddenResources[i])) { + return true; + } + } + return false; + } + + private boolean isNonOverridableClass(String name) { + for (int i = 0; i < nonOverridableClasses.length; i++) { + if (name.startsWith(nonOverridableClasses[i])) { + return true; + } + } + return false; + } + + private boolean isNonOverridableResource(String name) { + for (int i = 0; i < nonOverridableResources.length; i++) { + if (name.startsWith(nonOverridableResources[i])) { + return true; + } + } + return false; + } + + @SuppressWarnings("unchecked") + protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + // + // Check if class is in the loaded classes cache + // + Class cachedClass = findLoadedClass(name); + if (cachedClass != null) { + return resolveClass(cachedClass, resolve); + } + + // + // if we are using inverse class loading, check local urls first + // + if (inverseClassLoading && !isDestroyed() && !isNonOverridableClass(name)) { + try { + Class clazz = findClass(name); + return resolveClass(clazz, resolve); + } catch (ClassNotFoundException ignored) { + // Ignore it + } + } + + // + // Check parent class loaders + // + if (!isHiddenClass(name)) { + for (int i = 0; i < parents.length; i++) { + ClassLoader parent = parents[i]; + try { + Class clazz = parent.loadClass(name); + return resolveClass(clazz, resolve); + } catch (ClassNotFoundException ignored) { + // this parent didn't have the class; try the next one + } + } + } + + // + // if we are not using inverse class loading, check local urls now + // + // don't worry about excluding non-overridable classes here... we + // have alredy checked he parent and the parent didn't have the + // class, so we can override now + if (!isDestroyed()) { + try { + Class clazz = findClass(name); + return resolveClass(clazz, resolve); + } catch (ClassNotFoundException ignored) { + // Ignore it + } + } + + throw new ClassNotFoundException(name); + } + + private Class resolveClass(Class clazz, boolean resolve) { + if (resolve) { + resolveClass(clazz); + } + return clazz; + } + + private String[] toResources(String[] classes) { + String[] resources = new String[classes.length]; + for (int i = 0; i < classes.length; i++) { + String className = classes[i]; + resources[i] = className.replace('.', '/'); + } + return resources; + } + + public String toString() { + return "[" + getClass().getName() + "]"; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/AssemblyServiceImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/AssemblyServiceImpl.java new file mode 100644 index 0000000000..e264663dd4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/AssemblyServiceImpl.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.core.services.deployment; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.Map; +import java.util.HashMap; + +import org.apache.tuscany.host.deployment.AssemblyService; +import org.apache.tuscany.host.deployment.DeploymentException; +import org.apache.tuscany.host.deployment.UnsupportedContentTypeException; +import org.apache.tuscany.spi.deployer.ChangeSetHandlerRegistry; +import org.apache.tuscany.spi.deployer.ChangeSetHandler; + +/** + * @version $Rev$ $Date$ + */ +public class AssemblyServiceImpl implements AssemblyService, ChangeSetHandlerRegistry { + private final Map<String, ChangeSetHandler> registry = new HashMap<String, ChangeSetHandler>(); + + public void applyChanges(URL changeSet) throws DeploymentException, IOException { + if (changeSet == null) { + throw new IllegalArgumentException("changeSet is null"); + } + + URLConnection connection = changeSet.openConnection(); + String contentType = connection.getContentType(); + //todo try and figure out content type from the URL + if (contentType == null) { + throw new UnsupportedContentTypeException(null, changeSet.toString()); + } + + InputStream is = connection.getInputStream(); + try { + applyChanges(is, contentType); + } finally { + try { + is.close(); + } catch (IOException e) { + // ignore + } + } + } + + public void applyChanges(InputStream changeSet, String contentType) throws DeploymentException, IOException { + if (changeSet == null) { + throw new IllegalArgumentException("changeSet is null"); + } + if (contentType == null) { + throw new IllegalArgumentException("contentType is null"); + } + + ChangeSetHandler handler = registry.get(contentType); + if (handler == null) { + throw new UnsupportedContentTypeException(contentType); + } + + handler.applyChanges(changeSet); + } + + public void register(ChangeSetHandler handler) { + registry.put(handler.getContentType(), handler); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/ContentTypeDescriberImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/ContentTypeDescriberImpl.java new file mode 100644 index 0000000000..bae5c1d450 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/ContentTypeDescriberImpl.java @@ -0,0 +1,100 @@ +/*
+ * 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.core.services.deployment;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osoa.sca.annotations.EagerInit;
+import org.osoa.sca.annotations.Service;
+
+import org.apache.tuscany.spi.deployer.ContentTypeDescriber;
+
+import org.apache.tuscany.core.util.FileHelper;
+
+/**
+ * Implementation of the content describer
+ *
+ * @version $Rev$ $Date$
+ */
+@EagerInit
+@Service(ContentTypeDescriber.class)
+public class ContentTypeDescriberImpl implements ContentTypeDescriber {
+ private final Map<String, String> contentTypeRegistry = new HashMap<String, String>();
+
+ public ContentTypeDescriberImpl() {
+ super();
+ init();
+ }
+
+ /**
+ * Initialize contentType registry with know types based on known file extensions
+ */
+ private void init() {
+ contentTypeRegistry.put("SCDL", "application/v.tuscany.scdl");
+ contentTypeRegistry.put("COMPOSITE", "application/v.tuscany.scdl");
+ contentTypeRegistry.put("WSDL", "application/v.tuscany.wsdl");
+ contentTypeRegistry.put("JAR", "application/x-compressed");
+ }
+
+ protected String resolveContentyTypeByExtension(URL resourceURL) {
+ String artifactExtension = FileHelper.getExtension(resourceURL.getPath());
+ if (artifactExtension == null) {
+ return null;
+ }
+ return contentTypeRegistry.get(artifactExtension.toUpperCase());
+ }
+
+ /**
+ * Build contentType for a specific resource. We first check if the file is a supported one (looking into our
+ * registry based on resource extension) If not found, we try to check file contentType Or we return
+ * defaultContentType provided
+ *
+ * @param url
+ * @param defaultContentType
+ * @return
+ */
+ public String getContentType(URL resourceURL, String defaultContentType) {
+ URLConnection connection = null;
+ String contentType = defaultContentType;
+
+ contentType = resolveContentyTypeByExtension(resourceURL);
+ if (contentType == null) {
+ try {
+ connection = resourceURL.openConnection();
+ contentType = connection.getContentType();
+
+ if (contentType == null || contentType.equals("content/unknown")) {
+ // here we couldn't figure out from our registry or from URL
+ // return defaultContentType if provided
+ contentType = defaultContentType;
+ }
+ } catch (IOException io) {
+ // could not access artifact, just ignore and we will return
+ // null contentType
+ }
+ }
+ return contentType == null ? defaultContentType : contentType;
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionDirectoryWatcher.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionDirectoryWatcher.java new file mode 100644 index 0000000000..cbbd5f8623 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionDirectoryWatcher.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.core.services.deployment;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.osoa.sca.annotations.EagerInit;
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Property;
+import org.osoa.sca.annotations.Reference;
+
+import org.apache.tuscany.host.deployment.ContributionService;
+import org.apache.tuscany.host.deployment.DeploymentException;
+
+@EagerInit
+public class ContributionDirectoryWatcher {
+ private final String path;
+
+ private final ContributionService contributionService;
+
+ public ContributionDirectoryWatcher(@Reference ContributionService contributionService,
+ @Property(name = "path") String path) {
+ this.path = path;
+ this.contributionService = contributionService;
+ }
+
+ @Init
+ public void init() {
+ File extensionDir = new File(path);
+ if (!extensionDir.isDirectory()) {
+ // we don't have an extension directory, there's nothing to do
+ return;
+ }
+
+ File[] files = extensionDir.listFiles();
+ for (File file : files) {
+ try {
+ if (file.isDirectory()) {
+ this.contributionService.contribute(file.toURL(), false);
+ } else {
+ this.contributionService.contribute(file.toURL(), true);
+ }
+ } catch (DeploymentException de) {
+ // FIXME handle this
+ de.printStackTrace();
+ } catch (IOException ioe) {
+ // FIXME handle this
+ ioe.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionProcessorRegistryImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionProcessorRegistryImpl.java new file mode 100644 index 0000000000..5866789e7e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionProcessorRegistryImpl.java @@ -0,0 +1,95 @@ +/*
+ * 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.core.services.deployment;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osoa.sca.annotations.EagerInit;
+import org.osoa.sca.annotations.Reference;
+import org.osoa.sca.annotations.Service;
+
+import org.apache.tuscany.spi.deployer.ContentTypeDescriber;
+import org.apache.tuscany.spi.deployer.ContributionProcessor;
+import org.apache.tuscany.spi.deployer.ContributionProcessorRegistry;
+import org.apache.tuscany.spi.model.Contribution;
+
+import org.apache.tuscany.host.deployment.DeploymentException;
+import org.apache.tuscany.host.deployment.UnsupportedContentTypeException;
+
+/**
+ * Default implementation of ContributionProcessorRegistry
+ *
+ * @version $Rev$ $Date$
+ */
+@EagerInit
+@Service(ContributionProcessorRegistry.class)
+public class ContributionProcessorRegistryImpl implements ContributionProcessorRegistry {
+ /**
+ * Processor registry
+ */
+ private Map<String, ContributionProcessor> registry = new HashMap<String, ContributionProcessor>();
+ /**
+ * Helper method to describe contentType for each artifact
+ */
+ private ContentTypeDescriber contentTypeDescriber;
+
+ public ContributionProcessorRegistryImpl(@Reference ContentTypeDescriber contentTypeDescriber) {
+ if (contentTypeDescriber == null) {
+ this.contentTypeDescriber = new ContentTypeDescriberImpl();
+ } else {
+ this.contentTypeDescriber = contentTypeDescriber;
+ }
+ }
+
+ public void register(String contentType, ContributionProcessor processor) {
+ registry.put(contentType, processor);
+ }
+
+ public void unregister(String contentType) {
+ registry.remove(contentType);
+ }
+
+ public void processContent(Contribution contribution, URI source, InputStream inputStream)
+ throws DeploymentException, IOException {
+
+ URL locationURL = contribution.getArtifact(source).getLocation();
+ String contentType = this.contentTypeDescriber.getContentType(locationURL, null);
+ if (contentType == null) {
+ throw new UnsupportedContentTypeException("Invalid contentType: null");
+ }
+
+ ContributionProcessor processor = this.registry.get(contentType);
+ if (processor == null) {
+ throw new UnsupportedContentTypeException(contentType, locationURL.getPath());
+ }
+
+ processor.processContent(contribution, source, inputStream);
+
+ }
+
+ public void processModel(Contribution contribution, URI source, Object modelObject) throws DeploymentException,
+ IOException {
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionRepositoryImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionRepositoryImpl.java new file mode 100644 index 0000000000..6f4509c23f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionRepositoryImpl.java @@ -0,0 +1,144 @@ +/*
+ * 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.core.services.deployment;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.core.util.FileHelper;
+import org.apache.tuscany.core.util.IOHelper;
+import org.apache.tuscany.spi.deployer.ContributionRepository;
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.EagerInit;
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Property;
+
+/**
+ * The default implementation of ContributionRepository
+ *
+ * @version $Rev$ $Date$
+ */
+@EagerInit
+public class ContributionRepositoryImpl implements ContributionRepository {
+ protected final File rootFile;
+ protected final Map<URI, URL> reposirotyContent = new HashMap<URI, URL>();
+
+ /**
+ * Constructor with repository root
+ *
+ * @param repository
+ */
+ public ContributionRepositoryImpl(@Property(name = "repository") String repository) throws IOException {
+ this.rootFile = new File(repository);
+ FileHelper.forceMkdir(rootFile);
+ if (!rootFile.exists() || !rootFile.isDirectory() || !rootFile.canRead()) {
+ throw new IOException("The root is not a directory: " + repository);
+ }
+ }
+
+ /**
+ * Resolve contribution location in the repository -> root repository /
+ * contribution file -> contribution group id / artifact id / version
+ *
+ * @param contribution
+ * @return
+ */
+ private File mapToFile(URI contribution) {
+ // FIXME: Map the contribution URI to a file?
+ return new File(rootFile, FileHelper.getName(contribution.toString()));
+ }
+
+ /**
+ * Write a specific source inputstream to a file on disk
+ *
+ * @param source contents of the file to be written to disk
+ * @param target file to be written
+ * @throws IOException
+ */
+ public static void copy(InputStream source, File target) throws IOException {
+ BufferedOutputStream out = null;
+ BufferedInputStream in = null;
+
+ try {
+ out = new BufferedOutputStream(new FileOutputStream(target));
+ in = new BufferedInputStream(source);
+ IOHelper.copy(in, out);
+ } finally {
+ IOHelper.closeQuietly(out);
+ IOHelper.closeQuietly(in);
+ }
+ }
+
+ public URL store(URI contribution, InputStream contributionStream) throws IOException {
+ // where the file should be stored in the repository
+ File location = mapToFile(contribution);
+
+ copy(contributionStream, location);
+
+ // add contribution to repositoryContent
+ URL contributionURL = location.toURL();
+ reposirotyContent.put(contribution, contributionURL);
+
+ return contributionURL;
+ }
+
+ public URL find(URI contribution) {
+ if (contribution == null) {
+ return null;
+ }
+ return this.reposirotyContent.get(contribution);
+ }
+
+ public void remove(URI contribution) {
+ URL contributionURL = this.find(contribution);
+ if (contributionURL != null) {
+ // remove
+ try {
+ FileHelper.forceDelete(FileHelper.toFile(contributionURL));
+ this.reposirotyContent.remove(contribution);
+ } catch (IOException ioe) {
+ // handle file could not be removed
+ }
+ }
+ }
+
+ public List<URI> list() {
+ return new ArrayList<URI>(reposirotyContent.keySet());
+ }
+
+ @Init
+ public void init() {
+ }
+
+ @Destroy
+ public void destroy() {
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionServiceImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionServiceImpl.java new file mode 100644 index 0000000000..bf19683a7c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionServiceImpl.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.core.services.deployment; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.deployer.ContributionProcessorRegistry; +import org.apache.tuscany.spi.deployer.ContributionRepository; +import org.apache.tuscany.spi.model.Contribution; + +import org.apache.tuscany.core.util.IOHelper; +import org.apache.tuscany.host.deployment.ContributionService; +import org.apache.tuscany.host.deployment.DeploymentException; + +/** + * @version $Rev$ $Date$ + */ +public class ContributionServiceImpl implements ContributionService { + /** + * Repository where contributions are stored. Usually set by injection. + */ + protected ContributionRepository contributionRepository; + /** + * Registry of available processors. Usually set by injection. + */ + protected ContributionProcessorRegistry processorRegistry; + /** + * Contribution registry This is a registry of processed Contributios index by URI + */ + protected Map<URI, Contribution> contributionRegistry = new HashMap<URI, Contribution>(); + + public ContributionServiceImpl(@Reference ContributionRepository repository, + @Reference ContributionProcessorRegistry processorRegistry) { + super(); + this.contributionRepository = repository; + this.processorRegistry = processorRegistry; + } + + public URI contribute(URL contribution, boolean storeInRepository) throws DeploymentException, IOException { + if (contribution == null) { + throw new IllegalArgumentException("contribution is null"); + } + + URI source; + try { + source = contribution.toURI(); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("contribution cannot be converted to a URI", e); + } + + InputStream is = contribution.openConnection().getInputStream(); + try { + return contribute(source, is, storeInRepository); + } finally { + IOHelper.closeQuietly(is); + } + } + + public URI contribute(URI source, InputStream contributionStream, boolean storeInRepository) + throws DeploymentException, IOException { + if (source == null) { + throw new IllegalArgumentException("source URI for contribution is null"); + } + + if (contributionStream == null) { + throw new IllegalArgumentException("Invalid contribution stream : null"); + } + + // store the contribution in the contribution repository + URI contributionURI = URI.create("sca://contribution/" + UUID.randomUUID()); + URL locationURL; + if (storeInRepository) { + locationURL = this.contributionRepository.store(source, contributionStream); + } else { + locationURL = source.toURL(); + } + + + Contribution contribution = null; + contribution = new Contribution(contributionURI); + contribution.setLocation(locationURL); + + //process the contribution + this.processorRegistry.processContent(contribution, contributionURI, locationURL.openStream()); + + //store the contribution on the registry + this.contributionRegistry.put(contribution.getUri(), contribution); + + return contribution.getUri(); + } + + public Contribution getContribution(URI id) { + return this.contributionRegistry.get(id); + } + + public void remove(URI contribution) throws DeploymentException { + //remove from repository + this.contributionRegistry.remove(contribution); + //remove from registry + this.contributionRegistry.remove(contribution); + } + + public <T> T resolve(URI contribution, Class<T> definitionType, String namespace, String name) { + // TODO Auto-generated method stub + return null; + } + + public URL resolve(URI contribution, String namespace, URI uri, URI baseURI) { + // TODO Auto-generated method stub + return null; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/InvalidDocumentException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/InvalidDocumentException.java new file mode 100644 index 0000000000..f509929f29 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/InvalidDocumentException.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.services.deployment; + +import org.apache.tuscany.host.deployment.DeploymentException; + +/** + * Exception that indicates that the supplied XML Document invalid. + * + * @version $Rev$ $Date$ + */ +public class InvalidDocumentException extends DeploymentException { + protected InvalidDocumentException(String rootElement) { + super(rootElement); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/XMLChangeSetHandler.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/XMLChangeSetHandler.java new file mode 100644 index 0000000000..b3b38cb438 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/XMLChangeSetHandler.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.core.services.deployment; + +import java.io.IOException; +import java.io.InputStream; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; +import static javax.xml.stream.XMLStreamConstants.END_DOCUMENT; +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 org.apache.tuscany.spi.builder.Builder; +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.deployer.ChangeSetHandler; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.loader.Loader; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.model.ComponentDefinition; + +import org.apache.tuscany.core.deployer.RootDeploymentContext; +import org.apache.tuscany.host.deployment.ContentTypes; +import org.apache.tuscany.host.deployment.DeploymentException; + +/** + * @version $Rev$ $Date$ + */ +public class XMLChangeSetHandler implements ChangeSetHandler { + private static final String NS = "http://tuscany.apache.org/xmlns/1.0-SNAPSHOT"; + private static final QName CHANGESET = new QName(NS, "changeSet"); + private static final QName CREATECOMPONENT = new QName(NS, "createComponent"); + + private final Builder builder; + private final Loader loader; + private final XMLInputFactory xmlFactory; + + public XMLChangeSetHandler(Loader loader, Builder builder) { + this.loader = loader; + this.builder = builder; + xmlFactory = XMLInputFactory.newInstance("javax.xml.stream.XMLInputFactory", getClass().getClassLoader()); + } + + public String getContentType() { + return ContentTypes.CHANGESET_XML; + } + + public void applyChanges(InputStream changeSet) throws DeploymentException, IOException { + try { + XMLStreamReader xmlReader = xmlFactory.createXMLStreamReader(changeSet); + while (true) { + switch (xmlReader.next()) { + case START_ELEMENT: + if (!CHANGESET.equals(xmlReader.getName())) { + throw new InvalidDocumentException(xmlReader.getName().toString()); + } + processChanges(xmlReader); + break; + case END_DOCUMENT: + return; + } + } + } catch (XMLStreamException e) { + throw (IOException) new IOException(e.getMessage()).initCause(e); + } + } + + public void processChanges(XMLStreamReader xmlReader) throws XMLStreamException, DeploymentException { + while (true) { + switch (xmlReader.next()) { + case START_ELEMENT: + if (CREATECOMPONENT.equals(xmlReader.getName())) { + createComponent(xmlReader); + } else { + // reject unrecognized commands + throw new InvalidDocumentException(xmlReader.getName().toString()); + } + break; + case END_ELEMENT: + return; + } + } + } + + public void createComponent(XMLStreamReader xmlReader) throws XMLStreamException { + DeploymentContext deploymentContext = new RootDeploymentContext(null, null, null, xmlFactory, null, false); + try { + ComponentDefinition<?> componentDefinition = + (ComponentDefinition<?>) loader.load(null, xmlReader, deploymentContext); + builder.build(componentDefinition, deploymentContext); + } catch (LoaderException e) { + // FIXME throw something appropriate + throw new AssertionError("FIXME"); + } catch (BuilderException e) { + // FIXME throw something appropriate + throw new AssertionError("FIXME"); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/FolderContributionProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/FolderContributionProcessor.java new file mode 100644 index 0000000000..0855bb9d9a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/FolderContributionProcessor.java @@ -0,0 +1,125 @@ +/*
+ * 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.core.services.deployment.contribution;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.core.services.deployment.ContentTypeDescriberImpl;
+import org.apache.tuscany.host.deployment.DeploymentException;
+import org.apache.tuscany.spi.deployer.ContentTypeDescriber;
+import org.apache.tuscany.spi.deployer.ContributionProcessor;
+import org.apache.tuscany.spi.extension.ContributionProcessorExtension;
+import org.apache.tuscany.spi.model.Contribution;
+
+public class FolderContributionProcessor extends ContributionProcessorExtension implements ContributionProcessor {
+ public static final String CONTENT_TYPE = "application/v.tuscany.folder";
+
+ @Override
+ public String getContentType() {
+ return CONTENT_TYPE;
+ }
+
+
+ private void traverse(List<URL> fileList, File root) throws IOException {
+ if (root.isFile()) {
+ fileList.add(root.toURL());
+ } else if (root.isDirectory() && !root.getName().equals(".svn")) {
+ File[] files = root.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ traverse(fileList, files[i]);
+ }
+ }
+ }
+
+
+ /**
+ * Get a list of files from the directory
+ *
+ * @return
+ * @throws IOException
+ */
+ protected List<URL> getArtifacts(URL rootURL, InputStream sourceInputStream)
+ throws DeploymentException, IOException {
+ List<URL> artifacts = new ArrayList<URL>();
+
+ // Assume the root is a jar file
+ File rootFolder;
+
+ try {
+ rootFolder = new File(rootURL.toURI());
+ if (rootFolder.isDirectory()) {
+ this.traverse(artifacts, rootFolder);
+ }
+
+ } catch (URISyntaxException e) {
+ throw new InvalidFolderContributionURIException(rootURL.toExternalForm(), e);
+ }
+
+ return artifacts;
+ }
+
+
+ public void processContent(Contribution contribution, URI source, InputStream inputStream)
+ throws DeploymentException, IOException {
+ if (contribution == null) {
+ throw new IllegalArgumentException("Invalid null contribution.");
+ }
+
+ if (source == null) {
+ throw new IllegalArgumentException("Invalid null source uri.");
+ }
+
+ URL sourceURL = contribution.getArtifact(source).getLocation();
+
+ for (URL artifactURL : getArtifacts(sourceURL, inputStream)) {
+ // FIXME
+ // contribution.addArtifact(artifact)
+
+ ContentTypeDescriber contentTypeDescriber = new ContentTypeDescriberImpl();
+ String contentType = contentTypeDescriber.getContentType(artifactURL, null);
+ System.out.println("File : " + artifactURL);
+ System.out.println("Type : " + contentType);
+
+
+ //just process scdl for now
+ if ("application/v.tuscany.scdl".equals(contentType) || "application/java-vm".equals(contentType)) {
+ this.registry.processContent(contribution, source, inputStream);
+ }
+ // process each artifact
+ //this.registry.processContent(contribution, artifactURL, inputStream);
+
+ }
+
+ }
+
+ public void processModel(Contribution contribution, URI source, Object modelObject)
+ throws DeploymentException, IOException {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidComponentDefinitionlException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidComponentDefinitionlException.java new file mode 100644 index 0000000000..f0b47ccf7b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidComponentDefinitionlException.java @@ -0,0 +1,36 @@ +/*
+ * 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.core.services.deployment.contribution;
+
+import org.apache.tuscany.host.deployment.DeploymentException;
+
+/**
+ * Exception that indicates that the supplied XML Document invalid.
+ *
+ */
+public class InvalidComponentDefinitionlException extends DeploymentException {
+
+ protected InvalidComponentDefinitionlException(String componentDefinitionLocatoin) {
+ super(componentDefinitionLocatoin);
+ }
+
+ protected InvalidComponentDefinitionlException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidFolderContributionURIException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidFolderContributionURIException.java new file mode 100644 index 0000000000..547608e64d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidFolderContributionURIException.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.core.services.deployment.contribution;
+
+import org.apache.tuscany.host.deployment.DeploymentException;
+
+/**
+ * Exception that indicates that the supplied XML Document invalid.
+ *
+ */
+public class InvalidFolderContributionURIException extends DeploymentException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1564255850052593282L;
+
+ protected InvalidFolderContributionURIException(String componentDefinitionLocatoin) {
+ super(componentDefinitionLocatoin);
+ }
+
+ protected InvalidFolderContributionURIException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/JarContributionProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/JarContributionProcessor.java new file mode 100644 index 0000000000..6c9674f6fb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/JarContributionProcessor.java @@ -0,0 +1,144 @@ +/*
+ * 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.core.services.deployment.contribution;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+import org.apache.tuscany.core.services.deployment.ContentTypeDescriberImpl;
+import org.apache.tuscany.core.util.FileHelper;
+import org.apache.tuscany.host.deployment.DeploymentException;
+import org.apache.tuscany.spi.deployer.ContentTypeDescriber;
+import org.apache.tuscany.spi.deployer.ContributionProcessor;
+import org.apache.tuscany.spi.extension.ContributionProcessorExtension;
+import org.apache.tuscany.spi.model.Contribution;
+import org.apache.tuscany.spi.model.DeployedArtifact;
+
+public class JarContributionProcessor extends ContributionProcessorExtension implements ContributionProcessor {
+ public static final String CONTENT_TYPE = "application/x-compressed";
+
+ @Override
+ public String getContentType() {
+ return CONTENT_TYPE;
+ }
+
+ /**
+ * Get a list of resources inside the jar
+ *
+ * @return
+ * @throws IOException
+ */
+ protected List<URL> getArtifacts(URL rootURL, InputStream sourceInputStream) throws IOException {
+ List<URL> artifacts = new ArrayList<URL>();
+
+ // Assume the root is a jar file
+ JarInputStream jar = new JarInputStream(sourceInputStream);
+ try {
+ while (true) {
+ JarEntry entry = jar.getNextJarEntry();
+ if (entry == null) {
+ // EOF
+ break;
+ }
+ if (entry.isDirectory()) {
+ continue;
+ }
+
+ artifacts.add(new URL(rootURL, entry.getName()));
+ }
+ } finally {
+ jar.close();
+ }
+ return artifacts;
+ }
+
+ private URL forceJarURL(URL sourceURL) throws MalformedURLException {
+ if (sourceURL.toString().startsWith("jar:")) {
+ return sourceURL;
+ } else {
+ return new URL("jar:" + sourceURL.toExternalForm() + "!/");
+ }
+
+ }
+
+ public void processContent(Contribution contribution, URI source, InputStream inputStream)
+ throws DeploymentException, IOException {
+ if (contribution == null) {
+ throw new IllegalArgumentException("Invalid null contribution.");
+ }
+
+ if (source == null) {
+ throw new IllegalArgumentException("Invalid null source uri.");
+ }
+
+ if (inputStream == null) {
+ throw new IllegalArgumentException("Invalid null source inputstream.");
+ }
+
+ URL sourceURL = contribution.getArtifact(source).getLocation();
+
+ sourceURL = forceJarURL(sourceURL);
+
+ for (URL artifactURL : getArtifacts(sourceURL, inputStream)) {
+ URI artifactURI;
+
+ try {
+ artifactURI = new URI(source.toASCIIString() + "/" + FileHelper.getName(artifactURL.getPath()));
+ DeployedArtifact artifact = new DeployedArtifact(artifactURI);
+ artifact.setLocation(artifactURL);
+ contribution.addArtifact(artifact);
+
+
+ ContentTypeDescriber contentTypeDescriber = new ContentTypeDescriberImpl();
+ String contentType = contentTypeDescriber.getContentType(artifactURL, null);
+ System.out.println("Type : " + contentType);
+
+
+ //just process scdl for now
+ if ("application/v.tuscany.scdl".equals(contentType)
+ /* || "application/java-vm".equals(contentType) */) {
+ this.registry.processContent(contribution, artifactURI, artifactURL.openStream());
+ }
+ } catch (URISyntaxException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+
+
+ }
+
+ }
+
+ public void processModel(Contribution contribution, URI source, Object modelObject) throws DeploymentException,
+ IOException {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/JavaContributionProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/JavaContributionProcessor.java new file mode 100644 index 0000000000..d167ec42de --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/JavaContributionProcessor.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.core.services.deployment.contribution;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+
+import org.osoa.sca.annotations.Constructor;
+import org.osoa.sca.annotations.Reference;
+
+import org.apache.tuscany.spi.deployer.CompositeClassLoader;
+import org.apache.tuscany.spi.deployer.ContributionProcessor;
+import org.apache.tuscany.spi.extension.ContributionProcessorExtension;
+import org.apache.tuscany.spi.implementation.java.IntrospectionRegistry;
+import org.apache.tuscany.spi.model.Contribution;
+
+import org.apache.tuscany.host.deployment.DeploymentException;
+
+public class JavaContributionProcessor extends ContributionProcessorExtension implements ContributionProcessor {
+ public static final String CONTENT_TYPE = "application/java-vm";
+ //private Introspector introspector;
+
+ @Constructor
+ public JavaContributionProcessor(@Reference IntrospectionRegistry introspector) {
+ //this.introspector = introspector;
+ }
+
+ @Override
+ public String getContentType() {
+ return CONTENT_TYPE;
+ }
+
+ private String getClazzName(URL clazzURL) {
+ String clazzName;
+
+ clazzName = clazzURL.toExternalForm().substring(clazzURL.toExternalForm().lastIndexOf("!/") + 2,
+ clazzURL.toExternalForm().length() - ".class".length());
+ clazzName = clazzName.replace("/", ".");
+
+ return clazzName;
+ }
+
+
+ public void processContent(Contribution contribution, URI source, InputStream inputStream)
+ throws DeploymentException, IOException {
+ if (source == null) {
+ throw new IllegalArgumentException("Invalid null source uri.");
+ }
+
+ if (inputStream == null) {
+ throw new IllegalArgumentException("Invalid null source inputstream.");
+ }
+
+ // TODO Auto-generated method stub
+
+ //try {
+ CompositeClassLoader cl = new CompositeClassLoader(getClass().getClassLoader());
+ cl.addURL(contribution.getLocation());
+
+ String clazzName = getClazzName(contribution.getArtifact(source).getLocation());
+ System.out.println(clazzName);
+
+ //Class clazz = cl.loadClass(clazzName);
+
+// PojoComponentType javaInfo = introspector.introspect(null, clazz, null, null);
+// } catch (ClassNotFoundException cnfe) {
+// String msg = cnfe.getMessage();
+//
+// }
+// catch(ProcessingException pe){
+// String msg = pe.getMessage();
+
+
+ }
+
+ public void processModel(Contribution contribution, URI source, Object modelObject)
+ throws DeploymentException, IOException {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/ScdlContributionProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/ScdlContributionProcessor.java new file mode 100644 index 0000000000..1be4f3e2d4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/ScdlContributionProcessor.java @@ -0,0 +1,105 @@ +/*
+ * 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.core.services.deployment.contribution;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import javax.xml.stream.XMLInputFactory;
+
+import org.osoa.sca.annotations.Reference;
+
+import org.apache.tuscany.spi.deployer.CompositeClassLoader;
+import org.apache.tuscany.spi.deployer.ContributionProcessor;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.ContributionProcessorExtension;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.CompositeImplementation;
+import org.apache.tuscany.spi.model.Contribution;
+
+import org.apache.tuscany.core.deployer.RootDeploymentContext;
+import org.apache.tuscany.host.deployment.DeploymentException;
+
+public class ScdlContributionProcessor extends ContributionProcessorExtension implements ContributionProcessor {
+ public static final String CONTENT_TYPE = "application/v.tuscany.scdl";
+
+ private final LoaderRegistry registry;
+
+ private final XMLInputFactory xmlFactory;
+
+ public ScdlContributionProcessor(@Reference LoaderRegistry registry) {
+ super();
+ this.registry = registry;
+ this.xmlFactory = XMLInputFactory.newInstance("javax.xml.stream.XMLInputFactory", getClass().getClassLoader());
+ }
+
+ @Override
+ public String getContentType() {
+ return CONTENT_TYPE;
+ }
+
+
+ public void processContent(Contribution contribution, URI source, InputStream inputStream)
+ throws DeploymentException, IOException {
+ if (source == null) {
+ throw new IllegalArgumentException("Invalid null source uri.");
+ }
+
+ if (inputStream == null) {
+ throw new IllegalArgumentException("Invalid null source inputstream.");
+ }
+
+ try {
+ URI contributionId = contribution.getUri();
+ URL scdlLocation = contribution.getArtifact(source).getLocation();
+ CompositeClassLoader cl = new CompositeClassLoader(getClass().getClassLoader());
+ cl.addURL(contribution.getLocation());
+
+ DeploymentContext deploymentContext =
+ new RootDeploymentContext(cl, scdlLocation, contributionId, this.xmlFactory, null,
+ false);
+
+ CompositeComponentType componentType =
+ this.registry.load(null, scdlLocation, CompositeComponentType.class, deploymentContext);
+
+ CompositeImplementation implementation = new CompositeImplementation();
+ implementation.setComponentType(componentType);
+ ComponentDefinition<CompositeImplementation> componentDefinition =
+ new ComponentDefinition<CompositeImplementation>(implementation);
+
+ contribution.getArtifact(source).addModelObject(null, null, componentDefinition);
+
+ } catch (LoaderException le) {
+ throw new InvalidComponentDefinitionlException(contribution.getArtifact(source).getLocation()
+ .toExternalForm(), le);
+ }
+ }
+
+ public void processModel(Contribution contribution, URI source, Object modelObject) throws DeploymentException,
+ IOException {
+ // TODO Auto-generated method stub
+
+ }
+
+}
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/extension/AbstractExtensionDeployer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/extension/AbstractExtensionDeployer.java new file mode 100644 index 0000000000..37e599cc7b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/extension/AbstractExtensionDeployer.java @@ -0,0 +1,115 @@ +/* + * 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.core.services.extension; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; + +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.deployer.Deployer; + +/** + * @version $Rev$ $Date$ + */ +public class AbstractExtensionDeployer { + protected Deployer deployer; + protected Component parent; + + @Reference + public void setDeployer(Deployer deployer) { + this.deployer = deployer; + } + + protected void deployExtension(File file) { + // extension name is file name less any extension + String name = file.getName(); + int dot = name.lastIndexOf('.'); + if (dot > 0) { + name = name.substring(0, dot); + } + URL url; + try { + url = file.toURI().toURL(); + } catch (MalformedURLException e) { + // toURI should have encoded the URL + throw new AssertionError(); + } + + deployExtension(name, url); + } + + protected void deployExtension(String name, URL url) { + throw new UnsupportedOperationException(""); +// // FIXME for now, assume this class's ClassLoader is the Tuscany system classloader +// // FIXME we should really use the one associated with the parent composite +// CompositeClassLoader extensionCL = new CompositeClassLoader(getClass().getClassLoader()); +// +// // see if the URL points to a composite JAR by looking for a default SCDL file inside it +// URL scdlLocation; +// try { +// scdlLocation = new URL("jar:" + url.toExternalForm() + "!/META-INF/sca/default.scdl"); +// } catch (MalformedURLException e) { +// // the form of the jar: URL should be correct given url.toExternalForm() worked +// throw new AssertionError(); +// } +// try { +// scdlLocation.openStream().close(); +// // we connected to the SCDL so let's add the JAR file to the classloader +// extensionCL.addURL(url); +// } catch (IOException e) { +// // assume that the URL we were given is not a JAR file so just use the supplied resource +// scdlLocation = url; +// } +// +// // create a ComponentDefinition to represent the component we are going to deploy +// SystemCompositeImplementation implementation = new SystemCompositeImplementation(); +// implementation.setScdlLocation(scdlLocation); +// implementation.setClassLoader(extensionCL); +// URI uri = parent.getUri().resolve(name); +// ComponentDefinition<SystemCompositeImplementation> definition = +// new ComponentDefinition<SystemCompositeImplementation>(uri, implementation); +// +// // FIXME: [rfeng] Should we reset the thread context class loader here? +// // From the debugger with tomcat, the current TCCL is the RealmClassLoader +// // ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); +// try { +// // Thread.currentThread().setContextClassLoader(extensionCL); +// Component component; +// try { +// component = deployer.deploy(parent, definition); +// component.start(); +// } catch (BuilderException e) { +// // FIXME JFM handle the exception +// e.printStackTrace(); +// } catch (ComponentException e) { +// // FIXME handle the exception +// e.printStackTrace(); +// } catch (ResolutionException e) { +// // FIXME handle the exception +// e.printStackTrace(); +// } +// } catch (LoaderException e) { +// // FIXME handle the exception +// e.printStackTrace(); +// } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/host/DelegatingResourceHostRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/host/DelegatingResourceHostRegistry.java new file mode 100644 index 0000000000..38ce4d16d2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/host/DelegatingResourceHostRegistry.java @@ -0,0 +1,142 @@ +/* + * 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.core.services.host; + +import java.util.HashMap; +import java.util.Map; + +import org.osoa.sca.annotations.Service; + +import org.apache.tuscany.spi.host.ResourceHost; +import org.apache.tuscany.spi.host.ResourceHostRegistry; +import org.apache.tuscany.spi.host.ResourceResolutionException; + +/** + * The default implementation of a <code>ResourceRegisty</code> that resolves resources in the <code>SCA://</code> + * namespace against its parent composite and delegates resolution to registered <code>ResourceHost</code>s for other + * namespaces. The search order for resources resolved by type starts with the SCA namespace and proceeds to hosts in + * the order they were registered. + * + * @version $Rev$ $Date$ + */ +@Service(interfaces = {ResourceHost.class, ResourceHostRegistry.class}) +public class DelegatingResourceHostRegistry implements ResourceHost, ResourceHostRegistry { + private static final String SCA_PREFIX = "SCA://"; + private Map<String, ResourceHost> resourceHosts = new HashMap<String, ResourceHost>(); + private Map<Class<?>, Object> systemResources = new HashMap<Class<?>, Object>(); + private Map<Key, Object> mappedSystemResources = new HashMap<Key, Object>(); + + public DelegatingResourceHostRegistry() { + } + + public void registerResourceHost(String uri, ResourceHost host) { + resourceHosts.put(uri, host); + } + + public void unregisterResourceHost(String uri) { + resourceHosts.remove(uri); + } + + public void registerResource(Class<?> type, Object resource) { + systemResources.put(type, resource); + } + + public void registerResource(Class<?> type, String name, Object resource) { + mappedSystemResources.put(new Key(type, name), resource); + } + + public void unregisterResource(Class<?> type, String name) { + mappedSystemResources.remove(new Key(type, name)); + } + + public void unregisterResource(Class<?> type) { + systemResources.remove(type); + } + + public <T> T resolveResource(Class<T> type) throws ResourceResolutionException { + T instance = type.cast(systemResources.get(type)); + if (instance == null) { + for (ResourceHost host : resourceHosts.values()) { + instance = host.resolveResource(type); + if (instance != null) { + return instance; + } + } + } + return instance; + } + + public <T> T resolveResource(Class<T> type, String mappedName) throws ResourceResolutionException { + if (mappedName.startsWith(SCA_PREFIX)) { + String name = mappedName.substring(SCA_PREFIX.length()); + return type.cast(mappedSystemResources.get(new Key(type, name))); + } else { + int pos = mappedName.indexOf("://"); + if (pos == -1) { + return type.cast(mappedSystemResources.get(new Key(type, mappedName))); + } + String uri = mappedName.substring(0, pos + 3); + ResourceHost host = resourceHosts.get(uri); + if (host == null) { + throw new ResourceResolutionException("No resource host for URI", uri); + } + return host.resolveResource(type, mappedName); + } + } + + private class Key { + private Class<?> clazz; + private String name; + + public Key(Class<?> clazz, String name) { + this.clazz = clazz; + this.name = name; + } + + public Key(Class<?> clazz) { + this.clazz = clazz; + } + + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Key key = (Key) o; + + if (clazz != null ? !clazz.equals(key.clazz) : key.clazz != null) { + return false; + } + if (name != null ? !name.equals(key.name) : key.name != null) { + return false; + } + return true; + } + + public int hashCode() { + int result; + result = clazz != null ? clazz.hashCode() : 0; + result = 31 * result + (name != null ? name.hashCode() : 0); + return result; + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/store/memory/MemoryStore.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/store/memory/MemoryStore.java new file mode 100644 index 0000000000..a48cd5a2d7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/store/memory/MemoryStore.java @@ -0,0 +1,198 @@ +/* + * 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.core.services.store.memory; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Service; + +import org.apache.tuscany.spi.component.SCAObject; +import org.apache.tuscany.spi.event.AbstractEventPublisher; +import org.apache.tuscany.spi.services.store.DuplicateRecordException; +import org.apache.tuscany.spi.services.store.RecoveryListener; +import org.apache.tuscany.spi.services.store.Store; +import org.apache.tuscany.spi.services.store.StoreExpirationEvent; +import org.apache.tuscany.spi.services.store.StoreMonitor; +import org.apache.tuscany.spi.services.store.StoreWriteException; + +import org.apache.tuscany.api.annotation.Monitor; + +/** + * Implements a non-durable, non-transactional store using a simple in-memory map + * + * @version $Rev$ $Date$ + */ +@Service(Store.class) +@EagerInit +public class MemoryStore extends AbstractEventPublisher implements Store { + private Map<SCAObject, Map<String, Record>> store; + // TODO integrate with a core threading scheme + private ScheduledExecutorService scheduler; + private long reaperInterval = 300000; + private StoreMonitor monitor; + private long defaultExpirationOffset = 600000; // 10 minutes + + public MemoryStore(@Monitor StoreMonitor monitor) { + this.monitor = monitor; + this.store = new ConcurrentHashMap<SCAObject, Map<String, Record>>(); + this.scheduler = Executors.newSingleThreadScheduledExecutor(); + } + + /** + * Returns the maximum default expiration offset for records in the store + * + * @return the maximum default expiration offset for records in the store + */ + public long getDefaultExpirationOffset() { + return defaultExpirationOffset; + } + + /** + * Sets the maximum default expiration offset for records in the store + */ + @Property + public void setDefaultExpirationOffset(long defaultExpirationOffset) { + this.defaultExpirationOffset = defaultExpirationOffset; + } + + /** + * Sets the interval for expired entry scanning to be performed + */ + @Property + public void setReaperInterval(long reaperInterval) { + this.reaperInterval = reaperInterval; + } + + public long getReaperInterval() { + return reaperInterval; + } + + @Init + public void init() { + scheduler.scheduleWithFixedDelay(new Reaper(), reaperInterval, reaperInterval, TimeUnit.MILLISECONDS); + monitor.start("In-memory store started"); + } + + @Destroy + public void destroy() { + scheduler.shutdown(); + monitor.stop("In-memory store stopped"); + } + + public void insertRecord(SCAObject owner, String id, Object object, long expiration) throws StoreWriteException { + Map<String, Record> map = store.get(owner); + if (map == null) { + map = new ConcurrentHashMap<String, Record>(); + store.put(owner, map); + } + if (map.containsKey(id)) { + throw new DuplicateRecordException(owner.getUri().toString(), id); + } + map.put(id, new Record(object, expiration)); + } + + public void updateRecord(SCAObject owner, String id, Object object, long expiration) throws StoreWriteException { + Map<String, Record> map = store.get(owner); + if (map == null) { + throw new StoreWriteException("Record not found", owner.getUri().toString(), id); + } + Record record = map.get(id); + if (record == null) { + throw new StoreWriteException("Record not found", owner.getUri().toString(), id); + } + record.data = object; + } + + public Object readRecord(SCAObject owner, String id) { + Map<String, Record> map = store.get(owner); + if (map == null) { + return null; + } + Record record = map.get(id); + if (record != null) { + return record.data; + } + return null; + } + + public void removeRecords() { + store.clear(); + } + + public void removeRecord(SCAObject owner, String id) throws StoreWriteException { + Map<String, Record> map = store.get(owner); + if (map == null) { + throw new StoreWriteException("Owner not found", owner.getUri().toString(), id); + } + if (map.remove(id) == null) { + throw new StoreWriteException("Owner not found", owner.getUri().toString(), id); + } + } + + public void recover(RecoveryListener listener) { + throw new UnsupportedOperationException(); + } + + private class Record { + private Object data; + private long expiration = NEVER; + + public Record(Object data, long expiration) { + this.data = data; + this.expiration = expiration; + } + + public Object getData() { + return data; + } + + public long getExpiration() { + return expiration; + } + } + + private class Reaper implements Runnable { + + public void run() { + long now = System.currentTimeMillis(); + for (Map.Entry<SCAObject, Map<String, Record>> entries : store.entrySet()) { + for (Map.Entry<String, Record> entry : entries.getValue().entrySet()) { + final long expiration = entry.getValue().expiration; + if (expiration != NEVER && now >= expiration) { + SCAObject owner = entries.getKey(); + Object instance = entry.getValue().getData(); + // notify listeners of the expiration + StoreExpirationEvent event = new StoreExpirationEvent(this, owner, instance); + publish(event); + entries.getValue().remove(entry.getKey()); + } + } + } + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/work/jca/JcaWorkScheduler.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/work/jca/JcaWorkScheduler.java new file mode 100644 index 0000000000..79b7bf4ca1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/work/jca/JcaWorkScheduler.java @@ -0,0 +1,206 @@ +/* + * 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.core.services.work.jca; + +import javax.resource.spi.work.Work; +import javax.resource.spi.work.WorkEvent; +import javax.resource.spi.work.WorkException; +import javax.resource.spi.work.WorkListener; +import javax.resource.spi.work.WorkManager; +import javax.resource.spi.work.WorkRejectedException; + +import org.apache.tuscany.spi.services.work.NotificationListener; +import org.apache.tuscany.spi.services.work.WorkScheduler; +import org.apache.tuscany.spi.services.work.WorkSchedulerException; + +/** + * A work scheduler implementation based on the JCA SPI work manager. + * <p/> + * <p/> + * This needs a JCA SPI work manager implementation available for scheduling work. Instances can be configured with a + * work manager implementation that is injected in. It is the responsibility of the runtime environment to make a work + * manager implementaion available. </p> + */ +public class JcaWorkScheduler implements WorkScheduler { + + /** + * Underlying JCA work manager + */ + private WorkManager jcaWorkManager; + + /** + * Initializes the JCA work manager. + * + * @param jcaWorkManager JCA work manager. + */ + public JcaWorkScheduler(WorkManager jcaWorkManager) { + + if (jcaWorkManager == null) { + throw new IllegalArgumentException("Work manager cannot be null"); + } + this.jcaWorkManager = jcaWorkManager; + + } + + /** + * Schedules a unit of work for future execution. The notification listener is used to register interest in + * callbacks regarding the status of the work. + * + * @param work The unit of work that needs to be asynchronously executed. + */ + public <T extends Runnable> void scheduleWork(T work) { + scheduleWork(work, null); + } + + /** + * Schedules a unit of work for future execution. The notification listener is used to register interest in + * callbacks regarding the status of the work. + * + * @param work The unit of work that needs to be asynchronously executed. + * @param listener Notification listener for callbacks. + */ + public <T extends Runnable> void scheduleWork(T work, NotificationListener<T> listener) { + + if (work == null) { + throw new IllegalArgumentException("Work cannot be null"); + } + + JcaWork<T> jcaWork = new JcaWork<T>(work); + try { + if (listener == null) { + jcaWorkManager.scheduleWork(jcaWork); + } else { + JcaWorkListener<T> jcaWorkListener = new JcaWorkListener<T>(listener); + // TODO Clarify the usage of timeout and execution context + jcaWorkManager.scheduleWork(jcaWork, -1, null, jcaWorkListener); + } + } catch (WorkRejectedException ex) { + if (listener != null) { + listener.workRejected(work); + } else { + throw new WorkSchedulerException(ex); + } + } catch (WorkException ex) { + throw new WorkSchedulerException(ex); + } + + } + + /* + * Worklistener for keeping track of work status callbacks. + * + */ + private class JcaWorkListener<T extends Runnable> implements WorkListener { + + // Notification listener + private NotificationListener<T> listener; + + /* + * Initializes the notification listener. + */ + public JcaWorkListener(NotificationListener<T> listener) { + this.listener = listener; + } + + /* + * Callback when the work is accepted. + */ + public void workAccepted(WorkEvent workEvent) { + T work = getWork(workEvent); + listener.workAccepted(work); + } + + /* + * Callback when the work is rejected. + */ + public void workRejected(WorkEvent workEvent) { + T work = getWork(workEvent); + listener.workRejected(work); + } + + /* + * Callback when the work is started. + */ + public void workStarted(WorkEvent workEvent) { + T work = getWork(workEvent); + listener.workStarted(work); + } + + /* + * Callback when the work is completed. + */ + public void workCompleted(WorkEvent workEvent) { + T work = getWork(workEvent); + Exception exception = workEvent.getException(); + if (exception != null) { + listener.workFailed(work, exception); + } else { + listener.workCompleted(work); + } + } + + /* + * Gets the underlying work from the work event. + */ + @SuppressWarnings("unchecked") + private T getWork(WorkEvent workEvent) { + JcaWork<T> jcaWork = (JcaWork<T>) workEvent.getWork(); + return jcaWork.getWork(); + } + + } + + /* + * JCA work wrapper. + */ + private class JcaWork<T extends Runnable> implements Work { + + // Work that is being executed. + private T work; + + /* + * Initializes the work instance. + */ + public JcaWork(T work) { + this.work = work; + } + + /* + * Releases the work. + */ + public void release() { + } + + /* + * Performs the work. + */ + public void run() { + work.run(); + } + + /* + * Returns the completed work. + */ + public T getWork() { + return work; + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkScheduler.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkScheduler.java new file mode 100644 index 0000000000..401960c287 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkScheduler.java @@ -0,0 +1,217 @@ +/* + * 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.core.services.work.jsr237; + +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; + +import org.apache.tuscany.spi.services.work.NotificationListener; +import org.apache.tuscany.spi.services.work.WorkScheduler; +import org.apache.tuscany.spi.services.work.WorkSchedulerException; + +import commonj.work.Work; +import commonj.work.WorkEvent; +import commonj.work.WorkException; +import commonj.work.WorkListener; +import commonj.work.WorkManager; +import commonj.work.WorkRejectedException; + +/** + * A work scheduler implementation based on a JSR 237 work manager. + * <p/> + * <p/> + * This needs a JSR 237 work manager implementation available for scheduling work. Instances can be configured with a + * work manager implementation that is injected in. It is the responsibility of the runtime environment to make a work + * manager implementaion available. For example, if the managed environment supports work manager the runtime can use + * the appropriate lookup mechanism to inject the work manager implementation. </p> + */ +@Scope("COMPOSITE") +public class Jsr237WorkScheduler implements WorkScheduler { + + /** + * Underlying JSR-237 work manager + */ + private WorkManager jsr237WorkManager; + + /** + * Initializes the JSR 237 work manager. + * + * @param jsr237WorkManager JSR 237 work manager. + */ + public Jsr237WorkScheduler(@Reference WorkManager jsr237WorkManager) { + if (jsr237WorkManager == null) { + throw new IllegalArgumentException("Work manager cannot be null"); + } + this.jsr237WorkManager = jsr237WorkManager; + } + + /** + * Schedules a unit of work for future execution. The notification listener is used to register interest in + * callbacks regarding the status of the work. + * + * @param work The unit of work that needs to be asynchronously executed. + */ + public <T extends Runnable> void scheduleWork(T work) { + scheduleWork(work, null); + } + + /** + * Schedules a unit of work for future execution. The notification listener is used to register interest in + * callbacks regarding the status of the work. + * + * @param work The unit of work that needs to be asynchronously executed. + * @param listener Notification listener for callbacks. + */ + public <T extends Runnable> void scheduleWork(T work, NotificationListener<T> listener) { + + if (work == null) { + throw new IllegalArgumentException("Work cannot be null"); + } + + Jsr237Work<T> jsr237Work = new Jsr237Work<T>(work); + try { + if (listener == null) { + jsr237WorkManager.schedule(jsr237Work); + } else { + Jsr237WorkListener<T> jsr237WorkListener = new Jsr237WorkListener<T>(listener, work); + jsr237WorkManager.schedule(jsr237Work, jsr237WorkListener); + } + } catch (WorkRejectedException ex) { + if (listener != null) { + listener.workRejected(work); + } else { + throw new WorkSchedulerException(ex); + } + } catch (WorkException ex) { + throw new WorkSchedulerException(ex); + } + + } + + /* + * Worklistener for keeping track of work status callbacks. + * + */ + private class Jsr237WorkListener<T extends Runnable> implements WorkListener { + + // Notification listener + private NotificationListener<T> listener; + + // Work + private T work; + + /* + * Initializes the notification listener. + */ + public Jsr237WorkListener(NotificationListener<T> listener, T work) { + this.listener = listener; + this.work = work; + } + + /* + * Callback when the work is accepted. + */ + public void workAccepted(WorkEvent workEvent) { + T work = getWork(); + listener.workAccepted(work); + } + + /* + * Callback when the work is rejected. + */ + public void workRejected(WorkEvent workEvent) { + T work = getWork(); + listener.workRejected(work); + } + + /* + * Callback when the work is started. + */ + public void workStarted(WorkEvent workEvent) { + T work = getWork(); + listener.workStarted(work); + } + + /* + * Callback when the work is completed. + */ + public void workCompleted(WorkEvent workEvent) { + T work = getWork(); + Exception exception = workEvent.getException(); + if (exception != null) { + listener.workFailed(work, exception); + } else { + listener.workCompleted(work); + } + } + + /* + * Gets the underlying work from the work event. + */ + private T getWork() { + return work; + } + + } + + /* + * JCA work wrapper. + */ + private class Jsr237Work<T extends Runnable> implements Work { + + // Work that is being executed. + private T work; + + /* + * Initializes the work instance. + */ + public Jsr237Work(T work) { + this.work = work; + } + + /* + * Returns the completed work. + */ + public T getWork() { + return work; + } + + /* + * Release the work. + */ + public void release() { + } + + /* + * Work attributes are not daemon. + */ + public boolean isDaemon() { + return false; + } + + /* + * Runs the work. + */ + public void run() { + work.run(); + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/DefaultWorkEvent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/DefaultWorkEvent.java new file mode 100644 index 0000000000..c391d0b597 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/DefaultWorkEvent.java @@ -0,0 +1,73 @@ +/* + * 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.core.services.work.jsr237.workmanager; + +import commonj.work.WorkEvent; +import commonj.work.WorkException; +import commonj.work.WorkItem; + +/** + * Default immutable implementation of the <code>WorkEvent</code> class. + */ +class DefaultWorkEvent implements WorkEvent { + + // Work item for this event + private WorkItem workItem; + + // Exception if something has gone wrong + private WorkException exception; + + /** + * Instantiates the event. + * + * @param workItem Work item for this event. + */ + public DefaultWorkEvent(final DefaultWorkItem workItem) { + this.workItem = workItem; + this.exception = workItem.getException(); + } + + /** + * Returns the work type based on whether the work was accepted, started, + * rejected or completed. + * + * @return Work type. + */ + public int getType() { + return workItem.getStatus(); + } + + /** + * Returns the work item associated with this work type. + * + * @return Work item. + */ + public WorkItem getWorkItem() { + return workItem; + } + + /** + * Returns the exception if the work completed with an exception. + * + * @return Work exception. + */ + public WorkException getException() { + return exception; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/DefaultWorkItem.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/DefaultWorkItem.java new file mode 100644 index 0000000000..0adc005bb0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/DefaultWorkItem.java @@ -0,0 +1,166 @@ +/* + * 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.core.services.work.jsr237.workmanager; + +import commonj.work.Work; +import commonj.work.WorkException; +import commonj.work.WorkItem; + +/** + * An identity based immutable implementation of the <code>WorkItem</code> + * interface. + * + */ +class DefaultWorkItem implements WorkItem { + + // Id scoped for the VM + private String id; + + // Status + private int status = -1; + + // Result + private Work result; + + // Original work + private Work originalWork; + + // Exception + private WorkException exception; + + /** + * Instantiates an id for this item. + * + * @param id of this work event. + */ + protected DefaultWorkItem(final String id, final Work orginalWork) { + this.id = id; + this.originalWork = orginalWork; + } + + /** + * Returns the id. + * + * @return Id of this item. + */ + public String getId() { + return id; + } + + /** + * Returns the original work. + * + * @return Original work. + */ + public Work getOriginalWork() { + return originalWork; + } + + /** + * Returns the work result if the work completed. + * + * @return Work. + * @throws WorkException If the work completed with an exception. + */ + public Work getResult() throws WorkException { + return result; + } + + /** + * Sets the result. + * + * @param result Result. + */ + protected void setResult(final Work result) { + this.result = result; + } + + /** + * Returns the exception if work completed with an exception. + * + * @return Work exception. + */ + protected WorkException getException() { + return exception; + } + + /** + * Sets the exception. + * + * @param exception Exception. + */ + protected void setException(final WorkException exception) { + this.exception = exception; + } + + /** + * Returns the work type based on whether the work was accepted, started, + * rejected or completed. + * + * @return Work status. + */ + public int getStatus() { + return status; + } + + /** + * Sets the status. + * + * @param status Status. + */ + protected void setStatus(final int status) { + this.status = status; + } + + /** + * @see Object#hashCode() + */ + public int hashCode() { + return id.hashCode(); + } + + /** + * Indicates whether some other object is "equal to" this one. + * + * @param obj Object to be compared. + * @return true if this object is the same as the obj argument; false + * otherwise.. + */ + public boolean equals(final Object obj) { + return (obj != null) && (obj.getClass() == DefaultWorkItem.class) && ((DefaultWorkItem) obj).id.equals(id); + } + + /** + * Compares this object with the specified object for order. Returns a + * negative integer, zero, or a positive integer as this object is less + * than, equal to, or greater than the specified object. + * + * @param o Object to be compared. + * @return A negative integer, zero, or a positive integer as this object + * is less than, equal to, or greater than the specified object. + * @throws ClassCastException needs better documentation. + */ + public int compareTo(final Object o) { + if (o.getClass() != DefaultWorkItem.class) { + throw new ClassCastException(o.getClass().getName()); + } else { + return ((DefaultWorkItem) o).getId().compareTo(getId()); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/ThreadPoolWorkManager.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/ThreadPoolWorkManager.java new file mode 100644 index 0000000000..1a7639b41d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/ThreadPoolWorkManager.java @@ -0,0 +1,220 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.services.work.jsr237.workmanager; + +import java.rmi.server.UID; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionException; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Property; + +import commonj.work.Work; +import commonj.work.WorkEvent; +import commonj.work.WorkException; +import commonj.work.WorkItem; +import commonj.work.WorkListener; +import commonj.work.WorkManager; +import commonj.work.WorkRejectedException; + +/** + * A thread-pool based implementation for the JSR-237 work manager. + * <p/> + * <p/> + * This implementation supports only local work. + * <p/> + * TODO Elaborate the implementation. </p> + */ +public class ThreadPoolWorkManager implements WorkManager { + + // Map of work items currently handled by the work manager + private Map<DefaultWorkItem, WorkListener> workItems = new ConcurrentHashMap<DefaultWorkItem, WorkListener>(); + + // Thread-pool + private ExecutorService executor; + + /** + * Initializes the thread-pool. + * + * @param threadPoolSize Thread-pool size. + */ + public ThreadPoolWorkManager(@Property(name = "poolSize") int threadPoolSize) { + executor = Executors.newFixedThreadPool(threadPoolSize); + } + + /** + * Schedules a unit of work asynchronously. + * + * @param work Work that needs to be scheduled. + * @return Work Work item representing the asynchronous work + */ + public WorkItem schedule(Work work) throws WorkException { + return schedule(work, null); + } + + /** + * Schedules a unit of work asynchronously. + * + * @param work Work that needs to be scheduled. + * @param workListener Work listener for callbacks. + * @return Work Work item representing the asynchronous work + */ + public WorkItem schedule(Work work, WorkListener workListener) throws WorkRejectedException { + + DefaultWorkItem workItem = new DefaultWorkItem(new UID().toString(), work); + if (workListener != null) { + workItems.put(workItem, workListener); + } + workAccepted(workItem, work); + if (scheduleWork(work, workItem)) { + return workItem; + } else { + workItem.setStatus(WorkEvent.WORK_REJECTED); + if (workListener != null) { + workListener.workRejected(new DefaultWorkEvent(workItem)); + } + throw new WorkRejectedException("Unable to schedule work"); + } + } + + /** + * Wait for all the specified units of work to finish. + * + * @param works Units of the work that need to finish. + * @param timeout Timeout for waiting for the units of work to finish. + */ + public boolean waitForAll(Collection works, long timeout) { + throw new UnsupportedOperationException("waitForAll not supported"); + } + + /** + * Wait for any of the specified units of work to finish. + * + * @param works Units of the work that need to finish. + * @param timeout Timeout for waiting for the units of work to finish. + */ + public Collection waitForAny(Collection works, long timeout) { + throw new UnsupportedOperationException("waitForAny not supported"); + } + + /** + * Method provided for subclasses to indicate a work accptance. + * + * @param workItem Work item representing the work that was accepted. + * @param work Work that was accepted. + */ + private void workAccepted(final DefaultWorkItem workItem, final Work work) { + WorkListener listener = workItems.get(workItem); + if (listener != null) { + workItem.setStatus(WorkEvent.WORK_ACCEPTED); + WorkEvent event = new DefaultWorkEvent(workItem); + listener.workAccepted(event); + } + } + + /* + * Method to indicate a work start. + */ + private void workStarted(final DefaultWorkItem workItem, final Work work) { + WorkListener listener = workItems.get(workItem); + if (listener != null) { + workItem.setStatus(WorkEvent.WORK_STARTED); + WorkEvent event = new DefaultWorkEvent(workItem); + listener.workStarted(event); + } + } + + /* + * Method to indicate a work completion. + */ + private void workCompleted(final DefaultWorkItem workItem, final Work work) { + workCompleted(workItem, work, null); + } + + /* + * Method to indicate a work completion. + */ + private void workCompleted(final DefaultWorkItem workItem, final Work work, final WorkException exception) { + WorkListener listener = workItems.get(workItem); + if (listener != null) { + workItem.setStatus(WorkEvent.WORK_COMPLETED); + workItem.setResult(work); + workItem.setException(exception); + WorkEvent event = new DefaultWorkEvent(workItem); + listener.workCompleted(event); + workItems.remove(workItem); + } + } + + /* + * Schedules the work using the threadpool. + */ + private boolean scheduleWork(final Work work, final DefaultWorkItem workItem) { + try { + executor.execute(new DecoratingWork(workItem, work)); + return true; + } catch (RejectedExecutionException ex) { + return false; + } + } + + /* + * Class that decorates the original worker so that it can get callbacks when work is done. + */ + private final class DecoratingWork implements Runnable { + + // Work item for this work. + private DefaultWorkItem workItem; + + // The original work. + private Work decoratedWork; + + /* + * Initializes the work item and underlying work. + */ + private DecoratingWork(final DefaultWorkItem workItem, final Work decoratedWork) { + this.workItem = workItem; + this.decoratedWork = decoratedWork; + } + + /* + * Overrides the run method. + */ + public void run() { + workStarted(workItem, decoratedWork); + try { + decoratedWork.run(); + workCompleted(workItem, decoratedWork); + } catch (Throwable th) { + workCompleted(workItem, decoratedWork, new WorkException(th.getMessage(), th)); + } + } + + } + + @Destroy + public void destroy() { + executor.shutdown(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/util/FileHelper.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/util/FileHelper.java new file mode 100644 index 0000000000..e79ea7a74a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/util/FileHelper.java @@ -0,0 +1,285 @@ +/*
+ * 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.core.util;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URL;
+
+public class FileHelper {
+ /**
+ * The extension separator character.
+ */
+ private static final char EXTENSION_SEPARATOR = '.';
+
+ /**
+ * The Unix separator character.
+ */
+ private static final char UNIX_SEPARATOR = '/';
+
+ /**
+ * The Windows separator character.
+ */
+ private static final char WINDOWS_SEPARATOR = '\\';
+
+ protected FileHelper() {
+
+ }
+ /**
+ * Returns the index of the last directory separator character.
+ * <p>
+ * This method will handle a file in either Unix or Windows format.
+ * The position of the last forward or backslash is returned.
+ * <p>
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
+ * @param filename the filename to find the last path separator in, null returns -1
+ * @return the index of the last separator character, or -1 if there
+ * is no such character
+ */
+ public static int indexOfLastSeparator(String filename) {
+ if (filename == null) {
+ return -1;
+ }
+ int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR);
+ int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR);
+ return Math.max(lastUnixPos, lastWindowsPos);
+ }
+
+ /**
+ * Returns the index of the last extension separator character, which is a dot.
+ * <p>
+ * This method also checks that there is no directory separator after the last dot.
+ * To do this it uses {@link #indexOfLastSeparator(String)} which will
+ * handle a file in either Unix or Windows format.
+ * <p>
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
+ * @param filename the filename to find the last path separator in, null returns -1
+ * @return the index of the last separator character, or -1 if there
+ * is no such character
+ */
+ public static int indexOfExtension(String filename) {
+ if (filename == null) {
+ return -1;
+ }
+ int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR);
+ int lastSeparator = indexOfLastSeparator(filename);
+ return lastSeparator > extensionPos ? -1 : extensionPos;
+ }
+
+ /**
+ * Gets the name minus the path from a full filename.
+ * <p>
+ * This method will handle a file in either Unix or Windows format.
+ * The text after the last forward or backslash is returned.
+ * <pre>
+ * a/b/c.txt --> c.txt
+ * a.txt --> a.txt
+ * a/b/c --> c
+ * a/b/c/ --> ""
+ * </pre>
+ * <p>
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
+ * @param fileName the filename to query, null returns null
+ * @return the name of the file without the path, or an empty string if none exists
+ */
+ public static String getName(String fileName) {
+ if (fileName == null) {
+ return null;
+ }
+ int index = indexOfLastSeparator(fileName);
+ return fileName.substring(index + 1);
+ }
+
+ /**
+ * Gets the extension of a filename.
+ * <p>
+ * This method returns the textual part of the filename after the last dot.
+ * There must be no directory separator after the dot.
+ * <pre>
+ * foo.txt --> "txt"
+ * a/b/c.jpg --> "jpg"
+ * a/b.txt/c --> ""
+ * a/b/c --> ""
+ * </pre>
+ * <p>
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
+ * @param filename the filename to retrieve the extension of.
+ * @return the extension of the file or an empty string if none exists.
+ */
+ public static String getExtension(String filename) {
+ if (filename == null) {
+ return null;
+ }
+ int index = indexOfExtension(filename);
+ if (index == -1) {
+ return "";
+ } else {
+ return filename.substring(index + 1);
+ }
+ }
+
+ /**
+ * Make a directory, including any necessary but nonexistent parent
+ * directories. If there already exists a file with specified name or
+ * the directory cannot be created then an exception is thrown.
+ *
+ * @param directory directory to create, not null
+ * @throws NullPointerException if the directory is null
+ * @throws IOException if the directory cannot be created
+ */
+ public static void forceMkdir(File directory) throws IOException {
+ if (directory.exists()) {
+ if (directory.isFile()) {
+ String message =
+ "File "
+ + directory
+ + " exists and is "
+ + "not a directory. Unable to create directory.";
+ throw new IOException(message);
+ }
+ } else {
+ if (!directory.mkdirs()) {
+ String message =
+ "Unable to create directory " + directory;
+ throw new IOException(message);
+ }
+ }
+ }
+
+ /**
+ * Delete a file. If file is a directory, delete it and all sub-directories.
+ * <p>
+ * The difference between File.delete() and this method are:
+ * <ul>
+ * <li>A directory to be deleted does not have to be empty.</li>
+ * <li>You get exceptions when a file or directory cannot be deleted.
+ * (java.io.File methods returns a boolean)</li>
+ * </ul>
+ *
+ * @param file file or directory to delete, not null
+ * @throws NullPointerException if the directory is null
+ * @throws IOException in case deletion is unsuccessful
+ */
+ public static void forceDelete(File file) throws IOException {
+ if (file.isDirectory()) {
+ deleteDirectory(file);
+ } else {
+ if (!file.exists()) {
+ throw new FileNotFoundException("File does not exist: " + file);
+ }
+ if (!file.delete()) {
+ String message =
+ "Unable to delete file: " + file;
+ throw new IOException(message);
+ }
+ }
+ }
+
+ /**
+ * Recursively delete a directory.
+ *
+ * @param directory directory to delete
+ * @throws IOException in case deletion is unsuccessful
+ */
+ public static void deleteDirectory(File directory)
+ throws IOException {
+ if (!directory.exists()) {
+ return;
+ }
+
+ cleanDirectory(directory);
+ if (!directory.delete()) {
+ String message =
+ "Unable to delete directory " + directory + ".";
+ throw new IOException(message);
+ }
+ }
+
+ /**
+ * Clean a directory without deleting it.
+ *
+ * @param directory directory to clean
+ * @throws IOException in case cleaning is unsuccessful
+ */
+ public static void cleanDirectory(File directory) throws IOException {
+ if (!directory.exists()) {
+ String message = directory + " does not exist";
+ throw new IllegalArgumentException(message);
+ }
+
+ if (!directory.isDirectory()) {
+ String message = directory + " is not a directory";
+ throw new IllegalArgumentException(message);
+ }
+
+ File[] files = directory.listFiles();
+ if (files == null) { // null if security restricted
+ throw new IOException("Failed to list contents of " + directory);
+ }
+
+ IOException exception = null;
+ for (int i = 0; i < files.length; i++) {
+ File file = files[i];
+ try {
+ forceDelete(file);
+ } catch (IOException ioe) {
+ exception = ioe;
+ }
+ }
+
+ if (null != exception) {
+ throw exception;
+ }
+ }
+
+ /**
+ * Convert from a <code>URL</code> to a <code>File</code>.
+ * <p>
+ * From version 1.1 this method will decode the URL.
+ * Syntax such as <code>file:///my%20docs/file.txt</code> will be
+ * correctly decoded to <code>/my docs/file.txt</code>.
+ *
+ * @param url the file URL to convert, null returns null
+ * @return the equivalent <code>File</code> object, or <code>null</code>
+ * if the URL's protocol is not <code>file</code>
+ * @throws IllegalArgumentException if the file is incorrectly encoded
+ */
+ public static File toFile(URL url) {
+ if (url == null || !url.getProtocol().equals("file")) {
+ return null;
+ } else {
+ String filename = url.getFile().replace('/', File.separatorChar);
+ int pos = 0;
+ while ((pos = filename.indexOf('%', pos)) >= 0) { // NOPMD
+ if (pos + 2 < filename.length()) {
+ String hexStr = filename.substring(pos + 1, pos + 3);
+ char ch = (char) Integer.parseInt(hexStr, 16);
+ filename = filename.substring(0, pos) + ch + filename.substring(pos + 3);
+ }
+ }
+ return new File(filename);
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/util/IOHelper.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/util/IOHelper.java new file mode 100644 index 0000000000..bb504ef57e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/util/IOHelper.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.core.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class IOHelper {
+ /**
+ * The default buffer size to use.
+ */
+ private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
+
+ protected IOHelper() {
+
+ }
+
+ /**
+ * Unconditionally close an <code>InputStream</code>.
+ * <p/>
+ * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored. This is typically used in
+ * finally blocks.
+ *
+ * @param input the InputStream to close, may be null or already closed
+ */
+ public static void closeQuietly(InputStream input) {
+ try {
+ if (input != null) {
+ input.close();
+ }
+ } catch (IOException ioe) {
+ // ignore
+ }
+ }
+
+ /**
+ * Unconditionally close an <code>OutputStream</code>.
+ * <p/>
+ * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored. This is typically used in
+ * finally blocks.
+ *
+ * @param output the OutputStream to close, may be null or already closed
+ */
+ public static void closeQuietly(OutputStream output) {
+ try {
+ if (output != null) {
+ output.close();
+ }
+ } catch (IOException ioe) {
+ // ignore
+ }
+ }
+
+ /**
+ * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>.
+ * <p/>
+ * This method buffers the input internally, so there is no need to use a <code>BufferedInputStream</code>.
+ *
+ * @param input the <code>InputStream</code> to read from
+ * @param output the <code>OutputStream</code> to write to
+ * @return the number of bytes copied
+ * @throws NullPointerException if the input or output is null
+ * @throws IOException if an I/O error occurs
+ * @since Commons IO 1.1
+ */
+ public static int copy(InputStream input, OutputStream output) throws IOException {
+ byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
+ int count = 0;
+ int n = 0;
+ while (-1 != (n = input.read(buffer))) { //NOPMD
+ output.write(buffer, 0, n);
+ count += n;
+ }
+ return count;
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/util/JavaIntrospectionHelper.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/util/JavaIntrospectionHelper.java new file mode 100644 index 0000000000..6b11725481 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/util/JavaIntrospectionHelper.java @@ -0,0 +1,439 @@ +/* + * 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.core.util; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Implements various reflection-related operations + * + * @version $Rev$ $Date$ + */ +public final class JavaIntrospectionHelper { + + private static final Class[] EMPTY_CLASS_ARRY = new Class[0]; + + /** + * Hide the constructor + */ + private JavaIntrospectionHelper() { + } + + + /** + * Returns a collection of public, and protected fields declared by a class or one of its supertypes + */ + public static Set<Field> getAllPublicAndProtectedFields(Class clazz) { + return getAllPublicAndProtectedFields(clazz, new HashSet<Field>()); + } + + /** + * Recursively evaluates the type hierachy to return all fields that are public or protected + */ + private static Set<Field> getAllPublicAndProtectedFields(Class clazz, Set<Field> fields) { + if (clazz == null || clazz.isArray() || Object.class.equals(clazz)) { + return fields; + } + fields = getAllPublicAndProtectedFields(clazz.getSuperclass(), fields); + Field[] declaredFields = clazz.getDeclaredFields(); + for (Field field : declaredFields) { + int modifiers = field.getModifiers(); + if ((Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)) && !Modifier.isStatic(modifiers)) { + field.setAccessible(true); // ignore Java accessibility + fields.add(field); + } + } + return fields; + } + + /** + * Returns a collection of public and protected methods declared by a class or one of its supertypes. Note that + * overriden methods will not be returned in the collection (i.e. only the method override will be). <p/> This + * method can potentially be expensive as reflection information is not cached. It is assumed that this method will + * be used during a configuration phase. + */ + public static Set<Method> getAllUniquePublicProtectedMethods(Class clazz) { + return getAllUniqueMethods(clazz, new HashSet<Method>()); + } + + /** + * Recursively evaluates the type hierarchy to return all unique methods + */ + private static Set<Method> getAllUniqueMethods(Class pClass, Set<Method> methods) { + if (pClass == null || pClass.isArray() || Object.class.equals(pClass)) { + return methods; + } + // we first evaluate methods of the subclass and then move to the parent + Method[] declaredMethods = pClass.getDeclaredMethods(); + for (Method declaredMethod : declaredMethods) { + int modifiers = declaredMethod.getModifiers(); + if ((!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers)) || Modifier.isStatic(modifiers)) { + continue; + } + if (methods.size() == 0) { + methods.add(declaredMethod); + } else { + List<Method> temp = new ArrayList<Method>(); + boolean matched = false; + for (Method method : methods) { + // only add if not already in the set from a supclass (i.e. the + // method is not overrided) + if (exactMethodMatch(declaredMethod, method)) { + matched = true; + break; + } + } + if (!matched) { + // TODO ignore Java accessibility + declaredMethod.setAccessible(true); + temp.add(declaredMethod); + } + methods.addAll(temp); + temp.clear(); + } + } + // evaluate class hierarchy - this is done last to track inherited methods + methods = getAllUniqueMethods(pClass.getSuperclass(), methods); + return methods; + } + + /** + * Finds the closest matching field with the given name, that is, a field of the exact specified type or, + * alternately, of a supertype. + * + * @param name the name of the field + * @param type the field type + * @param fields the collection of fields to search + * @return the matching field or null if not found + */ + public static Field findClosestMatchingField(String name, Class type, Set<Field> fields) { + Field candidate = null; + for (Field field : fields) { + if (field.getName().equals(name)) { + if (field.getType().equals(type)) { + return field; // exact match + } else if (field.getType().isAssignableFrom(type) + || (field.getType().isPrimitive() && primitiveAssignable(field.getType(), type))) { + // We could have the situation where a field parameter is a primitive and the demarshalled value is + // an object counterpart (e.g. Integer and int) + // @spec issue + // either an interface or super class, so keep a reference until + // we know there are no closer types + candidate = field; + } + } + } + if (candidate != null) { + return candidate; + } else { + return null; + } + } + + /** + * Finds the closest matching method with the given name, that is, a method taking the exact parameter types or, + * alternately, parameter supertypes. + * + * @param name the name of the method + * @param types the method parameter types + * @param methods the collection of methods to search + * @return the matching method or null if not found + */ + public static Method findClosestMatchingMethod(String name, Class[] types, Set<Method> methods) { + if (types == null) { + types = EMPTY_CLASS_ARRY; + } + Method candidate = null; + for (Method method : methods) { + if (method.getName().equals(name) && method.getParameterTypes().length == types.length) { + Class<?>[] params = method.getParameterTypes(); + boolean disqualify = false; + boolean exactMatch = true; + for (int i = 0; i < params.length; i++) { + if (!params[i].equals(types[i]) && !params[i].isAssignableFrom(types[i])) { + // no match + disqualify = true; + exactMatch = false; + break; + } else if (!params[i].equals(types[i]) && params[i].isAssignableFrom(types[i])) { + // not exact match + exactMatch = false; + } + } + if (disqualify) { + continue; + } else if (exactMatch) { + return method; + } else { + candidate = method; + } + } + } + if (candidate != null) { + return candidate; + } else { + return null; + } + } + + /** + * Searches a collection of fields for one that matches by name and has a multiplicity type. i.e. a List or Array of + * interfaces + * + * @return a matching field or null + */ + public static Field findMultiplicityFieldByName(String name, Set<Field> fields) { + for (Field candidate : fields) { + if (candidate.getName().equals(name) + && (List.class.isAssignableFrom(candidate.getType()) || (candidate.getType().isArray() + && candidate.getType().getComponentType() != null && candidate.getType().getComponentType() + .isInterface()))) { + return candidate; + } + } + return null; + } + + /** + * Searches a collection of method for one that matches by name and has single parameter of a multiplicity type. + * i.e. a List or Array of interfaces + * + * @return a matching method or null + */ + public static Method findMultiplicityMethodByName(String name, Set<Method> methods) { + for (Method candidate : methods) { + if (candidate.getName().equals(name) + && candidate.getParameterTypes().length == 1 + && (List.class.isAssignableFrom(candidate.getParameterTypes()[0]) + || (candidate.getParameterTypes()[0].isArray() + && candidate.getParameterTypes()[0].getComponentType() != null + && candidate.getParameterTypes()[0].getComponentType().isInterface()))) { + return candidate; + } + } + return null; + } + + /** + * Determines if two methods "match" - that is, they have the same method names and exact parameter types (one is + * not a supertype of the other) + */ + public static boolean exactMethodMatch(Method method1, Method method2) { + if (!method1.getName().equals(method2.getName())) { + return false; + } + Class[] types1 = method1.getParameterTypes(); + Class[] types2 = method2.getParameterTypes(); + if (types1.length == 0 && types2.length == 0) { + return true; + } else if (types1.length == types2.length) { + for (int n = 0; n < types1.length; n++) { + if (!types1[n].equals(types2[n])) { + return false; + } + } + return true; + } + return false; + } + + public static <T> Constructor<T> getDefaultConstructor(Class<T> clazz) throws NoSuchMethodException { + return clazz.getConstructor((Class[]) null); + } + + /** + * Loads a class corresponding to the class name using the current context class loader. + * + * @throws ClassNotFoundException if the class was not found on the classpath + */ + public static Class loadClass(String pName) throws ClassNotFoundException { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + return Class.forName(pName, true, loader); + } + + /** + * Returns the simple name of a class - i.e. the class name devoid of its package qualifier + * + * @param implClass the implmentation class + */ + public static String getBaseName(Class<?> implClass) { + String baseName = implClass.getName(); + int lastDot = baseName.lastIndexOf('.'); + if (lastDot != -1) { + baseName = baseName.substring(lastDot + 1); + } + return baseName; + } + + public static boolean isImmutable(Class clazz) { + return String.class == clazz + || clazz.isPrimitive() + || Number.class.isAssignableFrom(clazz) + || Boolean.class.isAssignableFrom(clazz) + || Character.class.isAssignableFrom(clazz) + || Byte.class.isAssignableFrom(clazz); + } + + /** + * Takes a property name and converts it to a getter method name according to JavaBean conventions. For example, + * property <code>foo<code> is returned as <code>getFoo</code> + */ + public static String toGetter(String name) { + return "get" + name.toUpperCase().substring(0, 1) + name.substring(1); + } + + /** + * Takes a setter or getter method name and converts it to a property name according to JavaBean conventions. For + * example, <code>setFoo(var)</code> is returned as property <code>foo<code> + */ + public static String toPropertyName(String name) { + if (!name.startsWith("set")) { + return name; + } + return Character.toLowerCase(name.charAt(3)) + name.substring(4); + } + + /** + * Takes a property name and converts it to a setter method name according to JavaBean conventions. For example, the + * property <code>foo<code> is returned as <code>setFoo(var)</code> + */ + public static String toSetter(String name) { + return "set" + name.toUpperCase().substring(0, 1) + name.substring(1); + } + + /** + * Compares a two types, assuming one is a primitive, to determine if the other is its object counterpart + */ + private static boolean primitiveAssignable(Class memberType, Class param) { + if (memberType == Integer.class) { + return param == Integer.TYPE; + } else if (memberType == Double.class) { + return param == Double.TYPE; + } else if (memberType == Float.class) { + return param == Float.TYPE; + } else if (memberType == Short.class) { + return param == Short.TYPE; + } else if (memberType == Character.class) { + return param == Character.TYPE; + } else if (memberType == Boolean.class) { + return param == Boolean.TYPE; + } else if (memberType == Byte.class) { + return param == Byte.TYPE; + } else if (param == Integer.class) { + return memberType == Integer.TYPE; + } else if (param == Double.class) { + return memberType == Double.TYPE; + } else if (param == Float.class) { + return memberType == Float.TYPE; + } else if (param == Short.class) { + return memberType == Short.TYPE; + } else if (param == Character.class) { + return memberType == Character.TYPE; + } else if (param == Boolean.class) { + return memberType == Boolean.TYPE; + } else if (param == Byte.class) { + return memberType == Byte.TYPE; + } else { + return false; + } + } + + /** + * Returns the generic types represented in the given type. Usage as follows: <code> + * JavaIntrospectionHelper.getGenerics(field.getGenericType()); + * <p/> + * JavaIntrospectionHelper.getGenerics(m.getGenericParameterTypes()[0];); </code> + * + * @return the generic types in order of declaration or an empty array if the type is not genericized + */ + public static List<? extends Type> getGenerics(Type genericType) { + List<Type> classes = new ArrayList<Type>(); + if (genericType instanceof ParameterizedType) { + ParameterizedType ptype = (ParameterizedType) genericType; + // get the type arguments + Type[] targs = ptype.getActualTypeArguments(); + for (Type targ : targs) { + classes.add(targ); + } + } + return classes; + } + + /** + * Returns the generic type specified by the class at the given position as in: + * <p/> + * <code> public class Foo<Bar,Baz>{ //.. } + * <p/> + * JavaIntrospectionHelper.introspectGeneric(Foo.class,1); <code> + * <p/> + * will return Baz. + */ + public static Class introspectGeneric(Class<?> clazz, int pos) { + assert clazz != null : "No class specified"; + Type type = clazz.getGenericSuperclass(); + if (type instanceof ParameterizedType) { + Type[] args = ((ParameterizedType) type).getActualTypeArguments(); + if (args.length <= pos) { + throw new IllegalArgumentException("Invalid index value for generic class " + clazz.getName()); + } + return (Class) ((ParameterizedType) type).getActualTypeArguments()[pos]; + } else { + Type[] interfaces = clazz.getGenericInterfaces(); + for (Type itype : interfaces) { + if (!(itype instanceof ParameterizedType)) { + continue; + } + ParameterizedType interfaceType = (ParameterizedType) itype; + return (Class) interfaceType.getActualTypeArguments()[0]; + } + } + return null; + } + + /** + * Returns the set of interfaces implemented by the given class and its ancestors or a blank set if none + */ + public static Set<Class> getAllInterfaces(Class clazz) { + Set<Class> implemented = new HashSet<Class>(); + getAllInterfaces(clazz, implemented); + return implemented; + } + + private static void getAllInterfaces(Class clazz, Set<Class> implemented) { + Class[] interfaces = clazz.getInterfaces(); + for (Class interfaze : interfaces) { + implemented.add(interfaze); + } + Class<?> superClass = clazz.getSuperclass(); + // Object has no superclass so check for null + if (superClass != null && !superClass.equals(Object.class)) { + getAllInterfaces(superClass, implemented); + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/CallbackInterfaceInterceptor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/CallbackInterfaceInterceptor.java new file mode 100644 index 0000000000..c0bf7780f5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/CallbackInterfaceInterceptor.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.wire; + +import org.osoa.sca.NoRegisteredCallbackException; + +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.Message; + +/** + * An interceptor applied to the forward direction of a wire that ensures the callback target implements the required + * service contract. This is required as callback targets may be set dynamically by service implementations. + * + * @version $Rev$ $Date$ + */ +public class CallbackInterfaceInterceptor implements Interceptor { + private boolean invokingServiceImplements; + private Interceptor next; + + public CallbackInterfaceInterceptor(boolean invokingServiceImplements) { + this.invokingServiceImplements = invokingServiceImplements; + } + + public Message invoke(Message msg) { + // TODO check in the context if a callback object is set, if so invoke next since the setCallback will + // perform the check + if (!invokingServiceImplements) { + throw new NoRegisteredCallbackException("Callback target does not implement the callback interface"); + } + return next.invoke(msg); + } + + public void setNext(Interceptor next) { + this.next = next; + } + + public Interceptor getNext() { + return next; + } + + public boolean isOptimizable() { + return false; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/IncompatibleServiceContractExceptionFormatter.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/IncompatibleServiceContractExceptionFormatter.java new file mode 100644 index 0000000000..d5fca62e1b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/IncompatibleServiceContractExceptionFormatter.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.core.wire; + +import java.io.PrintWriter; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.IncompatibleServiceContractException; + +import org.apache.tuscany.host.monitor.ExceptionFormatter; +import org.apache.tuscany.host.monitor.FormatterRegistry; + +/** + * Formats {@link org.apache.tuscany.spi.wire.IncompatibleServiceContractException} for JDK logging + * + * @version $Rev$ $Date$ + */ +@EagerInit +public class IncompatibleServiceContractExceptionFormatter implements ExceptionFormatter { + private FormatterRegistry factory; + + public IncompatibleServiceContractExceptionFormatter(@Reference FormatterRegistry factory) { + this.factory = factory; + factory.register(this); + } + + public boolean canFormat(Class<?> type) { + return IncompatibleServiceContractException.class.isAssignableFrom(type); + } + + @Destroy + public void destroy() { + factory.unregister(this); + } + + public PrintWriter write(PrintWriter writer, Throwable exception) { + assert exception instanceof IncompatibleServiceContractException; + IncompatibleServiceContractException e = (IncompatibleServiceContractException) exception; + e.appendBaseMessage(writer); + ServiceContract<?> source = e.getSource(); + String sourceContractName = null; + if (source != null) { + sourceContractName = source.getInterfaceName(); + } + Operation<?> sourceOperation = e.getSourceOperation(); + String sourceOpName = null; + if (sourceOperation != null) { + sourceOpName = sourceOperation.getName(); + } + if (sourceOpName == null) { + writer.write("\nSource Contract: " + sourceContractName); + } else { + writer.write("\nSource Contract: " + sourceContractName + "/" + sourceOpName); + } + ServiceContract<?> target = e.getTarget(); + String targetContractName = null; + if (target != null) { + targetContractName = target.getInterfaceName(); + } + Operation<?> targetOperation = e.getTargetOperation(); + String targetOpName = null; + if (targetOperation != null) { + targetOpName = targetOperation.getName(); + } + if (targetOpName == null) { + writer.write("\nTarget Contract: " + targetContractName + "\n"); + } else { + writer.write("\nTarget Contract: " + targetContractName + "/" + targetOpName + "\n"); + + } + return writer; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/InvocationChainImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/InvocationChainImpl.java new file mode 100644 index 0000000000..d2e6ec504f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/InvocationChainImpl.java @@ -0,0 +1,95 @@ +/* + * 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.core.wire; + +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.model.Operation; + +/** + * Default implementation of an invocation chain + * + * @version $Rev$ $Date$ + */ +public class InvocationChainImpl implements InvocationChain { + protected Operation operation; + protected TargetInvoker targetInvoker; + protected Interceptor interceptorChainHead; + protected Interceptor interceptorChainTail; + + public InvocationChainImpl(Operation operation) { + assert operation != null; + this.operation = operation; + } + + public Operation getOperation() { + return operation; + } + + public void setTargetInvoker(TargetInvoker invoker) { + this.targetInvoker = invoker; + } + + public TargetInvoker getTargetInvoker() { + return targetInvoker; + } + + public void addInterceptor(Interceptor interceptor) { + if (interceptorChainHead == null) { + interceptorChainHead = interceptor; + } else { + interceptorChainTail.setNext(interceptor); + } + interceptorChainTail = interceptor; + } + + public void addInterceptor(int index, Interceptor interceptor) { + int i = 0; + Interceptor next = interceptorChainHead; + Interceptor prev = null; + while (next != null && i < index) { + prev = next; + next = next.getNext(); + i++; + } + if (i == index) { + if (prev != null) { + prev.setNext(interceptor); + } else { + interceptorChainHead = interceptor; + } + interceptor.setNext(next); + if (next == null) { + interceptorChainTail = interceptor; + } + } else { + throw new ArrayIndexOutOfBoundsException(index); + } + } + + public Interceptor getHeadInterceptor() { + return interceptorChainHead; + } + + public Interceptor getTailInterceptor() { + return interceptorChainTail; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/InvokerInterceptor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/InvokerInterceptor.java new file mode 100644 index 0000000000..90b17a930c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/InvokerInterceptor.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.core.wire; + +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; + +/** + * Serves as a tail interceptor on a target wire chain. This implementation dispatches to the target invoker passed + * inside the wire message. Target invokers are passed from the source in order to allow for caching of target + * instances. + * + * @version $Rev$ $Date$ + * @see org.apache.tuscany.spi.wire.TargetInvoker + */ +public class InvokerInterceptor implements Interceptor { + + public InvokerInterceptor() { + } + + 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/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/NoMethodForOperationException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/NoMethodForOperationException.java new file mode 100644 index 0000000000..aec281d190 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/NoMethodForOperationException.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.core.wire; + +import org.apache.tuscany.spi.wire.ProxyCreationException; + +/** + * Thrown when an {@link org.apache.tuscany.spi.model.Operation} cannot be mapped to a method on an interface + * @version $Rev$ $Date$ + */ +public class NoMethodForOperationException extends ProxyCreationException { + public NoMethodForOperationException() { + } + + public NoMethodForOperationException(String message) { + super(message); + } + + public NoMethodForOperationException(String message, Throwable cause) { + super(message, cause); + } + + public NoMethodForOperationException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/NonBlockingInterceptor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/NonBlockingInterceptor.java new file mode 100644 index 0000000000..b5e1be42d5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/NonBlockingInterceptor.java @@ -0,0 +1,172 @@ +/* + * 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.core.wire; + +import java.net.URI; +import java.util.LinkedList; + +import org.osoa.sca.ServiceRuntimeException; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.services.work.WorkScheduler; +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.TargetInvoker; + +/** + * Adds non-blocking behavior to an invocation chain + * + * @version $$Rev$$ $$Date$$ + */ +public class NonBlockingInterceptor implements Interceptor { + + private static final Message RESPONSE = new ImmutableMessage(); + + private WorkScheduler workScheduler; + private WorkContext workContext; + private Interceptor next; + + public NonBlockingInterceptor(WorkScheduler workScheduler, WorkContext workContext) { + this.workScheduler = workScheduler; + this.workContext = workContext; + } + + public NonBlockingInterceptor(WorkScheduler workScheduler, WorkContext workContext, Interceptor next) { + this.workScheduler = workScheduler; + this.workContext = workContext; + this.next = next; + } + + public Message invoke(final Message msg) { + // Retrieve conversation id to transfer to new thread + // Notice that we cannot clear the conversation id from the current thread + final Object conversationID = workContext.getIdentifier(Scope.CONVERSATION); + // Schedule the invocation of the next interceptor in a new Work instance + try { + workScheduler.scheduleWork(new Runnable() { + public void run() { + workContext.setCorrelationId(null); + // if we got a conversation id, transfer it to new thread + if (conversationID != null) { + workContext.setIdentifier(Scope.CONVERSATION, conversationID); + } + next.invoke(msg); + } + }); + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + return RESPONSE; + } + + public Interceptor getNext() { + return next; + } + + public void setNext(Interceptor next) { + this.next = next; + } + + public boolean isOptimizable() { + return false; + } + + /** + * A dummy message passed back on an invocation + */ + private static class ImmutableMessage implements Message { + + public Object getBody() { + return null; + } + + public void setBody(Object body) { + if (body != null) { + throw new UnsupportedOperationException(); + } + } + + public void setTargetInvoker(TargetInvoker invoker) { + throw new UnsupportedOperationException(); + } + + public TargetInvoker getTargetInvoker() { + return null; + } + + public Message getRelatedCallbackMessage() { + return null; + } + + public URI getFromAddress() { + return null; + } + + public void setFromAddress(URI fromAddress) { + throw new UnsupportedOperationException(); + } + + public void pushCallbackUri(URI fromAddress) { + throw new UnsupportedOperationException(); + } + + public LinkedList<URI> getCallbackUris() { + return null; + } + + public void setCallbackUris(LinkedList<URI> uris) { + throw new UnsupportedOperationException(); + } + + public Object getMessageId() { + return null; + } + + public void setMessageId(Object messageId) { + throw new UnsupportedOperationException(); + } + + public Object getCorrelationId() { + return null; + } + + public void setCorrelationId(Object correlationId) { + throw new UnsupportedOperationException(); + } + + public boolean isFault() { + return false; + } + + public void setBodyWithFault(Object fault) { + throw new UnsupportedOperationException(); + } + + public short getConversationSequence() { + return TargetInvoker.NONE; + } + + public void setConversationSequence(short sequence) { + + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/OptimizedWireObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/OptimizedWireObjectFactory.java new file mode 100644 index 0000000000..49c73e2808 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/OptimizedWireObjectFactory.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.core.wire; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.component.TargetResolutionException; +import org.apache.tuscany.spi.wire.Wire; + +/** + * Returns a target instance directly from a wire + * + * @version $Rev$ $Date$ + */ +public class OptimizedWireObjectFactory<B> implements ObjectFactory<B> { + private final Class<B> type; + private Wire wire; + + public OptimizedWireObjectFactory(Class<B> type, Wire factory) { + this.wire = factory; + this.type = type; + } + + public B getInstance() throws ObjectCreationException { + try { + return type.cast(wire.getTargetInstance()); + } catch (TargetResolutionException e) { + throw new ObjectCreationException(e); + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/ProxyServiceExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/ProxyServiceExtension.java new file mode 100644 index 0000000000..7c8cf0db3a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/ProxyServiceExtension.java @@ -0,0 +1,115 @@ +/* + * 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.core.wire; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.IncompatibleServiceContractException; +import org.apache.tuscany.spi.wire.ProxyService; + +/** + * Base class for wire service extensions + * + * @version $Rev$ $Date$ + */ +public abstract class ProxyServiceExtension implements ProxyService { + protected WorkContext context; + + protected ProxyServiceExtension(WorkContext context) { + this.context = context; + } + + public boolean checkCompatibility(ServiceContract<?> source, + ServiceContract<?> target, + boolean ignoreCallback, + boolean silent) + throws IncompatibleServiceContractException { + if (source == target) { + // Shortcut for performance + return true; + } + if (source.isRemotable() != target.isRemotable()) { + if (!silent) { + throw new IncompatibleServiceContractException("Remotable settings do not match", source, target); + } else { + return false; + } + } + if (source.isConversational() != target.isConversational()) { + if (!silent) { + throw new IncompatibleServiceContractException("Interaction scopes do not match", source, target); + } else { + return false; + } + } + + for (Operation<?> operation : source.getOperations().values()) { + Operation<?> targetOperation = target.getOperations().get(operation.getName()); + if (targetOperation == null) { + if (!silent) { + throw new IncompatibleServiceContractException("Operation not found on target", source, target); + } else { + return false; + } + } + if (!operation.equals(targetOperation)) { + if (!silent) { + throw new IncompatibleServiceContractException("Target operations are not compatible", source, + target); + } else { + return false; + } + } + } + + if (ignoreCallback) { + return true; + } + + for (Operation<?> operation : source.getCallbackOperations().values()) { + Operation<?> targetOperation = target.getCallbackOperations().get(operation.getName()); + if (targetOperation == null) { + if (!silent) { + throw new IncompatibleServiceContractException("Callback operation not found on target", + source, + target, + null, + targetOperation); + } else { + return false; + } + } + if (!operation.equals(targetOperation)) { + if (!silent) { + throw new IncompatibleServiceContractException("Target callback operation is not compatible", + source, + target, + operation, + targetOperation); + } else { + return false; + } + } + } + return true; + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/WireImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/WireImpl.java new file mode 100644 index 0000000000..0518ce5132 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/WireImpl.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.core.wire; + +import java.net.URI; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.TargetResolutionException; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; + +/** + * Default implementation of a Wire + * + * @version $Rev$ $Date$ + */ +public class WireImpl implements Wire { + private URI sourceUri; + private URI targetUri; + private QName bindingType; + private ServiceContract sourceContract; + private ServiceContract targetContract; + private boolean optimizable; + private Map<Operation<?>, InvocationChain> chains = new HashMap<Operation<?>, InvocationChain>(); + private Map<Operation<?>, InvocationChain> callbackChains = new HashMap<Operation<?>, InvocationChain>(); + private AtomicComponent target; + + /** + * Creates a wire with a local binding + */ + public WireImpl() { + } + + /** + * Creates a wire with the given binding type + * + * @param bindingType the binding type + */ + public WireImpl(QName bindingType) { + this.bindingType = bindingType; + } + + public URI getSourceUri() { + return sourceUri; + } + + public void setSourceUri(URI sourceUri) { + this.sourceUri = sourceUri; + } + + public URI getTargetUri() { + return targetUri; + } + + public void setTargetUri(URI targetUri) { + this.targetUri = targetUri; + } + + public QName getBindingType() { + return bindingType; + } + + + public ServiceContract getSourceContract() { + return sourceContract; + } + + public void setSourceContract(ServiceContract contract) { + this.sourceContract = contract; + } + + + public ServiceContract getTargetContract() { + return targetContract; + } + + public void setTargetContract(ServiceContract contract) { + this.targetContract = contract; + } + + public boolean isOptimizable() { + return optimizable; + } + + public void setOptimizable(boolean optimizable) { + this.optimizable = optimizable; + } + + public Object getTargetInstance() throws TargetResolutionException { + if (target == null) { + return null; + } + return target.getTargetInstance(); + } + + public void setTarget(AtomicComponent target) { + this.target = target; + } + + public Map<Operation<?>, InvocationChain> getInvocationChains() { + return Collections.unmodifiableMap(chains); + } + + public void addInvocationChain(Operation<?> operation, InvocationChain chain) { + chains.put(operation, chain); + } + + public Map<Operation<?>, InvocationChain> getCallbackInvocationChains() { + return Collections.unmodifiableMap(callbackChains); + } + + public void addCallbackInvocationChain(Operation<?> operation, InvocationChain chain) { + callbackChains.put(operation, chain); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/WireObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/WireObjectFactory.java new file mode 100644 index 0000000000..bb46d53e84 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/WireObjectFactory.java @@ -0,0 +1,84 @@ +/* + * 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.core.wire; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.component.TargetResolutionException; +import org.apache.tuscany.spi.wire.ChainHolder; +import org.apache.tuscany.spi.wire.Wire; +import org.apache.tuscany.spi.wire.ProxyService; + +/** + * Uses a wire to return an object instance + * + * @version $Rev$ $Date$ + */ +public class WireObjectFactory<T> implements ObjectFactory<T> { + private Class<T> interfaze; + private Wire wire; + private ProxyService proxyService; + // the cache of proxy interface method to operation mappings + private Map<Method, ChainHolder> mappings; + private boolean optimizable; + + /** + * Constructor. + * + * @param interfaze the interface to inject on the client + * @param wire the backing wire + * @param proxyService the wire service to create the proxy + * @throws NoMethodForOperationException + */ + public WireObjectFactory(Class<T> interfaze, Wire wire, ProxyService proxyService) + throws NoMethodForOperationException { + this.interfaze = interfaze; + this.wire = wire; + this.proxyService = proxyService; + this.mappings = WireUtils.createInterfaceToWireMapping(interfaze, wire); + if (wire.isOptimizable() + && wire.getSourceContract().getInterfaceClass() != null + && interfaze.isAssignableFrom(wire.getSourceContract().getInterfaceClass())) { + optimizable = true; + } + } + + public T getInstance() throws ObjectCreationException { + if (optimizable) { + try { + return interfaze.cast(wire.getTargetInstance()); + } catch (TargetResolutionException e) { + throw new ObjectCreationException(e); + } + } else { + // clone the cached mappings + Map<Method, ChainHolder> newChains = new HashMap<Method, ChainHolder>(mappings.size()); + for (Map.Entry<Method, ChainHolder> entry : mappings.entrySet()) { + newChains.put(entry.getKey(), entry.getValue().clone()); + } + return interfaze.cast(proxyService.createProxy(interfaze, wire, newChains)); + } + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/WireUtils.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/WireUtils.java new file mode 100644 index 0000000000..b3e9c8177e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/WireUtils.java @@ -0,0 +1,115 @@ +/* + * 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.core.wire; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +import static org.apache.tuscany.spi.idl.java.JavaIDLUtils.findMethod; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.ChainHolder; +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; + +/** + * Utilities for operating on wires + * + * @version $Rev$ $Date$ + */ +public final class WireUtils { + + private WireUtils() { + } + + /** + * Maps invocation chains on a wire to corresponding methods + * + * @param wire the wire containing the invocation chains to map + * @param methods the methods to map to + * @return a collection containing the method to invocation chain mapping + * @throws NoMethodForOperationException + */ + public static Map<Method, InvocationChain> createInboundMapping(Wire wire, Method[] methods) + throws NoMethodForOperationException { + Map<Method, InvocationChain> chains = new HashMap<Method, InvocationChain>(); + for (Map.Entry<Operation<?>, InvocationChain> entry : wire.getInvocationChains().entrySet()) { + Operation<?> operation = entry.getKey(); + InvocationChain chain = entry.getValue(); + Method method = findMethod(operation, methods); + if (method == null) { + throw new NoMethodForOperationException(operation.getName()); + } + chains.put(method, chain); + } + return chains; + } + + + /** + * Maps methods on an interface to operations on a wire + * + * @param interfaze the interface to map from + * @param wire the wire to map to + * @return a collection of method to operation mappings + * @throws NoMethodForOperationException + */ + public static Map<Method, ChainHolder> createInterfaceToWireMapping(Class<?> interfaze, Wire wire) + throws NoMethodForOperationException { + Map<Operation<?>, InvocationChain> invocationChains = wire.getInvocationChains(); + Map<Method, ChainHolder> chains = new HashMap<Method, ChainHolder>(invocationChains.size()); + Method[] methods = interfaze.getMethods(); + for (Map.Entry<Operation<?>, InvocationChain> entry : invocationChains.entrySet()) { + Operation operation = entry.getKey(); + Method method = findMethod(operation, methods); + if (method == null) { + throw new NoMethodForOperationException(operation.getName()); + } + chains.put(method, new ChainHolder(entry.getValue())); + } + return chains; + } + + /** + * Determines if the given wire is optimizable, i.e. its invocation chains may be bypassed during an invocation. + * This is typically calculated during the connect phase to optimize away invocation chains. + * + * @param wire the wire + * @return true if the wire is optimizable + */ + public static boolean isOptimizable(Wire wire) { + for (InvocationChain chain : wire.getInvocationChains().values()) { + if (chain.getHeadInterceptor() != null) { + Interceptor current = chain.getHeadInterceptor(); + if (current == null) { + break; + } + while (current != null) { + if (!current.isOptimizable()) { + return false; + } + current = current.getNext(); + } + } + } + // if there is a callback, the wire is never optimizable since the callback target needs to be disambiguated + return wire.getCallbackInvocationChains().isEmpty(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandler.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandler.java new file mode 100644 index 0000000000..9c67c17977 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandler.java @@ -0,0 +1,155 @@ +/* + * 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.core.wire.jdk; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.osoa.sca.NoRegisteredCallbackException; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ReactivationException; +import org.apache.tuscany.spi.component.SCAExternalizable; +import org.apache.tuscany.spi.component.WorkContext; +import static org.apache.tuscany.spi.idl.java.JavaIDLUtils.findOperation; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.AbstractInvocationHandler; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; +import org.apache.tuscany.spi.wire.WireInvocationHandler; + + +/** + * Responsible for dispatching to a callback through a wire. + * <p/> + * TODO cache target invoker + * + * @version $Rev$ $Date$ + */ +public class JDKCallbackInvocationHandler extends AbstractInvocationHandler + implements WireInvocationHandler, InvocationHandler, Externalizable, SCAExternalizable { + private transient WorkContext context; + private transient Map<URI, Wire> wires; + private List<String> sourceWireNames; + + /** + * Constructor used for deserialization only + */ + public JDKCallbackInvocationHandler() { + sourceWireNames = new ArrayList<String>(); + wires = new HashMap<URI, Wire>(); + } + + public JDKCallbackInvocationHandler(List<Wire> wireList, WorkContext context) { + this.context = context; + this.wires = new HashMap<URI, Wire>(); + for (Wire wire : wireList) { + wires.put(wire.getSourceUri(), wire); + } + sourceWireNames = new ArrayList<String>(); + for (URI uri : wires.keySet()) { + sourceWireNames.add(uri.getFragment()); + } + } + + @SuppressWarnings({"unchecked"}) + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if (method.getParameterTypes().length == 0 && "toString".equals(method.getName())) { + return "[Proxy - " + Integer.toHexString(hashCode()) + "]"; + } else if (method.getDeclaringClass().equals(Object.class) + && "equals".equals(method.getName())) { + // TODO implement + throw new UnsupportedOperationException(); + } else if (Object.class.equals(method.getDeclaringClass()) + && "hashCode".equals(method.getName())) { + return hashCode(); + // TODO beter hash algorithm + } + LinkedList<URI> callbackUris = context.getCallbackUris(); + assert callbackUris != null; + URI targetAddress = callbackUris.getLast(); + assert targetAddress != null; + Wire wire = wires.get(targetAddress); + assert wire != null; + Map<Operation<?>, InvocationChain> chains = wire.getCallbackInvocationChains(); + Operation operation = findOperation(method, chains.keySet()); + InvocationChain chain = chains.get(operation); + TargetInvoker invoker = chain.getTargetInvoker(); + Object correlationId = context.getCorrelationId(); + context.setCorrelationId(null); + try { + return invoke(chain, invoker, args, correlationId, callbackUris); + } catch (InvocationTargetException e) { + Throwable t = e.getCause(); + if (t instanceof NoRegisteredCallbackException) { + throw t; + } + throw e; + } + } + + + public Object invoke(Method method, Object[] args) throws Throwable { + return invoke(null, method, args); + } + + public void writeExternal(ObjectOutput out) throws IOException { + int i = sourceWireNames.size() - 1; + out.writeInt(i); + for (String name : sourceWireNames) { + out.writeObject(name); + } + } + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + int num = in.readInt(); + for (int i = 0; i <= num; i++) { + sourceWireNames.add((String) in.readObject()); + } + } + + public void setWorkContext(WorkContext context) { + this.context = context; + } + + public void reactivate() throws ReactivationException { + AtomicComponent owner = context.getCurrentAtomicComponent(); + if (owner == null) { + throw new ReactivationException("Current atomic component not set on work context"); + } + for (String name : sourceWireNames) { + // TODO JFM support multiplicity, remove get(0) + Wire wire = owner.getWires(name).get(0); + wires.put(wire.getSourceUri(), wire); + + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandler.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandler.java new file mode 100644 index 0000000000..8ca53a74db --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandler.java @@ -0,0 +1,263 @@ +/* + * 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.core.wire.jdk; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.net.URI; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ReactivationException; +import org.apache.tuscany.spi.component.SCAExternalizable; +import org.apache.tuscany.spi.component.TargetInvocationException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.AbstractInvocationHandler; +import org.apache.tuscany.spi.wire.ChainHolder; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; +import org.apache.tuscany.spi.wire.WireInvocationHandler; + +import org.apache.tuscany.core.wire.NoMethodForOperationException; +import org.apache.tuscany.core.wire.WireUtils; + + +/** + * Dispatches to a target through a wire. + * + * @version $Rev$ $Date$ + */ +public final class JDKInvocationHandler extends AbstractInvocationHandler + implements WireInvocationHandler, InvocationHandler, Externalizable, SCAExternalizable { + private static final long serialVersionUID = -6155278451964527325L; + + // the wire this handler fronts + private transient Wire wire; + // the name of the source reference the wire is attached to, used during deserialization + private String referenceName; + // the interface the reference proxy implements + private Class<?> proxyInterface; + private transient WorkContext workContext; + // if the associated wire has a callback + private transient boolean callback; + // if the associated wire is conversational + private transient boolean conversational; + /* + * an association of an operation to chain holder. The holder contains an invocation chain + * and a local clone of the master TargetInvoker. TargetInvokers will be cloned by the handler and placed in the + * holder if they are cacheable. This allows optimizations such as avoiding target resolution when a source refers + * to a target of greater scope since the target reference can be maintained by the invoker. When a target invoker + * is not cacheable, the master associated with the wire chains will be used. + */ + private transient Map<Method, ChainHolder> chains; + + /** + * Constructor used for deserialization only + */ + public JDKInvocationHandler() { + } + + public JDKInvocationHandler(Class<?> interfaze, Wire wire, WorkContext workContext) + throws NoMethodForOperationException { + this.workContext = workContext; + this.proxyInterface = interfaze; + this.wire = wire; + init(interfaze, wire, null); + } + + public JDKInvocationHandler(Class<?> interfaze, + Wire wire, + Map<Method, ChainHolder> mapping, + WorkContext workContext) + throws NoMethodForOperationException { + this.workContext = workContext; + this.proxyInterface = interfaze; + init(interfaze, wire, mapping); + } + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + ChainHolder holder = chains.get(method); + if (holder == null) { + if (method.getParameterTypes().length == 0 && "toString".equals(method.getName())) { + return "[Proxy - " + Integer.toHexString(hashCode()) + "]"; + } else if (method.getDeclaringClass().equals(Object.class) + && "equals".equals(method.getName())) { + // TODO implement + throw new UnsupportedOperationException(); + } else if (Object.class.equals(method.getDeclaringClass()) + && "hashCode".equals(method.getName())) { + return hashCode(); + // TODO beter hash algorithm + } + throw new TargetInvocationException("Operation not configured", method.getName()); + } + TargetInvoker invoker = getInvoker(holder); + InvocationChain chain = holder.getChain(); + +// JFM commonting out temporarily +// if (wireContainerIsAtomicComponent && contractHasCallback && !callbackIsImplemented) { +// throw new NoRegisteredCallbackException("Instance is does not implement callback: " +// + callbackClassName); +// } + + if (conversational) { + Object id = workContext.getIdentifier(Scope.CONVERSATION); + if (id == null) { + String convIdFromThread = createConversationID(); + workContext.setIdentifier(Scope.CONVERSATION, convIdFromThread); + } + } + LinkedList<URI> list = null; + if (callback) { + // set up callback address + list = workContext.getCallbackUris(); + if (list == null) { + list = new LinkedList<URI>(); + workContext.setCallbackUris(list); + } + list.add(wire.getSourceUri()); + } + // send the invocation down the wire + Object result = invoke(chain, invoker, args, null, list); + + if (callback) { + list = workContext.getCallbackUris(); + if (list != null) { + // pop last address + list.removeLast(); + } + } + return result; + } + + public Object invoke(Method method, Object[] args) throws Throwable { + return invoke(null, method, args); + } + + public void setWorkContext(WorkContext context) { + workContext = context; + } + + public void writeExternal(ObjectOutput out) throws IOException { + out.writeObject(referenceName); + out.writeObject(proxyInterface); + } + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + referenceName = (String) in.readObject(); + proxyInterface = (Class<?>) in.readObject(); + } + + public void reactivate() throws ReactivationException { + AtomicComponent owner = workContext.getCurrentAtomicComponent(); + if (owner == null) { + throw new ReactivationException("Current atomic component not set on work context"); + } + List<Wire> wires = owner.getWires(referenceName); + if (wires == null) { + throw new ReactivationException("Reference wire not found", referenceName, owner.getUri().toString()); + } + // TODO handle multiplicity + Wire wire = wires.get(0); + try { + init(proxyInterface, wire, null); + } catch (NoMethodForOperationException e) { + throw new ReactivationException(e); + } + } + + /** + * Reinitializes the proxy handler + * + * @param interfaze the interface the proxy implements + * @param wire the wire fronted by the proxy + * @param mapping a mapping from proxy interface methods to invocation chain holders + * @throws NoMethodForOperationException + */ + private void init(Class<?> interfaze, Wire wire, Map<Method, ChainHolder> mapping) + throws NoMethodForOperationException { + ServiceContract contract = wire.getSourceContract(); + this.referenceName = wire.getSourceUri().getFragment(); + this.conversational = contract.isConversational(); + this.callback = contract.getCallbackClass() != null; + // FIXME JFM this should not be dependent on PojoAtomicComponent + // JFM commenting out as this should not be specific to pojo types +// this.wireContainerIsAtomicComponent = scaObject instanceof PojoAtomicComponent; +// if (wireContainerIsAtomicComponent && contractHasCallback) { +// this.callbackIsImplemented = +// ((PojoAtomicComponent) scaObject).implementsCallback(contract.getCallbackClass()); +// } else { +// this.callbackIsImplemented = false; +// } + if (mapping == null) { + chains = WireUtils.createInterfaceToWireMapping(interfaze, wire); + } else { + chains = mapping; + } + } + + /** + * Returns the cached or a new target invoker to associate with the invocation + * + * @param holder the chain holder + * @return the target invoker + * @throws TargetInvocationException + * @throws CloneNotSupportedException + */ + private TargetInvoker getInvoker(ChainHolder holder) throws TargetInvocationException, CloneNotSupportedException { + InvocationChain chain = holder.getChain(); + if (holder.getCachedInvoker() == null) { + assert chain != null; + if (chain.getTargetInvoker() == null) { + String name = chain.getOperation().getName(); + throw new TargetInvocationException("No target invoker configured for operation", name); + } + if (chain.getTargetInvoker().isCacheable()) { + // clone and store the invoker locally + holder.setCachedInvoker((TargetInvoker) chain.getTargetInvoker().clone()); + return holder.getCachedInvoker(); + } else { + return chain.getTargetInvoker(); + } + } else { + assert chain != null; + return chain.getTargetInvoker(); + } + } + + /** + * Creates a new conversational id + * + * @return the conversational id + */ + private String createConversationID() { + return UUID.randomUUID().toString(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKProxyService.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKProxyService.java new file mode 100644 index 0000000000..ef3f30edb9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKProxyService.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.core.wire.jdk; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.List; +import java.util.Map; + +import org.osoa.sca.CallableReference; +import org.osoa.sca.annotations.Constructor; +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.wire.ChainHolder; +import org.apache.tuscany.spi.wire.ProxyCreationException; +import org.apache.tuscany.spi.wire.Wire; + +import org.apache.tuscany.core.wire.ProxyServiceExtension; + +/** + * the default implementation of a wire service that uses JDK dynamic proxies + * + * @version $$Rev$$ $$Date$$ + */ +@EagerInit +public class JDKProxyService extends ProxyServiceExtension { + + public JDKProxyService() { + super(null); + } + + @Constructor + public JDKProxyService(@Reference WorkContext context) { + super(context); + } + + public <T> T createProxy(Class<T> interfaze, Wire wire) throws ProxyCreationException { + assert interfaze != null; + assert wire != null; + JDKInvocationHandler handler = new JDKInvocationHandler(interfaze, wire, context); + ClassLoader cl = interfaze.getClassLoader(); + return interfaze.cast(Proxy.newProxyInstance(cl, new Class[]{interfaze}, handler)); + } + + public <T> T createProxy(Class<T> interfaze, Wire wire, Map<Method, ChainHolder> mapping) + throws ProxyCreationException { + assert interfaze != null; + assert wire != null; + assert mapping != null; + JDKInvocationHandler handler = new JDKInvocationHandler(interfaze, wire, context); + ClassLoader cl = interfaze.getClassLoader(); + return interfaze.cast(Proxy.newProxyInstance(cl, new Class[]{interfaze}, handler)); + } + + public Object createCallbackProxy(Class<?> interfaze, List<Wire> wires) throws ProxyCreationException { + ClassLoader cl = interfaze.getClassLoader(); + JDKCallbackInvocationHandler handler = new JDKCallbackInvocationHandler(wires, context); + return interfaze.cast(Proxy.newProxyInstance(cl, new Class[]{interfaze}, handler)); + } + + public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException { + InvocationHandler handler = Proxy.getInvocationHandler(target); + if (handler instanceof JDKInvocationHandler) { + // TODO return a ServiceReference + throw new UnsupportedOperationException(); + } else if (handler instanceof JDKCallbackInvocationHandler) { + // TODO return a CallbackReference + throw new UnsupportedOperationException(); + } else { + throw new IllegalArgumentException("Not a Tuscany SCA proxy"); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/composite.scdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/composite.scdl new file mode 100644 index 0000000000..8cdf0ac2a8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/composite.scdl @@ -0,0 +1,48 @@ +<?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. +--> +<!-- + Default system configuration for the launcher environment. + + $Rev$ $Date$ +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://tuscany.apache.org/xmlns/sca/system/2.0-alpha" + name="org.apache.tuscany.core.Composite" + autowire="true"> + + <!-- Composite implementation type --> + <component name="composite.loader"> + <system:implementation.system class="org.apache.tuscany.core.implementation.composite.CompositeLoader"/> + </component> + <component name="composite.implementationLoader"> + <system:implementation.system + class="org.apache.tuscany.core.implementation.composite.ImplementationCompositeLoader"/> + </component> + <component name="composite.dependencyLoader"> + <system:implementation.system class="org.apache.tuscany.core.loader.DependencyLoader"/> + </component> + <component name="composite.componentTypeLoader"> + <system:implementation.system + class="org.apache.tuscany.core.implementation.composite.CompositeComponentTypeLoader"/> + </component> + <component name="composite.builder"> + <system:implementation.system class="org.apache.tuscany.core.implementation.composite.CompositeBuilder"/> + </component> +</composite> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/databinding.scdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/databinding.scdl new file mode 100644 index 0000000000..c50422c34d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/databinding.scdl @@ -0,0 +1,165 @@ +<?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:system="http://tuscany.apache.org/xmlns/sca/system/2.0-alpha"
+ name="org.apache.tuscany.core.DataBinding"
+ autowire="true">
+
+ <component name="databinding.wirePostProcessor">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.DataBindingWirePostProcessor"/>
+ </component>
+
+ <component name="databinding.javaInterfaceProcessor">
+ <system:implementation.system
+ class="org.apache.tuscany.core.databinding.impl.DataBindingJavaInterfaceProcessor"/>
+ </component>
+
+ <component name="databinding.passByValueWirePostProcessor">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.PassByValueWirePostProcessor"/>
+ </component>
+
+ <!-- DataBinding registry -->
+ <component name="databinding.registry">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.DataBindingRegistryImpl"/>
+ </component>
+
+ <!-- DataBinding registry -->
+ <component name="databinding.mediator">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.MediatorImpl"/>
+ </component>
+
+ <!-- Transformer registry -->
+ <component name="databinding.transformerRegistry" initLevel="90">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.TransformerRegistryImpl"/>
+ </component>
+
+ <component name="dataType.loader">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.DataTypeLoader"/>
+ </component>
+
+ <!-- Simple databindings -->
+ <component name="databinding.dom">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.SimpleDataBinding"/>
+ <property name="className">org.w3c.dom.Node</property>
+ </component>
+
+ <component name="databinding.javabeans">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.javabeans.JavaBeansDataBinding"/>
+ </component>
+
+ <!-- Transformers -->
+
+ <component name="transformer.Input2InputTransformer">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.Input2InputTransformer"/>
+ </component>
+
+ <component name="transformer.Output2OutputTransformer">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.Output2OutputTransformer"/>
+ </component>
+
+ <component name="transformer.InputSource2Node">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.InputSource2Node"/>
+ </component>
+
+ <component name="transformer.InputSource2SAX">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.InputSource2SAX"/>
+ </component>
+
+ <component name="transformer.InputStream2Node">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.InputStream2Node"/>
+ </component>
+
+ <component name="transformer.InputStream2SAX">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.InputStream2SAX"/>
+ </component>
+
+ <component name="transformer.DOMNode2JavaBean">
+ <system:implementation.system
+ class="org.apache.tuscany.core.databinding.javabeans.DOMNode2JavaBeanTransformer"/>
+ </component>
+
+ <component name="transformer.Node2OutputStream">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.Node2OutputStream"/>
+ </component>
+
+ <component name="transformer.Node2String">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.Node2String"/>
+ </component>
+
+ <component name="transformer.Node2Writer">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.Node2Writer"/>
+ </component>
+
+ <component name="transformer.Node2XMLStreamReader">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.Node2XMLStreamReader"/>
+ </component>
+
+ <component name="transformer.JavaBean2DOMNode">
+ <system:implementation.system
+ class="org.apache.tuscany.core.databinding.javabeans.JavaBean2DOMNodeTransformer"/>
+ </component>
+
+ <component name="transformer.Reader2Node">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.Reader2Node"/>
+ </component>
+
+ <component name="transformer.Reader2SAX">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.Reader2SAX"/>
+ </component>
+
+ <component name="transformer.SAX2DOMPipe">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.SAX2DOMPipe"/>
+ </component>
+
+ <component name="transformer.Source2ResultTransformer">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.Source2ResultTransformer"/>
+ </component>
+
+ <component name="transformer.StreamDataPipe">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.StreamDataPipe"/>
+ </component>
+
+ <component name="transformer.String2Node">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.String2Node"/>
+ </component>
+
+ <component name="transformer.String2SAX">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.String2SAX"/>
+ </component>
+
+ <component name="transformer.String2XMLStreamReader">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.String2XMLStreamReader"/>
+ </component>
+
+ <component name="transformer.Writer2ReaderDataPipe">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.Writer2ReaderDataPipe"/>
+ </component>
+
+ <component name="transformer.XMLStreamReader2Node">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.XMLStreamReader2Node"/>
+ </component>
+
+ <component name="transformer.XMLStreamReader2SAX">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.XMLStreamReader2SAX"/>
+ </component>
+
+ <component name="transformer.XMLStreamReader2String">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.XMLStreamReader2String"/>
+ </component>
+</composite>
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/deployment.scdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/deployment.scdl new file mode 100644 index 0000000000..804bd0bead --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/deployment.scdl @@ -0,0 +1,62 @@ +<?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.
+-->
+<!--
+ Deployment-related system components
+
+ $Rev$ $Date$
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:system="http://tuscany.apache.org/xmlns/sca/system/2.0-alpha"
+ name="org.apache.tuscany.core.Deployment"
+ autowire="true">
+
+ <!-- Contribution Service -->
+ <component name="contributionDirectoryWatcher" initLevel="100">
+ <system:implementation.system class="org.apache.tuscany.core.services.deployment.ContributionDirectoryWatcher"/>
+ <property name="path">target/deployables</property>
+ </component>
+ <component name="contributionService" initLevel="90">
+ <system:implementation.system class="org.apache.tuscany.core.services.deployment.ContributionServiceImpl"/>
+ </component>
+ <component name="contributionRepository" initLevel="40">
+ <system:implementation.system class="org.apache.tuscany.core.services.deployment.ContributionRepositoryImpl"/>
+ <property name="repository">target/repository</property>
+ </component>
+
+ <component name="contributionProcessorRegistry" initLevel="35">
+ <system:implementation.system
+ class="org.apache.tuscany.core.services.deployment.ContributionProcessorRegistryImpl"/>
+ </component>
+ <component name="contentTypeDescriber" initLevel="30">
+ <system:implementation.system class="org.apache.tuscany.core.services.deployment.ContentTypeDescriberImpl"/>
+ </component>
+ <component name="JarContributionProcessor" initLevel="30">
+ <system:implementation.system
+ class="org.apache.tuscany.core.services.deployment.contribution.JarContributionProcessor"/>
+ </component>
+ <component name="JavaContributionProcessor" initLevel="30">
+ <system:implementation.system
+ class="org.apache.tuscany.core.services.deployment.contribution.JavaContributionProcessor"/>
+ </component>
+ <component name="ScdlContributionProcessor" initLevel="30">
+ <system:implementation.system
+ class="org.apache.tuscany.core.services.deployment.contribution.ScdlContributionProcessor"/>
+ </component>
+
+</composite>
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/formatters.scdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/formatters.scdl new file mode 100644 index 0000000000..5d2c0db012 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/formatters.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. +--> +<!-- + Formatter configurations for JDK logging. + + $Rev: 476250 $ $Date: 2006-11-17 10:56:22 -0800 (Fri, 17 Nov 2006) $ +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://tuscany.apache.org/xmlns/sca/system/2.0-alpha" + name="org.apache.tuscany.core.Formatters" + autowire="true"> + + <component name="LoaderExceptionFormatter"> + <system:implementation.system class="org.apache.tuscany.core.loader.LoaderExceptionFormatter"/> + </component> + + <component name="IncompatibleServiceContractExceptionFormatter"> + <system:implementation.system + class="org.apache.tuscany.core.wire.IncompatibleServiceContractExceptionFormatter"/> + </component> + + <component name="WireExceptionExceptionFormatter"> + <system:implementation.system + class="org.apache.tuscany.core.builder.WiringExceptionFormatter"/> + </component> + +</composite> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/implementation.scdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/implementation.scdl new file mode 100644 index 0000000000..c81115aafa --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/implementation.scdl @@ -0,0 +1,79 @@ +<?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. +--> +<!-- + Default system configuration for the launcher environment. + + $Rev$ $Date$ +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://tuscany.apache.org/xmlns/sca/system/2.0-alpha" + name="org.apache.tuscany.core.Implementation" + autowire="true"> + + <!-- Foundation implementation processors --> + <component name="implementation.ImplementationProcessorService"> + <system:implementation.system + class="org.apache.tuscany.core.implementation.processor.ImplementationProcessorServiceImpl"/> + </component> + <component name="implementation.Constructor"> + <system:implementation.system class="org.apache.tuscany.core.implementation.processor.ConstructorProcessor"/> + </component> + <component name="implementation.Destroy"> + <system:implementation.system class="org.apache.tuscany.core.implementation.processor.DestroyProcessor"/> + </component> + <component name="implementation.Init"> + <system:implementation.system class="org.apache.tuscany.core.implementation.processor.InitProcessor"/> + </component> + <component name="implementation.EagerInit"> + <system:implementation.system class="org.apache.tuscany.core.implementation.processor.EagerInitProcessor"/> + </component> + <component name="implementation.Scope"> + <system:implementation.system class="org.apache.tuscany.core.implementation.processor.ScopeProcessor"/> + </component> + <component name="implementation.AllowsPassByReference"> + <system:implementation.system + class="org.apache.tuscany.core.implementation.processor.AllowsPassByReferenceProcessor"/> + </component> + <component name="implementation.Property"> + <system:implementation.system class="org.apache.tuscany.core.implementation.processor.PropertyProcessor"/> + </component> + <component name="implementation.Reference"> + <system:implementation.system class="org.apache.tuscany.core.implementation.processor.ReferenceProcessor"/> + </component> + <component name="implementation.Service"> + <system:implementation.system class="org.apache.tuscany.core.implementation.processor.ServiceProcessor"/> + </component> + <component name="implementation.HeuristicPojo"> + <system:implementation.system class="org.apache.tuscany.core.implementation.processor.HeuristicPojoProcessor"/> + </component> + <component name="implementation.Monitor"> + <system:implementation.system class="org.apache.tuscany.core.implementation.processor.MonitorProcessor"/> + </component> + <component name="implementation.Resource"> + <system:implementation.system class="org.apache.tuscany.core.implementation.processor.ResourceProcessor"/> + </component> + <component name="implementation.Conversation"> + <system:implementation.system class="org.apache.tuscany.core.implementation.processor.ConversationProcessor"/> + </component> + <component name="implementation.ContextProcessor"> + <system:implementation.system class="org.apache.tuscany.core.implementation.processor.ContextProcessor"/> + </component> + +</composite> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/interfaceJava.scdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/interfaceJava.scdl new file mode 100644 index 0000000000..b0664dc67a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/interfaceJava.scdl @@ -0,0 +1,36 @@ +<?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. +--> +<!-- + Configuration for Java IDL support. + + $Rev$ $Date$ +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://tuscany.apache.org/xmlns/sca/system/2.0-alpha" + name="org.apache.tuscany.core.InterfaceJava" + autowire="true"> + + <component name="interfaceJava.interfaceProcessorRegistry"> + <system:implementation.system class="org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl"/> + </component> + <component name="interfaceJava.loader"> + <system:implementation.system class="org.apache.tuscany.core.idl.java.InterfaceJavaLoader"/> + </component> +</composite> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/javaImplementation.scdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/javaImplementation.scdl new file mode 100644 index 0000000000..69110ec05c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/javaImplementation.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. +--> +<!-- + Default system configuration for the launcher environment. + + $Rev$ $Date$ +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://tuscany.apache.org/xmlns/sca/system/2.0-alpha" + name="org.apache.tuscany.core.JavaImplementation" + autowire="true"> + + <!-- Java implementation type --> + <component name="java.implementationLoader"> + <system:implementation.system class="org.apache.tuscany.core.implementation.java.JavaImplementationLoader"/> + </component> + <component name="java.componentTypeLoader"> + <system:implementation.system class="org.apache.tuscany.core.implementation.java.JavaComponentTypeLoader"/> + </component> + <component name="java.componentBuilder"> + <system:implementation.system class="org.apache.tuscany.core.implementation.java.JavaComponentBuilder"/> + </component> +</composite> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/loader.scdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/loader.scdl new file mode 100644 index 0000000000..b22f5d05f1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/loader.scdl @@ -0,0 +1,53 @@ +<?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. +--> +<!-- + Default loader configuration for the launcher environment. + + $Rev$ $Date$ +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://tuscany.apache.org/xmlns/sca/system/2.0-alpha" + name="org.apache.tuscany.core.Loader" + autowire="true"> + + <!-- Foundation element loader implementations --> + <component name="elementLoader.component"> + <system:implementation.system class="org.apache.tuscany.core.loader.ComponentLoader"/> + </component> + <component name="elementLoader.componentType"> + <system:implementation.system class="org.apache.tuscany.core.loader.ComponentTypeElementLoader"/> + </component> + <component name="elementLoader.include"> + <system:implementation.system class="org.apache.tuscany.core.loader.IncludeLoader"/> + </component> + <component name="elementLoader.property"> + <system:implementation.system class="org.apache.tuscany.core.loader.PropertyLoader"/> + </component> + <component name="elementLoader.reference"> + <system:implementation.system class="org.apache.tuscany.core.loader.ReferenceLoader"/> + </component> + <component name="elementLoader.service"> + <system:implementation.system class="org.apache.tuscany.core.loader.ServiceLoader"/> + </component> + <component name="elementLoader.wire"> + <system:implementation.system class="org.apache.tuscany.core.loader.WireLoader"/> + </component> + +</composite> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/systemImplementation.scdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/systemImplementation.scdl new file mode 100644 index 0000000000..9a4178118f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/main/resources/org/apache/tuscany/core/systemImplementation.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. +--> +<!-- + Default system configuration for the launcher environment. + + $Rev$ $Date$ +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://tuscany.apache.org/xmlns/sca/system/2.0-alpha" + name="org.apache.tuscany.core.SystemImplementation" + autowire="true"> + + <!-- System implementation type --> + <component name="system.componentTypeLoader"> + <system:implementation.system + class="org.apache.tuscany.core.implementation.system.loader.SystemComponentTypeLoader"/> + </component> + + <component name="system.compositeComponentTypeLoader"> + <system:implementation.system + class="org.apache.tuscany.core.implementation.system.loader.SystemCompositeComponentTypeLoader"/> + </component> + <component name="system.implementationLoader"> + <system:implementation.system + class="org.apache.tuscany.core.implementation.system.loader.SystemImplementationLoader"/> + </component> + <component name="system.componentBuilder"> + <system:implementation.system + class="org.apache.tuscany.core.implementation.system.builder.SystemComponentBuilder"/> + </component> + <component name="system.compositeBuilder"> + <system:implementation.system class="org.apache.tuscany.core.implementation.composite.SystemCompositeBuilder"/> + </component> +</composite> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/AbstractLocalTargetInvokerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/AbstractLocalTargetInvokerTestCase.java new file mode 100644 index 0000000000..dfda132671 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/AbstractLocalTargetInvokerTestCase.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.binding.local; + +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; +import org.apache.tuscany.spi.wire.TargetInvoker; + +import junit.framework.TestCase; +import org.apache.tuscany.core.mock.wire.MockTargetInvoker; +import org.easymock.EasyMock; +import org.easymock.IAnswer; + +/** + * @version $Rev$ $Date$ + */ +public class AbstractLocalTargetInvokerTestCase extends TestCase { + + public void testInvokerWithInterceptor() throws Throwable { + AbstractLocalTargetInvoker invoker = new MockTargetInvoker(); + Interceptor interceptor = EasyMock.createMock(Interceptor.class); + interceptor.invoke(EasyMock.isA(Message.class)); + EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() { + public Object answer() throws Throwable { + Message msg = (Message) EasyMock.getCurrentArguments()[0]; + if (msg.getTargetInvoker() == null) { + fail("Target invoker not set"); + } + return null; + } + }); + EasyMock.replay(interceptor); + InvocationChain chain = EasyMock.createMock(InvocationChain.class); + EasyMock.expect(chain.getHeadInterceptor()).andReturn(interceptor); + EasyMock.replay(chain); + invoker.invoke(chain, EasyMock.createNiceMock(TargetInvoker.class), new MessageImpl()); + EasyMock.verify(chain); + EasyMock.verify(interceptor); + } + + public void testShortCircuitInvoke() throws Throwable { + AbstractLocalTargetInvoker invoker = new MockTargetInvoker(); + TargetInvoker targetInvoker = EasyMock.createMock(TargetInvoker.class); + EasyMock.expect(targetInvoker.invoke(EasyMock.isA(Message.class))).andReturn(new MessageImpl()); + EasyMock.replay(targetInvoker); + InvocationChain chain = EasyMock.createMock(InvocationChain.class); + EasyMock.expect(chain.getHeadInterceptor()).andReturn(null); + EasyMock.replay(chain); + invoker.invoke(chain, targetInvoker, new MessageImpl()); + EasyMock.verify(chain); + EasyMock.verify(targetInvoker); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalBindingBuilderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalBindingBuilderTestCase.java new file mode 100644 index 0000000000..e628df47e2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalBindingBuilderTestCase.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.binding.local; + +import java.net.URI; + +import org.apache.tuscany.spi.component.ServiceBinding; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class LocalBindingBuilderTestCase extends TestCase { + + public void testBuild() throws Exception { + LocalBindingBuilder builder = new LocalBindingBuilder(); + ServiceDefinition def = new ServiceDefinition(); + def.setUri(new URI("#foo")); + ServiceBinding binding = builder.build(def, null, null); + assertEquals(LocalServiceBinding.class, binding.getClass()); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalBindingLoaderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalBindingLoaderTestCase.java new file mode 100644 index 0000000000..0c35ae9a09 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalBindingLoaderTestCase.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.core.binding.local; + +import java.net.URI; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.loader.LoaderException; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class LocalBindingLoaderTestCase extends TestCase { + private LocalBindingLoader loader; + + public void testParse() throws Exception { + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getAttributeValue(null, "uri")).andReturn("foo"); + EasyMock.replay(reader); + LocalBindingDefinition definition = loader.load(null, reader, null); + assertEquals(new URI("foo"), definition.getTargetUri()); + EasyMock.verify(reader); + } + + public void testNoUri() throws Exception { + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getAttributeValue(null, "uri")).andReturn(null); + EasyMock.replay(reader); + LocalBindingDefinition definition = loader.load(null, reader, null); + assertNull(definition.getTargetUri()); + EasyMock.verify(reader); + } + + public void testBadUri() throws Exception { + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getAttributeValue(null, "uri")).andReturn("foo foo"); + EasyMock.replay(reader); + try { + loader.load(null, reader, null); + fail(); + } catch (LoaderException e) { + // expected + } + EasyMock.verify(reader); + } + + protected void setUp() throws Exception { + super.setUp(); + loader = new LocalBindingLoader(null); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerInvocationExceptionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerInvocationExceptionTestCase.java new file mode 100644 index 0000000000..9b83d95918 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerInvocationExceptionTestCase.java @@ -0,0 +1,84 @@ +/* + * 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.core.binding.local; + +import java.lang.reflect.Type; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.wire.InvocationChainImpl; +import org.apache.tuscany.core.wire.WireImpl; + +/** + * @version $Rev$ $Date$ + */ +public class LocalCallbackTargetInvokerInvocationExceptionTestCase extends TestCase { + + /** + * Verfies an InvocationTargetException thrown when invoking the target is propagated to the client correctly and + * the originating error is unwrapped + */ + public void testThrowableTargetInvocation() throws Exception { + Operation<Type> operation = new Operation<Type>("echo", null, null, null); + Interceptor head = new ErrorInterceptor(); + InvocationChain chain = new InvocationChainImpl(operation); + chain.addInterceptor(head); + Wire wire = new WireImpl(); + wire.addCallbackInvocationChain(operation, chain); + LocalCallbackTargetInvoker invoker = new LocalCallbackTargetInvoker(operation, wire); + Message msg = new MessageImpl(); + msg.setBody("foo"); + Message response = invoker.invoke(msg); + assertTrue(response.isFault()); + Object body = response.getBody(); + assertTrue(SomeException.class.equals(body.getClass())); + } + + private class SomeException extends Exception { + + } + + private class ErrorInterceptor implements Interceptor { + + public Message invoke(Message msg) { + msg.setBodyWithFault(new SomeException()); + return msg; + } + + public void setNext(Interceptor next) { + + } + + public Interceptor getNext() { + return null; + } + + public boolean isOptimizable() { + return false; + } + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerTestCase.java new file mode 100644 index 0000000000..d922ec8033 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerTestCase.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.core.binding.local; + +import java.lang.reflect.Type; +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class LocalCallbackTargetInvokerTestCase extends TestCase { + private Wire wire; + private Message message; + private InvocationChain chain; + private Interceptor head; + private LocalCallbackTargetInvoker invoker; + + /** + * Verfies the normal execution path through a callback + */ + public void testNormalPathMessageInvocation() throws Exception { + Message response = invoker.invoke(message); + assertEquals("response", response.getBody()); + EasyMock.verify(wire); + EasyMock.verify(chain); + EasyMock.verify(head); + } + + protected void setUp() throws Exception { + super.setUp(); + URI targetAddress = URI.create("from"); + message = new MessageImpl(); + message.pushCallbackUri(targetAddress); + message.setBody("foo"); + Message response = new MessageImpl(); + response.setBody("response"); + Operation<Type> operation = new Operation<Type>("echo", null, null, null); + head = EasyMock.createMock(Interceptor.class); + EasyMock.expect(head.invoke(EasyMock.isA(Message.class))).andReturn(response); + EasyMock.replay(head); + chain = EasyMock.createMock(InvocationChain.class); + EasyMock.expect(chain.getTargetInvoker()).andReturn(null); + EasyMock.expect(chain.getHeadInterceptor()).andReturn(head); + EasyMock.replay(chain); + Map<Operation<?>, InvocationChain> chains = new HashMap<Operation<?>, InvocationChain>(); + chains.put(operation, chain); + wire = EasyMock.createMock(Wire.class); + EasyMock.expect(wire.getCallbackInvocationChains()).andReturn(chains); + EasyMock.replay(wire); + + invoker = new LocalCallbackTargetInvoker(operation, wire); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerThrowableTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerThrowableTestCase.java new file mode 100644 index 0000000000..0c06842a60 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerThrowableTestCase.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.binding.local; + +import java.lang.reflect.Type; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.wire.InvocationChainImpl; +import org.apache.tuscany.core.wire.WireImpl; + +/** + * @version $Rev$ $Date$ + */ +public class LocalCallbackTargetInvokerThrowableTestCase extends TestCase { + private LocalCallbackTargetInvoker invoker; + + /** + * Verfies an exception thrown in the target is propagated to the client correctly + */ + public void testThrowableTargetInvocation() throws Exception { + Message message = new MessageImpl(); + message.setBody("foo"); + Message response = invoker.invoke(message); + assertTrue(response.isFault()); + Object body = response.getBody(); + if (!(body instanceof InsidiousException)) { + fail(); + } + } + + @SuppressWarnings("unchecked") + protected void setUp() throws Exception { + super.setUp(); + Operation<Type> operation = new Operation<Type>("echo", null, null, null); + InvocationChain chain = new InvocationChainImpl(operation); + chain.addInterceptor(new InsidiuousInterceptor()); + Wire wire = new WireImpl(); + wire.addCallbackInvocationChain(operation, chain); + invoker = new LocalCallbackTargetInvoker(operation, wire); + } + + private class InsidiousException extends RuntimeException { + + } + + private class InsidiuousInterceptor implements Interceptor { + + public Message invoke(Message msg) throws InsidiousException { + throw new InsidiousException(); + } + + public void setNext(Interceptor next) { + + } + + public Interceptor getNext() { + return null; + } + + public boolean isOptimizable() { + return false; + } + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalTargetInvokerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalTargetInvokerTestCase.java new file mode 100644 index 0000000000..e49447164d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/binding/local/LocalTargetInvokerTestCase.java @@ -0,0 +1,115 @@ +/* + * 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.core.binding.local; + +import java.net.URI; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.wire.InvocationChainImpl; +import org.apache.tuscany.core.wire.WireImpl; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class LocalTargetInvokerTestCase extends TestCase { + private ServiceContract<Object> serviceContract; + private Operation<Object> operation; + + public void testInvoke() { + TargetInvoker targetInvoker = EasyMock.createMock(TargetInvoker.class); + EasyMock.expect(targetInvoker.invoke(EasyMock.isA(Message.class))).andReturn(new MessageImpl()); + EasyMock.replay(targetInvoker); + InvocationChain chain = new InvocationChainImpl(operation); + chain.setTargetInvoker(targetInvoker); + Wire wire = new WireImpl(); + wire.addInvocationChain(operation, chain); + wire.setSourceContract(serviceContract); + TargetInvoker invoker = new LocalTargetInvoker(operation, wire); + Message msg = invoker.invoke(new MessageImpl()); + assertFalse(msg.isFault()); + EasyMock.verify(targetInvoker); + } + + public void testCallbackSetInvoke() { + ServiceContract<?> contract = new ServiceContract<Object>() { + + }; + contract.setCallbackClass(Object.class); + TargetInvoker targetInvoker = EasyMock.createMock(TargetInvoker.class); + EasyMock.expect(targetInvoker.invoke(EasyMock.isA(Message.class))).andReturn(new MessageImpl()); + EasyMock.replay(targetInvoker); + + InvocationChain chain = new InvocationChainImpl(operation); + chain.setTargetInvoker(targetInvoker); + InvocationChain callbackChain = new InvocationChainImpl(operation); + Wire wire = new WireImpl(); + wire.addInvocationChain(operation, chain); + wire.addCallbackInvocationChain(operation, callbackChain); + wire.setSourceContract(serviceContract); + URI uri = URI.create("foo"); + wire.setSourceUri(uri); + wire.addInvocationChain(operation, chain); + TargetInvoker invoker = new LocalTargetInvoker(operation, wire); + Message msg = EasyMock.createMock(Message.class); + msg.pushCallbackUri(EasyMock.eq(uri)); + EasyMock.replay(msg); + invoker.invoke(msg); + EasyMock.verify(msg); + EasyMock.verify(targetInvoker); + } + + public void testFaultInvoke() { + TargetInvoker targetInvoker = EasyMock.createMock(TargetInvoker.class); + EasyMock.expect(targetInvoker.invoke(EasyMock.isA(Message.class))).andThrow(new TestException()); + EasyMock.replay(targetInvoker); + + InvocationChain chain = new InvocationChainImpl(operation); + chain.setTargetInvoker(targetInvoker); + Wire wire = new WireImpl(); + wire.setSourceContract(serviceContract); + wire.addInvocationChain(operation, chain); + TargetInvoker invoker = new LocalTargetInvoker(operation, wire); + Message msg = invoker.invoke(new MessageImpl()); + assertTrue(msg.isFault()); + assertTrue(msg.getBody() instanceof TestException); + EasyMock.verify(targetInvoker); + } + + + protected void setUp() throws Exception { + super.setUp(); + serviceContract = new ServiceContract<Object>() { + }; + operation = new Operation<Object>("foo", null, null, null); + } + + + private class TestException extends RuntimeException { + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/bootstrap/BootstrapperTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/bootstrap/BootstrapperTestCase.java new file mode 100644 index 0000000000..75c18a8230 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/bootstrap/BootstrapperTestCase.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.core.bootstrap; + +import junit.framework.TestCase; + +import org.apache.tuscany.core.deployer.DeployerImpl; +import org.apache.tuscany.core.monitor.NullMonitorFactory; + +/** + * Verifies the default bootstrapper can be instantiated + * + * @version $Rev$ $Date$ + */ +public class BootstrapperTestCase extends TestCase { + private Bootstrapper bootstrapper; + + public void testDeployerBootstrap() { + DeployerImpl deployer = (DeployerImpl) bootstrapper.createDeployer(); + } + + protected void setUp() throws Exception { + super.setUp(); + bootstrapper = new DefaultBootstrapper(new NullMonitorFactory(), null, null, null, null); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/AtomicConnectorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/AtomicConnectorTestCase.java new file mode 100644 index 0000000000..b83f0fe57c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/AtomicConnectorTestCase.java @@ -0,0 +1,201 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.builder; + +import java.net.URI; + +import org.apache.tuscany.spi.builder.Connector; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.ReferenceBinding; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.component.ServiceBinding; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ReferenceTarget; +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.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.ComponentManager; +import org.apache.tuscany.core.component.ComponentManagerImpl; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.implementation.composite.CompositeComponentImpl; +import org.apache.tuscany.core.implementation.composite.ReferenceImpl; +import org.apache.tuscany.core.implementation.composite.ServiceImpl; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class AtomicConnectorTestCase extends TestCase { + private static final URI PARENT = URI.create("parent"); + private static final URI SOURCE = URI.create("source"); + private static final URI TARGET = URI.create("parent#target"); + private static final URI TARGET_NOFRAGMENT = URI.create("target"); + private static final URI REFERENCE_NAME = URI.create("#ref"); + private ComponentManager manager; + private Connector connector; + private ServiceContract<?> contract; + + /** + * Verifies connecting a wire from an atomic component to a target atomic component + */ + @SuppressWarnings({"unchecked"}) + public void testConnectToAtomic() throws Exception { + AtomicComponent source = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(source.getUri()).andReturn(SOURCE).atLeastOnce(); + EasyMock.expect(source.getScope()).andReturn(Scope.COMPOSITE); + source.attachWire(EasyMock.isA(Wire.class)); + EasyMock.replay(source); + manager.register(source); + + AtomicComponent target = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(target.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.expect(target.isOptimizable()).andReturn(false); + EasyMock.expect(target.getUri()).andReturn(TARGET_NOFRAGMENT).atLeastOnce(); + target.createTargetInvoker((String) EasyMock.isNull(), EasyMock.isA(Operation.class)); + EasyMock.expectLastCall().andReturn(null); + EasyMock.replay(target); + manager.register(target); + + Implementation impl = new Implementation() { + }; + ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + ReferenceDefinition referenceDefinition = new ReferenceDefinition(REFERENCE_NAME, contract); + type.add(referenceDefinition); + impl.setComponentType(type); + + ComponentDefinition<?> definition = new ComponentDefinition(impl); + definition.setUri(SOURCE); + ReferenceTarget referenceTarget = new ReferenceTarget(); + referenceTarget.setReferenceName(REFERENCE_NAME); + referenceTarget.addTarget(TARGET_NOFRAGMENT); + definition.add(referenceTarget); + + connector.connect(definition); + EasyMock.verify(source); + EasyMock.verify(target); + } + + @SuppressWarnings({"unchecked"}) + public void testConnectToReference() throws Exception { + AtomicComponent source = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(source.getUri()).andReturn(SOURCE).atLeastOnce(); + source.attachWire(EasyMock.isA(Wire.class)); + EasyMock.expect(source.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(source); + manager.register(source); + + ReferenceBinding binding = EasyMock.createMock(ReferenceBinding.class); + binding.createTargetInvoker(EasyMock.isA(String.class), EasyMock.isA(Operation.class)); + EasyMock.expectLastCall().andReturn(null); + EasyMock.replay(binding); + + Reference reference = new ReferenceImpl(TARGET, contract); + reference.addReferenceBinding(binding); + + Component component = new CompositeComponentImpl(PARENT); + component.register(reference); + manager.register(component); + + Implementation impl = new Implementation() { + }; + ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + ReferenceDefinition referenceDefinition = new ReferenceDefinition(REFERENCE_NAME, contract); + type.add(referenceDefinition); + impl.setComponentType(type); + + ComponentDefinition<?> definition = new ComponentDefinition(impl); + definition.setUri(SOURCE); + ReferenceTarget referenceTarget = new ReferenceTarget(); + referenceTarget.setReferenceName(REFERENCE_NAME); + referenceTarget.addTarget(TARGET); + definition.add(referenceTarget); + + connector.connect(definition); + EasyMock.verify(source); + EasyMock.verify(binding); + } + + @SuppressWarnings({"unchecked"}) + public void testConnectToService() throws Exception { + AtomicComponent source = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(source.getUri()).andReturn(SOURCE).atLeastOnce(); + EasyMock.expect(source.getScope()).andReturn(Scope.COMPOSITE); + source.attachWire(EasyMock.isA(Wire.class)); + EasyMock.replay(source); + manager.register(source); + + ServiceBinding binding = EasyMock.createMock(ServiceBinding.class); + binding.createTargetInvoker(EasyMock.isA(String.class), EasyMock.isA(Operation.class)); + EasyMock.expectLastCall().andReturn(null); + EasyMock.replay(binding); + + Service service = new ServiceImpl(TARGET, contract); + service.addServiceBinding(binding); + + Component component = new CompositeComponentImpl(PARENT); + component.register(service); + manager.register(component); + + Implementation impl = new Implementation() { + }; + ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + ReferenceDefinition referenceDefinition = new ReferenceDefinition(REFERENCE_NAME, contract); + type.add(referenceDefinition); + impl.setComponentType(type); + + ComponentDefinition<?> definition = new ComponentDefinition(impl); + definition.setUri(SOURCE); + ReferenceTarget referenceTarget = new ReferenceTarget(); + referenceTarget.setReferenceName(REFERENCE_NAME); + referenceTarget.addTarget(TARGET); + definition.add(referenceTarget); + + connector.connect(definition); + EasyMock.verify(source); + EasyMock.verify(binding); + } + + protected void setUp() throws Exception { + super.setUp(); + manager = new ComponentManagerImpl(); + connector = new ConnectorImpl(null, manager, null, null); + JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl(); + contract = registry.introspect(Foo.class); + } + + + private interface Foo { + void bar(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/BuilderRegistryNoBindingsTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/BuilderRegistryNoBindingsTestCase.java new file mode 100644 index 0000000000..f13ed3367d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/BuilderRegistryNoBindingsTestCase.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.builder; + +import java.net.URI; + +import org.apache.tuscany.spi.builder.BuilderRegistry; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.ReferenceBinding; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.component.ServiceBinding; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.Multiplicity; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; +import org.apache.tuscany.core.binding.local.LocalBindingBuilder; +import org.apache.tuscany.core.binding.local.LocalBindingDefinition; +import org.apache.tuscany.core.binding.local.LocalReferenceBinding; +import org.apache.tuscany.core.binding.local.LocalServiceBinding; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class BuilderRegistryNoBindingsTestCase extends TestCase { + private DeploymentContext deploymentContext; + private Component parent; + private BuilderRegistry registry; + + public void testNoServiceBindings() throws Exception { + ServiceBinding binding = EasyMock.createNiceMock(ServiceBinding.class); + EasyMock.replay(binding); + ServiceDefinition definition = new ServiceDefinition(URI.create("#foo"), null, false); + definition.setTarget(new URI("foo")); + EasyMock.replay(deploymentContext); + EasyMock.replay(parent); + + Service service = registry.build(definition, deploymentContext); + + assertEquals(1, service.getServiceBindings().size()); + assertTrue(service.getServiceBindings().get(0) instanceof LocalServiceBinding); + EasyMock.verify(deploymentContext); + EasyMock.verify(parent); + } + + public void testReferenceBindingBuilderDispatch() throws Exception { + ReferenceBinding binding = EasyMock.createNiceMock(ReferenceBinding.class); + EasyMock.replay(binding); + ReferenceDefinition definition = new ReferenceDefinition(URI.create("#foo"), null, Multiplicity.ONE_ONE); + EasyMock.replay(deploymentContext); + EasyMock.replay(parent); + + Reference reference = registry.build(definition, deploymentContext); + + assertEquals(1, reference.getReferenceBindings().size()); + assertTrue(reference.getReferenceBindings().get(0) instanceof LocalReferenceBinding); + EasyMock.verify(deploymentContext); + EasyMock.verify(parent); + } + + protected void setUp() throws Exception { + super.setUp(); + deploymentContext = EasyMock.createMock(DeploymentContext.class); + parent = EasyMock.createNiceMock(Component.class); + registry = new BuilderRegistryImpl(null); + registry.register(LocalBindingDefinition.class, new LocalBindingBuilder()); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/BuilderRegistryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/BuilderRegistryTestCase.java new file mode 100644 index 0000000000..34173154b8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/BuilderRegistryTestCase.java @@ -0,0 +1,190 @@ +/* + * 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.core.builder; + +import java.net.URI; +import java.util.Map; + +import org.apache.tuscany.spi.builder.BindingBuilder; +import org.apache.tuscany.spi.builder.BuilderConfigException; +import org.apache.tuscany.spi.builder.BuilderRegistry; +import org.apache.tuscany.spi.builder.ComponentBuilder; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.ReferenceBinding; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.ScopeRegistry; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.component.ServiceBinding; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.BindingDefinition; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.CompositeImplementation; +import org.apache.tuscany.spi.model.Implementation; +import static org.apache.tuscany.spi.model.Multiplicity.ONE_ONE; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class BuilderRegistryTestCase extends TestCase { + private DeploymentContext deploymentContext; + private ScopeContainer scopeContainer; + private Map<URI, Component> components; + + //private BuilderRegistryImpl registry; + private Component parent; + + @SuppressWarnings({"unchecked"}) + public void testRegistration() throws Exception { + URI componentId = URI.create("sca://localhost/component"); + CompositeImplementation implementation = new CompositeImplementation(); + ComponentDefinition<CompositeImplementation> componentDefinition = + new ComponentDefinition<CompositeImplementation>(implementation); + componentDefinition.getImplementation().setComponentType(new CompositeComponentType()); + + Component component = EasyMock.createMock(Component.class); + component.setDefaultPropertyValues(componentDefinition.getPropertyValues()); + component.setScopeContainer(scopeContainer); + EasyMock.expect(component.getUri()).andReturn(componentId); + EasyMock.replay(component); + + EasyMock.expect(deploymentContext.getCompositeScope()).andReturn(scopeContainer); + EasyMock.expect(deploymentContext.getComponents()).andReturn(components); + EasyMock.replay(deploymentContext); + + EasyMock.expect(components.put(componentId, component)).andReturn(null); + EasyMock.replay(components); + + ComponentBuilder builder = EasyMock.createMock(ComponentBuilder.class); + EasyMock.expect(builder.build(componentDefinition, deploymentContext)).andReturn(component); + EasyMock.replay(builder); + + BuilderRegistry registry = new BuilderRegistryImpl(null); + registry.register(CompositeImplementation.class, builder); + + assertSame(component, registry.build(componentDefinition, deploymentContext)); + EasyMock.verify(builder); + } + + @SuppressWarnings({"unchecked"}) + public void testServiceBindingBuilderDispatch() throws Exception { + BuilderRegistry registry = new BuilderRegistryImpl(null); + ServiceBinding binding = EasyMock.createNiceMock(ServiceBinding.class); + EasyMock.replay(binding); + BindingBuilder<MockBindingDefinition> builder = EasyMock.createMock(BindingBuilder.class); + EasyMock.expect(builder.build( + EasyMock.isA(ServiceDefinition.class), + EasyMock.isA(MockBindingDefinition.class), + EasyMock.isA(DeploymentContext.class))).andReturn(binding).times(2); + EasyMock.replay(builder); + registry.register(MockBindingDefinition.class, builder); + ServiceDefinition definition = new ServiceDefinition(URI.create("#foo"), null, false); + definition.addBinding(new MockBindingDefinition()); + definition.addBinding(new MockBindingDefinition()); + definition.setTarget(new URI("foo")); + Service service = registry.build(definition, deploymentContext); + assertEquals(2, service.getServiceBindings().size()); + } + + @SuppressWarnings({"unchecked"}) + public void testReferenceBindingBuilderDispatch() throws Exception { + BuilderRegistry registry = new BuilderRegistryImpl(null); + ReferenceBinding binding = EasyMock.createNiceMock(ReferenceBinding.class); + EasyMock.replay(binding); + BindingBuilder<MockBindingDefinition> builder = EasyMock.createMock(BindingBuilder.class); + EasyMock.expect(builder.build( + EasyMock.isA(ReferenceDefinition.class), + EasyMock.isA(MockBindingDefinition.class), + EasyMock.isA(DeploymentContext.class))).andReturn(binding).times(2); + EasyMock.replay(builder); + registry.register(MockBindingDefinition.class, builder); + ReferenceDefinition definition = new ReferenceDefinition(URI.create("#foo"), null, ONE_ONE); + definition.addBinding(new MockBindingDefinition()); + definition.addBinding(new MockBindingDefinition()); + Reference reference = registry.build(definition, deploymentContext); + assertEquals(2, reference.getReferenceBindings().size()); + } + + @SuppressWarnings({"unchecked"}) + public void testNoConversationalContract() throws Exception { + ScopeRegistry scopeRegistry = EasyMock.createMock(ScopeRegistry.class); + ScopeContainer scopeContainer = EasyMock.createNiceMock(ScopeContainer.class); + EasyMock.expect(scopeRegistry.getScopeContainer(EasyMock.isA(Scope.class))).andReturn(scopeContainer); + EasyMock.replay(scopeRegistry); + BuilderRegistry registry = new BuilderRegistryImpl(scopeRegistry); + + AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class); + EasyMock.replay(component); + ComponentBuilder<FooImplementation> builder = EasyMock.createMock(ComponentBuilder.class); + EasyMock.expect(builder.build( + EasyMock.isA(ComponentDefinition.class), + EasyMock.isA(DeploymentContext.class))).andReturn(component); + EasyMock.replay(builder); + registry.register(FooImplementation.class, builder); + + FooImplementation impl = new FooImplementation(); + ComponentType componentType = new ComponentType(); + componentType.setImplementationScope(Scope.CONVERSATION); + impl.setComponentType(componentType); + URI uri = URI.create("foo"); + ComponentDefinition<FooImplementation> definition = new ComponentDefinition<FooImplementation>(uri, impl); + try { + registry.build(definition, deploymentContext); + fail("Should throw NoConversationalContractException"); + } catch (NoConversationalContractException e) { + // expected + } + } + + @SuppressWarnings({"unchecked"}) + protected void setUp() throws Exception { + super.setUp(); + deploymentContext = EasyMock.createMock(DeploymentContext.class); + parent = EasyMock.createNiceMock(Component.class); + scopeContainer = EasyMock.createMock(ScopeContainer.class); + components = EasyMock.createMock(Map.class); + } + + private class MockBuilder implements ComponentBuilder<CompositeImplementation> { + public Component build( + ComponentDefinition componentDefinition, + DeploymentContext deploymentContext) throws BuilderConfigException { + return null; + } + } + + private class MockBindingDefinition extends BindingDefinition { + + } + + private class FooImplementation extends Implementation<ComponentType> { + + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/ConnectorImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/ConnectorImplTestCase.java new file mode 100644 index 0000000000..5c966e0bc5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/ConnectorImplTestCase.java @@ -0,0 +1,320 @@ +/* + * 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.core.builder; + +import java.lang.reflect.Type; +import java.net.URI; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ReferenceTarget; +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.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.ComponentManager; +import org.apache.tuscany.core.component.ComponentManagerImpl; +import org.apache.tuscany.core.wire.InvokerInterceptor; +import org.apache.tuscany.core.wire.NonBlockingInterceptor; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ConnectorImplTestCase extends TestCase { + private TestConnector connector; + private ComponentManager manager; + + public void testConnectTargetNotFound() throws Exception { + Implementation<ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>> impl = + new Implementation<ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>>() { + }; + ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + URI refUri = URI.create("ref"); + ReferenceDefinition referenceDefinition = new ReferenceDefinition(refUri, null); + referenceDefinition.setRequired(true); + type.add(referenceDefinition); + impl.setComponentType(type); + + URI sourceUri = URI.create("source"); + ComponentDefinition<?> definition = + new ComponentDefinition<Implementation<ComponentType<ServiceDefinition, + ReferenceDefinition, Property<?>>>>(impl); + definition.setUri(sourceUri); + ReferenceTarget referenceTarget = new ReferenceTarget(); + referenceTarget.setReferenceName(refUri); + referenceTarget.addTarget(URI.create("NotThere")); + definition.add(referenceTarget); + Component component = EasyMock.createMock(Component.class); + EasyMock.expect(component.getUri()).andReturn(sourceUri); + EasyMock.replay(component); + manager.register(component); + try { + connector.connect(definition); + fail(); + } catch (ComponentNotFoundException e) { + // expected + } + } + + /** + * Verifies a non-existent target does not throw an error. + * <p/> + * TODO JFM when the allocator is in place it should optimize connecting to non-existent targets but keep it for + * now + */ + public void testConnectTargetNotFoundNonRequiredReference() throws Exception { + Implementation<ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>> impl = + new Implementation<ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>>() { + }; + ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + URI refUri = URI.create("ref"); + ReferenceDefinition referenceDefinition = new ReferenceDefinition(refUri, null); + referenceDefinition.setRequired(false); + type.add(referenceDefinition); + impl.setComponentType(type); + + URI sourceUri = URI.create("source"); + ComponentDefinition<?> definition = + new ComponentDefinition<Implementation<ComponentType<ServiceDefinition, + ReferenceDefinition, Property<?>>>>(impl); + definition.setUri(sourceUri); + ReferenceTarget referenceTarget = new ReferenceTarget(); + referenceTarget.setReferenceName(refUri); + referenceTarget.addTarget(URI.create("NotThere")); + definition.add(referenceTarget); + Component component = EasyMock.createMock(Component.class); + EasyMock.expect(component.getUri()).andReturn(sourceUri); + EasyMock.replay(component); + manager.register(component); + connector.connect(definition); + } + + public void testNonOptimizableTargetComponent() throws Exception { + AtomicComponent source = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(source.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(source); + + AtomicComponent target = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(target.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.expect(target.isOptimizable()).andReturn(false); + EasyMock.replay(target); + + Wire wire = EasyMock.createMock(Wire.class); + wire.setOptimizable(false); + EasyMock.replay(wire); + connector.optimize(source, target, wire); + EasyMock.verify(source); + EasyMock.verify(target); + EasyMock.verify(wire); + } + + public void testOptimizableTargetComponent() throws Exception { + AtomicComponent source = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(source.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(source); + + AtomicComponent target = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(target.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.expect(target.isOptimizable()).andReturn(true); + EasyMock.replay(target); + + Wire wire = EasyMock.createMock(Wire.class); + wire.setOptimizable(true); + wire.setTarget(EasyMock.eq(target)); + wire.getInvocationChains(); + EasyMock.expectLastCall().andReturn(Collections.emptyMap()); + wire.getCallbackInvocationChains(); + EasyMock.expectLastCall().andReturn(Collections.emptyMap()); + EasyMock.replay(wire); + connector.optimize(source, target, wire); + EasyMock.verify(source); + EasyMock.verify(target); + } + + public void testIsOptimizable() { + assertTrue(connector.isOptimizable(Scope.STATELESS, Scope.STATELESS)); + assertTrue(connector.isOptimizable(Scope.STATELESS, Scope.COMPOSITE)); + assertFalse(connector.isOptimizable(Scope.STATELESS, Scope.CONVERSATION)); + assertTrue(connector.isOptimizable(Scope.STATELESS, Scope.REQUEST)); + assertTrue(connector.isOptimizable(Scope.STATELESS, Scope.SESSION)); + assertTrue(connector.isOptimizable(Scope.STATELESS, Scope.SYSTEM)); + + assertTrue(connector.isOptimizable(Scope.COMPOSITE, Scope.COMPOSITE)); + assertFalse(connector.isOptimizable(Scope.COMPOSITE, Scope.CONVERSATION)); + assertFalse(connector.isOptimizable(Scope.COMPOSITE, Scope.REQUEST)); + assertFalse(connector.isOptimizable(Scope.COMPOSITE, Scope.SESSION)); + assertFalse(connector.isOptimizable(Scope.COMPOSITE, Scope.STATELESS)); + assertTrue(connector.isOptimizable(Scope.COMPOSITE, Scope.SYSTEM)); + + assertFalse(connector.isOptimizable(Scope.CONVERSATION, Scope.COMPOSITE)); + assertFalse(connector.isOptimizable(Scope.CONVERSATION, Scope.CONVERSATION)); + assertFalse(connector.isOptimizable(Scope.CONVERSATION, Scope.REQUEST)); + assertFalse(connector.isOptimizable(Scope.CONVERSATION, Scope.SESSION)); + assertFalse(connector.isOptimizable(Scope.CONVERSATION, Scope.STATELESS)); + assertFalse(connector.isOptimizable(Scope.CONVERSATION, Scope.SYSTEM)); + + assertTrue(connector.isOptimizable(Scope.REQUEST, Scope.COMPOSITE)); + assertFalse(connector.isOptimizable(Scope.REQUEST, Scope.CONVERSATION)); + assertTrue(connector.isOptimizable(Scope.REQUEST, Scope.REQUEST)); + assertTrue(connector.isOptimizable(Scope.REQUEST, Scope.SESSION)); + assertFalse(connector.isOptimizable(Scope.REQUEST, Scope.STATELESS)); + assertTrue(connector.isOptimizable(Scope.REQUEST, Scope.SYSTEM)); + + assertTrue(connector.isOptimizable(Scope.SESSION, Scope.COMPOSITE)); + assertFalse(connector.isOptimizable(Scope.SESSION, Scope.CONVERSATION)); + assertFalse(connector.isOptimizable(Scope.SESSION, Scope.REQUEST)); + assertTrue(connector.isOptimizable(Scope.SESSION, Scope.SESSION)); + assertFalse(connector.isOptimizable(Scope.SESSION, Scope.STATELESS)); + assertTrue(connector.isOptimizable(Scope.SESSION, Scope.SYSTEM)); + + assertTrue(connector.isOptimizable(Scope.SYSTEM, Scope.COMPOSITE)); + assertFalse(connector.isOptimizable(Scope.SYSTEM, Scope.CONVERSATION)); + assertFalse(connector.isOptimizable(Scope.SYSTEM, Scope.REQUEST)); + assertFalse(connector.isOptimizable(Scope.SYSTEM, Scope.SESSION)); + assertFalse(connector.isOptimizable(Scope.SYSTEM, Scope.STATELESS)); + assertTrue(connector.isOptimizable(Scope.SYSTEM, Scope.SYSTEM)); + + assertFalse(connector.isOptimizable(Scope.UNDEFINED, Scope.COMPOSITE)); + assertFalse(connector.isOptimizable(Scope.UNDEFINED, Scope.CONVERSATION)); + assertFalse(connector.isOptimizable(Scope.UNDEFINED, Scope.REQUEST)); + assertFalse(connector.isOptimizable(Scope.UNDEFINED, Scope.SESSION)); + assertFalse(connector.isOptimizable(Scope.UNDEFINED, Scope.STATELESS)); + assertFalse(connector.isOptimizable(Scope.UNDEFINED, Scope.SYSTEM)); + + } + + public void testCreateSyncForwardWire() throws Exception { + ServiceContract<Type> contract = new ServiceContract<Type>() { + + }; + Operation<Type> operation = new Operation<Type>("operation", null, null, null); + Map<String, Operation<Type>> operations = new HashMap<String, Operation<Type>>(); + operations.put("operation", operation); + contract.setOperations(operations); + Wire wire = connector.createWire(URI.create("target"), URI.create("#ref"), contract, Wire.LOCAL_BINDING); + assertEquals(1, wire.getInvocationChains().size()); + InvocationChain chain = wire.getInvocationChains().get(operation); + Interceptor head = chain.getHeadInterceptor(); + assertTrue(head instanceof InvokerInterceptor); + } + + public void testCreateSyncCallbackWire() throws Exception { + ServiceContract<Type> contract = new ServiceContract<Type>() { + + }; + + Operation<Type> operation = new Operation<Type>("operation", null, null, null); + Map<String, Operation<Type>> operations = new HashMap<String, Operation<Type>>(); + operations.put("operation", operation); + contract.setOperations(operations); + + Operation<Type> callbackOperation = new Operation<Type>("operation", null, null, null); + Map<String, Operation<Type>> callbackOperations = new HashMap<String, Operation<Type>>(); + callbackOperations.put("operation", callbackOperation); + contract.setCallbackOperations(callbackOperations); + + Wire wire = connector.createWire(URI.create("target"), URI.create("#ref"), contract, Wire.LOCAL_BINDING); + assertEquals(1, wire.getCallbackInvocationChains().size()); + InvocationChain chain = wire.getCallbackInvocationChains().get(callbackOperation); + Interceptor head = chain.getHeadInterceptor(); + assertTrue(head instanceof InvokerInterceptor); + } + + public void testCreateNonBlockingForwardWire() throws Exception { + ServiceContract<Type> contract = new ServiceContract<Type>() { + + }; + Operation<Type> operation = new Operation<Type>("operation", null, null, null); + operation.setNonBlocking(true); + Map<String, Operation<Type>> operations = new HashMap<String, Operation<Type>>(); + operations.put("operation", operation); + contract.setOperations(operations); + Wire wire = connector.createWire(URI.create("target"), URI.create("#ref"), contract, Wire.LOCAL_BINDING); + assertEquals(1, wire.getInvocationChains().size()); + InvocationChain chain = wire.getInvocationChains().get(operation); + Interceptor head = chain.getHeadInterceptor(); + assertTrue(head instanceof NonBlockingInterceptor); + assertTrue(head.getNext() instanceof InvokerInterceptor); + } + + public void testCreateNonBlockingCallbackWire() throws Exception { + ServiceContract<Type> contract = new ServiceContract<Type>() { + + }; + + Operation<Type> operation = new Operation<Type>("operation", null, null, null); + operation.setNonBlocking(true); + Map<String, Operation<Type>> operations = new HashMap<String, Operation<Type>>(); + operations.put("operation", operation); + contract.setOperations(operations); + + Operation<Type> callbackOperation = new Operation<Type>("operation", null, null, null); + callbackOperation.setNonBlocking(true); + Map<String, Operation<Type>> callbackOperations = new HashMap<String, Operation<Type>>(); + callbackOperations.put("operation", callbackOperation); + contract.setCallbackOperations(callbackOperations); + + Wire wire = connector.createWire(URI.create("target"), URI.create("#ref"), contract, Wire.LOCAL_BINDING); + assertEquals(1, wire.getCallbackInvocationChains().size()); + InvocationChain chain = wire.getCallbackInvocationChains().get(callbackOperation); + Interceptor head = chain.getHeadInterceptor(); + assertTrue(head instanceof NonBlockingInterceptor); + assertTrue(head.getNext() instanceof InvokerInterceptor); + } + + protected void setUp() throws Exception { + super.setUp(); + manager = new ComponentManagerImpl(); + connector = new TestConnector(manager); + } + + private class TestConnector extends ConnectorImpl { + + public TestConnector(ComponentManager componentManager) { + super(componentManager); + } + + protected Wire createWire(URI sourceURI, URI targetUri, ServiceContract<?> contract, QName bindingType) { + return super.createWire(sourceURI, targetUri, contract, bindingType); + } + + public boolean isOptimizable(Scope pReferrer, Scope pReferee) { + return super.isOptimizable(pReferrer, pReferee); + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/IllegalCallbackExceptionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/IllegalCallbackExceptionTestCase.java new file mode 100644 index 0000000000..c6a9927db3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/IllegalCallbackExceptionTestCase.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.builder; + +import java.net.URI; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class IllegalCallbackExceptionTestCase extends TestCase { + + public void testInstantiation() throws Exception { + URI sourceUri = URI.create("source"); + URI targetUri = URI.create("target"); + IllegalCallbackException e = new IllegalCallbackException("message", "identifier", sourceUri, targetUri); + assertEquals("message", e.getMessage()); + assertEquals("identifier", e.getIdentifier()); + assertEquals(sourceUri, e.getSourceUri()); + assertEquals(targetUri, e.getTargetUri()); + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/IncompatibleInterfacesExceptionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/IncompatibleInterfacesExceptionTestCase.java new file mode 100644 index 0000000000..5d370fcfc5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/IncompatibleInterfacesExceptionTestCase.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.core.builder; + +import java.net.URI; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class IncompatibleInterfacesExceptionTestCase extends TestCase { + + public void testInstantiation() throws Exception { + URI sourceUri = URI.create("source"); + URI targetUri = URI.create("target"); + IncompatibleInterfacesException e = new IncompatibleInterfacesException(sourceUri, targetUri); + assertNotNull(e.getMessage()); + assertEquals("source", e.getSourceUri().toString()); + assertEquals("target", e.getTargetUri().toString()); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/InvalidSourceTypeExceptionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/InvalidSourceTypeExceptionTestCase.java new file mode 100644 index 0000000000..67ad003d58 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/InvalidSourceTypeExceptionTestCase.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.builder; + +import java.net.URI; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class InvalidSourceTypeExceptionTestCase extends TestCase { + + public void testInstantiation() throws Exception { + URI sourceUri = URI.create("source"); + URI targetUri = URI.create("target"); + InvalidSourceTypeException e = new InvalidSourceTypeException("message", sourceUri, targetUri); + assertEquals("message", e.getMessage()); + assertEquals(sourceUri, e.getSourceUri()); + assertEquals(targetUri, e.getTargetUri()); + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/InvalidTargetTypeExceptionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/InvalidTargetTypeExceptionTestCase.java new file mode 100644 index 0000000000..61060293ce --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/InvalidTargetTypeExceptionTestCase.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.builder; + +import java.net.URI; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class InvalidTargetTypeExceptionTestCase extends TestCase { + + public void testInstantiation() throws Exception { + URI sourceUri = URI.create("source"); + URI targetUri = URI.create("target"); + InvalidTargetTypeException e = new InvalidTargetTypeException("message", sourceUri, targetUri); + assertEquals("message", e.getMessage()); + assertEquals(sourceUri, e.getSourceUri()); + assertEquals(targetUri, e.getTargetUri()); + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/ReferenceConnectorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/ReferenceConnectorTestCase.java new file mode 100644 index 0000000000..53511db2cb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/ReferenceConnectorTestCase.java @@ -0,0 +1,156 @@ +/* + * 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.core.builder; + +import java.net.URI; + +import org.apache.tuscany.spi.builder.WiringException; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.ReferenceBinding; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.model.BindingDefinition; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.ComponentManager; +import org.apache.tuscany.core.component.ComponentManagerImpl; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.implementation.composite.CompositeComponentImpl; +import org.apache.tuscany.core.implementation.composite.ReferenceImpl; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ReferenceConnectorTestCase extends TestCase { + private static final URI PARENT = URI.create("parent"); + private static final URI SOURCE = URI.create("parent#source"); + private static final URI TARGET = URI.create("parent/target"); + private static final URI REFERENCE_TARGET = URI.create("parent#target"); + private ComponentManager manager; + private MockConnnector connector; + private ServiceContract<?> contract; + + /** + * Verifies connecting a wire from an atomic component to a target atomic component + */ + @SuppressWarnings({"unchecked"}) + public void testConnectToAtomic() throws Exception { + ReferenceBinding binding = EasyMock.createMock(ReferenceBinding.class); + EasyMock.expect(binding.getTargetUri()).andReturn(TARGET); + EasyMock.expect(binding.getBindingType()).andReturn(Wire.LOCAL_BINDING).atLeastOnce(); + binding.getBindingServiceContract(); + EasyMock.expectLastCall().andReturn(contract); + binding.setWire(EasyMock.isA(Wire.class)); + EasyMock.replay(binding); + + Reference reference = new ReferenceImpl(SOURCE, contract); + reference.addReferenceBinding(binding); + + Component component = new CompositeComponentImpl(PARENT); + component.register(reference); + manager.register(component); + + + AtomicComponent target = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(target.getUri()).andReturn(TARGET).atLeastOnce(); + target.createTargetInvoker((String) EasyMock.isNull(), EasyMock.isA(Operation.class)); + EasyMock.expectLastCall().andReturn(null); + EasyMock.replay(target); + manager.register(target); + + ReferenceDefinition definition = new ReferenceDefinition(SOURCE, contract); + BindingDefinition bindingDefinition = new BindingDefinition(TARGET) { + }; + definition.addBinding(bindingDefinition); + + connector.connect(definition); + + EasyMock.verify(binding); + EasyMock.verify(target); + } + + @SuppressWarnings({"unchecked"}) + public void testConnectToReference() throws Exception { + ReferenceBinding binding = EasyMock.createMock(ReferenceBinding.class); + EasyMock.expect(binding.getTargetUri()).andReturn(REFERENCE_TARGET); + EasyMock.expect(binding.getBindingType()).andReturn(Wire.LOCAL_BINDING).atLeastOnce(); + binding.getBindingServiceContract(); + EasyMock.expectLastCall().andReturn(contract); + binding.setWire(EasyMock.isA(Wire.class)); + EasyMock.replay(binding); + + Reference reference = new ReferenceImpl(SOURCE, contract); + reference.addReferenceBinding(binding); + + Component component = new CompositeComponentImpl(PARENT); + component.register(reference); + + ReferenceBinding refBinding = EasyMock.createMock(ReferenceBinding.class); + refBinding.createTargetInvoker(EasyMock.isA(String.class), EasyMock.isA(Operation.class)); + EasyMock.expectLastCall().andReturn(null); + EasyMock.replay(refBinding); + Reference target = new ReferenceImpl(REFERENCE_TARGET, contract); + target.addReferenceBinding(refBinding); + component.register(target); + manager.register(component); + + ReferenceDefinition definition = new ReferenceDefinition(SOURCE, contract); + BindingDefinition bindingDefinition = new BindingDefinition(TARGET) { + }; + definition.addBinding(bindingDefinition); + + connector.connect(definition); + + EasyMock.verify(binding); + EasyMock.verify(refBinding); + } + + + protected void setUp() throws Exception { + super.setUp(); + manager = new ComponentManagerImpl(); + connector = new MockConnnector(manager); + JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl(); + contract = registry.introspect(Foo.class); + } + + + private interface Foo { + void bar(); + } + + private class MockConnnector extends ConnectorImpl { + + public MockConnnector(ComponentManager componentManager) { + super(componentManager); + } + + public void connect(ReferenceDefinition definition) throws WiringException { + super.connect(definition); + } + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/ServiceConnectorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/ServiceConnectorTestCase.java new file mode 100644 index 0000000000..32dede5a16 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/ServiceConnectorTestCase.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.core.builder; + +import java.net.URI; + +import org.apache.tuscany.spi.builder.WiringException; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.component.ServiceBinding; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.ReferenceBinding; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.model.BindingDefinition; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.model.ServiceDefinition; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.ComponentManager; +import org.apache.tuscany.core.component.ComponentManagerImpl; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.implementation.composite.CompositeComponentImpl; +import org.apache.tuscany.core.implementation.composite.ServiceImpl; +import org.apache.tuscany.core.implementation.composite.ReferenceImpl; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ServiceConnectorTestCase extends TestCase { + private static final URI PARENT = URI.create("parent"); + private static final URI SOURCE = URI.create("parent#source"); + private static final URI TARGET = URI.create("parent/target"); + private static final URI REFERENCE_TARGET = URI.create("parent#target"); + private ComponentManager manager; + private MockConnnector connector; + private ServiceContract<?> contract; + + /** + * Verifies connecting a wire from an atomic component to a target atomic component + */ + @SuppressWarnings({"unchecked"}) + public void testConnectToAtomic() throws Exception { + ServiceBinding binding = EasyMock.createMock(ServiceBinding.class); + EasyMock.expect(binding.getBindingType()).andReturn(Wire.LOCAL_BINDING); + binding.setWire(EasyMock.isA(Wire.class)); + EasyMock.replay(binding); + + Service service = new ServiceImpl(SOURCE, contract); + service.addServiceBinding(binding); + + Component component = new CompositeComponentImpl(PARENT); + component.register(service); + manager.register(component); + + + AtomicComponent target = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(target.getUri()).andReturn(TARGET).atLeastOnce(); + target.createTargetInvoker((String) EasyMock.isNull(), EasyMock.isA(Operation.class)); + EasyMock.expectLastCall().andReturn(null); + EasyMock.replay(target); + manager.register(target); + + ServiceDefinition definition = new ServiceDefinition(SOURCE, contract, false); + definition.setTarget(TARGET); + BindingDefinition bindingDefinition = new BindingDefinition(TARGET) { + }; + definition.addBinding(bindingDefinition); + connector.connect(definition); + + EasyMock.verify(binding); + EasyMock.verify(target); + } + + @SuppressWarnings({"unchecked"}) + public void testConnectToReference() throws Exception { + ServiceBinding binding = EasyMock.createMock(ServiceBinding.class); + EasyMock.expect(binding.getBindingType()).andReturn(Wire.LOCAL_BINDING); + binding.setWire(EasyMock.isA(Wire.class)); + EasyMock.replay(binding); + + Service service = new ServiceImpl(SOURCE, contract); + service.addServiceBinding(binding); + + Component component = new CompositeComponentImpl(PARENT); + component.register(service); + + ReferenceBinding refBinding = EasyMock.createMock(ReferenceBinding.class); + refBinding.createTargetInvoker(EasyMock.isA(String.class), EasyMock.isA(Operation.class)); + EasyMock.expectLastCall().andReturn(null); + EasyMock.replay(refBinding); + Reference target = new ReferenceImpl(REFERENCE_TARGET, contract); + target.addReferenceBinding(refBinding); + component.register(target); + manager.register(component); + + ServiceDefinition definition = new ServiceDefinition(SOURCE, contract, false); + definition.setTarget(REFERENCE_TARGET); + BindingDefinition bindingDefinition = new BindingDefinition(REFERENCE_TARGET) { + }; + definition.addBinding(bindingDefinition); + connector.connect(definition); + + EasyMock.verify(binding); + EasyMock.verify(refBinding); + } + + + protected void setUp() throws Exception { + super.setUp(); + manager = new ComponentManagerImpl(); + connector = new MockConnnector(manager); + JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl(); + contract = registry.introspect(Foo.class); + } + + + private interface Foo { + void bar(); + } + + private class MockConnnector extends ConnectorImpl { + + public MockConnnector(ComponentManager componentManager) { + super(componentManager); + } + + public void connect(ServiceDefinition definition) throws WiringException { + super.connect(definition); + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/TargetServiceNotFoundExceptionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/TargetServiceNotFoundExceptionTestCase.java new file mode 100644 index 0000000000..2d056ac964 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/TargetServiceNotFoundExceptionTestCase.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.core.builder; + +import java.net.URI; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class TargetServiceNotFoundExceptionTestCase extends TestCase { + + public void testInstantiation() throws Exception { + URI sourceUri = URI.create("source"); + URI targetUri = URI.create("target"); + TargetServiceNotFoundException e = new TargetServiceNotFoundException("message", sourceUri, targetUri); + assertEquals("message", e.getMessage()); + assertEquals(sourceUri, e.getSourceUri()); + assertEquals(targetUri, e.getTargetUri()); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/WirePostProcessorRegistryImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/WirePostProcessorRegistryImplTestCase.java new file mode 100644 index 0000000000..fcd5f03189 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/WirePostProcessorRegistryImplTestCase.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.core.builder; + +import org.apache.tuscany.spi.wire.Wire; +import org.apache.tuscany.spi.wire.WirePostProcessor; +import org.apache.tuscany.spi.wire.WirePostProcessorRegistry; + +import junit.framework.TestCase; +import org.easymock.EasyMock; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.verify; + +/** + * @version $Rev$ $Date$ + */ +public class WirePostProcessorRegistryImplTestCase extends TestCase { + + public void testRegisterUnregister() throws Exception { + WirePostProcessorRegistry registry = new WirePostProcessorRegistryImpl(); + Wire wire = EasyMock.createMock(Wire.class); + WirePostProcessor processor = createMock(WirePostProcessor.class); + processor.process(EasyMock.eq(wire)); + EasyMock.replay(processor); + registry.register(processor); + registry.process(wire); + registry.unregister(processor); + registry.process(wire); + verify(processor); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/WiringExceptionFormatterTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/WiringExceptionFormatterTestCase.java new file mode 100644 index 0000000000..e05a162d7a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/builder/WiringExceptionFormatterTestCase.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.core.builder; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.URI; + +import org.apache.tuscany.spi.builder.WiringException; + +import junit.framework.TestCase; +import org.apache.tuscany.host.monitor.FormatterRegistry; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class WiringExceptionFormatterTestCase extends TestCase { + WiringExceptionFormatter formatter = new WiringExceptionFormatter(EasyMock.createNiceMock(FormatterRegistry.class)); + + public void testFormat() throws Exception { + WiringException e = + new MockWiringException("message", "identifier", URI.create("source"), URI.create("target")); + StringWriter writer = new StringWriter(); + PrintWriter pw = new PrintWriter(writer); + formatter.write(pw, e); + String buffer = writer.toString(); + assertTrue(buffer.indexOf("message") >= 0); + assertTrue(buffer.indexOf("identifier") >= 0); + assertTrue(buffer.indexOf("source") >= 0); + assertTrue(buffer.indexOf("target") >= 0); + } + + + public void testFormatNulls() throws Exception { + WiringException e = new MockWiringException("message", + "identifier", + null, + null); + StringWriter writer = new StringWriter(); + PrintWriter pw = new PrintWriter(writer); + formatter.write(pw, e); + String buffer = writer.toString(); + assertTrue(buffer.indexOf("message") >= 0); + assertTrue(buffer.indexOf("identifier") >= 0); + } + + private class MockWiringException extends WiringException { + + public MockWiringException(String message, String identifier, URI source, URI reference) { + super(message, identifier, source, reference); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/ComponentContextImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/ComponentContextImplTestCase.java new file mode 100644 index 0000000000..8bd25d3a16 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/ComponentContextImplTestCase.java @@ -0,0 +1,91 @@ +/* + * 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.core.component; + +import java.net.URI; + +import junit.framework.TestCase; +import org.easymock.classextension.EasyMock; + +import org.apache.tuscany.core.implementation.PojoAtomicComponent; + +/** + * @version $Rev$ $Date$ + */ +public class ComponentContextImplTestCase extends TestCase { + private PojoAtomicComponent component; + private ComponentContextImpl context; + + public void testURI() { + URI uri = URI.create("foo"); + EasyMock.expect(component.getUri()).andReturn(uri); + EasyMock.replay(component); + assertEquals(uri.toString(), context.getURI()); + EasyMock.verify(component); + } + + public void testGetProperty() { + String name = "foo"; + String value = "bar"; + EasyMock.expect(component.getProperty(String.class, name)).andReturn(value); + EasyMock.replay(component); + assertSame(value, context.getProperty(String.class, name)); + EasyMock.verify(component); + } + + public void testGetPropertyThatIsIncompatible() { + String name = "foo"; + EasyMock.expect(component.getProperty(Integer.class, name)).andThrow(new ClassCastException()); + EasyMock.replay(component); + try { + context.getProperty(Integer.class, name); + fail(); + } catch (ClassCastException e) { + // expected + } + EasyMock.verify(component); + } + + public void testGetPropertyThatIsSubclass() { + String name = "foo"; + String value = "bar"; + EasyMock.expect(component.getProperty(Object.class, name)).andReturn(value); + EasyMock.replay(component); + assertSame(value, context.getProperty(Object.class, name)); + EasyMock.verify(component); + } + + public void testGetService() { + String name = "foo"; + FooService service = EasyMock.createMock(FooService.class); + EasyMock.expect(component.getService(FooService.class, name)).andReturn(service); + EasyMock.replay(component); + assertSame(service, context.getService(FooService.class, name)); + EasyMock.verify(component); + } + + protected void setUp() throws Exception { + super.setUp(); + component = EasyMock.createMock(PojoAtomicComponent.class); + context = new ComponentContextImpl(component); + } + + public interface FooService { + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/ComponentManagerImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/ComponentManagerImplTestCase.java new file mode 100644 index 0000000000..c1710e9b8e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/ComponentManagerImplTestCase.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.core.component; + +import java.net.URI; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.DuplicateNameException; + +/** + * @version $Rev$ $Date$ + */ +public class ComponentManagerImplTestCase extends TestCase { + private static final URI DOMAIN = URI.create("sca://localhost/"); + private static final URI ROOT1 = DOMAIN.resolve("root1"); + private static final URI GRANDCHILD = DOMAIN.resolve("parent/child2/grandchild"); + + private ComponentManagerImpl manager; + + public void testRegister() throws Exception { + Component root = EasyMock.createMock(Component.class); + EasyMock.expect(root.getUri()).andReturn(ROOT1); + EasyMock.replay(root); + manager.register(root); + assertEquals(root, manager.getComponent(ROOT1)); + EasyMock.verify(root); + + EasyMock.reset(root); + EasyMock.expect(root.getUri()).andReturn(ROOT1); + EasyMock.replay(root); + manager.unregister(root); + EasyMock.verify(root); + assertEquals(null, manager.getComponent(ROOT1)); + } + + public void testRegisterGrandchild() throws Exception { + Component root = EasyMock.createMock(Component.class); + EasyMock.expect(root.getUri()).andReturn(GRANDCHILD); + EasyMock.replay(root); + manager.register(root); + assertEquals(root, manager.getComponent(GRANDCHILD)); + EasyMock.verify(root); + } + + public void testRegisterDuplicate() throws Exception { + Component root = EasyMock.createMock(Component.class); + EasyMock.expect(root.getUri()).andReturn(ROOT1); + EasyMock.replay(root); + + Component duplicate = EasyMock.createMock(Component.class); + EasyMock.expect(duplicate.getUri()).andReturn(ROOT1); + EasyMock.replay(duplicate); + + manager.register(root); + assertEquals(root, manager.getComponent(ROOT1)); + try { + manager.register(duplicate); + fail(); + } catch (DuplicateNameException e) { + // expected + } + assertEquals(root, manager.getComponent(ROOT1)); + EasyMock.verify(root); + EasyMock.verify(duplicate); + } + + protected void setUp() throws Exception { + super.setUp(); + manager = new ComponentManagerImpl(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/JavaObjectRegistrationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/JavaObjectRegistrationTestCase.java new file mode 100644 index 0000000000..e2ffb770fd --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/JavaObjectRegistrationTestCase.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.core.component; + +import java.net.URI; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.DuplicateNameException; +import org.apache.tuscany.spi.model.ServiceContract; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class JavaObjectRegistrationTestCase extends TestCase { + private ComponentManager componentManager; + + public void testRegistration() throws Exception { + MockComponent instance = new MockComponent(); + URI uri = URI.create("foo"); + ServiceContract<MockComponent> contract = new ServiceContract<MockComponent>(MockComponent.class) { + }; + componentManager.registerJavaObject(uri, contract, instance); + Component component = componentManager.getComponent(URI.create("foo")); + assertTrue(component instanceof AtomicComponent); + MockComponent resolvedInstance = (MockComponent) ((AtomicComponent) component).getTargetInstance(); + assertSame(instance, resolvedInstance); + } + + public void testDuplicateRegistration() throws Exception { + MockComponent instance = new MockComponent(); + URI uri = URI.create("foo"); + ServiceContract<MockComponent> contract = new ServiceContract<MockComponent>(MockComponent.class) { + }; + componentManager.registerJavaObject(uri, contract, instance); + try { + componentManager.registerJavaObject(uri, contract, instance); + fail(); + } catch (DuplicateNameException e) { + // ok + } + } + + protected void setUp() throws Exception { + super.setUp(); + componentManager = new ComponentManagerImpl(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + private static class MockComponent { + public String hello(String message) { + return message; + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/SystemSingletonAtomicComponentTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/SystemSingletonAtomicComponentTestCase.java new file mode 100644 index 0000000000..efa7456a52 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/SystemSingletonAtomicComponentTestCase.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.core.component; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.model.ServiceContract; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class SystemSingletonAtomicComponentTestCase extends TestCase { + + public void testGetInstance() throws TargetException { + ServiceContract<Foo> contract = new ServiceContract<Foo>(Foo.class) { + + }; + FooImpl foo = new FooImpl(); + SystemSingletonAtomicComponent<Foo, FooImpl> component = + new SystemSingletonAtomicComponent<Foo, FooImpl>(URI.create("foo"), contract, foo); + assertEquals(foo, component.getTargetInstance()); + } + + public void testGetInstanceMultipleServices() throws TargetException { + FooImpl foo = new FooImpl(); + List<ServiceContract<?>> services = new ArrayList<ServiceContract<?>>(); + services.add(new ServiceContract<Foo>(Foo.class) { + }); + services.add(new ServiceContract<Bar>(Bar.class) { + }); + SystemSingletonAtomicComponent<Foo, FooImpl> component = + new SystemSingletonAtomicComponent<Foo, FooImpl>(URI.create("foo"), services, foo); + assertEquals(foo, component.getTargetInstance()); + } + + public void testOptimizable() { + ServiceContract<Foo> contract = new ServiceContract<Foo>(Foo.class) { + }; + FooImpl foo = new FooImpl(); + SystemSingletonAtomicComponent<Foo, FooImpl> component = + new SystemSingletonAtomicComponent<Foo, FooImpl>(URI.create("foo"), contract, foo); + assertTrue(component.isOptimizable()); + } + + + protected void setUp() throws Exception { + super.setUp(); + } + + private interface Foo { + + } + + private interface Bar { + + } + + private class FooImpl implements Foo, Bar { + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/WorkContextImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/WorkContextImplTestCase.java new file mode 100644 index 0000000000..aee910ddaf --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/WorkContextImplTestCase.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.core.component; + +import org.apache.tuscany.spi.component.WorkContext; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class WorkContextImplTestCase extends TestCase { + + public void testPushPopServiceNames() throws Exception { + WorkContext context = new WorkContextImpl(); + context.pushServiceName("foo"); + context.pushServiceName("bar"); + assertEquals("bar", context.getCurrentServiceName()); + assertEquals("bar", context.popServiceName()); + assertEquals("foo", context.getCurrentServiceName()); + assertEquals("foo", context.popServiceName()); + assertNull(context.getCurrentServiceName()); + } + + public void testGetCurrentServiceNamesNull() throws Exception { + WorkContext context = new WorkContextImpl(); + assertNull(context.getCurrentServiceName()); + } + + public void testPopCurrentServiceNamesNull() throws Exception { + WorkContext context = new WorkContextImpl(); + assertNull(context.popServiceName()); + } + + public void testClearServiceNames() throws Exception { + WorkContext context = new WorkContextImpl(); + context.pushServiceName("foo"); + context.pushServiceName("bar"); + context.clearServiceNames(); + assertNull(context.getCurrentServiceName()); + } + + public void testClearServiceNamesNull() throws Exception { + WorkContext context = new WorkContextImpl(); + context.clearServiceNames(); + assertNull(context.getCurrentServiceName()); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/event/EventTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/event/EventTestCase.java new file mode 100644 index 0000000000..93cb50ddcb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/event/EventTestCase.java @@ -0,0 +1,69 @@ +/* + * 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.core.component.event; + +import java.net.URI; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class EventTestCase extends TestCase { + private URI uri = URI.create("foo"); + + public void testCompositeStart() { + ComponentStart event = new ComponentStart(this, uri); + assertEquals(uri, event.getComponentUri()); + } + + public void testCompositeStop() { + ComponentStop event = new ComponentStop(this, uri); + assertEquals(uri, event.getComponentUri()); + } + + public void testHttpSessionStart() { + Object id = new Object(); + HttpSessionEvent event = new HttpSessionStart(this, id); + assertEquals(this, event.getSource()); + assertEquals(id, event.getId()); + } + + public void testHttpSessionEnd() { + Object id = new Object(); + HttpSessionEvent event = new HttpSessionEnd(this, id); + assertEquals(this, event.getSource()); + assertEquals(id, event.getId()); + } + + public void testRequestStart() { + RequestStart event = new RequestStart(this); + assertEquals(this, event.getSource()); + } + + public void testReequestEnd() { + RequestEnd event = new RequestEnd(this); + assertEquals(this, event.getSource()); + } + + + protected void setUp() throws Exception { + super.setUp(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/AbstractScopeContainerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/AbstractScopeContainerTestCase.java new file mode 100644 index 0000000000..f8f8dd5f60 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/AbstractScopeContainerTestCase.java @@ -0,0 +1,126 @@ +/* + * 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.core.component.scope; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.event.Event; +import org.apache.tuscany.spi.event.EventFilter; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.event.TrueFilter; +import org.apache.tuscany.spi.model.Scope; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class AbstractScopeContainerTestCase extends TestCase { + + public void testFireListener() { + TestContainer container = new TestContainer("foo"); + RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class); + Event event = new TestEvent(); + listener.onEvent(EasyMock.eq(event)); + EasyMock.replay(listener); + container.addListener(listener); + container.publish(event); + EasyMock.verify(listener); + } + + public void testRemoveListener() { + TestContainer container = new TestContainer("foo"); + RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class); + EasyMock.replay(listener); + Event event = new TestEvent(); + container.addListener(listener); + container.removeListener(listener); + container.publish(event); + EasyMock.verify(listener); + } + + public void testFalseFilterListener() { + TestContainer container = new TestContainer("foo"); + RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class); + Event event = new TestEvent(); + EasyMock.replay(listener); + container.addListener(new FalseFilter(), listener); + container.publish(event); + EasyMock.verify(listener); + } + + public void testTrueFilterListener() { + TestContainer container = new TestContainer("foo"); + RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class); + Event event = new TestEvent(); + listener.onEvent(EasyMock.eq(event)); + EasyMock.replay(listener); + container.addListener(new TrueFilter(), listener); + container.publish(event); + EasyMock.verify(listener); + } + + public void testToString() { + TestContainer container = new TestContainer("foo"); + assertNotNull(container.toString()); + } + + private class TestContainer extends AbstractScopeContainer { + + public TestContainer(String name) { + super(null, null); + } + + protected InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create) { + return null; + } + + public Scope getScope() { + return null; + } + + public void register(AtomicComponent component) { + + } + + public void onEvent(Event event) { + + } + + public WorkContext getWorkContext() { + return super.getWorkContext(); + } + } + + private class TestEvent implements Event { + public Object getSource() { + return null; + } + } + + private class FalseFilter implements EventFilter { + + public boolean match(Event event) { + return false; + } + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/BasicCompositeScopeTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/BasicCompositeScopeTestCase.java new file mode 100644 index 0000000000..b07de8a677 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/BasicCompositeScopeTestCase.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.core.component.scope; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.TargetNotFoundException; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.event.ComponentStop; +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl; +import org.apache.tuscany.core.injection.EventInvoker; +import org.apache.tuscany.core.injection.MethodEventInvoker; +import org.apache.tuscany.core.injection.PojoObjectFactory; +import org.apache.tuscany.core.mock.component.CompositeScopeInitDestroyComponent; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class BasicCompositeScopeTestCase extends TestCase { + + private EventInvoker<Object> initInvoker; + private EventInvoker<Object> destroyInvoker; + private PojoObjectFactory<?> factory; + + public void testLifecycleManagement() throws Exception { + CompositeScopeContainer scopeContext = new CompositeScopeContainer(null); + scopeContext.start(); + AtomicComponent component = createComponent(scopeContext); + // start the request + CompositeScopeInitDestroyComponent o1 = + (CompositeScopeInitDestroyComponent) scopeContext.getInstance(component); + assertTrue(o1.isInitialized()); + assertFalse(o1.isDestroyed()); + CompositeScopeInitDestroyComponent o2 = + (CompositeScopeInitDestroyComponent) scopeContext.getInstance(component); + assertEquals(o1, o2); + scopeContext.onEvent(new ComponentStop(this, null)); + assertTrue(o1.isDestroyed()); + scopeContext.stop(); + } + + + public void testGetAssociatedInstance() throws Exception { + CompositeScopeContainer scopeContext = new CompositeScopeContainer(null); + scopeContext.start(); + AtomicComponent component = createComponent(scopeContext); + // start the request + scopeContext.getInstance(component); + scopeContext.getAssociatedInstance(component); + } + + public void testGetAssociatedInstanceNonExistent() throws Exception { + CompositeScopeContainer scopeContext = new CompositeScopeContainer(null); + scopeContext.start(); + AtomicComponent component = createComponent(scopeContext); + // start the request + try { + scopeContext.getAssociatedInstance(component); + fail(); + } catch (TargetNotFoundException e) { + // expected + } + } + + public void testCompositeIsolation() throws Exception { + CompositeScopeContainer scopeContext = new CompositeScopeContainer(null); + scopeContext.start(); + + AtomicComponent component = createComponent(scopeContext); + + CompositeScopeInitDestroyComponent o1 = + (CompositeScopeInitDestroyComponent) scopeContext.getInstance(component); + assertTrue(o1.isInitialized()); + assertFalse(o1.isDestroyed()); + + CompositeScopeInitDestroyComponent o2 = + (CompositeScopeInitDestroyComponent) scopeContext.getInstance(component); + assertSame(o1, o2); + scopeContext.onEvent(new ComponentStop(this, null)); + assertTrue(o1.isDestroyed()); + scopeContext.stop(); + } + + protected void setUp() throws Exception { + super.setUp(); + factory = new PojoObjectFactory<CompositeScopeInitDestroyComponent>( + CompositeScopeInitDestroyComponent.class.getConstructor((Class[]) null)); + initInvoker = new MethodEventInvoker<Object>(CompositeScopeInitDestroyComponent.class.getMethod( + "init", (Class[]) null)); + destroyInvoker = new MethodEventInvoker<Object>(CompositeScopeInitDestroyComponent.class.getMethod( + "destroy", (Class[]) null)); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + private AtomicComponent createComponent(ScopeContainer scopeContainer) { + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setInstanceFactory(factory); + configuration.setInitInvoker(initInvoker); + configuration.setDestroyInvoker(destroyInvoker); + try { + configuration.setName(new URI("foo")); + } catch (URISyntaxException e) { + // will not happen + } + SystemAtomicComponentImpl component = new SystemAtomicComponentImpl(configuration); + component.setScopeContainer(scopeContainer); + component.start(); + return component; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/BasicConversationalScopeTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/BasicConversationalScopeTestCase.java new file mode 100644 index 0000000000..d15bfff4be --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/BasicConversationalScopeTestCase.java @@ -0,0 +1,136 @@ +/*
+ * 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.core.component.scope;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.services.store.StoreMonitor;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.component.event.ConversationEnd;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl;
+import org.apache.tuscany.core.injection.EventInvoker;
+import org.apache.tuscany.core.injection.MethodEventInvoker;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.mock.component.ConversationalScopeInitDestroyComponent;
+import org.apache.tuscany.core.services.store.memory.MemoryStore;
+import org.easymock.EasyMock;
+
+/**
+ * @version $$Rev: 471111 $$ $$Date: 2006-11-03 23:06:48 -0500 (Fri, 03 Nov 2006) $$
+ */
+public class BasicConversationalScopeTestCase extends TestCase {
+
+ private EventInvoker<Object> initInvoker;
+ private EventInvoker<Object> destroyInvoker;
+ private PojoObjectFactory<?> factory;
+
+ public void testLifecycleManagement() throws Exception {
+ StoreMonitor monitor = EasyMock.createMock(StoreMonitor.class);
+ monitor.start(EasyMock.isA(String.class));
+ monitor.stop(EasyMock.isA(String.class));
+ MemoryStore store = new MemoryStore(monitor);
+ WorkContext workContext = new WorkContextImpl();
+ ConversationalScopeContainer scopeContext = new ConversationalScopeContainer(store, workContext, null);
+ scopeContext.start();
+ AtomicComponent atomicContext = createContext(scopeContext);
+ // start the request
+ String conversation = "conv";
+ workContext.setIdentifier(Scope.CONVERSATION, conversation);
+ ConversationalScopeInitDestroyComponent o1 =
+ (ConversationalScopeInitDestroyComponent) scopeContext.getInstance(atomicContext);
+ //assertTrue(o1.isInitialized());
+ assertFalse(o1.isDestroyed());
+ ConversationalScopeInitDestroyComponent o2 =
+ (ConversationalScopeInitDestroyComponent) scopeContext.getInstance(atomicContext);
+ assertSame(o1, o2);
+ scopeContext.onEvent(new ConversationEnd(this, conversation));
+ //assertTrue(o1.isDestroyed());
+ scopeContext.stop();
+ }
+
+ public void testCompositeIsolation() throws Exception {
+ StoreMonitor monitor = EasyMock.createMock(StoreMonitor.class);
+ monitor.start(EasyMock.isA(String.class));
+ monitor.stop(EasyMock.isA(String.class));
+ MemoryStore store = new MemoryStore(monitor);
+ WorkContext workContext = new WorkContextImpl();
+ ConversationalScopeContainer scopeContext = new ConversationalScopeContainer(store, workContext, null);
+ scopeContext.start();
+
+ AtomicComponent atomicContext = createContext(scopeContext);
+
+ String conversation1 = "conv";
+ workContext.setIdentifier(Scope.CONVERSATION, conversation1);
+ ConversationalScopeInitDestroyComponent o1 =
+ (ConversationalScopeInitDestroyComponent) scopeContext.getInstance(atomicContext);
+ //assertTrue(o1.isInitialized());
+ assertFalse(o1.isDestroyed());
+
+ String conversation2 = "conv2";
+ workContext.setIdentifier(Scope.CONVERSATION, conversation2);
+ ConversationalScopeInitDestroyComponent o2 =
+ (ConversationalScopeInitDestroyComponent) scopeContext.getInstance(atomicContext);
+ assertNotSame(o1, o2);
+
+ scopeContext.onEvent(new ConversationEnd(this, conversation1));
+ //assertTrue(o1.isDestroyed());
+ assertFalse(o2.isDestroyed());
+ scopeContext.onEvent(new ConversationEnd(this, conversation2));
+ //assertTrue(o2.isDestroyed());
+ scopeContext.stop();
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ factory = new PojoObjectFactory<ConversationalScopeInitDestroyComponent>(
+ ConversationalScopeInitDestroyComponent.class.getConstructor((Class[]) null));
+ initInvoker = new MethodEventInvoker<Object>(
+ ConversationalScopeInitDestroyComponent.class.getMethod("init", (Class[]) null));
+ destroyInvoker = new MethodEventInvoker<Object>(
+ ConversationalScopeInitDestroyComponent.class.getMethod("destroy", (Class[]) null));
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ private AtomicComponent createContext(ScopeContainer scopeContainer) {
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInstanceFactory(factory);
+ configuration.setInitInvoker(initInvoker);
+ configuration.setDestroyInvoker(destroyInvoker);
+ try {
+ configuration.setName(new URI("foo"));
+ } catch (URISyntaxException e) {
+ // will not happen
+ }
+ SystemAtomicComponentImpl component = new SystemAtomicComponentImpl(configuration);
+ component.setScopeContainer(scopeContainer);
+ component.start();
+ return component;
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/BasicHttpSessionScopeTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/BasicHttpSessionScopeTestCase.java new file mode 100644 index 0000000000..9392e92159 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/BasicHttpSessionScopeTestCase.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.core.component.scope; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.TargetNotFoundException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.Scope; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.component.event.HttpSessionEnd; +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl; +import org.apache.tuscany.core.injection.EventInvoker; +import org.apache.tuscany.core.injection.MethodEventInvoker; +import org.apache.tuscany.core.injection.PojoObjectFactory; +import org.apache.tuscany.core.mock.component.SessionScopeInitDestroyComponent; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class BasicHttpSessionScopeTestCase extends TestCase { + private EventInvoker<Object> initInvoker; + private EventInvoker<Object> destroyInvoker; + private PojoObjectFactory<?> factory; + + public void testLifecycleManagement() throws Exception { + WorkContext workContext = new WorkContextImpl(); + HttpSessionScopeContainer scopeContext = new HttpSessionScopeContainer(workContext, null); + scopeContext.start(); + AtomicComponent component = createComponent(scopeContext); + // start the request + Object session = new Object(); + workContext.setIdentifier(Scope.SESSION, session); + SessionScopeInitDestroyComponent o1 = + (SessionScopeInitDestroyComponent) scopeContext.getInstance(component); + assertTrue(o1.isInitialized()); + assertFalse(o1.isDestroyed()); + SessionScopeInitDestroyComponent o2 = + (SessionScopeInitDestroyComponent) scopeContext.getInstance(component); + assertSame(o1, o2); + scopeContext.onEvent(new HttpSessionEnd(this, session)); + assertTrue(o1.isDestroyed()); + scopeContext.stop(); + } + + public void testGetAssociatedInstance() throws Exception { + WorkContext workContext = new WorkContextImpl(); + HttpSessionScopeContainer scopeContext = new HttpSessionScopeContainer(workContext, null); + scopeContext.start(); + AtomicComponent component = createComponent(scopeContext); + // start the request + Object session = new Object(); + workContext.setIdentifier(Scope.SESSION, session); + scopeContext.getInstance(component); + scopeContext.getAssociatedInstance(component); + } + + public void testGetAssociatedInstanceNonExistent() throws Exception { + WorkContext workContext = new WorkContextImpl(); + HttpSessionScopeContainer scopeContext = new HttpSessionScopeContainer(workContext, null); + scopeContext.start(); + AtomicComponent component = createComponent(scopeContext); + // start the request + Object session = new Object(); + workContext.setIdentifier(Scope.SESSION, session); + try { + scopeContext.getAssociatedInstance(component); + fail(); + } catch (TargetNotFoundException e) { + // expected + } + } + + public void testSessionIsolation() throws Exception { + WorkContext workContext = new WorkContextImpl(); + HttpSessionScopeContainer scopeContext = new HttpSessionScopeContainer(workContext, null); + scopeContext.start(); + + AtomicComponent component = createComponent(scopeContext); + + Object session1 = new Object(); + workContext.setIdentifier(Scope.SESSION, session1); + SessionScopeInitDestroyComponent o1 = + (SessionScopeInitDestroyComponent) scopeContext.getInstance(component); + assertTrue(o1.isInitialized()); + + Object session2 = new Object(); + workContext.setIdentifier(Scope.SESSION, session2); + SessionScopeInitDestroyComponent o2 = + (SessionScopeInitDestroyComponent) scopeContext.getInstance(component); + assertNotSame(o1, o2); + + scopeContext.onEvent(new HttpSessionEnd(this, session1)); + assertTrue(o1.isDestroyed()); + assertFalse(o2.isDestroyed()); + scopeContext.onEvent(new HttpSessionEnd(this, session2)); + assertTrue(o2.isDestroyed()); + scopeContext.stop(); + } + + protected void setUp() throws Exception { + super.setUp(); + factory = new PojoObjectFactory<SessionScopeInitDestroyComponent>( + SessionScopeInitDestroyComponent.class.getConstructor((Class[]) null)); + initInvoker = new MethodEventInvoker<Object>( + SessionScopeInitDestroyComponent.class.getMethod("init", (Class[]) null)); + destroyInvoker = new MethodEventInvoker<Object>( + SessionScopeInitDestroyComponent.class.getMethod("destroy", (Class[]) null)); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + private AtomicComponent createComponent(ScopeContainer scopeContainer) { + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setInstanceFactory(factory); + configuration.setInitInvoker(initInvoker); + configuration.setDestroyInvoker(destroyInvoker); + try { + configuration.setName(new URI("foo")); + } catch (URISyntaxException e) { + // will not happen + } + SystemAtomicComponentImpl component = new SystemAtomicComponentImpl(configuration); + component.setScopeContainer(scopeContainer); + component.start(); + return component; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/BasicRequestScopeTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/BasicRequestScopeTestCase.java new file mode 100644 index 0000000000..aa2f55d57f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/BasicRequestScopeTestCase.java @@ -0,0 +1,135 @@ +/* + * 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.core.component.scope; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.TargetNotFoundException; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.event.RequestEnd; +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl; +import org.apache.tuscany.core.injection.EventInvoker; +import org.apache.tuscany.core.injection.MethodEventInvoker; +import org.apache.tuscany.core.injection.PojoObjectFactory; +import org.apache.tuscany.core.mock.component.RequestScopeInitDestroyComponent; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class BasicRequestScopeTestCase extends TestCase { + private EventInvoker<Object> initInvoker; + private EventInvoker<Object> destroyInvoker; + private PojoObjectFactory<?> factory; + + public void testLifecycleManagement() throws Exception { + RequestScopeContainer scopeContainer = new RequestScopeContainer(null, null); + scopeContainer.start(); + AtomicComponent component = createComponent(scopeContainer); + // start the request + RequestScopeInitDestroyComponent o1 = + (RequestScopeInitDestroyComponent) scopeContainer.getInstance(component); + assertTrue(o1.isInitialized()); + assertFalse(o1.isDestroyed()); + RequestScopeInitDestroyComponent o2 = + (RequestScopeInitDestroyComponent) scopeContainer.getInstance(component); + assertSame(o1, o2); + scopeContainer.onEvent(new RequestEnd(this)); + assertTrue(o1.isDestroyed()); + scopeContainer.stop(); + } + + public void testGetAssociatedInstance() throws Exception { + RequestScopeContainer scopeContainer = new RequestScopeContainer(null, null); + scopeContainer.start(); + AtomicComponent component = createComponent(scopeContainer); + // start the request + scopeContainer.getInstance(component); + scopeContainer.getAssociatedInstance(component); + scopeContainer.stop(); + } + + public void testGetAssociatedInstanceNonExistent() throws Exception { + RequestScopeContainer scopeContainer = new RequestScopeContainer(null, null); + scopeContainer.start(); + AtomicComponent component = createComponent(scopeContainer); + // start the request + try { + scopeContainer.getAssociatedInstance(component); + fail(); + } catch (TargetNotFoundException e) { + // expected + } + scopeContainer.stop(); + } + + public void testRequestIsolation() throws Exception { + RequestScopeContainer scopeContainer = new RequestScopeContainer(null, null); + scopeContainer.start(); + + AtomicComponent component = createComponent(scopeContainer); + + RequestScopeInitDestroyComponent o1 = + (RequestScopeInitDestroyComponent) scopeContainer.getInstance(component); + assertTrue(o1.isInitialized()); + scopeContainer.onEvent(new RequestEnd(this)); + assertTrue(o1.isDestroyed()); + + RequestScopeInitDestroyComponent o2 = + (RequestScopeInitDestroyComponent) scopeContainer.getInstance(component); + assertNotSame(o1, o2); + scopeContainer.onEvent(new RequestEnd(this)); + assertTrue(o2.isDestroyed()); + scopeContainer.stop(); + } + + protected void setUp() throws Exception { + super.setUp(); + factory = new PojoObjectFactory<RequestScopeInitDestroyComponent>( + RequestScopeInitDestroyComponent.class.getConstructor((Class[]) null)); + initInvoker = new MethodEventInvoker<Object>( + RequestScopeInitDestroyComponent.class.getMethod("init", (Class[]) null)); + destroyInvoker = new MethodEventInvoker<Object>( + RequestScopeInitDestroyComponent.class.getMethod("destroy", (Class[]) null)); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + private AtomicComponent createComponent(ScopeContainer scopeContainer) { + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setInstanceFactory(factory); + configuration.setInitInvoker(initInvoker); + configuration.setDestroyInvoker(destroyInvoker); + try { + configuration.setName(new URI("foo")); + } catch (URISyntaxException e) { + // will not happen + } + SystemAtomicComponentImpl component = new SystemAtomicComponentImpl(configuration); + component.setScopeContainer(scopeContainer); + component.start(); + return component; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/BasicStatelessScopeTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/BasicStatelessScopeTestCase.java new file mode 100644 index 0000000000..ca1bd2a35a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/BasicStatelessScopeTestCase.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.core.component.scope; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.TargetNotFoundException; +import org.apache.tuscany.spi.component.WorkContext; + +import junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl; +import org.apache.tuscany.core.injection.PojoObjectFactory; +import org.apache.tuscany.core.mock.component.StatelessComponent; +import org.apache.tuscany.core.mock.component.StatelessComponentImpl; + +/** + * Unit tests for the composite scope container + * + * @version $Rev$ $Date$ + */ +public class BasicStatelessScopeTestCase extends TestCase { + private PojoObjectFactory<StatelessComponentImpl> factory; + + /** + * Verfies instance identity is properly maintained + */ + public void testInstanceManagement() throws Exception { + WorkContext ctx = new WorkContextImpl(); + StatelessScopeContainer scope = new StatelessScopeContainer(ctx, null); + scope.start(); + AtomicComponent component1 = createComponent(scope); + scope.register(component1); + AtomicComponent component2 = createComponent(scope); + scope.register(component2); + StatelessComponentImpl comp1 = (StatelessComponentImpl) scope.getInstance(component1); + Assert.assertNotNull(comp1); + StatelessComponentImpl comp2 = (StatelessComponentImpl) scope.getInstance(component2); + Assert.assertNotNull(comp2); + Assert.assertNotSame(comp1, comp2); + scope.stop(); + } + + public void testGetAssociatedInstance() throws Exception { + WorkContext ctx = new WorkContextImpl(); + StatelessScopeContainer scope = new StatelessScopeContainer(ctx, null); + scope.start(); + AtomicComponent component1 = createComponent(scope); + scope.register(component1); + try { + // always throws an exception, which is the semantic for stateless implementations + scope.getAssociatedInstance(component1); + fail(); + } catch (TargetNotFoundException e) { + // expected + } + scope.stop(); + } + + public void testRegisterContextAfterRequest() throws Exception { + WorkContext ctx = new WorkContextImpl(); + StatelessScopeContainer scope = new StatelessScopeContainer(ctx, null); + + scope.start(); + AtomicComponent component1 = createComponent(scope); + scope.register(component1); + StatelessComponent comp1 = (StatelessComponentImpl) scope.getInstance(component1); + Assert.assertNotNull(comp1); + AtomicComponent component2 = createComponent(scope); + scope.register(component2); + StatelessComponentImpl comp2 = (StatelessComponentImpl) scope.getInstance(component2); + Assert.assertNotNull(comp2); + scope.stop(); + } + + + /** + * Tests setting no components in the scope + */ + public void testSetNullComponents() throws Exception { + WorkContext ctx = new WorkContextImpl(); + StatelessScopeContainer scope = new StatelessScopeContainer(ctx, null); + scope.start(); + scope.stop(); + } + + protected void setUp() throws Exception { + super.setUp(); + factory = + new PojoObjectFactory<StatelessComponentImpl>(StatelessComponentImpl.class.getConstructor((Class[]) null)); + + } + + private AtomicComponent createComponent(ScopeContainer scopeContainer) { + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setInstanceFactory(factory); + try { + configuration.setName(new URI("foo")); + } catch (URISyntaxException e) { + // will not happen + } + AtomicComponent component = new SystemAtomicComponentImpl(configuration); + component.setScopeContainer(scopeContainer); + return component; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeInitDestroyErrorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeInitDestroyErrorTestCase.java new file mode 100644 index 0000000000..1391959989 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeInitDestroyErrorTestCase.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.core.component.scope; + +import java.net.URI; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainerMonitor; +import org.apache.tuscany.spi.component.TargetDestructionException; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.event.ComponentStart; +import org.apache.tuscany.core.component.event.ComponentStop; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class CompositeScopeInitDestroyErrorTestCase extends TestCase { + + public void testInitializeErrorMonitor() throws Exception { + ScopeContainerMonitor monitor; + monitor = EasyMock.createMock(ScopeContainerMonitor.class); + monitor.eagerInitializationError(EasyMock.isA(ObjectCreationException.class)); + EasyMock.replay(monitor); + CompositeScopeContainer scope = new CompositeScopeContainer(monitor); + scope.start(); + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(component.getUri()).andReturn(URI.create("foo")).atLeastOnce(); + EasyMock.expect(component.createInstance()).andThrow(new ObjectCreationException("")); + EasyMock.expect(component.getInitLevel()).andReturn(1); + EasyMock.replay(component); + scope.register(component); + scope.onEvent(new ComponentStart(this, null)); + EasyMock.verify(monitor); + } + + public void testDestroyErrorMonitor() throws Exception { + ScopeContainerMonitor monitor; + monitor = EasyMock.createMock(ScopeContainerMonitor.class); + monitor.destructionError(EasyMock.isA(TargetDestructionException.class)); + EasyMock.replay(monitor); + CompositeScopeContainer scope = new CompositeScopeContainer(monitor); + scope.start(); + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(component.createInstance()).andReturn(new Object()); + EasyMock.expect(component.getInitLevel()).andReturn(1); + component.init(EasyMock.isA(Object.class)); + component.destroy(EasyMock.isA(Object.class)); + EasyMock.expectLastCall().andThrow(new TargetDestructionException("", "")); + EasyMock.replay(component); + scope.register(component); + scope.onEvent(new ComponentStart(this, null)); + scope.onEvent(new ComponentStop(this, null)); + EasyMock.verify(monitor); + } + + + protected void setUp() throws Exception { + super.setUp(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeInstanceLifecycleTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeInstanceLifecycleTestCase.java new file mode 100644 index 0000000000..e4efdcdbfa --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeInstanceLifecycleTestCase.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.core.component.scope; + + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.TargetException; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.event.ComponentStart; +import org.apache.tuscany.core.component.event.ComponentStop; +import org.apache.tuscany.core.mock.component.OrderedInitPojo; +import org.apache.tuscany.core.mock.component.OrderedInitPojoImpl; +import org.easymock.EasyMock; +import org.easymock.IAnswer; + +/** + * Lifecycle unit tests for the composite scope container + * + * @version $Rev$ $Date$ + */ +public class CompositeScopeInstanceLifecycleTestCase extends TestCase { + + /** + * Verify init and stop by scope container on an atomic component + * + * @throws Exception + */ + public void testInitDestroy() throws Exception { + CompositeScopeContainer scope = new CompositeScopeContainer(null); + scope.start(); + Foo comp = new Foo(); + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(component.createInstance()).andReturn(comp); + EasyMock.expect(component.getInitLevel()).andReturn(1).atLeastOnce(); + component.init(EasyMock.eq(comp)); + component.destroy(EasyMock.eq(comp)); + EasyMock.replay(component); + scope.register(component); + scope.onEvent(new ComponentStart(this, null)); + assertNotNull(scope.getInstance(component)); + // expire composite + scope.onEvent(new ComponentStop(this, null)); + scope.stop(); + EasyMock.verify(component); + } + + /** + * Verify init and stop by scope container on an atomic component when set to eager initialize + * + * @throws Exception + */ + public void testEagerInitDestroy() throws Exception { + CompositeScopeContainer scope = new CompositeScopeContainer(null); + scope.start(); + Foo comp = new Foo(); + AtomicComponent initDestroyComponent = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(initDestroyComponent.createInstance()).andReturn(comp); + EasyMock.expect(initDestroyComponent.getInitLevel()).andReturn(1).atLeastOnce(); + initDestroyComponent.init(EasyMock.eq(comp)); + initDestroyComponent.destroy(EasyMock.eq(comp)); + EasyMock.replay(initDestroyComponent); + scope.register(initDestroyComponent); + scope.onEvent(new ComponentStart(this, null)); + // expire composite + scope.onEvent(new ComponentStop(this, null)); + scope.stop(); + EasyMock.verify(initDestroyComponent); + } + + + public void testDestroyOrder() throws Exception { + CompositeScopeContainer scope = new CompositeScopeContainer(null); + scope.start(); + + AtomicComponent oneComponent = createComponent(0); + scope.register(oneComponent); + AtomicComponent twoComponent = createComponent(0); + scope.register(twoComponent); + AtomicComponent threeComponent = createComponent(0); + scope.register(threeComponent); + + scope.onEvent(new ComponentStart(this, null)); + OrderedInitPojo one = (OrderedInitPojo) scope.getInstance(oneComponent); + assertNotNull(one); + assertEquals(1, one.getNumberInstantiated()); + assertEquals(1, one.getInitOrder()); + + OrderedInitPojo two = (OrderedInitPojo) scope.getInstance(twoComponent); + assertNotNull(two); + assertEquals(2, two.getNumberInstantiated()); + assertEquals(2, two.getInitOrder()); + + OrderedInitPojo three = (OrderedInitPojo) scope.getInstance(threeComponent); + assertNotNull(three); + assertEquals(3, three.getNumberInstantiated()); + assertEquals(3, three.getInitOrder()); + + // expire composite + scope.onEvent(new ComponentStop(this, null)); + assertEquals(0, one.getNumberInstantiated()); + scope.stop(); + EasyMock.verify(oneComponent); + EasyMock.verify(twoComponent); + EasyMock.verify(threeComponent); + } + + public void testEagerInitDestroyOrder() throws Exception { + CompositeScopeContainer scope = new CompositeScopeContainer(null); + scope.start(); + + AtomicComponent oneComponent = createComponent(1); + scope.register(oneComponent); + AtomicComponent twoComponent = createComponent(1); + scope.register(twoComponent); + AtomicComponent threeComponent = createComponent(1); + scope.register(threeComponent); + + scope.onEvent(new ComponentStart(this, null)); + OrderedInitPojo one = (OrderedInitPojo) scope.getInstance(oneComponent); + assertNotNull(one); + + OrderedInitPojo two = (OrderedInitPojo) scope.getInstance(twoComponent); + assertNotNull(two); + + OrderedInitPojo three = (OrderedInitPojo) scope.getInstance(threeComponent); + assertNotNull(three); + + // expire composite + scope.onEvent(new ComponentStop(this, null)); + assertEquals(0, one.getNumberInstantiated()); + scope.stop(); + EasyMock.verify(oneComponent); + EasyMock.verify(twoComponent); + EasyMock.verify(threeComponent); + } + + @SuppressWarnings("unchecked") + private AtomicComponent createComponent(int init) throws TargetException { + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(component.createInstance()).andStubAnswer(new IAnswer() { + public Object answer() throws Throwable { + return new OrderedInitPojoImpl(); + } + }); + EasyMock.expect(component.getInitLevel()).andReturn(init).atLeastOnce(); + component.init(EasyMock.isA(OrderedInitPojoImpl.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer() { + public Object answer() throws Throwable { + OrderedInitPojoImpl pojo = (OrderedInitPojoImpl) EasyMock.getCurrentArguments()[0]; + pojo.init(); + return null; + } + }); + component.destroy(EasyMock.isA(OrderedInitPojoImpl.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer() { + public Object answer() throws Throwable { + OrderedInitPojoImpl pojo = (OrderedInitPojoImpl) EasyMock.getCurrentArguments()[0]; + pojo.destroy(); + return null; + } + }); + EasyMock.replay(component); + return component; + } + + private class Foo { + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactoryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactoryTestCase.java new file mode 100644 index 0000000000..611fbfc13f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactoryTestCase.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.core.component.scope; + +import org.apache.tuscany.spi.component.ScopeRegistry; +import org.apache.tuscany.spi.model.Scope; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class CompositeScopeObjectFactoryTestCase extends TestCase { + + public void testCreation() { + ScopeRegistry registry = EasyMock.createMock(ScopeRegistry.class); + registry.registerFactory(EasyMock.isA(Scope.class), EasyMock.isA(CompositeScopeObjectFactory.class)); + + assertNotNull(new CompositeScopeObjectFactory(registry, null).getInstance()); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeRestartTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeRestartTestCase.java new file mode 100644 index 0000000000..eaaed3a29e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeRestartTestCase.java @@ -0,0 +1,100 @@ +/* + * 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.core.component.scope; + +import java.lang.reflect.Constructor; +import java.net.URI; + +import org.apache.tuscany.spi.component.AtomicComponent; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.event.ComponentStart; +import org.apache.tuscany.core.component.event.ComponentStop; +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl; +import org.apache.tuscany.core.injection.MethodEventInvoker; +import org.apache.tuscany.core.injection.PojoObjectFactory; + +/** + * Verifies the scope container properly disposes resources and canbe restarted + * + * @version $$Rev$$ $$Date$$ + */ +public class CompositeScopeRestartTestCase extends TestCase { + + public void testRestart() throws Exception { + CompositeScopeContainer scope = new CompositeScopeContainer(null); + scope.start(); + MethodEventInvoker<Object> initInvoker = + new MethodEventInvoker<Object>(InitDestroyOnce.class.getMethod("init")); + MethodEventInvoker<Object> destroyInvoker = + new MethodEventInvoker<Object>(InitDestroyOnce.class.getMethod("destroy")); + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setInitInvoker(initInvoker); + configuration.setDestroyInvoker(destroyInvoker); + Constructor<InitDestroyOnce> ctr = InitDestroyOnce.class.getConstructor((Class<?>[]) null); + configuration.setInstanceFactory(new PojoObjectFactory<InitDestroyOnce>(ctr)); + configuration.setName(new URI("InitDestroy")); + AtomicComponent component = new SystemAtomicComponentImpl(configuration); + component.setScopeContainer(scope); + component.start(); + + scope.onEvent(new ComponentStart(this, null)); + Object instance = component.getTargetInstance(); + assertSame(instance, component.getTargetInstance()); + + scope.onEvent(new ComponentStop(this, null)); + scope.stop(); + component.stop(); + + scope.start(); + scope.onEvent(new ComponentStart(this, null)); + component.start(); + assertNotSame(instance, component.getTargetInstance()); + scope.onEvent(new ComponentStop(this, null)); + scope.stop(); + component.stop(); + } + + public static class InitDestroyOnce { + + private boolean initialized; + private boolean destroyed; + + public InitDestroyOnce() { + } + + public void init() { + if (!initialized) { + initialized = true; + } else { + fail("Scope did not clean up properly - Init called more than once"); + } + } + + public void destroy() { + if (!destroyed) { + destroyed = true; + } else { + fail("Scope did not clean up properly - Destroyed called more than once"); + } + } + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerDestroyOnExpirationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerDestroyOnExpirationTestCase.java new file mode 100644 index 0000000000..a1a3616d0a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerDestroyOnExpirationTestCase.java @@ -0,0 +1,121 @@ +/* + * 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.core.component.scope; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.SCAObject; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.event.Event; +import org.apache.tuscany.spi.event.EventFilter; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.services.store.RecoveryListener; +import org.apache.tuscany.spi.services.store.Store; +import org.apache.tuscany.spi.services.store.StoreExpirationEvent; +import org.apache.tuscany.spi.services.store.StoreReadException; +import org.apache.tuscany.spi.services.store.StoreWriteException; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ConversationalScopeContainerDestroyOnExpirationTestCase extends TestCase { + private ScopeContainer container; + private TestStore store; + private AtomicComponent component; + + /** + * Verifies the scope container registers a callback listener for component instance destroy events when a + * conversational instance expires + */ + public void testDestroyNotification() throws Exception { + store.getListener().onEvent(new StoreExpirationEvent(this, component, new Object())); + EasyMock.verify(component); + } + + protected void setUp() throws Exception { + super.setUp(); + component = EasyMock.createMock(AtomicComponent.class); + component.destroy(EasyMock.isA(Object.class)); + EasyMock.replay(component); + store = new TestStore(); + WorkContext context = new WorkContextImpl(); + container = new ConversationalScopeContainer(store, context, null); + container.start(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + container.stop(); + } + + private class TestStore implements Store { + private RuntimeEventListener listener; + + public RuntimeEventListener getListener() { + return listener; + } + + public void insertRecord(SCAObject owner, String id, Object object, long expiration) + throws StoreWriteException { + + } + + public void updateRecord(SCAObject owner, String id, Object object, long expiration) + throws StoreWriteException { + + } + + public Object readRecord(SCAObject owner, String id) throws StoreReadException { + return null; + } + + public void removeRecord(SCAObject owner, String id) throws StoreWriteException { + + } + + public void removeRecords() throws StoreWriteException { + + } + + public void recover(RecoveryListener listener) throws StoreReadException { + + } + + public void publish(Event object) { + + } + + public void addListener(RuntimeEventListener listener) { + this.listener = listener; + } + + public void addListener(EventFilter filter, RuntimeEventListener listener) { + + } + + public void removeListener(RuntimeEventListener listener) { + + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerMaxAgeTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerMaxAgeTestCase.java new file mode 100644 index 0000000000..b41daeb7f1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerMaxAgeTestCase.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.core.component.scope; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.SCAObject; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.services.store.Store; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ConversationalScopeContainerMaxAgeTestCase extends TestCase { + + private ScopeContainer container; + private WorkContext context; + private Store store; + private AtomicComponent component; + + public void testMaxAgeUpdate() throws Exception { + context.setIdentifier(Scope.CONVERSATION, "12345"); + container.getInstance(component); + EasyMock.verify(store); + } + + protected void setUp() throws Exception { + super.setUp(); + ConversationalScopeContainerMaxAgeTestCase.Foo foo = new ConversationalScopeContainerMaxAgeTestCase.Foo(); + context = new WorkContextImpl(); + component = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(component.getMaxIdleTime()).andReturn(-1L).atLeastOnce(); + EasyMock.expect(component.getMaxAge()).andReturn(600000L).atLeastOnce(); + EasyMock.replay(component); + store = EasyMock.createMock(Store.class); + EasyMock.expect(store.readRecord(EasyMock.isA(SCAObject.class), EasyMock.isA(String.class))).andReturn(foo); + store.addListener(EasyMock.isA(RuntimeEventListener.class)); + EasyMock.replay(store); + container = new ConversationalScopeContainer(store, context, null); + container.start(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + context.clearIdentifier(Scope.CONVERSATION); + container.stop(); + } + + private class Foo { + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerMaxIdleTimeTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerMaxIdleTimeTestCase.java new file mode 100644 index 0000000000..5719d698c8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerMaxIdleTimeTestCase.java @@ -0,0 +1,78 @@ +/* + * 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.core.component.scope; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.SCAObject; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.services.store.Store; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ConversationalScopeContainerMaxIdleTimeTestCase extends TestCase { + + private ScopeContainer container; + private WorkContext context; + private Store store; + private AtomicComponent component; + + public void testMaxIdleTimeUpdate() throws Exception { + context.setIdentifier(Scope.CONVERSATION, "12345"); + container.getInstance(component); + EasyMock.verify(store); + } + + protected void setUp() throws Exception { + super.setUp(); + Foo foo = new Foo(); + context = new WorkContextImpl(); + component = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(component.getMaxIdleTime()).andReturn(600000L).atLeastOnce(); + EasyMock.replay(component); + store = EasyMock.createMock(Store.class); + EasyMock.expect(store.readRecord(EasyMock.isA(SCAObject.class), EasyMock.isA(String.class))).andReturn(foo); + store.addListener(EasyMock.isA(RuntimeEventListener.class)); + store.updateRecord(EasyMock.isA(SCAObject.class), + EasyMock.isA(String.class), + EasyMock.eq(foo), + EasyMock.anyLong()); + EasyMock.replay(store); + container = new ConversationalScopeContainer(store, context, null); + container.start(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + context.clearIdentifier(Scope.CONVERSATION); + container.stop(); + } + + private class Foo { + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerPersistenceTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerPersistenceTestCase.java new file mode 100644 index 0000000000..f0824daffd --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerPersistenceTestCase.java @@ -0,0 +1,182 @@ +/* + * 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.core.component.scope; + +import java.util.UUID; +import java.net.URI; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.TargetNotFoundException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.services.store.Store; +import org.apache.tuscany.spi.services.store.StoreMonitor; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.services.store.memory.MemoryStore; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ConversationalScopeContainerPersistenceTestCase extends TestCase { + private ScopeContainer container; + private WorkContext context; + + /** + * Verifies the scope container properly creates an instance + */ + public void testNotYetPersistedInMemory() throws Exception { + String id = UUID.randomUUID().toString(); + context.setIdentifier(Scope.CONVERSATION, id); + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + component.addListener(EasyMock.eq(container)); + EasyMock.expect(component.createInstance()).andReturn(new Foo()); + EasyMock.expect(component.getMaxAge()).andReturn(600000L).atLeastOnce(); + component.init(EasyMock.isA(Object.class)); + EasyMock.replay(component); + container.register(component); + assertTrue(container.getInstance(component) instanceof Foo); + EasyMock.verify(component); + } + + public void testPersistNewInMemory() throws Exception { + String id = UUID.randomUUID().toString(); + String id2 = UUID.randomUUID().toString(); + context.setIdentifier(Scope.CONVERSATION, id); + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + component.addListener(EasyMock.eq(container)); + EasyMock.expect(component.getMaxIdleTime()).andReturn(-1L).atLeastOnce(); + EasyMock.replay(component); + container.register(component); + Foo foo = new Foo(); + Foo foo2 = new Foo(); + container.persistNew(component, id, foo, System.currentTimeMillis() + 100000); + assertEquals(foo, container.getInstance(component)); + container.persistNew(component, id2, foo2, System.currentTimeMillis() + 100000); + context.setIdentifier(Scope.CONVERSATION, id2); + assertEquals(foo2, container.getInstance(component)); + EasyMock.verify(component); + } + + public void testPersistInMemory() throws Exception { + String id = UUID.randomUUID().toString(); + context.setIdentifier(Scope.CONVERSATION, id); + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + component.addListener(EasyMock.eq(container)); + EasyMock.expect(component.getMaxIdleTime()).andReturn(-1L).atLeastOnce(); + EasyMock.replay(component); + container.register(component); + Foo foo = new Foo(); + container.persistNew(component, id, foo, System.currentTimeMillis() + 100000); + assertEquals(foo, container.getInstance(component)); + container.persist(component, id, foo, System.currentTimeMillis() + 100000); + assertEquals(foo, container.getInstance(component)); + EasyMock.verify(component); + } + + public void testRemoveInMemory() throws Exception { + String id = UUID.randomUUID().toString(); + context.setIdentifier(Scope.CONVERSATION, id); + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + component.addListener(EasyMock.eq(container)); + EasyMock.expect(component.getMaxIdleTime()).andReturn(-1L).atLeastOnce(); + EasyMock.expect(component.getUri()).andReturn(URI.create("foo")).atLeastOnce(); + EasyMock.replay(component); + container.register(component); + Foo foo = new Foo(); + container.persistNew(component, id, foo, System.currentTimeMillis() + 100000); + assertEquals(foo, container.getInstance(component)); + container.remove(component); + try { + container.getAssociatedInstance(component); + fail(); + } catch (TargetNotFoundException e) { + //expected + } + EasyMock.verify(component); + } + + public void testRecreateAfterRemoveInMemory() throws Exception { + String id = UUID.randomUUID().toString(); + context.setIdentifier(Scope.CONVERSATION, id); + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + component.addListener(EasyMock.eq(container)); + EasyMock.expect(component.getMaxAge()).andReturn(600000L).atLeastOnce(); + component.init(EasyMock.isA(Object.class)); + EasyMock.expect(component.getMaxIdleTime()).andReturn(-1L).atLeastOnce(); + EasyMock.expect(component.createInstance()).andReturn(new Foo()); + EasyMock.replay(component); + container.register(component); + Foo foo = new Foo(); + container.persistNew(component, id, foo, System.currentTimeMillis() + 100000); + assertEquals(foo, container.getInstance(component)); + container.remove(component); + Foo foo2 = (Foo) container.getInstance(component); + assertNotNull(foo2); + assertNotSame(foo, foo2); + EasyMock.verify(component); + } + + public void testGetPersistedInstance() throws Exception { + String id = UUID.randomUUID().toString(); + String id2 = UUID.randomUUID().toString(); + context.setIdentifier(Scope.CONVERSATION, id); + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(component.getUri()).andReturn(URI.create("foo")).atLeastOnce(); + EasyMock.expect(component.getMaxIdleTime()).andReturn(-1L).atLeastOnce(); + component.addListener(EasyMock.eq(container)); + EasyMock.replay(component); + container.register(component); + Foo foo = new Foo(); + container.persistNew(component, id, foo, System.currentTimeMillis() + 100000); + assertEquals(foo, container.getAssociatedInstance(component)); + assertEquals(foo, container.getAssociatedInstance(component)); + context.setIdentifier(Scope.CONVERSATION, id2); + try { + container.getAssociatedInstance(component); + fail(); + } catch (TargetNotFoundException e) { + //expected + } + EasyMock.verify(component); + } + + protected void setUp() throws Exception { + super.setUp(); + context = new WorkContextImpl(); + StoreMonitor mock = EasyMock.createNiceMock(StoreMonitor.class); + EasyMock.replay(mock); + Store store = new MemoryStore(mock); + container = new ConversationalScopeContainer(store, context, null); + container.start(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + context.clearIdentifier(Scope.CONVERSATION); + container.stop(); + } + + private class Foo { + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeInstanceLifecycleTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeInstanceLifecycleTestCase.java new file mode 100644 index 0000000000..782b175b47 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeInstanceLifecycleTestCase.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.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.services.store.StoreMonitor;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.services.store.memory.MemoryStore;
+import org.easymock.EasyMock;
+
+/**
+ * Lifecycle unit tests for the conversational scope container
+ *
+ * @version $Rev: 451895 $ $Date: 2006-10-02 02:58:18 -0400 (Mon, 02 Oct 2006) $
+ */
+public class ConversationalScopeInstanceLifecycleTestCase extends TestCase {
+
+ public void testInitRemove() throws Exception {
+ StoreMonitor monitor = EasyMock.createMock(StoreMonitor.class);
+ monitor.start(EasyMock.isA(String.class));
+ monitor.stop(EasyMock.isA(String.class));
+ MemoryStore store = new MemoryStore(monitor);
+ WorkContext ctx = new WorkContextImpl();
+ ConversationalScopeContainer scope = new ConversationalScopeContainer(store, ctx, null);
+ scope.start();
+
+ Foo comp = new Foo();
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.createInstance()).andReturn(comp);
+ component.init(EasyMock.eq(comp));
+ EasyMock.expect(component.getMaxAge()).andReturn(1L).anyTimes();
+ component.addListener(EasyMock.isA(RuntimeEventListener.class));
+ EasyMock.replay(component);
+ scope.register(component);
+ String convID = "ConvID";
+ ctx.setIdentifier(Scope.CONVERSATION, convID);
+ assertNotNull(scope.getInstance(component));
+ // expire
+ scope.remove(component);
+ scope.stop();
+ EasyMock.verify(component);
+ scope.stop();
+ }
+
+ private class Foo {
+
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeRestartTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeRestartTestCase.java new file mode 100644 index 0000000000..b60c097766 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeRestartTestCase.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.core.component.scope;
+
+import java.lang.reflect.Constructor;
+import java.net.URI;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.services.store.StoreMonitor;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.component.event.ConversationEnd;
+import org.apache.tuscany.core.component.event.ConversationStart;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl;
+import org.apache.tuscany.core.injection.MethodEventInvoker;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.services.store.memory.MemoryStore;
+import org.easymock.EasyMock;
+
+/**
+ * Verifies the scope container properly disposes resources and can be restarted
+ *
+ * @version $$Rev: 471111 $$ $$Date: 2006-11-03 23:06:48 -0500 (Fri, 03 Nov 2006) $$
+ */
+public class ConversationalScopeRestartTestCase extends TestCase {
+
+ public void testRestart() throws Exception {
+ StoreMonitor monitor = EasyMock.createMock(StoreMonitor.class);
+ monitor.start(EasyMock.isA(String.class));
+ monitor.stop(EasyMock.isA(String.class));
+ MemoryStore store = new MemoryStore(monitor);
+ WorkContext ctx = new WorkContextImpl();
+ ConversationalScopeContainer scope = new ConversationalScopeContainer(store, ctx, null);
+ scope.start();
+ MethodEventInvoker<Object> initInvoker = new MethodEventInvoker<Object>(
+ ConversationalScopeRestartTestCase.InitDestroyOnce.class.getMethod("init"));
+ MethodEventInvoker<Object> destroyInvoker =
+ new MethodEventInvoker<Object>(InitDestroyOnce.class.getMethod("destroy"));
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInitInvoker(initInvoker);
+ configuration.setDestroyInvoker(destroyInvoker);
+ Constructor<InitDestroyOnce> ctr = InitDestroyOnce.class.getConstructor((Class<?>[]) null);
+ configuration.setInstanceFactory(new PojoObjectFactory<InitDestroyOnce>(ctr));
+ configuration.setName(new URI("InitDestroy"));
+ AtomicComponent component = new SystemAtomicComponentImpl(configuration);
+ component.setScopeContainer(scope);
+ component.start();
+
+ String conversation = "conv";
+ ctx.setIdentifier(Scope.CONVERSATION, conversation);
+ scope.onEvent(new ConversationStart(this, conversation));
+ Object instance = component.getTargetInstance();
+ assertSame(instance, component.getTargetInstance());
+
+ scope.onEvent(new ConversationEnd(this, conversation));
+ scope.stop();
+ component.stop();
+
+ scope.start();
+ scope.onEvent(new ConversationStart(this, conversation));
+ component.start();
+ //assertNotSame(instance, context.getServiceInstance());
+ scope.onEvent(new ConversationEnd(this, conversation));
+ scope.stop();
+ component.stop();
+ }
+
+ public static class InitDestroyOnce {
+
+ private boolean initialized;
+ private boolean destroyed;
+
+ public InitDestroyOnce() {
+ }
+
+ public void init() {
+ if (!initialized) {
+ initialized = true;
+ } else {
+ fail("Scope did not clean up properly - Init called more than once");
+ }
+ }
+
+ public void destroy() {
+ if (!destroyed) {
+ destroyed = true;
+ } else {
+ fail("Scope did not clean up properly - Destroyed called more than once");
+ }
+ }
+
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/DependencyLifecycleTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/DependencyLifecycleTestCase.java new file mode 100644 index 0000000000..ab8806929b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/DependencyLifecycleTestCase.java @@ -0,0 +1,170 @@ +/* + * 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.core.component.scope; + +import java.util.Map; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.Scope; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.component.event.ComponentStart; +import org.apache.tuscany.core.component.event.ComponentStop; +import org.apache.tuscany.core.component.event.HttpSessionEnd; +import org.apache.tuscany.core.component.event.RequestEnd; +import org.apache.tuscany.core.component.event.RequestStart; +import org.apache.tuscany.core.mock.component.OrderedDependentPojo; +import org.apache.tuscany.core.mock.component.OrderedDependentPojoImpl; +import org.apache.tuscany.core.mock.component.OrderedInitPojo; +import org.apache.tuscany.core.mock.component.OrderedInitPojoImpl; + +/** + * Tests dependencies are initalized and destroyed in the proper order (i.e. LIFO) + * + * @version $Rev$ $Date$ + */ +public class DependencyLifecycleTestCase extends TestCase { + + public void testInitDestroyOrderCompositeScope() throws Exception { + CompositeScopeContainer scopeCtx = new CompositeScopeContainer(null); + scopeCtx.start(); + Map<String, AtomicComponent> components = MockFactory.createWiredComponents("source", + OrderedDependentPojoImpl.class, + scopeCtx, + "target", + OrderedInitPojoImpl.class, + scopeCtx); + for (AtomicComponent component : components.values()) { + scopeCtx.register(component); + } + AtomicComponent sourceComponent = components.get("source"); + AtomicComponent targetComponent = components.get("target"); + scopeCtx.register(sourceComponent); + scopeCtx.register(targetComponent); + scopeCtx.onEvent(new ComponentStart(this, null)); + OrderedDependentPojo source = (OrderedDependentPojo) scopeCtx.getInstance(sourceComponent); + OrderedInitPojo target = (OrderedInitPojo) scopeCtx.getInstance(targetComponent); + assertNotNull(source.getPojo()); + assertNotNull(target); + assertEquals(2, source.getNumberInstantiated()); + scopeCtx.onEvent(new ComponentStop(this, null)); + assertEquals(0, source.getNumberInstantiated()); + scopeCtx.stop(); + } + + public void testInitDestroyOrderAfterStartCompositeScope() throws Exception { + CompositeScopeContainer scopeCtx = new CompositeScopeContainer(null); + scopeCtx.start(); + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", + OrderedDependentPojoImpl.class, + scopeCtx, + "target", + OrderedInitPojoImpl.class, + scopeCtx); + AtomicComponent sourceComponent = contexts.get("source"); + AtomicComponent targetComponent = contexts.get("target"); + scopeCtx.onEvent(new ComponentStart(this, null)); + scopeCtx.register(sourceComponent); + scopeCtx.register(targetComponent); + OrderedDependentPojo source = (OrderedDependentPojo) scopeCtx.getInstance(sourceComponent); + OrderedInitPojo target = (OrderedInitPojo) scopeCtx.getInstance(targetComponent); + assertNotNull(source.getPojo()); + assertNotNull(target); + assertEquals(2, source.getNumberInstantiated()); + scopeCtx.onEvent(new ComponentStop(this, null)); + assertEquals(0, source.getNumberInstantiated()); + scopeCtx.stop(); + } + + + public void testInitDestroyOrderSessionScope() throws Exception { + WorkContext ctx = new WorkContextImpl(); + HttpSessionScopeContainer scopeCtx = new HttpSessionScopeContainer(ctx, null); + scopeCtx.start(); + Object session = new Object(); + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", + OrderedDependentPojoImpl.class, + scopeCtx, + "target", + OrderedInitPojoImpl.class, + scopeCtx); + AtomicComponent sourceComponent = contexts.get("source"); + AtomicComponent targetComponent = contexts.get("target"); + scopeCtx.register(sourceComponent); + scopeCtx.register(targetComponent); + ctx.setIdentifier(Scope.SESSION, session); + OrderedDependentPojo source = (OrderedDependentPojo) scopeCtx.getInstance(sourceComponent); + assertNotNull(source.getPojo()); + assertEquals(2, source.getNumberInstantiated()); + scopeCtx.onEvent(new HttpSessionEnd(this, session)); + assertEquals(0, source.getNumberInstantiated()); + scopeCtx.stop(); + } + + + public void testInitDestroyOrderAfterStartSessionScope() throws Exception { + WorkContext ctx = new WorkContextImpl(); + HttpSessionScopeContainer scopeCtx = new HttpSessionScopeContainer(ctx, null); + scopeCtx.start(); + Object session = new Object(); + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", + OrderedDependentPojoImpl.class, + scopeCtx, + "target", + OrderedInitPojoImpl.class, + scopeCtx); + AtomicComponent sourceComponent = contexts.get("source"); + AtomicComponent targetComponent = contexts.get("target"); + ctx.setIdentifier(Scope.SESSION, session); + scopeCtx.register(sourceComponent); + scopeCtx.register(targetComponent); + OrderedDependentPojo source = (OrderedDependentPojo) scopeCtx.getInstance(sourceComponent); + assertNotNull(source.getPojo()); + assertEquals(2, source.getNumberInstantiated()); + scopeCtx.onEvent(new HttpSessionEnd(this, session)); + assertEquals(0, source.getNumberInstantiated()); + scopeCtx.stop(); + } + + public void testInitDestroyOrderRequestScope() throws Exception { + WorkContext ctx = new WorkContextImpl(); + RequestScopeContainer scopeCtx = new RequestScopeContainer(ctx, null); + scopeCtx.start(); + scopeCtx.onEvent(new RequestStart(this)); + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", + OrderedDependentPojoImpl.class, + scopeCtx, + "target", + OrderedInitPojoImpl.class, + scopeCtx); + AtomicComponent sourceComponent = contexts.get("source"); + AtomicComponent targetComponent = contexts.get("target"); + scopeCtx.register(sourceComponent); + scopeCtx.register(targetComponent); + OrderedDependentPojo source = (OrderedDependentPojo) scopeCtx.getInstance(sourceComponent); + assertNotNull(source.getPojo()); + assertEquals(2, source.getNumberInstantiated()); + scopeCtx.onEvent(new RequestEnd(this)); + assertEquals(0, source.getNumberInstantiated()); + scopeCtx.stop(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeInitDestroyErrorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeInitDestroyErrorTestCase.java new file mode 100644 index 0000000000..be05a5b15b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeInitDestroyErrorTestCase.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.core.component.scope; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainerMonitor; +import org.apache.tuscany.spi.component.TargetDestructionException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.model.Scope; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.component.event.HttpSessionEnd; +import org.apache.tuscany.core.component.event.HttpSessionStart; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class HttpSessionScopeInitDestroyErrorTestCase extends TestCase { + + public void testDestroyErrorMonitor() throws Exception { + ScopeContainerMonitor monitor; + monitor = EasyMock.createMock(ScopeContainerMonitor.class); + monitor.destructionError(EasyMock.isA(TargetDestructionException.class)); + EasyMock.replay(monitor); + WorkContext workContext = new WorkContextImpl(); + HttpSessionScopeContainer scope = new HttpSessionScopeContainer(workContext, monitor); + scope.start(); + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + component.addListener(EasyMock.isA(RuntimeEventListener.class)); + EasyMock.expect(component.createInstance()).andReturn(new Object()); + EasyMock.expect(component.isEagerInit()).andReturn(true); + component.init(EasyMock.isA(Object.class)); + component.destroy(EasyMock.isA(Object.class)); + EasyMock.expectLastCall().andThrow(new TargetDestructionException("", "")); + EasyMock.replay(component); + scope.register(component); + Object id = new Object(); + scope.onEvent(new HttpSessionStart(this, id)); + workContext.setIdentifier(Scope.SESSION, id); + scope.getInstance(component); + scope.onEvent(new HttpSessionEnd(this, id)); + EasyMock.verify(monitor); + } + + + protected void setUp() throws Exception { + super.setUp(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeInstanceLifecycleTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeInstanceLifecycleTestCase.java new file mode 100644 index 0000000000..29d6d54450 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeInstanceLifecycleTestCase.java @@ -0,0 +1,136 @@ +/* + * 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.core.component.scope; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.model.Scope; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.component.event.HttpSessionEnd; +import org.apache.tuscany.core.component.event.HttpSessionStart; +import org.apache.tuscany.core.mock.component.OrderedInitPojo; +import org.apache.tuscany.core.mock.component.OrderedInitPojoImpl; +import org.easymock.EasyMock; +import org.easymock.IAnswer; + +/** + * Lifecycle unit tests for the composite scope container + * + * @version $Rev$ $Date$ + */ +public class HttpSessionScopeInstanceLifecycleTestCase extends TestCase { + + public void testInitDestroy() throws Exception { + WorkContext ctx = new WorkContextImpl(); + HttpSessionScopeContainer scope = new HttpSessionScopeContainer(ctx, null); + scope.start(); + Foo comp = new Foo(); + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(component.createInstance()).andReturn(comp); + component.addListener(EasyMock.isA(RuntimeEventListener.class)); + component.init(EasyMock.eq(comp)); + component.destroy(EasyMock.eq(comp)); + EasyMock.replay(component); + scope.register(component); + Object session = new Object(); + ctx.setIdentifier(Scope.SESSION, session); + scope.onEvent(new HttpSessionStart(this, session)); + assertNotNull(scope.getInstance(component)); + // expire + scope.onEvent(new HttpSessionEnd(this, session)); + scope.stop(); + EasyMock.verify(component); + scope.stop(); + } + + public void testDestroyOrder() throws Exception { + WorkContext ctx = new WorkContextImpl(); + HttpSessionScopeContainer scope = new HttpSessionScopeContainer(ctx, null); + scope.start(); + + AtomicComponent oneComponent = createComponent(); + scope.register(oneComponent); + AtomicComponent twoComponent = createComponent(); + scope.register(twoComponent); + AtomicComponent threeComponent = createComponent(); + scope.register(threeComponent); + + Object session = new Object(); + ctx.setIdentifier(Scope.SESSION, session); + scope.onEvent(new HttpSessionStart(this, session)); + OrderedInitPojo one = (OrderedInitPojo) scope.getInstance(oneComponent); + assertNotNull(one); + assertEquals(1, one.getNumberInstantiated()); + assertEquals(1, one.getInitOrder()); + + OrderedInitPojo two = (OrderedInitPojo) scope.getInstance(twoComponent); + assertNotNull(two); + assertEquals(2, two.getNumberInstantiated()); + assertEquals(2, two.getInitOrder()); + + OrderedInitPojo three = (OrderedInitPojo) scope.getInstance(threeComponent); + assertNotNull(three); + assertEquals(3, three.getNumberInstantiated()); + assertEquals(3, three.getInitOrder()); + + scope.onEvent(new HttpSessionEnd(this, session)); + assertEquals(0, one.getNumberInstantiated()); + scope.stop(); + EasyMock.verify(oneComponent); + EasyMock.verify(twoComponent); + EasyMock.verify(threeComponent); + } + + @SuppressWarnings("unchecked") + private AtomicComponent createComponent() throws TargetException { + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(component.createInstance()).andStubAnswer(new IAnswer() { + public Object answer() throws Throwable { + return new OrderedInitPojoImpl(); + } + }); + component.addListener(EasyMock.isA(RuntimeEventListener.class)); + component.init(EasyMock.isA(OrderedInitPojoImpl.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer() { + public Object answer() throws Throwable { + OrderedInitPojoImpl pojo = (OrderedInitPojoImpl) EasyMock.getCurrentArguments()[0]; + pojo.init(); + return null; + } + }); + component.destroy(EasyMock.isA(OrderedInitPojoImpl.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer() { + public Object answer() throws Throwable { + OrderedInitPojoImpl pojo = (OrderedInitPojoImpl) EasyMock.getCurrentArguments()[0]; + pojo.destroy(); + return null; + } + }); + EasyMock.replay(component); + return component; + } + + private class Foo { + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeRestartTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeRestartTestCase.java new file mode 100644 index 0000000000..2baecf1e17 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeRestartTestCase.java @@ -0,0 +1,106 @@ +/* + * 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.core.component.scope; + +import java.lang.reflect.Constructor; +import java.net.URI; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.Scope; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.component.event.HttpSessionEnd; +import org.apache.tuscany.core.component.event.HttpSessionStart; +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl; +import org.apache.tuscany.core.injection.MethodEventInvoker; +import org.apache.tuscany.core.injection.PojoObjectFactory; + +/** + * Verifies the scope container properly disposes resources and canbe restarted + * + * @version $$Rev$$ $$Date$$ + */ +public class HttpSessionScopeRestartTestCase extends TestCase { + + public void testRestart() throws Exception { + WorkContext ctx = new WorkContextImpl(); + HttpSessionScopeContainer scope = new HttpSessionScopeContainer(ctx, null); + scope.start(); + MethodEventInvoker<Object> initInvoker = new MethodEventInvoker<Object>( + HttpSessionScopeRestartTestCase.InitDestroyOnce.class.getMethod("init")); + MethodEventInvoker<Object> destroyInvoker = + new MethodEventInvoker<Object>(InitDestroyOnce.class.getMethod("destroy")); + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setInitInvoker(initInvoker); + configuration.setDestroyInvoker(destroyInvoker); + Constructor<InitDestroyOnce> ctr = InitDestroyOnce.class.getConstructor((Class<?>[]) null); + configuration.setInstanceFactory(new PojoObjectFactory<InitDestroyOnce>(ctr)); + configuration.setName(new URI("InitDestroy")); + AtomicComponent component = new SystemAtomicComponentImpl(configuration); + component.setScopeContainer(scope); + component.start(); + + Object session = new Object(); + ctx.setIdentifier(Scope.SESSION, session); + scope.onEvent(new HttpSessionStart(this, session)); + Object instance = component.getTargetInstance(); + assertSame(instance, component.getTargetInstance()); + + scope.onEvent(new HttpSessionEnd(this, session)); + scope.stop(); + component.stop(); + + scope.start(); + scope.onEvent(new HttpSessionStart(this, session)); + component.start(); + assertNotSame(instance, component.getTargetInstance()); + scope.onEvent(new HttpSessionEnd(this, session)); + scope.stop(); + component.stop(); + } + + public static class InitDestroyOnce { + + private boolean initialized; + private boolean destroyed; + + public InitDestroyOnce() { + } + + public void init() { + if (!initialized) { + initialized = true; + } else { + fail("Scope did not clean up properly - Init called more than once"); + } + } + + public void destroy() { + if (!destroyed) { + destroyed = true; + } else { + fail("Scope did not clean up properly - Destroyed called more than once"); + } + } + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/InstanceWrapperBaseTestClass.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/InstanceWrapperBaseTestClass.java new file mode 100644 index 0000000000..d75100d0e1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/InstanceWrapperBaseTestClass.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.core.component.scope; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class InstanceWrapperBaseTestClass extends TestCase { + private static final Object INSTANCE = new Object(); + private InstanceWrapperBase<Object> wrapper; + + public void testLifecycle() throws Exception { + assertFalse(wrapper.isStarted()); + try { + wrapper.getInstance(); + fail(); + } catch (AssertionError e) { + // expected + } + wrapper.start(); + assertTrue(wrapper.isStarted()); + assertSame(INSTANCE, wrapper.getInstance()); + wrapper.stop(); + assertFalse(wrapper.isStarted()); + try { + wrapper.getInstance(); + fail(); + } catch (AssertionError e) { + // expected + } + } + + public void testNullCheck() { + try { + new InstanceWrapperBase<Object>(null); + fail(); + } catch (AssertionError e) { + // expected + } + } + + protected void setUp() throws Exception { + super.setUp(); + wrapper = new InstanceWrapperBase<Object>(INSTANCE); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/InstanceWrapperTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/InstanceWrapperTestCase.java new file mode 100644 index 0000000000..f1fd74aeb0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/InstanceWrapperTestCase.java @@ -0,0 +1,66 @@ +/* + * 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.core.component.scope; + +import org.apache.tuscany.spi.component.AtomicComponent; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class InstanceWrapperTestCase extends TestCase { + + public void testExceptionInit() throws Exception { + AtomicComponent component = getComponent(); + InstanceWrapper wrapper = new InstanceWrapperImpl(component, new Object()); + try { + wrapper.start(); + fail(); + } catch (SomeException e) { + // expected + } + assertFalse(wrapper.isStarted()); + EasyMock.verify(component); + } + + public void testNonStart() throws Exception { + AtomicComponent comp = EasyMock.createNiceMock(AtomicComponent.class); // class-level one has an expects + InstanceWrapper wrapper = new InstanceWrapperImpl(comp, new Object()); + try { + wrapper.getInstance(); + fail(); + } catch (AssertionError e) { + // expected + } + } + + private AtomicComponent getComponent() throws Exception { + // do not use setUp() since we do not need this in all testcases + AtomicComponent comp = EasyMock.createMock(AtomicComponent.class); + comp.init(EasyMock.isA(Object.class)); + EasyMock.expectLastCall().andThrow(new SomeException()); + EasyMock.replay(comp); + return comp; + } + + private class SomeException extends RuntimeException { + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/MockFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/MockFactory.java new file mode 100644 index 0000000000..d7f78f46dd --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/MockFactory.java @@ -0,0 +1,125 @@ +/* + * 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.core.component.scope; + +import java.lang.reflect.Method; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Map; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Init; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.wire.Wire; + +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl; +import org.apache.tuscany.core.injection.MethodEventInvoker; +import org.apache.tuscany.core.injection.PojoObjectFactory; +import org.apache.tuscany.core.wire.WireImpl; + +/** + * @version $$Rev$$ $$Date$$ + */ +public final class MockFactory { + + private MockFactory() { + } + + @SuppressWarnings("unchecked") + public static Map<String, AtomicComponent> createWiredComponents(String source, + Class<?> sourceClass, + ScopeContainer sourceScopeContainer, + String target, + Class<?> targetClass, + ScopeContainer targetScopeContainer) + throws NoSuchMethodException, URISyntaxException { + + Map<String, AtomicComponent> components = new HashMap<String, AtomicComponent>(); + AtomicComponent targetComponent = createAtomicComponent(target, targetScopeContainer, targetClass); + PojoConfiguration sourceConfig = new PojoConfiguration(); + sourceConfig.setInstanceFactory(new PojoObjectFactory(sourceClass.getConstructor())); + Method[] sourceMethods = sourceClass.getMethods(); + Class[] interfaces = targetClass.getInterfaces(); + EagerInit eager = targetClass.getAnnotation(EagerInit.class); + if (eager != null) { + sourceConfig.setInitLevel(50); + } + Method setter = null; + for (Class interfaze : interfaces) { + for (Method method : sourceMethods) { + if (method.getParameterTypes().length == 1) { + if (interfaze.isAssignableFrom(method.getParameterTypes()[0])) { + setter = method; + } + } + if (method.getAnnotation(Init.class) != null) { + sourceConfig.setInitInvoker(new MethodEventInvoker<Object>(method)); + + } else if (method.getAnnotation(Destroy.class) != null) { + sourceConfig.setDestroyInvoker(new MethodEventInvoker<Object>(method)); + } + } + } + if (setter == null) { + throw new IllegalArgumentException("No setter found on source for target"); + } + sourceConfig.addReferenceSite(setter.getName(), setter); + sourceConfig.setName(new URI(source)); + AtomicComponent sourceComponent = new SystemAtomicComponentImpl(sourceConfig); + sourceComponent.setScopeContainer(sourceScopeContainer); + Wire wire = new WireImpl(); + wire.setSourceUri(URI.create("#" + setter.getName())); + wire.setSourceContract(new JavaServiceContract(targetClass)); + wire.setTarget(targetComponent); + sourceComponent.attachWire(wire); + components.put(source, sourceComponent); + components.put(target, targetComponent); + return components; + } + + @SuppressWarnings("unchecked") + public static AtomicComponent createAtomicComponent(String name, ScopeContainer container, Class<?> clazz) + throws NoSuchMethodException, URISyntaxException { + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setInstanceFactory(new PojoObjectFactory(clazz.getConstructor())); + EagerInit eager = clazz.getAnnotation(EagerInit.class); + if (eager != null) { + configuration.setInitLevel(50); + } + Method[] methods = clazz.getMethods(); + for (Method method : methods) { + if (method.getAnnotation(Init.class) != null) { + configuration.setInitInvoker(new MethodEventInvoker<Object>(method)); + } else if (method.getAnnotation(Destroy.class) != null) { + configuration.setDestroyInvoker(new MethodEventInvoker<Object>(method)); + } + } + configuration.setName(new URI(name)); + AtomicComponent component = new SystemAtomicComponentImpl(configuration); + component.setScopeContainer(container); + return component; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeInitDestroyErrorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeInitDestroyErrorTestCase.java new file mode 100644 index 0000000000..e62392cf76 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeInitDestroyErrorTestCase.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.core.component.scope; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainerMonitor; +import org.apache.tuscany.spi.component.TargetDestructionException; +import org.apache.tuscany.spi.event.RuntimeEventListener; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.component.event.RequestEnd; +import org.apache.tuscany.core.component.event.RequestStart; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class RequestScopeInitDestroyErrorTestCase extends TestCase { + + public void testDestroyErrorMonitor() throws Exception { + ScopeContainerMonitor monitor; + monitor = EasyMock.createMock(ScopeContainerMonitor.class); + monitor.destructionError(EasyMock.isA(TargetDestructionException.class)); + EasyMock.replay(monitor); + RequestScopeContainer scope = new RequestScopeContainer(new WorkContextImpl(), monitor); + scope.start(); + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + component.addListener(EasyMock.isA(RuntimeEventListener.class)); + EasyMock.expect(component.createInstance()).andReturn(new Object()); + component.init(EasyMock.isA(Object.class)); + component.destroy(EasyMock.isA(Object.class)); + EasyMock.expectLastCall().andThrow(new TargetDestructionException("", "")); + EasyMock.replay(component); + scope.register(component); + scope.onEvent(new RequestStart(this)); + scope.getInstance(component); + scope.onEvent(new RequestEnd(this)); + EasyMock.verify(monitor); + } + + + protected void setUp() throws Exception { + super.setUp(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeInstanceLifecycleTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeInstanceLifecycleTestCase.java new file mode 100644 index 0000000000..6601640c3b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeInstanceLifecycleTestCase.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.core.component.scope; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.component.WorkContext; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.component.event.RequestEnd; +import org.apache.tuscany.core.component.event.RequestStart; +import org.apache.tuscany.core.mock.component.OrderedInitPojo; +import org.apache.tuscany.core.mock.component.OrderedInitPojoImpl; +import org.easymock.EasyMock; +import org.easymock.IAnswer; + +/** + * Lifecycle unit tests for the request scope container + * + * @version $Rev$ $Date$ + */ +public class RequestScopeInstanceLifecycleTestCase extends TestCase { + + public void testInitDestroy() throws Exception { + WorkContext ctx = new WorkContextImpl(); + RequestScopeContainer scope = new RequestScopeContainer(ctx, null); + scope.start(); + Foo comp = new Foo(); + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(component.createInstance()).andReturn(comp); + component.init(EasyMock.eq(comp)); + component.destroy(EasyMock.eq(comp)); + EasyMock.replay(component); + scope.register(component); + scope.onEvent(new RequestStart(this)); + assertNotNull(scope.getInstance(component)); + // expire + scope.onEvent(new RequestEnd(this)); + scope.stop(); + EasyMock.verify(component); + scope.stop(); + } + + public void testDestroyOrder() throws Exception { + WorkContext ctx = new WorkContextImpl(); + RequestScopeContainer scope = new RequestScopeContainer(ctx, null); + scope.start(); + + AtomicComponent oneComponent = createComponent(); + scope.register(oneComponent); + AtomicComponent twoComponent = createComponent(); + scope.register(twoComponent); + AtomicComponent threeComponent = createComponent(); + scope.register(threeComponent); + + scope.onEvent(new RequestStart(this)); + OrderedInitPojo one = (OrderedInitPojo) scope.getInstance(oneComponent); + assertNotNull(one); + assertEquals(1, one.getNumberInstantiated()); + assertEquals(1, one.getInitOrder()); + + OrderedInitPojo two = (OrderedInitPojo) scope.getInstance(twoComponent); + assertNotNull(two); + assertEquals(2, two.getNumberInstantiated()); + assertEquals(2, two.getInitOrder()); + + OrderedInitPojo three = (OrderedInitPojo) scope.getInstance(threeComponent); + assertNotNull(three); + assertEquals(3, three.getNumberInstantiated()); + assertEquals(3, three.getInitOrder()); + + scope.onEvent(new RequestEnd(this)); + assertEquals(0, one.getNumberInstantiated()); + scope.stop(); + EasyMock.verify(oneComponent); + EasyMock.verify(twoComponent); + EasyMock.verify(threeComponent); + } + + @SuppressWarnings("unchecked") + private AtomicComponent createComponent() throws TargetException { + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(component.createInstance()).andStubAnswer(new IAnswer() { + public Object answer() throws Throwable { + return new OrderedInitPojoImpl(); + } + }); + component.init(EasyMock.isA(OrderedInitPojoImpl.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer() { + public Object answer() throws Throwable { + OrderedInitPojoImpl pojo = (OrderedInitPojoImpl) EasyMock.getCurrentArguments()[0]; + pojo.init(); + return null; + } + }); + component.destroy(EasyMock.isA(OrderedInitPojoImpl.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer() { + public Object answer() throws Throwable { + OrderedInitPojoImpl pojo = (OrderedInitPojoImpl) EasyMock.getCurrentArguments()[0]; + pojo.destroy(); + return null; + } + }); + EasyMock.replay(component); + return component; + } + + private class Foo { + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeRestartTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeRestartTestCase.java new file mode 100644 index 0000000000..d22c2eb538 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeRestartTestCase.java @@ -0,0 +1,100 @@ +/* + * 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.core.component.scope; + +import java.lang.reflect.Constructor; +import java.net.URI; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.WorkContext; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.component.event.RequestEnd; +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl; +import org.apache.tuscany.core.injection.MethodEventInvoker; +import org.apache.tuscany.core.injection.PojoObjectFactory; + +/** + * Verifies the scope container properly disposes resources and canbe restarted + * + * @version $$Rev$$ $$Date$$ + */ +public class RequestScopeRestartTestCase extends TestCase { + + public void testRestart() throws Exception { + WorkContext ctx = new WorkContextImpl(); + RequestScopeContainer scope = new RequestScopeContainer(ctx, null); + scope.start(); + MethodEventInvoker<Object> initInvoker = + new MethodEventInvoker<Object>(InitDestroyOnce.class.getMethod("init")); + MethodEventInvoker<Object> destroyInvoker = + new MethodEventInvoker<Object>(InitDestroyOnce.class.getMethod("destroy")); + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setInitInvoker(initInvoker); + configuration.setDestroyInvoker(destroyInvoker); + Constructor<InitDestroyOnce> ctr = InitDestroyOnce.class.getConstructor((Class<?>[]) null); + configuration.setInstanceFactory(new PojoObjectFactory<InitDestroyOnce>(ctr)); + configuration.setName(new URI("InitDestroy")); + AtomicComponent component = new SystemAtomicComponentImpl(configuration); + component.setScopeContainer(scope); + component.start(); + + Object instance = component.getTargetInstance(); + assertSame(instance, component.getTargetInstance()); + + scope.onEvent(new RequestEnd(this)); + scope.stop(); + component.stop(); + + scope.start(); + component.start(); + assertNotSame(instance, component.getTargetInstance()); + scope.onEvent(new RequestEnd(this)); + scope.stop(); + component.stop(); + } + + public static class InitDestroyOnce { + + private boolean initialized; + private boolean destroyed; + + public InitDestroyOnce() { + } + + public void init() { + if (!initialized) { + initialized = true; + } else { + fail("Scope did not clean up properly - Init called more than once"); + } + } + + public void destroy() { + if (!destroyed) { + destroyed = true; + } else { + fail("Scope did not clean up properly - Destroyed called more than once"); + } + } + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ScopeRegistryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ScopeRegistryTestCase.java new file mode 100644 index 0000000000..e1380eb4c0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/ScopeRegistryTestCase.java @@ -0,0 +1,80 @@ +/* + * 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.core.component.scope; + +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.ScopeRegistry; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.Scope; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; + +/** + * Verifies retrieval of standard scope contexts from the default scope registry + * + * @version $$Rev$$ $$Date$$ + */ +public class ScopeRegistryTestCase extends TestCase { + public void testScopeContextCreation() throws Exception { + WorkContext context = new WorkContextImpl(); + ScopeRegistry scopeRegistry = new ScopeRegistryImpl(); + scopeRegistry.registerFactory(Scope.REQUEST, new RequestScopeObjectFactory(context, null)); + HttpSessionScopeObjectFactory sessionFactory = new HttpSessionScopeObjectFactory(scopeRegistry, context, null); + scopeRegistry.registerFactory(Scope.SESSION, sessionFactory); + scopeRegistry.registerFactory(Scope.CONVERSATION, + new ConversationalScopeObjectFactory(scopeRegistry, context, null, null)); + ScopeContainer request = scopeRegistry.getScopeContainer(Scope.REQUEST); + assertTrue(request instanceof RequestScopeContainer); + assertSame(request, scopeRegistry.getScopeContainer(Scope.REQUEST)); + ScopeContainer session = scopeRegistry.getScopeContainer(Scope.SESSION); + assertTrue(session instanceof HttpSessionScopeContainer); + assertSame(session, scopeRegistry.getScopeContainer(Scope.SESSION)); + assertNotSame(request, session); + ScopeContainer conversation = scopeRegistry.getScopeContainer(Scope.CONVERSATION); + assertTrue(conversation instanceof ConversationalScopeContainer); + assertSame(conversation, scopeRegistry.getScopeContainer(Scope.CONVERSATION)); + assertNotSame(session, conversation); + } + + public void testDeregisterFactory() throws Exception { + WorkContext context = new WorkContextImpl(); + ScopeRegistry scopeRegistry = new ScopeRegistryImpl(); + RequestScopeObjectFactory factory = new RequestScopeObjectFactory(context, null); + scopeRegistry.registerFactory(Scope.REQUEST, factory); + scopeRegistry.deregisterFactory(Scope.REQUEST); + assertNull(scopeRegistry.getScopeContainer(Scope.REQUEST)); + ConversationalScopeObjectFactory convFactory = + new ConversationalScopeObjectFactory(scopeRegistry, context, null, null); + scopeRegistry.registerFactory(Scope.CONVERSATION, convFactory); + scopeRegistry.deregisterFactory(Scope.CONVERSATION); + assertNull(scopeRegistry.getScopeContainer(Scope.CONVERSATION)); + } + + public void testScopeNotRegistered() throws Exception { + WorkContext workContext = new WorkContextImpl(); + ScopeRegistry scopeRegistry = new ScopeRegistryImpl(); + assertNull(scopeRegistry.getScopeContainer(Scope.REQUEST)); + assertNull(scopeRegistry.getScopeContainer(Scope.SESSION)); + assertNull(scopeRegistry.getScopeContainer(Scope.CONVERSATION)); + assertNull(scopeRegistry.getScopeContainer(Scope.STATELESS)); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/StatelessScopeContainerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/StatelessScopeContainerTestCase.java new file mode 100644 index 0000000000..89cd9b51d7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/StatelessScopeContainerTestCase.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.core.component.scope; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class StatelessScopeContainerTestCase extends TestCase { + + public void testBadStopWithoutStart() throws Exception { + StatelessScopeContainer container = new StatelessScopeContainer(null, null); + try { + container.stop(); + fail(); + } catch (IllegalStateException e) { + //expected + } + } + + public void testBadDoubleStart() throws Exception { + StatelessScopeContainer container = new StatelessScopeContainer(null, null); + try { + container.start(); + container.start(); + fail(); + } catch (IllegalStateException e) { + //expected + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactoryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactoryTestCase.java new file mode 100644 index 0000000000..0902b9d78c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactoryTestCase.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.core.component.scope; + +import org.apache.tuscany.spi.component.ScopeRegistry; +import org.apache.tuscany.spi.model.Scope; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class StatelessScopeObjectFactoryTestCase extends TestCase { + + public void testCreation() { + ScopeRegistry registry = EasyMock.createMock(ScopeRegistry.class); + registry.registerFactory(EasyMock.isA(Scope.class), EasyMock.isA(StatelessScopeObjectFactory.class)); + assertNotNull(new StatelessScopeObjectFactory(registry, null, null).getInstance()); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/WorkContextTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/WorkContextTestCase.java new file mode 100644 index 0000000000..c67b61a78f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/component/scope/WorkContextTestCase.java @@ -0,0 +1,212 @@ +/* + * 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.core.component.scope; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.WorkContext; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class WorkContextTestCase extends TestCase { + + public void testRemoteComponent() throws Exception { + WorkContext ctx = new WorkContextImpl(); + Component component = EasyMock.createNiceMock(Component.class); + Component component2 = EasyMock.createNiceMock(Component.class); + ctx.setRemoteComponent(component); + assertEquals(component, ctx.getRemoteComponent()); + ctx.setRemoteComponent(component2); + assertEquals(component2, ctx.getRemoteComponent()); + } + + public void testNonSetRemoteComponent() throws Exception { + WorkContext ctx = new WorkContextImpl(); + assertNull(ctx.getRemoteComponent()); + } + + public void testSetCurrentAtomicComponent() throws Exception { + WorkContext ctx = new WorkContextImpl(); + AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class); + AtomicComponent component2 = EasyMock.createNiceMock(AtomicComponent.class); + ctx.setCurrentAtomicComponent(component); + assertEquals(component, ctx.getCurrentAtomicComponent()); + ctx.setCurrentAtomicComponent(component2); + assertEquals(component2, ctx.getCurrentAtomicComponent()); + } + + public void testNonSetCurrentAtomicComponent() throws Exception { + WorkContext ctx = new WorkContextImpl(); + assertNull(ctx.getCurrentAtomicComponent()); + } + + public void testIndentifier() throws Exception { + WorkContext ctx = new WorkContextImpl(); + Object id = new Object(); + ctx.setIdentifier(this, id); + assertEquals(id, ctx.getIdentifier(this)); + } + + public void testClearIndentifier() throws Exception { + WorkContext ctx = new WorkContextImpl(); + Object id = new Object(); + ctx.setIdentifier(this, id); + ctx.clearIdentifier(this); + assertNull(ctx.getIdentifier(this)); + } + + public void testClearIndentifiers() throws Exception { + WorkContext ctx = new WorkContextImpl(); + Object id = new Object(); + Object id2 = new Object(); + ctx.setIdentifier(id, id); + ctx.setIdentifier(id2, id2); + ctx.clearIdentifiers(); + assertNull(ctx.getIdentifier(id)); + assertNull(ctx.getIdentifier(id2)); + } + + public void testClearNonExistentIndentifier() throws Exception { + WorkContext ctx = new WorkContextImpl(); + ctx.clearIdentifier(this); + } + + public void testNullIndentifier() throws Exception { + WorkContext ctx = new WorkContextImpl(); + Object id = new Object(); + ctx.setIdentifier(this, id); + ctx.clearIdentifier(null); + assertEquals(id, ctx.getIdentifier(this)); + } + + public void testNoIndentifier() throws Exception { + WorkContext ctx = new WorkContextImpl(); + assertNull(ctx.getIdentifier(this)); + } + + public void testSetGetCorrelationId() { + WorkContext context = new WorkContextImpl(); + context.setCorrelationId("msg-005"); + assertEquals(context.getCorrelationId(), "msg-005"); + context.setCorrelationId(null); + assertNull(context.getCorrelationId()); + } + + public void testSetGetCorrelationIdInNewThread() throws InterruptedException { + WorkContext context = new WorkContextImpl(); + context.setCorrelationId("msg-005"); + assertEquals(context.getCorrelationId(), "msg-005"); + context.setIdentifier("TX", "002"); + ChildThread t = new ChildThread(context); + t.start(); + t.join(); + assertTrue(t.passed); + context.setCorrelationId(null); + assertNull(context.getCorrelationId()); + } + + public void testCurrentAtomicComponentDoesNotPropagateToChildThread() throws InterruptedException { + // NOTE should behaviour be to propagate? + WorkContext context = new WorkContextImpl(); + context.setCurrentAtomicComponent(EasyMock.createNiceMock(AtomicComponent.class)); + TestCurrentAtomicComponentChildThread t = new TestCurrentAtomicComponentChildThread(context); + t.start(); + t.join(); + assertTrue(t.passed); + context.setCurrentAtomicComponent(null); + assertNull(context.getCurrentAtomicComponent()); + } + + public void testCurrentRemoteComponentDoesNotPropagateToChildThread() throws InterruptedException { + // NOTE should behaviour be to propagate? + WorkContext context = new WorkContextImpl(); + context.setRemoteComponent(EasyMock.createNiceMock(Component.class)); + TestCurrentRemoteComponentChildThread t = new TestCurrentRemoteComponentChildThread(context); + t.start(); + t.join(); + assertTrue(t.passed); + context.setRemoteComponent(null); + assertNull(context.getRemoteComponent()); + } + + private static final class ChildThread extends Thread { + private WorkContext context; + private boolean passed = true; + + private ChildThread(WorkContext context) { + this.context = context; + } + + @Override + public void run() { + try { + assertNull(context.getCorrelationId()); + assertEquals("002", context.getIdentifier("TX")); + } catch (AssertionError e) { + passed = false; + } + } + + } + + private static final class TestCurrentAtomicComponentChildThread extends Thread { + private WorkContext context; + private boolean passed = true; + + private TestCurrentAtomicComponentChildThread(WorkContext context) { + this.context = context; + } + + @Override + public void run() { + try { + assertNull(context.getCurrentAtomicComponent()); + } catch (AssertionError e) { + passed = false; + } + } + + } + + private static final class TestCurrentRemoteComponentChildThread extends Thread { + private WorkContext context; + private boolean passed = true; + + private TestCurrentRemoteComponentChildThread(WorkContext context) { + this.context = context; + } + + @Override + public void run() { + try { + assertNull(context.getRemoteComponent()); + } catch (AssertionError e) { + passed = false; + } + } + + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingInterceptorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingInterceptorTestCase.java new file mode 100644 index 0000000000..086649ea75 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingInterceptorTestCase.java @@ -0,0 +1,126 @@ +/* + * 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.core.databinding.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.databinding.Mediator; +import org.apache.tuscany.spi.model.DataType; +import org.apache.tuscany.spi.model.Operation; +import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION; +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.Assert; +import junit.framework.TestCase; +import org.easymock.EasyMock; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.replay; + +/** + * @version $Rev$ $Date$ + */ +public class DataBindingInterceptorTestCase extends TestCase { + + @SuppressWarnings("unchecked") + public final void testInvoke() { + DataType<Class> type1 = new DataType<Class>("xml:string", String.class, String.class); + List<DataType<Class>> types1 = new ArrayList<DataType<Class>>(); + types1.add(type1); + DataType<List<DataType<Class>>> inputType1 = + new DataType<List<DataType<Class>>>("xml:string", Object[].class, types1); + + DataType<Class> type2 = new DataType<Class>("foo", Foo.class, Foo.class); + List<DataType<Class>> types2 = new ArrayList<DataType<Class>>(); + types2.add(type2); + DataType<List<DataType<Class>>> inputType2 = + new DataType<List<DataType<Class>>>("foo", Object[].class, types2); + + Operation<Class> operation1 = + new Operation<Class>("call", inputType1, type1, null, false, "xml:string", NO_CONVERSATION); + Operation<Class> operation2 = + new Operation<Class>("call", inputType2, type2, null, false, "org.w3c.dom.Node", NO_CONVERSATION); + + DataType<DataType> outputType1 = + new DataType<DataType>("idl:output", Object.class, operation1.getOutputType()); + DataType<DataType> outputType2 = + new DataType<DataType>("idl:output", Object.class, operation2.getOutputType()); + + Wire outboundWire = EasyMock.createMock(Wire.class); + Component composite = EasyMock.createMock(Component.class); + Component component = EasyMock.createMock(Component.class); + EasyMock.replay(outboundWire, composite, component); + + DataBindingInteceptor interceptor = new DataBindingInteceptor(outboundWire, operation1, operation2); + Mediator mediator = createMock(Mediator.class); + Object[] source = new Object[]{"<foo>bar</foo>"}; + Foo foo = new Foo(); + foo.bar = "bar"; + Object[] target = new Object[]{foo}; + expect(mediator.mediate(EasyMock.same(source), + EasyMock.same(inputType1), + EasyMock.same(inputType2), + EasyMock.isA(Map.class))).andReturn(target); + // expect(mediator.mediate(target[0], type2, + // type1)).andReturn(source[0]); + expect(mediator.mediate(EasyMock.same(target[0]), + EasyMock.eq(outputType2), + EasyMock.eq(outputType1), + EasyMock.isA(Map.class))).andReturn(source[0]); + replay(mediator); + interceptor.setMediator(mediator); + Message msg = createMock(Message.class); + msg.setBody(EasyMock.anyObject()); + expectLastCall().anyTimes(); + expect(msg.getBody()).andReturn(source).once().andReturn(target[0]).once().andReturn(source[0]); + expect(msg.isFault()).andReturn(false).once(); + replay(msg); + Interceptor next = createMock(Interceptor.class); + expect(next.invoke(msg)).andReturn(msg); + replay(next); + interceptor.setNext(next); + interceptor.invoke(msg); + String result = (String) msg.getBody(); + Assert.assertEquals(source[0], result); + EasyMock.verify(mediator, msg, next); + } + + protected void setUp() throws Exception { + super.setUp(); + } + + private static class Foo { + private String bar; + + public String getBar() { + return bar; + } + + public void setBar(String bar) { + this.bar = bar; + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingJavaInterfaceProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingJavaInterfaceProcessorTestCase.java new file mode 100644 index 0000000000..91702ac091 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingJavaInterfaceProcessorTestCase.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.core.databinding.impl; + +import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.tuscany.api.annotation.DataContext; +import org.apache.tuscany.api.annotation.DataType; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.model.Operation; +import org.osoa.sca.annotations.Remotable; +import org.w3c.dom.Node; + +/** + * + */ +public class DataBindingJavaInterfaceProcessorTestCase extends TestCase { + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + } + + /** + * @throws InvalidServiceContractException + */ + public final void testVisitInterface() throws InvalidServiceContractException { + DataBindingJavaInterfaceProcessor processor = new DataBindingJavaInterfaceProcessor(); + JavaServiceContract contract = new JavaServiceContract(MockInterface.class); + Map<String, Operation<Type>> operations = new HashMap<String, Operation<Type>>(); + Operation<Type> operation = new Operation<Type>("call", null, null, null, false, null, NO_CONVERSATION); + Operation<Type> operation1 = new Operation<Type>("call1", null, null, null, false, null, NO_CONVERSATION); + operations.put("call", operation); + operations.put("call1", operation1); + contract.setOperations(operations); + processor.visitInterface(MockInterface.class, null, contract); + Assert.assertEquals("org.w3c.dom.Node", contract.getDataBinding()); + Assert.assertEquals("element", (String)contract.getMetaData().get("nodeType")); + Assert.assertEquals("org.w3c.dom.Node", contract.getOperations().get("call").getDataBinding()); + Assert.assertEquals("xml:string", contract.getOperations().get("call1").getDataBinding()); + } + + @DataType(name = "org.w3c.dom.Node", context = {@DataContext(key = "nodeType", value = "element")}) + @Remotable + public static interface MockInterface { + Node call(Node msg); + + @DataType(name = "xml:string") + String call1(String msg); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingLoaderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingLoaderTestCase.java new file mode 100644 index 0000000000..6941e10a0c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingLoaderTestCase.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.core.databinding.impl; + +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.tuscany.spi.loader.InvalidValueException; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.model.DataType; +import org.apache.tuscany.spi.model.ModelObject; +import org.easymock.EasyMock; + +/** + * Testcase for DataBindingLoader + */ +public class DataBindingLoaderTestCase extends TestCase { + private XMLStreamReader reader; + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + } + + public final void testLoad() throws LoaderException, XMLStreamException { + reader = EasyMock.createMock(XMLStreamReader.class); + // EasyMock.expect(reader.getEventType()).andReturn(XMLStreamConstants.START_ELEMENT); + EasyMock.expect(reader.hasNext()).andReturn(true).anyTimes(); + EasyMock.expect(reader.getName()).andReturn(DataTypeLoader.DATA_BINDING); + EasyMock.expect(reader.getAttributeValue(null, "name")).andReturn("ABC"); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.replay(reader); + + ModelObject mo = new DataTypeLoader(null).load(null, reader, null); + Assert.assertTrue(mo instanceof DataType); + Assert.assertEquals("ABC", ((DataType<?>)mo).getDataBinding()); + EasyMock.verify(reader); + + EasyMock.reset(reader); + + // EasyMock.expect(reader.getEventType()).andReturn(XMLStreamConstants.START_ELEMENT); + EasyMock.expect(reader.hasNext()).andReturn(true).anyTimes(); + EasyMock.expect(reader.getName()).andReturn(DataTypeLoader.DATA_BINDING); + EasyMock.expect(reader.getAttributeValue(null, "name")).andReturn(null); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.replay(reader); + try { + mo = new DataTypeLoader(null).load(null, reader, null); + Assert.fail("InvalidValueException should have been thrown"); + } catch (InvalidValueException e) { + Assert.assertTrue(true); + } + EasyMock.verify(reader); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingRegistryImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingRegistryImplTestCase.java new file mode 100644 index 0000000000..75eafe8380 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingRegistryImplTestCase.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.core.databinding.impl; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; + +import javax.xml.stream.XMLStreamReader; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.tuscany.spi.databinding.DataBinding; +import org.apache.tuscany.spi.databinding.DataBindingRegistry; +import org.apache.tuscany.spi.model.DataType; +import org.easymock.EasyMock; +import org.xml.sax.ContentHandler; + +/** + * + */ +public class DataBindingRegistryImplTestCase extends TestCase { + private DataBindingRegistry registry; + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + registry = new DataBindingRegistryImpl(); + } + + public void testRegistry() { + DataBinding db1 = createMock(DataBinding.class); + expect(db1.getName()).andReturn(ContentHandler.class.getName()).anyTimes(); + DataType<Class> dataType1 = new DataType<Class>(ContentHandler.class, ContentHandler.class); + expect(db1.introspect(ContentHandler.class)).andReturn(dataType1); + expect(db1.introspect((Class)EasyMock.anyObject())).andReturn(null).anyTimes(); + replay(db1); + + registry.register(db1); + + DataBinding db2 = createMock(DataBinding.class); + expect(db2.getName()).andReturn(XMLStreamReader.class.getName()).anyTimes(); + DataType<Class> dataType2 = new DataType<Class>(XMLStreamReader.class, XMLStreamReader.class); + expect(db2.introspect(XMLStreamReader.class)).andReturn(dataType2); + expect(db2.introspect((Class)EasyMock.anyObject())).andReturn(null).anyTimes(); + replay(db2); + + registry.register(db2); + + String name = db1.getName(); + DataBinding db3 = registry.getDataBinding(name); + Assert.assertTrue(db1 == db3); + + DataType<?> dt = registry.introspectType(ContentHandler.class); + Assert.assertEquals(dataType1, dt); + Assert.assertTrue(dt.getDataBinding().equalsIgnoreCase(name)); + + registry.unregister(name); + DataBinding db4 = registry.getDataBinding(name); + Assert.assertNull(db4); + + + dt = registry.introspectType(ContentHandler.class); + Assert.assertNotNull(dt); + Assert.assertEquals("java.lang.Object", dt.getDataBinding()); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingTestCase.java new file mode 100644 index 0000000000..de5c537274 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingTestCase.java @@ -0,0 +1,49 @@ +/* + * 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.core.databinding.impl; + +import java.lang.reflect.Method; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.tuscany.api.annotation.DataContext; +import org.apache.tuscany.api.annotation.DataType; + +public class DataBindingTestCase extends TestCase { + @SuppressWarnings("unused") + public void testDataType() throws Exception { + Class<Test> testClass = Test.class; + DataType d = testClass.getAnnotation(DataType.class); + Assert.assertEquals(d.name(), "sdo"); + Assert.assertEquals(d.context().length, 0); + + Method method = testClass.getMethod("test", new Class[] {Object.class}); + DataType d2 = method.getAnnotation(DataType.class); + Assert.assertEquals(d2.name(), "jaxb"); + Assert.assertEquals(d2.context()[0].key(), "contextPath"); + Assert.assertEquals(d2.context()[0].value(), "com.example.ipo.jaxb"); + } + + @DataType(name = "sdo") + private static interface Test { + @DataType(name = "jaxb", context = {@DataContext(key = "contextPath", value = "com.example.ipo.jaxb")}) + Object test(Object object); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessorOptimizationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessorOptimizationTestCase.java new file mode 100644 index 0000000000..de46eb0542 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessorOptimizationTestCase.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.databinding.impl; + +import java.lang.reflect.Type; +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.spi.databinding.Mediator; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * Verifies that data binding interceptor is not added to invocation chains when the data binding types are not set on + * service contracts + * + * @version $Rev$ $Date$ + */ +public class DataBindingWirePostProcessorOptimizationTestCase extends TestCase { + private DataBindingWirePostProcessor processor; + private InvocationChain outboundChain; + private InvocationChain callbackChain; + private Wire wire; + + public void testNoInterceptorInterposed() { + processor.process(wire); + EasyMock.verify(outboundChain); + EasyMock.verify(callbackChain); + } + + protected void setUp() throws Exception { + super.setUp(); + + Mediator mediator = new MediatorImpl(); + processor = new DataBindingWirePostProcessor(mediator); + + ServiceContract<Type> contract = new JavaServiceContract(null); + Operation<Type> operation = new Operation<Type>("test", null, null, null); + operation.setServiceContract(contract); + Map<String, Operation<Type>> operations = new HashMap<String, Operation<Type>>(); + operations.put("test", operation); + contract.setOperations(operations); + contract.setCallbackOperations(operations); + + outboundChain = EasyMock.createMock(InvocationChain.class); + EasyMock.replay(outboundChain); + Map<Operation<?>, InvocationChain> outboundChains = new HashMap<Operation<?>, InvocationChain>(); + outboundChains.put(operation, outboundChain); + + callbackChain = EasyMock.createMock(InvocationChain.class); + EasyMock.replay(callbackChain); + Map<Operation<?>, InvocationChain> callbackChains = new HashMap<Operation<?>, InvocationChain>(); + callbackChains.put(operation, callbackChain); + + wire = EasyMock.createMock(Wire.class); + EasyMock.expect(wire.getInvocationChains()).andReturn(outboundChains); + EasyMock.expect(wire.getSourceContract()).andReturn(contract).anyTimes(); + EasyMock.expect(wire.getTargetContract()).andReturn(contract).anyTimes(); + EasyMock.expect(wire.getCallbackInvocationChains()).andReturn(callbackChains).anyTimes(); + URI uri = URI.create("foo"); + EasyMock.expect(wire.getSourceUri()).andReturn(uri).anyTimes(); + + EasyMock.replay(wire); + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessorTestCase.java new file mode 100644 index 0000000000..ccc522c0cb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessorTestCase.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.core.databinding.impl; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.databinding.Mediator; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.model.DataType; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.easymock.EasyMock; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; + +/** + * @version $Rev$ $Date$ + */ +public class DataBindingWirePostProcessorTestCase extends TestCase { + private DataBindingWirePostProcessor processor; + + protected void setUp() throws Exception { + super.setUp(); + Mediator mediator = new MediatorImpl(); + this.processor = new DataBindingWirePostProcessor(mediator); + } + + public void testProcess1() { + Wire outboundWire = createMock(Wire.class); + + Component component = createMock(Component.class); + Component composite = createMock(Component.class); + + Map<Operation<?>, InvocationChain> outboundChains = + new HashMap<Operation<?>, InvocationChain>(); + DataType<Type> type1 = new DataType<Type>(String.class, String.class); + List<DataType<Type>> types = new ArrayList<DataType<Type>>(); + types.add(type1); + DataType<List<DataType<Type>>> inputType1 = new DataType<List<DataType<Type>>>(Object[].class, types); + DataType<Type> outputType1 = new DataType<Type>(String.class, String.class); + Operation<Type> op1 = new Operation<Type>("test", inputType1, outputType1, null); + ServiceContract<Type> outboundContract = new JavaServiceContract(null); + outboundContract.setDataBinding(String.class.getName()); + op1.setServiceContract(outboundContract); + Map<String, Operation<Type>> outboundOperations = new HashMap<String, Operation<Type>>(); + outboundOperations.put("test", op1); + + outboundContract.setOperations(outboundOperations); + InvocationChain outboundChain = createMock(InvocationChain.class); + outboundChains.put(op1, outboundChain); + expect(outboundWire.getInvocationChains()).andReturn(outboundChains); + outboundChain.addInterceptor(EasyMock.anyInt(), (Interceptor) EasyMock.anyObject()); + + + ServiceContract<Type> contract = new JavaServiceContract(); + Map<String, Operation<Type>> operations = Collections.emptyMap(); + contract.setCallbackOperations(operations); + expect(outboundWire.getSourceContract()).andReturn(outboundContract); + expect(outboundWire.getTargetContract()).andReturn(outboundContract); + + EasyMock.replay(composite, component, outboundWire, outboundChain); + + processor.process(outboundWire); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DirectedGraphTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DirectedGraphTestCase.java new file mode 100755 index 0000000000..70244df8e2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/DirectedGraphTestCase.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.databinding.impl; + +import java.util.List; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.tuscany.core.databinding.impl.DirectedGraph.Edge; +import org.apache.tuscany.core.databinding.impl.DirectedGraph.Vertex; + +public class DirectedGraphTestCase extends TestCase { + private DirectedGraph<String, Object> graph; + + protected void setUp() throws Exception { + super.setUp(); + graph = new DirectedGraph<String, Object>(); + graph.addEdge("a", "b", null, 3); + graph.addEdge("b", "c", null, 1); + graph.addEdge("a", "c", null, 8); + graph.addEdge("a", "d", null, 3); + graph.addEdge("b", "d", null, 2); + graph.addEdge("c", "b", null, 1); + graph.addEdge("c", "d", null, 2); + graph.addEdge("d", "b", null, 1); + graph.addEdge("a", "e", null, 8); + graph.addEdge("c", "c", null, 2); + } + + public void testGraph() { + // System.out.println(graph); + + Vertex vertex = graph.getVertex("a"); + Assert.assertNotNull(vertex); + Assert.assertEquals(vertex.getValue(), "a"); + + Assert.assertNull(graph.getVertex("1")); + + Edge edge = graph.getEdge("a", "b"); + Assert.assertNotNull(edge); + Assert.assertEquals(edge.getWeight(), 3); + + edge = graph.getEdge("b", "a"); + Assert.assertNull(edge); + + DirectedGraph<String, Object>.Path path = graph.getShortestPath("a", "c"); + + List<DirectedGraph<String, Object>.Edge> edges = path.getEdges(); + Assert.assertEquals(edges.size(), 2); + Assert.assertEquals(edges.get(0), graph.getEdge("a", "b")); + Assert.assertEquals(edges.get(1), graph.getEdge("b", "c")); + + Assert.assertEquals(path.getWeight(), 4); + + DirectedGraph<String, Object>.Path path2 = graph.getShortestPath("b", "e"); + Assert.assertNull(path2); + + DirectedGraph<String, Object>.Path path3 = graph.getShortestPath("a", "a"); + Assert.assertTrue(path3.getWeight() == 0 && path3.getEdges().isEmpty()); + + DirectedGraph<String, Object>.Path path4 = graph.getShortestPath("c", "c"); + Assert.assertTrue(path4.getWeight() == 2 && path4.getEdges().size() == 1); + + // System.out.println(path); + + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/IDLTransformerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/IDLTransformerTestCase.java new file mode 100644 index 0000000000..079e97a275 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/IDLTransformerTestCase.java @@ -0,0 +1,220 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.databinding.impl; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.namespace.QName; + +import junit.framework.TestCase; + +import org.apache.tuscany.core.databinding.javabeans.DOMNode2JavaBeanTransformer; +import org.apache.tuscany.core.databinding.javabeans.JavaBean2DOMNodeTransformer; +import org.apache.tuscany.core.databinding.xml.DOMDataBinding; +import org.apache.tuscany.core.databinding.xml.Node2String; +import org.apache.tuscany.core.databinding.xml.String2Node; +import org.apache.tuscany.spi.databinding.DataBindingRegistry; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.extension.DOMHelper; +import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension; +import org.apache.tuscany.spi.model.ElementInfo; +import org.apache.tuscany.spi.model.TypeInfo; +import org.apache.tuscany.spi.model.DataType; +import org.apache.tuscany.spi.model.WrapperInfo; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class IDLTransformerTestCase extends TestCase { + private static final String IPO_XML = + "<?xml version=\"1.0\"?>" + "<order1" + + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + + " xmlns:ipo=\"http://www.example.com/IPO\"" + + " xsi:schemaLocation=\"http://www.example.com/IPO ipo.xsd\"" + + " orderDate=\"1999-12-01\">" + + " <shipTo exportCode=\"1\" xsi:type=\"ipo:UKAddress\">" + + " <name>Helen Zoe</name>" + + " <street>47 Eden Street</street>" + + " <city>Cambridge</city>" + + " <postcode>CB1 1JR</postcode>" + + " </shipTo>" + + " <billTo xsi:type=\"ipo:USAddress\">" + + " <name>Robert Smith</name>" + + " <street>8 Oak Avenue</street>" + + " <city>Old Town</city>" + + " <state>PA</state>" + + " <zip>95819</zip>" + + " </billTo>" + + " <items>" + + " <item partNum=\"833-AA\">" + + " <productName>Lapis necklace</productName>" + + " <quantity>1</quantity>" + + " <USPrice>99.95</USPrice>" + + " <ipo:comment>Want this for the holidays</ipo:comment>" + + " <shipDate>1999-12-05</shipDate>" + + " </item>" + + " </items>" + + "</order1>"; + + private static final String URI_ORDER_XSD = "http://example.com/order.xsd"; + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + } + + public void testTransform() throws Exception { + List<DataType<QName>> types0 = new ArrayList<DataType<QName>>(); + DataType<QName> wrapperType = + new DataType<QName>(null, Object.class, new QName(URI_ORDER_XSD, "checkOrderStatus")); + types0.add(wrapperType); + DataType<List<DataType<QName>>> inputType0 = + new DataType<List<DataType<QName>>>("idl:input", Object[].class, types0); + + List<DataType<QName>> types1 = new ArrayList<DataType<QName>>(); + DataType<QName> customerIdType = + new DataType<QName>(null, Object.class, new QName(URI_ORDER_XSD, "customerId")); + DataType<QName> orderType = + new DataType<QName>(null, Object.class, new QName(URI_ORDER_XSD, "order")); + DataType<QName> flagType = new DataType<QName>(null, Object.class, new QName(URI_ORDER_XSD, "flag")); + types1.add(customerIdType); + types1.add(orderType); + types1.add(flagType); + DataType<List<DataType<QName>>> inputType = + new DataType<List<DataType<QName>>>("idl:input", Object[].class, types1); + + DataType<QName> statusType = + new DataType<QName>(null, Object.class, new QName(URI_ORDER_XSD, "status")); + DataType<QName> responseType = + new DataType<QName>(null, Object.class, new QName(URI_ORDER_XSD, "checkOrderStatusResponse")); + + org.apache.tuscany.spi.model.Operation<QName> op = + new org.apache.tuscany.spi.model.Operation<QName>("checkOrderStatus", inputType0, responseType, + null); + op.setDataBinding(DOMDataBinding.NAME); + + inputType0.setOperation(op); + op.setWrapperStyle(true); + ElementInfo inputElement = + new ElementInfo(new QName(URI_ORDER_XSD, "checkOrderStatus"), new TypeInfo(null, false, null)); + wrapperType.setMetadata(ElementInfo.class.getName(), inputElement); + + ElementInfo customerId = + new ElementInfo(new QName("", "customerId"), SimpleTypeMapperExtension.XSD_SIMPLE_TYPES + .get("string")); + ElementInfo order = + new ElementInfo(new QName("", "order"), new TypeInfo(new QName(URI_ORDER_XSD), false, null)); + ElementInfo flag = + new ElementInfo(new QName("", "flag"), SimpleTypeMapperExtension.XSD_SIMPLE_TYPES.get("int")); + + customerIdType.setMetadata(ElementInfo.class.getName(), customerId); + orderType.setMetadata(ElementInfo.class.getName(), order); + flagType.setMetadata(ElementInfo.class.getName(), flag); + + customerIdType.setOperation(op); + orderType.setOperation(op); + flagType.setOperation(op); + + List<ElementInfo> inputElements = new ArrayList<ElementInfo>(); + inputElements.add(customerId); + inputElements.add(order); + inputElements.add(flag); + + ElementInfo statusElement = + new ElementInfo(new QName("", "status"), SimpleTypeMapperExtension.XSD_SIMPLE_TYPES.get("string")); + + statusType.setMetadata(ElementInfo.class.getName(), statusElement); + statusType.setOperation(op); + + List<ElementInfo> outputElements = new ArrayList<ElementInfo>(); + outputElements.add(statusElement); + + ElementInfo outputElement = + new ElementInfo(new QName(URI_ORDER_XSD, "checkOrderStatusResponse"), new TypeInfo(null, false, + null)); + + responseType.setMetadata(ElementInfo.class.getName(), inputElement); + responseType.setOperation(op); + + WrapperInfo wrapperInfo = + new WrapperInfo(inputElement, outputElement, inputElements, outputElements, inputType, statusType); + op.setWrapper(wrapperInfo); + op.setDataBinding(DOMDataBinding.NAME); + + MediatorImpl m = new MediatorImpl(); + TransformerRegistryImpl tr = new TransformerRegistryImpl(); + tr.registerTransformer(new String2Node()); + tr.registerTransformer(new Node2String()); + tr.registerTransformer(new DOMNode2JavaBeanTransformer()); + tr.registerTransformer(new JavaBean2DOMNodeTransformer()); + m.setTransformerRegistry(tr); + DataBindingRegistry dataBindingRegistry = new DataBindingRegistryImpl(); + dataBindingRegistry.register(new DOMDataBinding()); + m.setDataBindingRegistry(dataBindingRegistry); + + Object[] source = new Object[] {"cust001", IPO_XML, Integer.valueOf(1)}; + Input2InputTransformer t = new Input2InputTransformer(); + t.setDataBindingRegistry(dataBindingRegistry); + t.setMediator(m); + + TransformationContext context = new TransformationContextImpl(); + List<DataType<Class>> types = new ArrayList<DataType<Class>>(); + types.add(new DataType<Class>(Object.class.getName(), String.class, String.class)); + types.add(new DataType<Class>("java.lang.String", String.class, String.class)); + types.add(new DataType<Class>(Object.class.getName(), int.class, int.class)); + DataType<List<DataType<Class>>> inputType1 = + new DataType<List<DataType<Class>>>("idl:input", Object[].class, types); + context.setSourceDataType(inputType1); + context.setTargetDataType(op.getInputType()); + Object[] results = t.transform(source, context); + assertEquals(1, results.length); + assertTrue(results[0] instanceof Element); + Element element = (Element)results[0]; + assertEquals("http://example.com/order.xsd", element.getNamespaceURI()); + assertEquals("checkOrderStatus", element.getLocalName()); + + TransformationContext context1 = new TransformationContextImpl(); + DataType<DataType> sourceType = + new DataType<DataType>("idl:output", Object.class, op.getOutputType()); + sourceType.setOperation(op.getOutputType().getOperation()); + + context1.setSourceDataType(sourceType); + DataType<DataType> targetType = + new DataType<DataType>("idl:output", Object.class, + new DataType<Class>("java.lang.Object", String.class, String.class)); + context1.setTargetDataType(targetType); + + Document factory = DOMHelper.newDocument(); + Element responseElement = + factory.createElementNS("http://example.com/order.wsdl", "p:checkOrderStatusResponse"); + Element status = factory.createElement("status"); + responseElement.appendChild(status); + status.appendChild(factory.createTextNode("shipped")); + Output2OutputTransformer t2 = new Output2OutputTransformer(); + t2.setMediator(m); + t2.setDataBindingRegistry(dataBindingRegistry); + Object st = t2.transform(responseElement, context1); + assertEquals("shipped", st); + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/MediatorImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/MediatorImplTestCase.java new file mode 100644 index 0000000000..3cb7f243a9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/MediatorImplTestCase.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.core.databinding.impl; + +import java.io.StringWriter; +import java.io.Writer; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.tuscany.core.databinding.xml.Node2String; +import org.apache.tuscany.core.databinding.xml.Node2Writer; +import org.apache.tuscany.core.databinding.xml.SAX2DOMPipe; +import org.apache.tuscany.core.databinding.xml.String2SAX; +import org.apache.tuscany.spi.databinding.DataBindingRegistry; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformerRegistry; +import org.apache.tuscany.spi.model.DataType; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Test case for MediatorImpl + */ +public class MediatorImplTestCase extends TestCase { + private static final String IPO_XML = + "<?xml version=\"1.0\"?>" + "<ipo:purchaseOrder" + + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + + " xmlns:ipo=\"http://www.example.com/IPO\"" + + " xsi:schemaLocation=\"http://www.example.com/IPO ipo.xsd\"" + + " orderDate=\"1999-12-01\">" + + " <shipTo exportCode=\"1\" xsi:type=\"ipo:UKAddress\">" + + " <name>Helen Zoe</name>" + + " <street>47 Eden Street</street>" + + " <city>Cambridge</city>" + + " <postcode>CB1 1JR</postcode>" + + " </shipTo>" + + " <billTo xsi:type=\"ipo:USAddress\">" + + " <name>Robert Smith</name>" + + " <street>8 Oak Avenue</street>" + + " <city>Old Town</city>" + + "<state>PA</state>" + + " <zip>95819</zip>" + + " </billTo>" + + " <items>" + + " <item partNum=\"833-AA\">" + + " <productName>Lapis necklace</productName>" + + " <quantity>1</quantity>" + + "<USPrice>99.95</USPrice>" + + " <ipo:comment>Want this for the holidays</ipo:comment>" + + " <shipDate>1999-12-05</shipDate>" + + " </item>" + + " </items>" + + "</ipo:purchaseOrder>"; + + private MediatorImpl mediator; + + protected void setUp() throws Exception { + super.setUp(); + + TransformerRegistry registry = new TransformerRegistryImpl(); + registry.registerTransformer(new String2SAX()); + registry.registerTransformer(new SAX2DOMPipe()); + registry.registerTransformer(new Node2String()); + registry.registerTransformer(new Node2Writer()); + + mediator = new MediatorImpl(); + mediator.setTransformerRegistry(registry); + + DataBindingRegistry dataBindingRegistry = new DataBindingRegistryImpl(); + mediator.setDataBindingRegistry(dataBindingRegistry); + } + + private TransformationContext createTransformationContext(Class sourceType, Class targetType) { + TransformationContext context = new TransformationContextImpl(); + DataType sourceDataType = new DataType<Class>(sourceType, sourceType); + DataType targetDataType = new DataType<Class>(targetType, targetType); + context.setSourceDataType(sourceDataType); + context.setTargetDataType(targetDataType); + return context; + } + + public void testTransform1() { + TransformationContext context = createTransformationContext(String.class, Node.class); + Object node = + mediator.mediate(IPO_XML, context.getSourceDataType(), context.getTargetDataType(), null); + Assert.assertTrue(node instanceof Document); + Element root = ((Document)node).getDocumentElement(); + Assert.assertEquals(root.getNamespaceURI(), "http://www.example.com/IPO"); + Assert.assertEquals(root.getLocalName(), "purchaseOrder"); + } + + public void testTransform2() { + TransformationContext context = createTransformationContext(String.class, Writer.class); + Writer writer = new StringWriter(); + mediator.mediate(IPO_XML, writer, context.getSourceDataType(), context.getTargetDataType(), null); + String str = writer.toString(); + Assert.assertTrue(str != null && str.indexOf("<shipDate>1999-12-05</shipDate>") != -1); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/PassByValueInterceptorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/PassByValueInterceptorTestCase.java new file mode 100644 index 0000000000..571f5ae7ab --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/PassByValueInterceptorTestCase.java @@ -0,0 +1,69 @@ +/*
+ * 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.core.databinding.impl;
+
+import java.io.Serializable;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for ByValueInterceptor
+ */
+public class PassByValueInterceptorTestCase extends TestCase {
+ private MySerialiable serialiable = new MySerialiable();
+ private String str = "ABC";
+ private Integer i = new Integer(1);
+ private String[] array = new String[] {"1", "2"};
+ private Object[] values;
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ values = new Object[] {serialiable, str, i, serialiable, array};
+ }
+
+ private static class MySerialiable implements Serializable {
+ private static final long serialVersionUID = 7827201707529055310L;
+ private final String name = "Serializable";
+ private final int age = 100;
+
+ public int getAge() {
+ return age;
+ }
+
+ public String getName() {
+ return name;
+ }
+ }
+
+ public void testCopy() {
+ Object[] copy = new PassByValueInterceptor().copy(values);
+ assertTrue(copy[0] instanceof MySerialiable);
+ MySerialiable copied = (MySerialiable)copy[0];
+ assertNotSame(serialiable, copy[0]);
+ assertEquals(serialiable.getName(), copied.getName());
+ assertEquals(serialiable.getAge(), copied.getAge());
+ assertSame(copy[1], str);
+ assertSame(copy[2], i);
+ assertSame(copy[0], copy[3]);
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/PassByValueWirePostProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/PassByValueWirePostProcessorTestCase.java new file mode 100644 index 0000000000..0cbd8a1014 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/PassByValueWirePostProcessorTestCase.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.core.databinding.impl;
+
+import java.net.URI;
+import java.util.List;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.databinding.DataBindingRegistry;
+import org.apache.tuscany.spi.extension.AtomicComponentExtension;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.apache.tuscany.spi.wire.Wire;
+
+import junit.framework.TestCase;
+import static org.easymock.EasyMock.createMock;
+
+/**
+ * Testcase for testing if the PassByValueWireProcessor adds the PassByValueInterceptor to the invocation chains and
+ * also ensure that the outbound and inbound chain of interceptors are linked after this insertion
+ *
+ * @version $Rev$ $Date$
+ */
+public class PassByValueWirePostProcessorTestCase extends TestCase {
+ private PassByValueWirePostProcessor processor;
+
+ public void testProcessInclusionOfInterceptor() {
+//
+// InboundWire inboundWire = createMock(InboundWire.class);
+// OutboundWire outboundWire = createMock(OutboundWire.class);
+//
+// ServiceContract<Type> serviceContract = new JavaServiceContract(null);
+// serviceContract.setRemotable(true);
+// Map<Operation<?>, InboundInvocationChain> inChainsMap =
+// new Hashtable<Operation<?>, InboundInvocationChain>();
+//
+// Operation<Type> operation1 = new Operation<Type>("testMethod", null, null, null);
+// operation1.setServiceContract(serviceContract);
+// InboundInvocationChainImpl inChain = new InboundInvocationChainImpl(operation1);
+// inChainsMap.put(operation1, inChain);
+//
+// AtomicComponentExtension componentExtn = new FooComponent();
+//
+// Map<Operation<?>, OutboundInvocationChain> outChainsMap =
+// new Hashtable<Operation<?>, OutboundInvocationChain>();
+// OutboundInvocationChainImpl outChain = new OutboundInvocationChainImpl(operation1);
+// outChainsMap.put(operation1, outChain);
+//
+// expect(inboundWire.getSourceContract()).andReturn(serviceContract);
+// expect(inboundWire.getInboundInvocationChains()).andReturn(inChainsMap);
+// expect(outboundWire.getSourceContract()).andReturn(serviceContract).times(2);
+// expect(outboundWire.getOutboundInvocationChains()).andReturn(outChainsMap).times(2);
+//
+// Interceptor inInterceptor = createMock(Interceptor.class);
+// Interceptor outInterceptor = createMock(Interceptor.class);
+// inChain.addInterceptor(0, inInterceptor);
+// outChain.addInterceptor(0, outInterceptor);
+// //outChain.addInterceptor(new SynchronousBridgingInterceptor(inChain.getHeadInterceptor()));
+//
+// EasyMock.replay(inboundWire, outboundWire);
+// processor.process(componentExtn, outboundWire, componentExtn, inboundWire);
+//
+// assertEquals(true, inChain.getHeadInterceptor() instanceof PassByValueInterceptor);
+// assertEquals(true,
+// outChain.getTailInterceptor().getNext() instanceof PassByValueInterceptor);
+// assertEquals(true, outChain.getTailInterceptor().getNext().equals(
+// inChain.getHeadInterceptor()));
+//
+ }
+
+ public void testProcessExclusionOfInterceptorWhenAllowsPassByReference() {
+// Wire inboundWire = createMock(Wire.class);
+// Wire outboundWire = createMock(Wire.class);
+//
+// ServiceContract<Type> serviceContract = new JavaServiceContract(null);
+// serviceContract.setRemotable(true);
+// Map<Operation<?>, InvocationChain> inChainsMap =
+// new Hashtable<Operation<?>, InvocationChain>();
+//
+// Operation<?> operation1 = new Operation<Type>("testMethod", null, null, null);
+// InvocationChainImpl inChain = new InvocationChainImpl(operation1);
+// inChainsMap.put(operation1, inChain);
+//
+// AtomicComponentExtension componentExtn = new FooComponent();
+// componentExtn.setAllowsPassByReference(true);
+//
+//
+// Map<Operation<?>, InvocationChain> outChainsMap =
+// new Hashtable<Operation<?>, InvocationChain>();
+// InvocationChainImpl outChain = new InvocationChainImpl(operation1);
+// outChainsMap.put(operation1, outChain);
+//
+// expect(inboundWire.getSourceContract()).andReturn(serviceContract);
+// expect(inboundWire.getInvocationChains()).andReturn(inChainsMap);
+// expect(outboundWire.getSourceContract()).andReturn(serviceContract).times(2);
+// expect(outboundWire.getInvocationChains()).andReturn(outChainsMap).times(2);
+//
+// Interceptor inInterceptor = createMock(Interceptor.class);
+// Interceptor outInterceptor = createMock(Interceptor.class);
+// inChain.addInterceptor(0, inInterceptor);
+// outChain.addInterceptor(0, outInterceptor);
+// //outChain.addInterceptor(new SynchronousBridgingInterceptor(inChain.getHeadInterceptor()));
+//
+// EasyMock.replay(inboundWire, outboundWire);
+// processor.process(componentExtn, outboundWire, componentExtn, inboundWire);
+//
+// assertEquals(false, inChain.getHeadInterceptor() instanceof PassByValueInterceptor);
+// assertEquals(false,
+// outChain.getTailInterceptor().getNext() instanceof PassByValueInterceptor);
+// assertEquals(true, outChain.getTailInterceptor().getNext().equals(
+// inChain.getHeadInterceptor()));
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.processor = new PassByValueWirePostProcessor();
+ DataBindingRegistry dataBindingRegistry = createMock(DataBindingRegistry.class);
+ processor.setDataBindingRegistry(dataBindingRegistry);
+ }
+
+ private class FooComponent extends AtomicComponentExtension {
+
+ public FooComponent() {
+ super(URI.create("foo"), null, null, 0, -1, -1);
+ }
+
+ public List<Wire> getWires(String name) {
+ return null;
+ }
+
+ public void attachCallbackWire(Wire wire) {
+
+ }
+
+ public void attachWire(Wire wire) {
+
+ }
+
+ public void attachWires(List<Wire> wires) {
+
+ }
+
+ public Object createInstance() throws ObjectCreationException {
+ return null;
+ }
+
+ public Object getTargetInstance() throws TargetResolutionException {
+ return null;
+ }
+
+ public TargetInvoker createTargetInvoker(String targetName, Operation operation) {
+ return null;
+ }
+
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/TransformerRegistryImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/TransformerRegistryImplTestCase.java new file mode 100644 index 0000000000..6250efd897 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/impl/TransformerRegistryImplTestCase.java @@ -0,0 +1,106 @@ +/* + * 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.core.databinding.impl; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; + +import java.util.List; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.TransformerRegistry; + +/** + * + */ +public class TransformerRegistryImplTestCase extends TestCase { + private TransformerRegistry registry; + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + registry = new TransformerRegistryImpl(); + } + + public void testRegisterTransformer1() { + Transformer transformer = createMock(Transformer.class); + registry.registerTransformer("a", "b", 10, transformer); + Transformer t = registry.getTransformer("a", "b"); + Assert.assertSame(t, transformer); + } + + public void testRegisterTransformerTransformer() { + Transformer transformer = createMock(Transformer.class); + expect(transformer.getSourceDataBinding()).andReturn("a"); + expect(transformer.getTargetDataBinding()).andReturn("b"); + expect(transformer.getWeight()).andReturn(10); + replay(transformer); + registry.registerTransformer(transformer); + Transformer t = registry.getTransformer("a", "b"); + Assert.assertSame(t, transformer); + } + + public void testUnregisterTransformer() { + Transformer transformer = createMock(Transformer.class); + registry.registerTransformer("a", "b", 10, transformer); + boolean result = registry.unregisterTransformer("a", "b"); + Assert.assertTrue(result); + Transformer t = registry.getTransformer("a", "b"); + Assert.assertNull(t); + } + + public void testGetTransformerChain() { + Transformer t1 = createMock(Transformer.class); + expect(t1.getSourceDataBinding()).andReturn("a"); + expect(t1.getTargetDataBinding()).andReturn("b"); + expect(t1.getWeight()).andReturn(10); + replay(t1); + Transformer t2 = createMock(Transformer.class); + expect(t2.getSourceDataBinding()).andReturn("b"); + expect(t2.getTargetDataBinding()).andReturn("c"); + expect(t2.getWeight()).andReturn(20); + replay(t2); + + Transformer t3 = createMock(Transformer.class); + expect(t3.getSourceDataBinding()).andReturn("a"); + expect(t3.getTargetDataBinding()).andReturn("c"); + expect(t3.getWeight()).andReturn(120); + replay(t3); + + registry.registerTransformer(t1); + registry.registerTransformer(t2); + registry.registerTransformer(t3); + + List<Transformer> l1 = registry.getTransformerChain("a", "b"); + Assert.assertTrue(l1.size() == 1 && l1.get(0) == t1); + List<Transformer> l2 = registry.getTransformerChain("a", "c"); + Assert.assertTrue(l2.size() == 2 && l2.get(0) == t1 && l2.get(1) == t2); + List<Transformer> l3 = registry.getTransformerChain("a", "d"); + Assert.assertNull(l3); + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/javabeans/DOMNode2JavaBeanTransformerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/javabeans/DOMNode2JavaBeanTransformerTestCase.java new file mode 100644 index 0000000000..842051782b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/javabeans/DOMNode2JavaBeanTransformerTestCase.java @@ -0,0 +1,178 @@ +/*
+ * 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.core.databinding.javabeans;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.extension.DOMHelper;
+import org.apache.tuscany.spi.model.ElementInfo;
+import org.apache.tuscany.spi.model.TypeInfo;
+import org.apache.tuscany.spi.model.DataType;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * Testcase to test the XMLTypeMapperExtension which is the back bone for all transformations supported by the JavaBeans
+ * Databinding.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DOMNode2JavaBeanTransformerTestCase extends TestCase {
+ private DOMNode2JavaBeanTransformer dom2JavaTransformer = new DOMNode2JavaBeanTransformer();
+
+ public void testFieldSettings() throws Exception {
+ String samplePropertyXML =
+ "<property name=\"prop2\" >" + "<integerNumber>27</integerNumber>"
+ + "<floatNumber>79.34</floatNumber>"
+ + "<doubleNumber>184.52</doubleNumber>" + "<innerProperty>"
+ + "<integerNumber>54</integerNumber>" + "<floatNumber>158.68</floatNumber>"
+ + "<doubleNumber>369.04</doubleNumber>" + "</innerProperty>"
+ + "<stringArray>TestString_1</stringArray>"
+ + "<stringArray>TestString_2</stringArray>" + "<boolArray>true</boolArray>"
+ + "<boolArray>false</boolArray>" + "</property>";
+
+ DocumentBuilder builder = DOMHelper.newDocumentBuilder();
+ InputSource inputSource = new InputSource(new StringReader(samplePropertyXML));
+ Node samplePropertyNode = builder.parse(inputSource);
+ TypeInfo typeInfo = new TypeInfo(null, false, null);
+
+ TransformationContext context = EasyMock.createMock(TransformationContext.class);
+ DataType<Class> targetDataType = new DataType<Class>(null, SamplePropertyBean.class);
+ EasyMock.expect(context.getTargetDataType()).andReturn(targetDataType).anyTimes();
+
+ DataType<Class> sourceDataType = new DataType<Class>(null, null);
+ ElementInfo eleInfo = new ElementInfo(null, typeInfo);
+ sourceDataType.setMetadata(ElementInfo.class.getName(), eleInfo);
+ EasyMock.expect(context.getSourceDataType()).andReturn(sourceDataType).anyTimes();
+ EasyMock.replay(context);
+
+ Object javaObject =
+ dom2JavaTransformer.transform(((Document) samplePropertyNode).getDocumentElement(), context);
+
+ assertTrue(javaObject instanceof SamplePropertyBean);
+ SamplePropertyBean samplePropBean = (SamplePropertyBean) javaObject;
+ assertEquals(samplePropBean.getIntegerNumber(), 27);
+ assertEquals((float) 79.34, samplePropBean.getFloatNumber());
+ assertEquals(samplePropBean.getInnerProperty().getDoubleNumber(), 369.04);
+
+ assertEquals(samplePropBean.getStringArray()[0], "TestString_1");
+ assertEquals(samplePropBean.boolArray[0], true);
+
+ /** testing for object to node * */
+ javax.xml.transform.Transformer transformer =
+ TransformerFactory.newInstance().newTransformer();
+ JavaBean2DOMNodeTransformer java2DomTransformer = new JavaBean2DOMNodeTransformer();
+ Node aNode = java2DomTransformer.transform(javaObject, context);
+ StringWriter sw = new StringWriter();
+ transformer.transform(new DOMSource(aNode), new StreamResult(sw));
+ String nodeString = sw.toString();
+ //System.out.println(nodeString);
+
+ // testing the case when field and getter method do not have public access
+ assertTrue(nodeString.indexOf("<doubleNumber>184.52</doubleNumber>") == -1);
+ // test the case for fields that are of array type
+ assertTrue(nodeString.indexOf("<stringArray>TestString_1</stringArray>"
+ + "<stringArray>TestString_2</stringArray>") != -1);
+ // testing the case for non-public field with public getter method
+ assertTrue(nodeString.indexOf("<integerNumber>27</integerNumber>") != -1);
+ // test the case for public field that is a another java bean .i.e. embeded javabean
+ int startIndex = nodeString.indexOf("<innerProperty>");
+ int endIndex = nodeString.indexOf("</innerProperty>");
+ String fragment = nodeString.substring(startIndex, endIndex);
+ assertTrue(fragment.indexOf("<integerNumber>54</integerNumber>") != -1);
+
+ // System.out.println(sw.toString());
+
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ private static class SamplePropertyBean {
+ public boolean[] boolArray;
+ private float floatNumber = 50;
+ private SamplePropertyBean innerProperty;
+ private double doubleNumber = 75;
+ private int integerNumber = 25;
+ private String[] stringArray;
+
+ public SamplePropertyBean() {
+
+ }
+
+ double getDoubleNumber() {
+ return doubleNumber;
+ }
+
+ public void setDoubleNumber(double doubleNumber) {
+ this.doubleNumber = doubleNumber;
+ }
+
+ public float getFloatNumber() {
+ return floatNumber;
+ }
+
+ public void setFloatNumber(float floatNumber) {
+ this.floatNumber = floatNumber;
+ }
+
+ public int getIntegerNumber() {
+ return integerNumber;
+ }
+
+ public void setIntegerNumber(int integerNumber) {
+ this.integerNumber = integerNumber;
+ }
+
+ public SamplePropertyBean getInnerProperty() {
+ return innerProperty;
+ }
+
+ public void setInnerProperty(SamplePropertyBean prop) {
+ this.innerProperty = prop;
+ }
+
+ public String toString() {
+ return Double.toString(integerNumber + floatNumber + doubleNumber) + " & "
+ + ((innerProperty == null) ? "" : innerProperty.toString());
+ }
+
+ public String[] getStringArray() {
+ return stringArray;
+ }
+
+ public void setStringArray(String[] stringArray) {
+ this.stringArray = stringArray;
+ }
+
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2DOMNodeTransformerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2DOMNodeTransformerTestCase.java new file mode 100644 index 0000000000..839c7429b1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2DOMNodeTransformerTestCase.java @@ -0,0 +1,126 @@ +/*
+ * 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.core.databinding.javabeans;
+
+import java.io.StringWriter;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Node;
+
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.model.DataType;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * Testcase to test the XMLTypeMapperExtension which is the back bone for all transformations supported by the JavaBeans
+ * Databinding.
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaBean2DOMNodeTransformerTestCase extends TestCase {
+ private JavaBean2DOMNodeTransformer aTransformer = new JavaBean2DOMNodeTransformer();
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public void testTranformation() throws Exception {
+ TransformationContext context = EasyMock.createMock(TransformationContext.class);
+ DataType<Class> dataType = new DataType<Class>(null, SamplePropertyBean.class);
+ EasyMock.expect(context.getTargetDataType()).andReturn(dataType).anyTimes();
+ EasyMock.replay(context);
+
+ javax.xml.transform.Transformer transformer =
+ TransformerFactory.newInstance().newTransformer();
+ Object data = new int[]{10, 20, 30, 40};
+ Node aNode = aTransformer.transform(data, context);
+ StringWriter sw = new StringWriter();
+ transformer.transform(new DOMSource(aNode), new StreamResult(sw));
+
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><int_collection><int>10</int><int>20</int>"
+ + "<int>30</int><int>40</int></int_collection>",
+ sw.toString());
+ }
+
+ public static class SamplePropertyBean {
+ private float floatNumber = 50;
+ private SamplePropertyBean innerProperty;
+ private double doubleNumber = 75;
+ private int integerNumber = 25;
+ private String[] stringArray;
+
+ public SamplePropertyBean() {
+
+ }
+
+ double getDoubleNumber() {
+ return doubleNumber;
+ }
+
+ public void setDoubleNumber(double doubleNumber) {
+ this.doubleNumber = doubleNumber;
+ }
+
+ public float getFloatNumber() {
+ return floatNumber;
+ }
+
+ public void setFloatNumber(float floatNumber) {
+ this.floatNumber = floatNumber;
+ }
+
+ public int getIntegerNumber() {
+ return integerNumber;
+ }
+
+ public void setIntegerNumber(int integerNumber) {
+ this.integerNumber = integerNumber;
+ }
+
+ public SamplePropertyBean getInnerProperty() {
+ return innerProperty;
+ }
+
+ public void setInnerProperty(SamplePropertyBean prop) {
+ this.innerProperty = prop;
+ }
+
+ public String toString() {
+ return Double.toString(integerNumber + floatNumber + doubleNumber) + " & "
+ + ((innerProperty == null) ? "" : innerProperty.toString());
+ }
+
+ public String[] getStringArray() {
+ return stringArray;
+ }
+
+ public void setStringArray(String[] stringArray) {
+ this.stringArray = stringArray;
+ }
+
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/DOM2StAXTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/DOM2StAXTestCase.java new file mode 100644 index 0000000000..942b2d67e9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/DOM2StAXTestCase.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.core.databinding.xml; + +import javax.xml.stream.XMLStreamReader; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.w3c.dom.Node; + +public class DOM2StAXTestCase extends TestCase { + private static final String IPO_XML = + "<?xml version=\"1.0\"?>" + "<ipo:purchaseOrder" + + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + + " xmlns:ipo=\"http://www.example.com/IPO\"" + + " xsi:schemaLocation=\"http://www.example.com/IPO ipo.xsd\"" + + " orderDate=\"1999-12-01\">" + + " <shipTo exportCode=\"1\" xsi:type=\"ipo:UKAddress\">" + + " <name>Helen Zoe</name>" + + " <street>47 Eden Street</street>" + + " <city>Cambridge</city>" + + " <postcode>CB1 1JR</postcode>" + + " </shipTo>" + + " <billTo xsi:type=\"ipo:USAddress\">" + + " <name>Robert Smith</name>" + + " <street>8 Oak Avenue</street>" + + " <city>Old Town</city>" + + " <state>PA</state>" + + " <zip>95819</zip>" + + " </billTo>" + + " <items>" + + " <item partNum=\"833-AA\">" + + " <productName>Lapis necklace</productName>" + + " <quantity>1</quantity>" + + " <USPrice>99.95</USPrice>" + + " <ipo:comment>Want this for the holidays</ipo:comment>" + + " <shipDate>1999-12-05</shipDate>" + + " </item>" + + " </items>" + + "</ipo:purchaseOrder>"; + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + } + + public void testTransformation() { + String2Node t1 = new String2Node(); + Node node = t1.transform(IPO_XML, null); + Node2XMLStreamReader t2 = new Node2XMLStreamReader(); + XMLStreamReader reader = t2.transform(node, null); + XMLStreamReader2String t3 = new XMLStreamReader2String(); + String xml = t3.transform(reader, null); + Assert.assertTrue(xml != null && xml.indexOf("<shipDate>1999-12-05</shipDate>") != -1); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/DataPipeTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/DataPipeTestCase.java new file mode 100644 index 0000000000..d4eaf9b2a9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/DataPipeTestCase.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.core.databinding.xml; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.tuscany.core.databinding.impl.PipedTransformer; +import org.apache.tuscany.spi.databinding.extension.DOMHelper; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Test case for DataPipe + */ +public class DataPipeTestCase extends TestCase { + + public final void testStreamPipe() throws IOException { + byte[] bytes = new byte[] {1, 2, 3}; + StreamDataPipe pipe = new StreamDataPipe(); + Assert.assertSame(OutputStream.class, pipe.getSourceType()); + Assert.assertSame(InputStream.class, pipe.getTargetType()); + OutputStream os = pipe.getSink(); + os.write(bytes); + byte[] newBytes = new byte[16]; + int count = pipe.getResult().read(newBytes); + Assert.assertEquals(3, count); + for (int i = 0; i < bytes.length; i++) { + Assert.assertEquals(bytes[i], newBytes[i]); + } + } + + public final void testWriter2ReaderPipe() throws IOException { + String str = "ABC"; + Writer2ReaderDataPipe pipe = new Writer2ReaderDataPipe(); + Assert.assertSame(Writer.class, pipe.getSourceType()); + Assert.assertSame(Reader.class, pipe.getTargetType()); + pipe.getSink().write(str); + char[] buf = new char[16]; + int count = pipe.getResult().read(buf); + Assert.assertEquals(3, count); + for (int i = 0; i < str.length(); i++) { + Assert.assertEquals(str.charAt(i), buf[i]); + } + } + + public final void testPiped() throws Exception { + Node2Writer node2Writer = new Node2Writer(); + Writer2ReaderDataPipe pipe = new Writer2ReaderDataPipe(); + PipedTransformer<Node, Writer, Reader> transformer = + new PipedTransformer<Node, Writer, Reader>(node2Writer, pipe); + Document document = DOMHelper.newDocument(); + Element element = document.createElementNS("http://ns1", "root"); + document.appendChild(element); + Reader reader = transformer.transform(document, null); + Assert.assertEquals(transformer.getWeight(), node2Writer.getWeight() + pipe.getWeight()); + Assert.assertEquals(transformer.getSourceDataBinding(), node2Writer.getSourceDataBinding()); + Assert.assertEquals(transformer.getTargetDataBinding(), pipe.getTargetDataBinding()); + char[] buf = new char[120]; + int count = reader.read(buf); + String xml = new String(buf, 0, count); + Assert.assertTrue(xml.contains("<root xmlns=\"http://ns1\"/>")); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/Node2StringTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/Node2StringTestCase.java new file mode 100755 index 0000000000..9b9aa3b893 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/Node2StringTestCase.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.databinding.xml; + +import junit.framework.TestCase; + +import org.apache.tuscany.spi.databinding.extension.DOMHelper; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class Node2StringTestCase extends TestCase { + public void testTransformation() throws Exception { + Document document = DOMHelper.newDocument(); + Element element = document.createElementNS("http://ns1", "test"); + document.appendChild(element); + + new Node2String().transform(document, null); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/PushTransformationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/PushTransformationTestCase.java new file mode 100644 index 0000000000..a2318b2faa --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/PushTransformationTestCase.java @@ -0,0 +1,81 @@ +/* + * 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.core.databinding.xml; + +import javax.xml.stream.XMLStreamReader; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.tuscany.core.databinding.impl.PipedTransformer; +import org.w3c.dom.Node; +import org.xml.sax.ContentHandler; + +public class PushTransformationTestCase extends TestCase { + private static final String IPO_XML = + "<?xml version=\"1.0\"?>" + "<ipo:purchaseOrder" + + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + + " xmlns:ipo=\"http://www.example.com/IPO\"" + + " xsi:schemaLocation=\"http://www.example.com/IPO ipo.xsd\"" + + " orderDate=\"1999-12-01\">" + + " <shipTo exportCode=\"1\" xsi:type=\"ipo:UKAddress\">" + + " <name>Helen Zoe</name>" + + " <street>47 Eden Street</street>" + + " <city>Cambridge</city>" + + " <postcode>CB1 1JR</postcode>" + + " </shipTo>" + + " <billTo xsi:type=\"ipo:USAddress\">" + + " <name>Robert Smith</name>" + + " <street>8 Oak Avenue</street>" + + " <city>Old Town</city>" + + " <state>PA</state>" + + " <zip>95819</zip>" + + " </billTo>" + + " <items>" + + " <item partNum=\"833-AA\">" + + " <productName>Lapis necklace</productName>" + + " <quantity>1</quantity>" + + " <USPrice>99.95</USPrice>" + + " <ipo:comment>Want this for the holidays</ipo:comment>" + + " <shipDate>1999-12-05</shipDate>" + + " </item>" + + " </items>" + + "</ipo:purchaseOrder>"; + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + } + + public void testTransformation() { + String2XMLStreamReader t1 = new String2XMLStreamReader(); + XMLStreamReader reader = t1.transform(IPO_XML, null); + XMLStreamReader2SAX t2 = new XMLStreamReader2SAX(); + PipedTransformer<XMLStreamReader, ContentHandler, Node> t3 = + new PipedTransformer<XMLStreamReader, ContentHandler, Node>(t2, new SAX2DOMPipe()); + Node node = t3.transform(reader, null); + Assert.assertNotNull(node); + Node2String t4 = new Node2String(); + String xml = t4.transform(node, null); + Assert.assertTrue(xml != null && xml.indexOf("<shipDate>1999-12-05</shipDate>") != -1); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/StAXHelperTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/StAXHelperTestCase.java new file mode 100644 index 0000000000..7d18e83ac6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/StAXHelperTestCase.java @@ -0,0 +1,47 @@ +/* + * 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.core.databinding.xml; + +import javax.xml.stream.XMLStreamReader; + +import junit.framework.TestCase; + +/** + * Test Case for StAXHelper + */ +public class StAXHelperTestCase extends TestCase { + private static final String XML = + "<a:foo xmlns:a='http://a' name='foo'><bar name='bar'>" + "<doo a:name='doo' xmlns:a='http://doo'/>" + + "</bar></a:foo>"; + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + } + + public void testHelper() throws Exception { + XMLStreamReader reader = StAXHelper.createXMLStreamReader(XML); + String xml = StAXHelper.save(reader); + reader = StAXHelper.createXMLStreamReader(xml); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/TraxTransformerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/TraxTransformerTestCase.java new file mode 100644 index 0000000000..7e9494d423 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/databinding/xml/TraxTransformerTestCase.java @@ -0,0 +1,99 @@ +/* + * 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.core.databinding.xml; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import java.net.URL; + +import junit.framework.TestCase; + +import org.w3c.dom.Node; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * + */ +public class TraxTransformerTestCase extends TestCase { + private URL url; + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + url = getClass().getResource("foo.xml"); + } + + public void testTransformDOM() throws IOException { + InputStream is = url.openStream(); + InputStream2Node t1 = new InputStream2Node(); + Node node = t1.transform(is, null); + is.close(); + Writer writer = new StringWriter(); + Node2Writer t2 = new Node2Writer(); + t2.transform(node, writer, null); + String str = writer.toString(); + StringReader reader = new StringReader(str); + Reader2Node t3 = new Reader2Node(); + node = t3.transform(reader, null); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + Node2OutputStream t4 = new Node2OutputStream(); + t4.transform(node, os, null); + InputSource inputSource = new InputSource(new ByteArrayInputStream(os.toByteArray())); + InputSource2Node t5 = new InputSource2Node(); + node = t5.transform(inputSource, null); + } + + public void testTransformSAX() throws IOException { + MyContentHandler handler = new MyContentHandler(); + InputStream is = url.openStream(); + InputStream2SAX t1 = new InputStream2SAX(); + t1.transform(is, handler, null); + is.close(); + + String xml = "<foo xmlns=\"http://foo\">bar</foo>"; + + InputSource inputSource = new InputSource(new StringReader(xml)); + InputSource2SAX t2 = new InputSource2SAX(); + MyContentHandler handler2 = new MyContentHandler(); + t2.transform(inputSource, handler2, null); + + } + + private static class MyContentHandler extends DefaultHandler { + + @Override + public void startElement(String namespaceURI, String localName, String qName, Attributes atts) + throws SAXException { + super.startElement(namespaceURI, localName, qName, atts); + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/deployer/BootstrapDeployerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/deployer/BootstrapDeployerTestCase.java new file mode 100644 index 0000000000..0cb29ac377 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/deployer/BootstrapDeployerTestCase.java @@ -0,0 +1,170 @@ +/* + * 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.core.deployer; + +import java.net.URI; +import java.net.URL; +import java.util.Collection; +import java.util.Map; +import javax.xml.stream.XMLInputFactory; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.builder.Connector; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.model.BindingDefinition; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.Include; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.PropertyValue; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; +import org.apache.tuscany.core.bootstrap.Bootstrapper; +import org.apache.tuscany.core.bootstrap.DefaultBootstrapper; +import org.apache.tuscany.core.builder.ConnectorImpl; +import org.apache.tuscany.core.component.ComponentManager; +import org.apache.tuscany.core.component.ComponentManagerImpl; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.implementation.system.model.SystemCompositeImplementation; +import org.apache.tuscany.core.mock.component.BasicInterface; +import org.apache.tuscany.core.monitor.NullMonitorFactory; +import org.apache.tuscany.core.resolver.DefaultAutowireResolver; +import org.easymock.EasyMock; +import static org.easymock.EasyMock.createNiceMock; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; + +/** + * Verifies the default boostrap deployer + * + * @version $Rev$ $Date$ + */ +public class BootstrapDeployerTestCase extends TestCase { + private DeployerImpl deployer; + private DeploymentContext deploymentContext; + private ComponentDefinition<SystemCompositeImplementation> componentDefinition; + private SystemCompositeImplementation implementation; + private URI componentId; + + @SuppressWarnings("unchecked") + public void testBoot1Load() throws LoaderException { + Component parent = createNiceMock(Component.class); + URI uri = URI.create("sca://parent"); + EasyMock.expect(parent.getUri()).andReturn(uri).atLeastOnce(); + EasyMock.replay(parent); + URL scdl = BootstrapDeployerTestCase.class.getResource("boot1.scdl"); + implementation.setScdlLocation(scdl); + deployer.load(parent, componentDefinition, deploymentContext); + CompositeComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> composite = + implementation.getComponentType(); + assertNotNull(composite); + assertEquals(new QName("http://example.com", "boot1"), composite.getName()); + + // check parse of <service> + Map<String, ServiceDefinition> services = composite.getDeclaredServices(); + assertEquals(1, services.size()); // included doesn't count + services = composite.getServices(); + assertEquals(2, services.size()); // included counts + ServiceDefinition serviceDefinition = services.get("service"); + assertNotNull(serviceDefinition); + assertEquals(componentId.resolve("#service"), serviceDefinition.getUri()); + assertEquals(BasicInterface.class, serviceDefinition.getServiceContract().getInterfaceClass()); + Collection<BindingDefinition> bindings = serviceDefinition.getBindings(); + assertTrue(bindings.isEmpty()); + + // check parse of <component> + Map<String, ComponentDefinition<? extends Implementation<?>>> components = composite.getDeclaredComponents(); + assertEquals(1, components.size()); // included doesn't count + components = composite.getComponents(); + assertEquals(2, components.size()); // included counts + ComponentDefinition<? extends Implementation<?>> component = components.get("component"); + assertNotNull(component); + PropertyValue<?> propVal = component.getPropertyValues().get("publicProperty"); + assertEquals("propval", propVal.getValueFactory().getInstance()); + + // check introspection of implementation + ComponentType<?, ?, ?> componentType = component.getImplementation().getComponentType(); + assertNotNull(componentType); // details checked in SystemComponentTypeLoaderTestCase + + // check included component + Map<String, Include> includes = composite.getIncludes(); + assertEquals(1, includes.size()); + Include include = includes.get("boot1-include"); + assertNotNull(include); + CompositeComponentType included = include.getIncluded(); + assertNotNull(included); + assertEquals(1, included.getComponents().size()); + } + + public void testBoot1Deployment() throws Exception { + URL scdl = BootstrapDeployerTestCase.class.getResource("boot1.scdl"); + implementation.setScdlLocation(scdl); + Component parent = EasyMock.createMock(Component.class); + replay(parent); + // load the boot1 file using the bootstrap deployer + componentDefinition.setUri(URI.create("sca://parent/simple")); + Collection<Component> components = deployer.deploy(parent, componentDefinition); + assertFalse(components.isEmpty()); + verify(parent); + } + + public void testBoot2Deployment() throws Exception { + URL scdl = BootstrapDeployerTestCase.class.getResource("boot2.scdl"); + implementation.setScdlLocation(scdl); + Component parent = createNiceMock(Component.class); + replay(parent); + // load the boot2 file using the bootstrap deployer + componentDefinition.setUri(URI.create("newDeployer")); + Collection<Component> components = deployer.deploy(parent, componentDefinition); + assertFalse(components.isEmpty()); + verify(parent); + for (Component component : components) { + component.start(); + } + } + + @SuppressWarnings({"unchecked"}) + protected void setUp() throws Exception { + super.setUp(); + componentId = URI.create("sca://localhost/parent"); + XMLInputFactory xmlFactory = XMLInputFactory.newInstance(); + DefaultAutowireResolver resolver = new DefaultAutowireResolver(); + ComponentManager manager = new ComponentManagerImpl(null, resolver); + Connector connector = new ConnectorImpl(manager); + JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl(); + ServiceContract contract = registry.introspect(ComponentManager.class); + manager.registerJavaObject(URI.create("ComponentManager"), contract, manager); + NullMonitorFactory monitorFactory = new NullMonitorFactory(); + Bootstrapper bootstrapper = + new DefaultBootstrapper(monitorFactory, xmlFactory, manager, resolver, connector); + deployer = (DeployerImpl) bootstrapper.createDeployer(); + deploymentContext = new RootDeploymentContext(null, null, componentId, xmlFactory, null, false); + implementation = new SystemCompositeImplementation(); + implementation.setClassLoader(getClass().getClassLoader()); + componentDefinition = new ComponentDefinition<SystemCompositeImplementation>(implementation); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/idl/java/ConversationalIntrospectionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/idl/java/ConversationalIntrospectionTestCase.java new file mode 100644 index 0000000000..07888bbc69 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/idl/java/ConversationalIntrospectionTestCase.java @@ -0,0 +1,80 @@ +/* + * 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.core.idl.java; + +import org.osoa.sca.annotations.Conversational; +import org.osoa.sca.annotations.EndsConversation; + +import org.apache.tuscany.spi.idl.InvalidConversationalOperationException; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.model.Operation; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class ConversationalIntrospectionTestCase extends TestCase { + private JavaInterfaceProcessorRegistryImpl registry = new JavaInterfaceProcessorRegistryImpl(); + + public void testServiceContractConversationalInformationIntrospection() throws Exception { + JavaServiceContract contract = registry.introspect(Foo.class); + assertTrue(contract.isConversational()); + int seq = contract.getOperations().get("operation").getConversationSequence(); + assertEquals(Operation.CONVERSATION_CONTINUE, seq); + seq = contract.getOperations().get("endOperation").getConversationSequence(); + assertEquals(Operation.CONVERSATION_END, seq); + } + + public void testBadServiceContract() throws Exception { + try { + registry.introspect(BadFoo.class); + fail(); + } catch (InvalidConversationalOperationException e) { + //expected + } + } + + public void testNonConversationalInformationIntrospection() throws Exception { + JavaServiceContract contract = registry.introspect(NonConversationalFoo.class); + assertFalse(contract.isConversational()); + int seq = contract.getOperations().get("operation").getConversationSequence(); + assertEquals(Operation.NO_CONVERSATION, seq); + } + + @Conversational + private interface Foo { + void operation(); + + @EndsConversation + void endOperation(); + } + + private interface BadFoo { + void operation(); + + @EndsConversation + void endOperation(); + } + + private interface NonConversationalFoo { + void operation(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/idl/java/JavaInterfaceProcessorRegistryImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/idl/java/JavaInterfaceProcessorRegistryImplTestCase.java new file mode 100644 index 0000000000..e3a7deb10a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/idl/java/JavaInterfaceProcessorRegistryImplTestCase.java @@ -0,0 +1,100 @@ +/* + * 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.core.idl.java; + +import java.lang.reflect.Type; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessor; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.model.DataType; +import org.apache.tuscany.spi.model.Operation; + +import junit.framework.TestCase; +import org.apache.tuscany.core.util.JavaIntrospectionHelper; +import org.easymock.EasyMock; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.eq; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.isA; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; + +/** + * @version $Rev$ $Date$ + */ +public class JavaInterfaceProcessorRegistryImplTestCase extends TestCase { + private JavaInterfaceProcessorRegistryImpl impl; + + public void testSimpleInterface() throws InvalidServiceContractException { + JavaServiceContract contract = impl.introspect(Simple.class); + // TODO spec to clairfy interface name + assertEquals(JavaIntrospectionHelper.getBaseName(Simple.class), contract.getInterfaceName()); + assertEquals(Simple.class, contract.getInterfaceClass()); + Map<String, Operation<Type>> operations = contract.getOperations(); + assertEquals(1, operations.size()); + Operation<Type> baseInt = operations.get("baseInt"); + assertNotNull(baseInt); + + DataType<Type> returnType = baseInt.getOutputType(); + assertEquals(Integer.TYPE, returnType.getPhysical()); + assertEquals(Integer.TYPE, returnType.getLogical()); + + List<DataType<Type>> parameterTypes = baseInt.getInputType().getLogical(); + assertEquals(1, parameterTypes.size()); + DataType<Type> arg0 = parameterTypes.get(0); + assertEquals(Integer.TYPE, arg0.getPhysical()); + assertEquals(Integer.TYPE, arg0.getLogical()); + + List<DataType<Type>> faultTypes = baseInt.getFaultTypes(); + assertEquals(1, faultTypes.size()); + DataType<Type> fault0 = faultTypes.get(0); + assertEquals(IllegalArgumentException.class, fault0.getPhysical()); + assertEquals(IllegalArgumentException.class, fault0.getLogical()); + } + + public void testUnregister() throws Exception { + JavaInterfaceProcessor processor = createMock(JavaInterfaceProcessor.class); + processor.visitInterface(eq(Base.class), EasyMock.same((Class)null), isA(JavaServiceContract.class)); + expectLastCall().once(); + replay(processor); + impl.registerProcessor(processor); + impl.introspect(Base.class); + impl.unregisterProcessor(processor); + impl.introspect(Base.class); + verify(processor); + } + + protected void setUp() throws Exception { + super.setUp(); + impl = new JavaInterfaceProcessorRegistryImpl(); + + } + + private static interface Base { + int baseInt(int param) throws IllegalArgumentException; + } + + private static interface Simple extends Base { + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/IntrospectionRegistryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/IntrospectionRegistryTestCase.java new file mode 100644 index 0000000000..622e8e479a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/IntrospectionRegistryTestCase.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.core.implementation; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessor; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; + +import junit.framework.TestCase; +import org.apache.tuscany.core.implementation.IntrospectionRegistryImpl.Monitor; +import org.apache.tuscany.core.monitor.NullMonitorFactory; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class IntrospectionRegistryTestCase extends TestCase { + + private Monitor monitor; + + public void testRegister() throws Exception { + IntrospectionRegistryImpl registry = new IntrospectionRegistryImpl(monitor); + ImplementationProcessor processor = EasyMock.createNiceMock(ImplementationProcessor.class); + registry.registerProcessor(processor); + } + + public void testUnegister() throws Exception { + IntrospectionRegistryImpl registry = new IntrospectionRegistryImpl(monitor); + ImplementationProcessor processor = EasyMock.createNiceMock(ImplementationProcessor.class); + registry.registerProcessor(processor); + registry.unregisterProcessor(processor); + } + + @SuppressWarnings("unchecked") + public void testWalk() throws Exception { + IntrospectionRegistryImpl registry = new IntrospectionRegistryImpl(monitor); + ImplementationProcessor processor = EasyMock.createMock(ImplementationProcessor.class); + processor.visitClass( + EasyMock.eq(Bar.class), + EasyMock.isA(PojoComponentType.class), + EasyMock.isA(DeploymentContext.class)); + processor.visitConstructor( + EasyMock.isA(Constructor.class), + EasyMock.isA(PojoComponentType.class), + EasyMock.isA(DeploymentContext.class)); + processor.visitMethod( + EasyMock.isA(Method.class), + EasyMock.isA(PojoComponentType.class), + EasyMock.isA(DeploymentContext.class)); + processor.visitField( + EasyMock.isA(Field.class), + EasyMock.isA(PojoComponentType.class), + EasyMock.isA(DeploymentContext.class)); + processor.visitSuperClass( + EasyMock.isA(Class.class), + EasyMock.isA(PojoComponentType.class), + EasyMock.isA(DeploymentContext.class)); + processor.visitEnd( + EasyMock.isA(Class.class), + EasyMock.isA(PojoComponentType.class), + EasyMock.isA(DeploymentContext.class)); + + // mock.expects(once()).method("visitClass"); +// mock.expects(once()).method("visitMethod"); +// mock.expects(once()).method("visitField"); +// mock.expects(once()).method("visitConstructor"); +// mock.expects(once()).method("visitSuperClass"); +// mock.expects(once()).method("visitEnd"); + EasyMock.replay(processor); + registry.registerProcessor(processor); + registry.introspect( + Bar.class, + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(), + EasyMock.createNiceMock(DeploymentContext.class)); + EasyMock.verify(processor); + } + + + protected void setUp() throws Exception { + super.setUp(); + monitor = new NullMonitorFactory().getMonitor(Monitor.class); + } + + private class Baz { + + } + + private class Bar extends Baz { + + protected String bar; + + public Bar() { + } + + public void bar() { + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/PhysicalComponentTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/PhysicalComponentTestCase.java new file mode 100644 index 0000000000..f3bdf5e332 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/PhysicalComponentTestCase.java @@ -0,0 +1,80 @@ +/* + * 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.core.implementation; + +import junit.framework.TestCase; +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Init; + +import org.apache.tuscany.core.component.InstanceFactory; +import org.apache.tuscany.core.component.scope.InstanceWrapper; +import org.apache.tuscany.core.component.scope.InstanceWrapperBase; +import org.apache.tuscany.spi.component.TargetDestructionException; +import org.apache.tuscany.spi.component.TargetInitializationException; + +/** + * @version $Rev$ $Date$ + */ +public class PhysicalComponentTestCase extends TestCase { + public void testSomething() { + + } + + /** + * This is the class supplied by the user. + */ + public static class UserImplementation { + @Init + void init() { + } + + @Destroy + void destroy() { + } + } + + /** + * This is the generated wrapper class. + */ + public static class UserWrapper extends InstanceWrapperBase<UserImplementation> { + public UserWrapper(UserImplementation instance) { + super(instance); + } + + public void start() throws TargetInitializationException { + instance.init(); + super.start(); + } + + public void stop() throws TargetDestructionException { + super.stop(); + instance.destroy(); + } + } + + /** + * This is the generated factory class. + */ + public static class UserFactory implements InstanceFactory<UserImplementation> { + public InstanceWrapper<UserImplementation> newInstance() { + UserImplementation instance = new UserImplementation(); + return new UserWrapper(instance); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/PojoAtomicComponentTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/PojoAtomicComponentTestCase.java new file mode 100644 index 0000000000..ccb2c88767 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/PojoAtomicComponentTestCase.java @@ -0,0 +1,193 @@ +/* + * 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.core.implementation; + +import java.net.URI; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.TargetInvokerCreationException; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.injection.EventInvoker; +import org.apache.tuscany.core.injection.PojoObjectFactory; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class PojoAtomicComponentTestCase extends TestCase { + private PojoConfiguration config; + + @SuppressWarnings({"unchecked"}) + public void testDestroy() throws Exception { + EventInvoker<Object> invoker = EasyMock.createMock(EventInvoker.class); + invoker.invokeEvent(EasyMock.notNull()); + EasyMock.replay(invoker); + config.setDestroyInvoker(invoker); + AtomicComponent component = new TestAtomicComponent(config); + assertTrue(component.isDestroyable()); + component.destroy(new Object()); + EasyMock.verify(invoker); + } + + @SuppressWarnings({"unchecked"}) + public void testNoCallbackWires() throws Exception { + ScopeContainer container = EasyMock.createMock(ScopeContainer.class); + EasyMock.expect(container.getScope()).andReturn(Scope.CONVERSATION); + container.register(EasyMock.isA(AtomicComponent.class)); + EasyMock.replay(container); + config.addCallbackSite("callback", Foo.class.getMethod("setCallback", Object.class)); + AtomicComponent component = new TestAtomicComponent(config); + component.setScopeContainer(container); + component.start(); + EasyMock.verify(container); + } + + @SuppressWarnings({"unchecked"}) + public void testInit() throws Exception { + EventInvoker<Object> invoker = EasyMock.createMock(EventInvoker.class); + invoker.invokeEvent(EasyMock.notNull()); + EasyMock.replay(invoker); + config.setInitInvoker(invoker); + AtomicComponent component = new TestAtomicComponent(config); + component.init(new Object()); + EasyMock.verify(invoker); + } + + public void testOptimizable() throws Exception { + TestAtomicComponent component = new TestAtomicComponent(config); + assertTrue(component.isOptimizable()); + } + + @SuppressWarnings({"unchecked"}) + public void testDestroyableButOptimizable() throws Exception { + EventInvoker<Object> invoker = EasyMock.createMock(EventInvoker.class); + invoker.invokeEvent(EasyMock.notNull()); + EasyMock.replay(invoker); + config.setDestroyInvoker(invoker); + TestAtomicComponent component = new TestAtomicComponent(config); + assertTrue(component.isOptimizable()); + } + + @SuppressWarnings({"unchecked"}) + public void testStatelessOptimizable() throws Exception { + TestAtomicComponent component = new TestAtomicComponent(config, Scope.STATELESS); + assertTrue(component.isOptimizable()); + } + + @SuppressWarnings({"unchecked"}) + public void testNotOptimizable() throws Exception { + EventInvoker<Object> invoker = EasyMock.createMock(EventInvoker.class); + invoker.invokeEvent(EasyMock.notNull()); + EasyMock.replay(invoker); + config.setDestroyInvoker(invoker); + TestAtomicComponent component = new TestAtomicComponent(config, Scope.STATELESS); + assertFalse(component.isOptimizable()); + } + + public void testPropertyAccess() { + String value = "Foo!"; + ObjectFactory objectFactory = EasyMock.createMock(ObjectFactory.class); + EasyMock.expect(objectFactory.getInstance()).andReturn(value); + EasyMock.replay(objectFactory); + + TestAtomicComponent component = new TestAtomicComponent(config); + component.addPropertyFactory("foo", objectFactory); + assertSame(value, component.getProperty(String.class, "foo")); + } + + public void testServiceLookup() { + URI uri = URI.create("#service"); + FooService foo = EasyMock.createMock(FooService.class); + Wire wire = EasyMock.createMock(Wire.class); + EasyMock.expect(wire.getSourceUri()).andReturn(uri).atLeastOnce(); + EasyMock.replay(wire); + ObjectFactory factory = EasyMock.createMock(ObjectFactory.class); + EasyMock.expect(factory.getInstance()).andReturn(foo); + EasyMock.replay(factory); + TestAtomicComponent component = new TestAtomicComponent(config, Scope.COMPOSITE, factory); + component.attachWire(wire); + assertSame(foo, component.getService(FooService.class, "service")); + EasyMock.verify(wire); + EasyMock.verify(factory); + } + + protected void setUp() throws Exception { + super.setUp(); + PojoObjectFactory<Foo> factory = new PojoObjectFactory<Foo>(Foo.class.getConstructor()); + + config = new PojoConfiguration(); + config.setInstanceFactory(factory); + config.setName(URI.create("foo")); + } + + private class TestAtomicComponent extends PojoAtomicComponent { + private final ObjectFactory factory; + private final Scope scope; + + public TestAtomicComponent(PojoConfiguration configuration) { + this(configuration, Scope.COMPOSITE, null); + } + + public TestAtomicComponent(PojoConfiguration configuration, Scope scope) { + this(configuration, scope, null); + } + + public TestAtomicComponent(PojoConfiguration configuration, Scope scope, ObjectFactory factory) { + super(configuration); + this.scope = scope; + this.factory = factory; + } + + public Scope getScope() { + return scope; + } + + @SuppressWarnings({"unchecked"}) + protected <B> ObjectFactory<B> createWireFactory(Class<B> interfaze, Wire wire) { + return factory; + } + + public TargetInvoker createTargetInvoker(String targetName, Operation operation) + throws TargetInvokerCreationException { + return null; + } + } + + private static class Foo { + public Foo() { + } + + public void setCallback(Object callback) { + + } + } + + public static interface FooService { + } + +} + + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeBuilderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeBuilderTestCase.java new file mode 100644 index 0000000000..96808add34 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeBuilderTestCase.java @@ -0,0 +1,199 @@ +/* + * 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.core.implementation.composite; + +import java.net.URI; +import java.util.Map; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.ScopeContainerMonitor; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.CompositeImplementation; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ReferenceTarget; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; +import org.apache.tuscany.core.binding.local.LocalBindingBuilder; +import org.apache.tuscany.core.binding.local.LocalBindingDefinition; +import org.apache.tuscany.core.builder.BuilderRegistryImpl; +import org.apache.tuscany.core.component.scope.CompositeScopeContainer; +import org.apache.tuscany.core.deployer.RootDeploymentContext; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.implementation.java.JavaComponentBuilder; +import org.apache.tuscany.core.implementation.java.JavaImplementation; +import org.apache.tuscany.core.mock.component.OtherTarget; +import org.apache.tuscany.core.mock.component.Source; +import org.apache.tuscany.core.mock.component.SourceImpl; +import org.apache.tuscany.core.mock.component.Target; +import org.apache.tuscany.core.mock.component.TargetImpl; +import org.easymock.EasyMock; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class CompositeBuilderTestCase extends TestCase { + private static final URI TOP_COMPONENT = URI.create("Top"); + private static final URI SOURCE_COMPONENT = URI.create("Top/Parent/SourceComponent"); + private static final URI TARGET_COMPONENT = URI.create("Top/Parent/TargetComponent"); + private static final URI INNER_SOURCE_COMPONENT = URI.create("Top/Parent/SourceComponent/InnerSourceComponent"); + + private DeploymentContext deploymentContext; + + @SuppressWarnings("unchecked") + public void testBuild() throws Exception { + CompositeBuilder builder = new CompositeBuilder(); + BuilderRegistryImpl builderRegistry = new BuilderRegistryImpl(null); + JavaComponentBuilder jBuilder = new JavaComponentBuilder(); + builderRegistry.register(JavaImplementation.class, jBuilder); + builderRegistry.register(CompositeImplementation.class, builder); + builderRegistry.register(LocalBindingDefinition.class, new LocalBindingBuilder()); + builder.setBuilderRegistry(builderRegistry); + + Component component = + builder.build(createTopComponentDef(), deploymentContext); + Map<URI, Component> components = deploymentContext.getComponents(); + Component sourceComponent = components.get(SOURCE_COMPONENT); + assertNotNull(sourceComponent.getService("InnerSourceService")); + AtomicComponent innerSourceComponent = (AtomicComponent) components.get(INNER_SOURCE_COMPONENT); + assertNotNull(innerSourceComponent); + } + + protected void setUp() throws Exception { + super.setUp(); + ScopeContainerMonitor monitor = EasyMock.createNiceMock(ScopeContainerMonitor.class); + CompositeScopeContainer container = new CompositeScopeContainer(monitor); + container.start(); + deploymentContext = new RootDeploymentContext(null, null, TOP_COMPONENT, null, container, false); + } + + private ComponentDefinition createTopComponentDef() throws Exception { + CompositeComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> outerType = + new CompositeComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + outerType.add(createSourceComponentDef()); + outerType.add(createTargetComponentDef()); + + CompositeImplementation outerImpl = new CompositeImplementation(); + outerImpl.setComponentType(outerType); + + ComponentDefinition def = new ComponentDefinition<CompositeImplementation>(outerImpl); + def.setUri(TOP_COMPONENT); + return def; + } + + private ComponentDefinition<CompositeImplementation> createSourceComponentDef() throws Exception { + + CompositeComponentType<ServiceDefinition, ReferenceDefinition, JavaMappedProperty<?>> innerType = + new CompositeComponentType<ServiceDefinition, ReferenceDefinition, JavaMappedProperty<?>>(); + innerType.add(createInnerSourceComponentDef()); + ReferenceDefinition reference = new ReferenceDefinition(); + reference.setUri(URI.create("#TargetComponentRef")); + JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl(); + JavaServiceContract targetContract = registry.introspect(Target.class); + reference.setServiceContract(targetContract); + innerType.add(reference); + ServiceDefinition service = new ServiceDefinition(); + service.setUri(URI.create("#InnerSourceService")); + JavaServiceContract sourceContract = registry.introspect(Source.class); + service.setServiceContract(sourceContract); + service.setTarget(INNER_SOURCE_COMPONENT); + innerType.add(service); + + CompositeImplementation innerImpl = new CompositeImplementation(); + innerImpl.setComponentType(innerType); + + ComponentDefinition<CompositeImplementation> sourceComponentDefinition = + new ComponentDefinition<CompositeImplementation>(SOURCE_COMPONENT, innerImpl); + ReferenceTarget refTarget = new ReferenceTarget(); + refTarget.setReferenceName(URI.create("#TargetComponentRef")); + refTarget.addTarget(TARGET_COMPONENT); + sourceComponentDefinition.add(refTarget); + + return sourceComponentDefinition; + } + + private ComponentDefinition<JavaImplementation> createInnerSourceComponentDef() throws Exception { + + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> sourceType = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + sourceType.setImplementationScope(Scope.COMPOSITE); + JavaMappedReference reference = new JavaMappedReference(); + reference.setUri(URI.create("#targetReference")); + JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl(); + ServiceContract<?> targetContract = registry.introspect(Target.class); + targetContract.setCallbackClass(OtherTarget.class); + targetContract.setCallbackName("OtherTarget"); + reference.setServiceContract(targetContract); + reference.setMember(SourceImpl.class.getMethod("setTarget", Target.class)); + sourceType.add(reference); + + ServiceContract<?> sourceContract = registry.introspect(Source.class); + + JavaMappedService sourceServiceDefinition = new JavaMappedService(); + sourceServiceDefinition.setUri(URI.create("#Source")); + sourceServiceDefinition.setServiceContract(sourceContract); + + sourceType.add(sourceServiceDefinition); + sourceType.setConstructorDefinition(new ConstructorDefinition<SourceImpl>(SourceImpl.class.getConstructor())); + JavaImplementation sourceImpl = new JavaImplementation(SourceImpl.class, sourceType); + ComponentDefinition<JavaImplementation> innerSourceComponentDefinition = + new ComponentDefinition<JavaImplementation>(INNER_SOURCE_COMPONENT, sourceImpl); + ReferenceTarget refTarget = new ReferenceTarget(); + refTarget.setReferenceName(URI.create("#targetReference")); + refTarget.addTarget(new URI("#TargetComponentRef")); + innerSourceComponentDefinition.add(refTarget); + + return innerSourceComponentDefinition; + } + + private ComponentDefinition<JavaImplementation> createTargetComponentDef() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> targetType = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + targetType.setImplementationScope(Scope.COMPOSITE); + + JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl(); + ServiceContract<?> targetContract = registry.introspect(Target.class); + targetContract.setCallbackClass(OtherTarget.class); + targetContract.setCallbackName("OtherTarget"); + + JavaMappedService serviceDefinition = new JavaMappedService(); + serviceDefinition.setUri(URI.create("Target")); + serviceDefinition.setServiceContract(targetContract); + serviceDefinition.setCallbackReferenceName("otherTarget"); + + targetType.add(serviceDefinition); + targetType.setConstructorDefinition(new ConstructorDefinition<TargetImpl>(TargetImpl.class.getConstructor())); + JavaImplementation targetImpl = new JavaImplementation(TargetImpl.class, targetType); + //URI uri = URI.create("TargetComponent"); + return new ComponentDefinition<JavaImplementation>(TARGET_COMPONENT, targetImpl); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImplTestCase.java new file mode 100644 index 0000000000..a5574c7f78 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImplTestCase.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.core.implementation.composite; + +import java.net.URI; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.event.Event; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.model.Scope; + +import junit.framework.Assert; +import junit.framework.TestCase; +import org.easymock.EasyMock; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.eq; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.replay; + +/** + * @version $Rev$ $Date$ + */ +public class CompositeComponentImplTestCase extends TestCase { + + public void testGetScope() { + Component composite = new CompositeComponentImpl(URI.create("parent")); + Assert.assertEquals(Scope.SYSTEM, composite.getScope()); + } + + public void testRegisterService() throws Exception { + Component composite = new CompositeComponentImpl(URI.create("parent")); + Service service = new ServiceImpl(URI.create("foo#service"), null); + composite.register(service); + assertNotNull(composite.getService("service")); + } + + public void testRegisterReference() throws Exception { + Component composite = new CompositeComponentImpl(URI.create("parent")); + Reference reference = new ReferenceImpl(URI.create("foo#reference"), null); + composite.register(reference); + assertNotNull(composite.getReference("reference")); + } + + public void testOnEvent() { + CompositeComponentImpl composite = new CompositeComponentImpl(URI.create("parent")); + Event event = new Event() { + public Object getSource() { + return null; + } + }; + RuntimeEventListener listener = createMock(RuntimeEventListener.class); + listener.onEvent(eq(event)); + expectLastCall(); + replay(listener); + composite.addListener(listener); + composite.start(); + composite.onEvent(event); + EasyMock.verify(listener); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeLoaderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeLoaderTestCase.java new file mode 100644 index 0000000000..84c5825e82 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeLoaderTestCase.java @@ -0,0 +1,201 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.implementation.composite; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamReader; + +import static org.osoa.sca.Constants.SCA_NS; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.ModelObject; + +import junit.framework.TestCase; +import org.apache.tuscany.core.deployer.RootDeploymentContext; +import org.easymock.EasyMock; +import org.easymock.IAnswer; + +/** + * @version $Rev$ $Date$ + */ +public class CompositeLoaderTestCase extends TestCase { + public static final QName COMPOSITE = new QName(SCA_NS, "composite"); + private CompositeLoader loader; + private QName name; + + public void testLoadNameAndDefaultAutowire() throws Exception { + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getAttributeValue(null, "name")).andReturn(name.getLocalPart()); + EasyMock.expect(reader.getAttributeValue(null, "targetNamespace")).andReturn(name.getNamespaceURI()); + EasyMock.expect(reader.getAttributeValue(null, "autowire")).andReturn(null); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.expect(reader.getName()).andReturn(COMPOSITE); + EasyMock.replay(reader); + CompositeComponentType<?, ?, ?> type = loader.load(null, reader, null); + assertEquals(name, type.getName()); + assertFalse(type.isAutowire()); + EasyMock.verify(reader); + } + + public void testAutowire() throws Exception { + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getAttributeValue(null, "name")).andReturn(name.getLocalPart()); + EasyMock.expect(reader.getAttributeValue(null, "targetNamespace")).andReturn(name.getNamespaceURI()); + EasyMock.expect(reader.getAttributeValue(null, "autowire")).andReturn("true"); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.expect(reader.getName()).andReturn(COMPOSITE); + EasyMock.replay(reader); + CompositeComponentType<?, ?, ?> type = loader.load(null, reader, null); + assertTrue(type.isAutowire()); + EasyMock.verify(reader); + } + + /** + * Tests autowire enabled is propagated when children are loaded + */ + public void testAutowireContextEnabledPropagation() throws Exception { + LoaderRegistry registry = EasyMock.createMock(LoaderRegistry.class); + registry.load(EasyMock.isA(ModelObject.class), + EasyMock.isA(XMLStreamReader.class), + EasyMock.isA(DeploymentContext.class)); + EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() { + public Object answer() throws Throwable { + DeploymentContext context = (DeploymentContext) EasyMock.getCurrentArguments()[2]; + assertTrue("autowire not propagated", context.isAutowire()); + return null; + } + }); + EasyMock.replay(registry); + DeploymentContext context = new RootDeploymentContext(null, null, null, null, null, true); + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getAttributeValue(null, "name")).andReturn(name.getLocalPart()); + EasyMock.expect(reader.getAttributeValue(null, "targetNamespace")).andReturn(name.getNamespaceURI()); + EasyMock.expect(reader.getAttributeValue(null, "autowire")).andReturn("true"); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.START_ELEMENT); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.expect(reader.getName()).andReturn(COMPOSITE); + EasyMock.replay(reader); + loader.load(null, reader, context); + assertTrue(context.isAutowire()); + } + + /** + * Tests autowire enabled is propagated when children are loaded and composite is set to use inherited autowire + * settings + */ + public void testAutowireContextEnabledInheritedPropagation() throws Exception { + LoaderRegistry registry = EasyMock.createMock(LoaderRegistry.class); + registry.load(EasyMock.isA(ModelObject.class), + EasyMock.isA(XMLStreamReader.class), + EasyMock.isA(DeploymentContext.class)); + EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() { + public Object answer() throws Throwable { + DeploymentContext context = (DeploymentContext) EasyMock.getCurrentArguments()[2]; + assertTrue("autowire not propagated", context.isAutowire()); + return null; + } + }); + EasyMock.replay(registry); + DeploymentContext context = new RootDeploymentContext(null, null, null, null, null, true); + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getAttributeValue(null, "name")).andReturn(name.getLocalPart()); + EasyMock.expect(reader.getAttributeValue(null, "targetNamespace")).andReturn(name.getNamespaceURI()); + EasyMock.expect(reader.getAttributeValue(null, "autowire")).andReturn(null); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.START_ELEMENT); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.expect(reader.getName()).andReturn(COMPOSITE); + EasyMock.replay(reader); + loader.load(null, reader, context); + assertTrue(context.isAutowire()); + } + + /** + * Tests autowire false is propagated when children are loaded and composite inherits autowire settings + */ + public void testAutowireFalseContextPropagation() throws Exception { + LoaderRegistry registry = EasyMock.createMock(LoaderRegistry.class); + registry.load(EasyMock.isA(ModelObject.class), + EasyMock.isA(XMLStreamReader.class), + EasyMock.isA(DeploymentContext.class)); + EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() { + public Object answer() throws Throwable { + DeploymentContext context = (DeploymentContext) EasyMock.getCurrentArguments()[2]; + assertFalse("autowire not propagated", context.isAutowire()); + return null; + } + }); + EasyMock.replay(registry); + DeploymentContext context = new RootDeploymentContext(null, null, null, null, null, false); + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getAttributeValue(null, "name")).andReturn(name.getLocalPart()); + EasyMock.expect(reader.getAttributeValue(null, "targetNamespace")).andReturn(name.getNamespaceURI()); + EasyMock.expect(reader.getAttributeValue(null, "autowire")).andReturn(null); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.START_ELEMENT); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.expect(reader.getName()).andReturn(COMPOSITE); + EasyMock.replay(reader); + loader.load(null, reader, context); + assertFalse(context.isAutowire()); + } + + /** + * Tests autowire false is propagated when children are loaded and composite autowire is set to false + */ + public void testAutowireCompositeFalsePropagation() throws Exception { + LoaderRegistry registry = EasyMock.createMock(LoaderRegistry.class); + registry.load(EasyMock.isA(ModelObject.class), + EasyMock.isA(XMLStreamReader.class), + EasyMock.isA(DeploymentContext.class)); + EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() { + public Object answer() throws Throwable { + DeploymentContext context = (DeploymentContext) EasyMock.getCurrentArguments()[2]; + assertFalse("autowire not propagated", context.isAutowire()); + return null; + } + }); + EasyMock.replay(registry); + DeploymentContext context = new RootDeploymentContext(null, null, null, null, null, true); + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getAttributeValue(null, "name")).andReturn(name.getLocalPart()); + EasyMock.expect(reader.getAttributeValue(null, "targetNamespace")).andReturn(name.getNamespaceURI()); + EasyMock.expect(reader.getAttributeValue(null, "autowire")).andReturn("false"); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.START_ELEMENT); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.expect(reader.getName()).andReturn(COMPOSITE); + EasyMock.replay(reader); + loader.load(null, reader, context); + assertTrue(context.isAutowire()); + } + + + protected void setUp() throws Exception { + super.setUp(); + LoaderRegistry registry = EasyMock.createNiceMock(LoaderRegistry.class); + EasyMock.replay(registry); + loader = new CompositeLoader(registry, null); + name = new QName("http://example.com", "composite"); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeLoaderWireResolutionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeLoaderWireResolutionTestCase.java new file mode 100644 index 0000000000..47574c02b6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeLoaderWireResolutionTestCase.java @@ -0,0 +1,230 @@ +/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.implementation.composite;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.loader.InvalidWireException;
+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.model.ReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.apache.tuscany.spi.model.WireDefinition;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.java.JavaImplementation;
+
+/**
+ * This class tests the wire resolution function of the composite loader
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompositeLoaderWireResolutionTestCase extends TestCase {
+ private CompositeComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> componentType;
+ private CompositeLoader compositeLoader = new CompositeLoader(null, null);
+
+ public void testCompositeSvc2CompositeReferenceWire() throws Exception {
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("compositeService1"));
+ wireDefn.setTarget(new URI("compositeReference"));
+ componentType.add(wireDefn);
+ compositeLoader.resolveWires(componentType);
+ }
+
+ public void testCompositeSvc2ComponentValid() throws Exception {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("compositeService1"));
+ wireDefn.setTarget(new URI("Component1"));
+ componentType.add(wireDefn);
+ compositeLoader.resolveWires(componentType);
+ }
+
+ public void testCompositeSvc2ComponentQualifiedValid() throws Exception {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("compositeService1"));
+ wireDefn.setTarget(new URI("Component2#pojoSvc3"));
+ componentType.add(wireDefn);
+ compositeLoader.resolveWires(componentType);
+ }
+
+ public void testCompositeSvc2ComponentQualifiedInvalid() throws URISyntaxException {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("compositeService1"));
+ wireDefn.setTarget(new URI("Component2#pojoSvc5"));
+ componentType.add(wireDefn);
+ try {
+ compositeLoader.resolveWires(componentType);
+ fail();
+ } catch (InvalidWireException e) {
+ // expected
+ }
+ }
+
+ public void testCompositeSvc2ComponentUnQualifiedInvalid() throws URISyntaxException {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("compositeService1"));
+ wireDefn.setTarget(new URI("Component2"));
+ componentType.add(wireDefn);
+ try {
+ compositeLoader.resolveWires(componentType);
+ fail();
+ } catch (InvalidWireException e) {
+ // expected
+ }
+ }
+
+ public void testComponent2CompositeReferenceValid() throws Exception {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("Component1#pojoRef1"));
+ wireDefn.setTarget(new URI("compositeReference"));
+ componentType.add(wireDefn);
+ compositeLoader.resolveWires(componentType);
+ }
+
+ public void testComponent2CompositeReferenceQualifiedValid() throws Exception {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("Component2#pojoRef3"));
+ wireDefn.setTarget(new URI("compositeReference"));
+ componentType.add(wireDefn);
+ compositeLoader.resolveWires(componentType);
+ }
+
+ public void testComponent2CompositeReferenceUnQualifiedInvalid() throws URISyntaxException {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("Component2"));
+ wireDefn.setTarget(new URI("compositeReference"));
+ componentType.add(wireDefn);
+
+ try {
+ compositeLoader.resolveWires(componentType);
+ fail();
+ } catch (InvalidWireException e) {
+ // expected
+ }
+ }
+
+ public void testComponent2ComponentQualifedValid() throws Exception {
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("Component1#pojoRef1"));
+ wireDefn.setTarget(new URI("Component2#pojoSvc3"));
+ componentType.add(wireDefn);
+ compositeLoader.resolveWires(componentType);
+ }
+
+ public void testComponent2ComponentUnQualifedInvalid() throws URISyntaxException {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("Component1"));
+ wireDefn.setTarget(new URI("Component2"));
+ componentType.add(wireDefn);
+ try {
+ compositeLoader.resolveWires(componentType);
+ fail();
+ } catch (InvalidWireException e) {
+ // expected
+ }
+ }
+
+ public void testInvalidWireDefinitions() throws URISyntaxException {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("undefinedSource"));
+ wireDefn.setTarget(new URI("compositeReference"));
+ componentType.add(wireDefn);
+
+ try {
+ compositeLoader.resolveWires(componentType);
+ fail();
+ } catch (InvalidWireException e) {
+ // expected
+ }
+
+ try {
+ wireDefn.setSource(new URI("compositeService1"));
+ wireDefn.setTarget(new URI("undefinedTarget"));
+ componentType.add(wireDefn);
+ compositeLoader.resolveWires(componentType);
+ fail();
+ } catch (InvalidWireException e) {
+ // expected
+ }
+ }
+
+ public void setUp() throws Exception {
+ componentType = new CompositeComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>();
+
+ //add a service to the composite
+ ServiceDefinition serviceDefn = new ServiceDefinition(URI.create("#compositeService1"), null, true);
+ ServiceDefinition boundSvcDefn = new ServiceDefinition(URI.create("#boundSvc"), null, true, null);
+ ServiceDefinition boundSvcDefnWithTarget =
+ new ServiceDefinition(URI.create("#boundSvcWithTarget"), null, true);
+ boundSvcDefnWithTarget.setTarget(new URI("orgTarget"));
+ componentType.add(serviceDefn);
+ componentType.add(boundSvcDefn);
+ componentType.add(boundSvcDefnWithTarget);
+
+ ReferenceDefinition compositeReference = new ReferenceDefinition(URI.create("#compositeReference"), null);
+ componentType.add(compositeReference);
+
+ PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> pojoComponentType1 =
+ new PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>();
+ ServiceDefinition pojoSvc1 = new ServiceDefinition(URI.create("#pojoSvc1"), null, false);
+ pojoComponentType1.add(pojoSvc1);
+ ReferenceDefinition pojoRef1 = new ReferenceDefinition(URI.create("#pojoRef1"), null);
+ pojoComponentType1.add(pojoRef1);
+ JavaImplementation pojoImpl1 = new JavaImplementation(null, pojoComponentType1);
+
+ URI uri = URI.create("Component1");
+ ComponentDefinition<JavaImplementation> component1 =
+ new ComponentDefinition<JavaImplementation>(uri, pojoImpl1);
+ componentType.add(component1);
+
+ PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> pojoComponentType2 =
+ new PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>();
+ ServiceDefinition pojoSvc2 = new ServiceDefinition(URI.create("#pojoSvc2"), null, false);
+ pojoComponentType2.add(pojoSvc2);
+ ServiceDefinition pojoSvc3 = new ServiceDefinition(URI.create("#pojoSvc3"), null, false);
+ pojoComponentType2.add(pojoSvc3);
+ ReferenceDefinition pojoRef2 = new ReferenceDefinition(URI.create("#pojoRef2"), null);
+ pojoComponentType2.add(pojoRef2);
+ ReferenceDefinition pojoRef3 = new ReferenceDefinition(URI.create("#pojoRef3"), null);
+ pojoComponentType2.add(pojoRef3);
+ JavaImplementation pojoImpl2 = new JavaImplementation(null, pojoComponentType2);
+
+ URI uri2 = URI.create("Component2");
+ ComponentDefinition<JavaImplementation> component2 =
+ new ComponentDefinition<JavaImplementation>(uri2, pojoImpl2);
+ componentType.add(component2);
+ }
+
+
+
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/DuplicateRegistrationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/DuplicateRegistrationTestCase.java new file mode 100644 index 0000000000..c3394c1043 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/DuplicateRegistrationTestCase.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.core.implementation.composite; + +import java.net.URI; + +import org.apache.tuscany.spi.component.DuplicateNameException; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.Component; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * Verfies children with the same name cannot be registered in the same composite + * + * @version $Rev$ $Date$ + */ +public class DuplicateRegistrationTestCase extends TestCase { + + public void testDuplicateServiceRegistration() throws Exception { + Component parent = new CompositeComponentImpl(URI.create("parent")); + parent.start(); + + Service service1 = EasyMock.createMock(Service.class); + EasyMock.expect(service1.getUri()).andReturn(URI.create("#service")).atLeastOnce(); + service1.stop(); + EasyMock.replay(service1); + + Service service2 = EasyMock.createMock(Service.class); + EasyMock.expect(service2.getUri()).andReturn(URI.create("#service")).atLeastOnce(); + service2.stop(); + EasyMock.replay(service2); + + parent.register(service2); + try { + parent.register(service1); + fail(); + } catch (DuplicateNameException e) { + // ok + } + parent.stop(); + } + + public void testDuplicateReferenceRegistration() throws Exception { + Component parent = new CompositeComponentImpl(URI.create("parent")); + parent.start(); + + Reference reference1 = EasyMock.createMock(Reference.class); + EasyMock.expect(reference1.getUri()).andReturn(URI.create("#reference")).atLeastOnce(); + reference1.stop(); + EasyMock.replay(reference1); + + Reference reference2 = EasyMock.createMock(Reference.class); + EasyMock.expect(reference2.getUri()).andReturn(URI.create("#reference")).atLeastOnce(); + reference2.stop(); + EasyMock.replay(reference2); + + parent.register(reference2); + try { + parent.register(reference1); + fail(); + } catch (DuplicateNameException e) { + // ok + } + parent.stop(); + + } + + public void testDuplicateServiceReferenceRegistration() throws Exception { + Component parent = new CompositeComponentImpl(URI.create("parent")); + parent.start(); + + Service service1 = EasyMock.createMock(Service.class); + EasyMock.expect(service1.getUri()).andReturn(URI.create("#child")).atLeastOnce(); + service1.stop(); + EasyMock.replay(service1); + + Reference service2 = EasyMock.createMock(Reference.class); + EasyMock.expect(service2.getUri()).andReturn(URI.create("#child")).atLeastOnce(); + service2.stop(); + EasyMock.replay(service2); + + parent.register(service2); + try { + parent.register(service1); + fail(); + } catch (DuplicateNameException e) { + // ok + } + parent.stop(); + + } + + protected void setUp() throws Exception { + super.setUp(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/ImplementationCompositeLoaderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/ImplementationCompositeLoaderTestCase.java new file mode 100644 index 0000000000..f0207a168a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/ImplementationCompositeLoaderTestCase.java @@ -0,0 +1,194 @@ +/* + * 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.core.implementation.composite; + +import java.net.MalformedURLException; +import java.net.URL; +import javax.xml.namespace.QName; +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import static org.osoa.sca.Constants.SCA_NS; + +import org.apache.tuscany.spi.deployer.CompositeClassLoader; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.model.CompositeImplementation; +import org.apache.tuscany.spi.services.artifact.Artifact; +import org.apache.tuscany.spi.services.artifact.ArtifactRepository; + +import junit.framework.TestCase; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.reportMatcher; +import static org.easymock.EasyMock.verify; +import org.easymock.IArgumentMatcher; + +/** + * @version $Rev$ $Date$ + */ +public class ImplementationCompositeLoaderTestCase extends TestCase { + private static final QName IMPLEMENTATION_COMPOSITE = new QName(SCA_NS, "implementation.composite"); + + private ClassLoader cl; + private ImplementationCompositeLoader loader; + private XMLStreamReader reader; + private DeploymentContext context; + private ArtifactRepository artifactRepository; + + public void testName() throws LoaderException, XMLStreamException, MalformedURLException { + String name = "foo"; + expect(reader.getName()).andReturn(IMPLEMENTATION_COMPOSITE); + expect(reader.getAttributeValue(null, "name")).andReturn(name); + expect(reader.getAttributeValue(null, "group")).andReturn(null); + expect(reader.getAttributeValue(null, "version")).andReturn(null); + expect(reader.getAttributeValue(null, "scdlLocation")).andReturn(null); + expect(reader.getAttributeValue(null, "jarLocation")).andReturn(null); + expect(reader.next()).andReturn(END_ELEMENT); + replay(reader); + + replay(context); + replay(artifactRepository); + + CompositeImplementation impl = loader.load(null, reader, context); + verify(reader); + verify(context); + verify(artifactRepository); + assertEquals(name, impl.getName()); + assertNull(impl.getScdlLocation()); + assertNull(impl.getClassLoader()); + } + + public void testWithArtifact() throws LoaderException, XMLStreamException, MalformedURLException { + String name = "foo"; + expect(reader.getName()).andReturn(IMPLEMENTATION_COMPOSITE); + expect(reader.getAttributeValue(null, "name")).andReturn(name); + expect(reader.getAttributeValue(null, "group")).andReturn("com.example"); + expect(reader.getAttributeValue(null, "version")).andReturn("1.0"); + expect(reader.getAttributeValue(null, "scdlLocation")).andReturn(null); + expect(reader.getAttributeValue(null, "jarLocation")).andReturn(null); + expect(reader.next()).andReturn(END_ELEMENT); + replay(reader); + + expect(context.getClassLoader()).andReturn(cl); + replay(context); + URL url = new URL("http://www.example.com/sca/base.jar"); + artifactRepository.resolve(artifactMatcher(url, "com.example", name, "1.0")); + replay(artifactRepository); + + CompositeImplementation impl = loader.load(null, reader, context); + verify(reader); + verify(context); + verify(artifactRepository); + assertEquals(name, impl.getName()); + assertEquals(new URL("jar:http://www.example.com/sca/base.jar!/META-INF/sca/default.scdl"), + impl.getScdlLocation()); + assertTrue(impl.getClassLoader() instanceof CompositeClassLoader); + } + + public void testWithScdlLocation() throws LoaderException, XMLStreamException, MalformedURLException { + String name = "foo"; + expect(reader.getName()).andReturn(IMPLEMENTATION_COMPOSITE); + expect(reader.getAttributeValue(null, "name")).andReturn(name); + expect(reader.getAttributeValue(null, "group")).andReturn(null); + expect(reader.getAttributeValue(null, "version")).andReturn(null); + expect(reader.getAttributeValue(null, "scdlLocation")).andReturn("bar.scdl"); + expect(reader.getAttributeValue(null, "jarLocation")).andReturn(null); + expect(reader.next()).andReturn(END_ELEMENT); + replay(reader); + + expect(context.getScdlLocation()).andReturn(new URL("http://www.example.com/sca/base.scdl")); + expect(context.getClassLoader()).andReturn(cl); + replay(context); + replay(artifactRepository); + + CompositeImplementation impl = loader.load(null, reader, context); + verify(reader); + verify(context); + verify(artifactRepository); + assertEquals(name, impl.getName()); + assertEquals(new URL("http://www.example.com/sca/bar.scdl"), impl.getScdlLocation()); + assertSame(cl, impl.getClassLoader()); + } + + public void testWithJarLocation() throws LoaderException, XMLStreamException, MalformedURLException { + String name = "foo"; + expect(reader.getName()).andReturn(IMPLEMENTATION_COMPOSITE); + expect(reader.getAttributeValue(null, "name")).andReturn(name); + expect(reader.getAttributeValue(null, "group")).andReturn(null); + expect(reader.getAttributeValue(null, "version")).andReturn(null); + expect(reader.getAttributeValue(null, "scdlLocation")).andReturn(null); + expect(reader.getAttributeValue(null, "jarLocation")).andReturn("bar.jar"); + expect(reader.next()).andReturn(END_ELEMENT); + replay(reader); + + expect(context.getScdlLocation()).andReturn(new URL("http://www.example.com/sca/base.scdl")); + expect(context.getClassLoader()).andReturn(cl); + replay(context); + replay(artifactRepository); + + CompositeImplementation impl = loader.load(null, reader, context); + verify(reader); + verify(context); + verify(artifactRepository); + assertEquals(name, impl.getName()); + assertEquals(new URL("jar:http://www.example.com/sca/bar.jar!/META-INF/sca/default.scdl"), + impl.getScdlLocation()); + } + + protected void setUp() throws Exception { + super.setUp(); + artifactRepository = createMock(ArtifactRepository.class); + reader = createMock(XMLStreamReader.class); + context = createMock(DeploymentContext.class); + cl = getClass().getClassLoader(); + loader = new ImplementationCompositeLoader(null, artifactRepository); + } + + protected static Artifact artifactMatcher(final URL url, + final String group, + final String name, + final String version) { + reportMatcher(new IArgumentMatcher() { + + public boolean matches(Object object) { + if (!(object instanceof Artifact)) { + return false; + } + + Artifact artifact = (Artifact) object; + boolean match = group.equals(artifact.getGroup()) + && name.equals(artifact.getName()) + && version.equals(artifact.getVersion()) + && "jar".equals(artifact.getType()); + if (match) { + artifact.setUrl(url); + } + return match; + } + + public void appendTo(StringBuffer stringBuffer) { + stringBuffer.append(group).append(':').append(name).append(':').append(version); + } + }); + return null; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/ManagedRequestContextTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/ManagedRequestContextTestCase.java new file mode 100644 index 0000000000..12299e762b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/ManagedRequestContextTestCase.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.core.implementation.composite; + +import org.osoa.sca.RequestContext; + +import org.apache.tuscany.spi.component.WorkContext; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ManagedRequestContextTestCase extends TestCase { + + public void testGetServiceName() { + WorkContext workContext = EasyMock.createMock(WorkContext.class); + EasyMock.expect(workContext.getCurrentServiceName()).andReturn("foo"); + EasyMock.replay(workContext); + RequestContext context = new ManagedRequestContext(workContext); + assertEquals("foo", context.getServiceName()); + EasyMock.verify(workContext); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/ReferenceImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/ReferenceImplTestCase.java new file mode 100644 index 0000000000..34d37469a7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/ReferenceImplTestCase.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.core.implementation.composite; + +import java.net.URI; + +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.ReferenceBinding; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ReferenceImplTestCase extends TestCase { + + public void testStart() { + ReferenceBinding binding = EasyMock.createMock(ReferenceBinding.class); + binding.start(); + EasyMock.replay(binding); + Reference reference = new ReferenceImpl(URI.create("ref"), null); + reference.addReferenceBinding(binding); + reference.start(); + EasyMock.verify(binding); + + } + + public void testStop() { + ReferenceBinding binding = EasyMock.createMock(ReferenceBinding.class); + binding.stop(); + EasyMock.replay(binding); + Reference reference = new ReferenceImpl(URI.create("ref"), null); + reference.addReferenceBinding(binding); + reference.stop(); + EasyMock.verify(binding); + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/ServiceImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/ServiceImplTestCase.java new file mode 100644 index 0000000000..bb8ed020e0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/ServiceImplTestCase.java @@ -0,0 +1,56 @@ +/* + * 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.core.implementation.composite; + +import java.net.URI; + +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.component.ServiceBinding; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ServiceImplTestCase extends TestCase { + + public void testStart() { + ServiceBinding binding = EasyMock.createMock(ServiceBinding.class); + binding.start(); + EasyMock.replay(binding); + Service service = new ServiceImpl(URI.create("foo#bar"), null, null); + service.addServiceBinding(binding); + service.start(); + EasyMock.verify(binding); + + } + + public void testStop() { + ServiceBinding binding = EasyMock.createMock(ServiceBinding.class); + binding.stop(); + EasyMock.replay(binding); + Service service = new ServiceImpl(URI.create("foo#bar"), null, null); + service.addServiceBinding(binding); + service.stop(); + EasyMock.verify(binding); + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/SystemComponentBuilderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/SystemComponentBuilderTestCase.java new file mode 100644 index 0000000000..7ee6583df7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/composite/SystemComponentBuilderTestCase.java @@ -0,0 +1,182 @@ +/* + * 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.core.implementation.composite; + +import java.lang.reflect.Method; +import java.net.URI; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.PropertyValue; +import org.apache.tuscany.spi.model.Scope; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.event.ComponentStart; +import org.apache.tuscany.core.component.event.ComponentStop; +import org.apache.tuscany.core.component.scope.CompositeScopeContainer; +import org.apache.tuscany.core.implementation.system.builder.SystemComponentBuilder; +import org.apache.tuscany.core.implementation.system.model.SystemImplementation; +import org.apache.tuscany.core.injection.SingletonObjectFactory; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class SystemComponentBuilderTestCase extends TestCase { + Component parent; + DeploymentContext deploymentContext; + SystemComponentBuilder builder = new SystemComponentBuilder(); + CompositeScopeContainer container; + + /** + * Verifies lifecycle callbacks are made + */ + public void testLifecycleBuild() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + type.setInitLevel(50); + Method initMethod = FooImpl.class.getMethod("init"); + initMethod.setAccessible(true); + type.setInitMethod(initMethod); + Method destroyMethod = FooImpl.class.getMethod("destroy"); + destroyMethod.setAccessible(true); + type.setDestroyMethod(destroyMethod); + type.setImplementationScope(Scope.COMPOSITE); + ConstructorDefinition<FooImpl> ctorDef = new ConstructorDefinition<FooImpl>(FooImpl.class.getConstructor()); + type.setConstructorDefinition(ctorDef); + SystemImplementation impl = new SystemImplementation(); + impl.setComponentType(type); + impl.setImplementationClass(FooImpl.class); + ComponentDefinition<SystemImplementation> definition = new ComponentDefinition<SystemImplementation>(impl); + definition.setUri(URI.create("component")); + AtomicComponent component = builder.build(definition, deploymentContext); + component.setScopeContainer(container); + component.start(); + container.onEvent(new ComponentStart(this, null)); + FooImpl foo = (FooImpl) component.getTargetInstance(); + assertTrue(foo.initialized); + container.onEvent(new ComponentStop(this, null)); + assertTrue(foo.destroyed); + } + + /** + * Verifies properties are built properly + */ + public void testPropertyBuild() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + type.setInitLevel(50); + Method initMethod = FooImpl.class.getMethod("init"); + initMethod.setAccessible(true); + type.setInitMethod(initMethod); + Method destroyMethod = FooImpl.class.getMethod("destroy"); + destroyMethod.setAccessible(true); + type.setDestroyMethod(destroyMethod); + type.setImplementationScope(Scope.COMPOSITE); + JavaMappedProperty mappedProp = new JavaMappedProperty(); + mappedProp.setName("prop"); + Method propMethod = FooImpl.class.getMethod("setProp", String.class); + propMethod.setAccessible(true); + mappedProp.setMember(propMethod); + type.add(mappedProp); + ConstructorDefinition<FooImpl> ctorDef = new ConstructorDefinition<FooImpl>(FooImpl.class.getConstructor()); + type.setConstructorDefinition(ctorDef); + SystemImplementation impl = new SystemImplementation(); + impl.setComponentType(type); + impl.setImplementationClass(FooImpl.class); + ComponentDefinition<SystemImplementation> definition = new ComponentDefinition<SystemImplementation>(impl); + definition.setUri(URI.create("component")); + PropertyValue<String> propVal = new PropertyValue<String>(); + propVal.setName("prop"); + propVal.setValueFactory(new SingletonObjectFactory<String>("value")); + definition.add(propVal); + AtomicComponent component = builder.build(definition, deploymentContext); + component.setScopeContainer(container); + component.start(); + FooImpl foo = (FooImpl) component.getTargetInstance(); + assertEquals("value", foo.prop); + container.onEvent(new ComponentStop(this, null)); + } + + protected void setUp() throws Exception { + super.setUp(); + parent = EasyMock.createNiceMock(Component.class); + container = new CompositeScopeContainer(null); + container.start(); + deploymentContext = EasyMock.createMock(DeploymentContext.class); + EasyMock.expect(deploymentContext.getCompositeScope()).andReturn(container).atLeastOnce(); + EasyMock.replay(deploymentContext); + } + + private static interface Foo { + + } + + private static class FooImpl implements Foo { + private boolean initialized; + private boolean destroyed; + private String prop; + private Foo ref; + + public FooImpl() { + } + + public void init() { + if (initialized) { + fail(); + } + initialized = true; + } + + public void destroy() { + if (destroyed) { + fail(); + } + destroyed = true; + } + + public boolean isInitialized() { + return initialized; + } + + public String getProp() { + return prop; + } + + public void setProp(String prop) { + this.prop = prop; + } + + public Foo getRef() { + return ref; + } + + public void setRef(Foo ref) { + this.ref = ref; + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponentMetadataInjectionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponentMetadataInjectionTestCase.java new file mode 100644 index 0000000000..5186119345 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponentMetadataInjectionTestCase.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.core.implementation.java; + +import junit.framework.TestCase; + +/** + * Tests SCA metadata such as <code>@ComponentName</code> and <code>@SCAObject</code> are handled properly + * + * @version $Rev$ $Date$ + */ +public class JavaAtomicComponentMetadataInjectionTestCase extends TestCase { + + public void testComponentNameSet() throws Exception { + // TODO implement + } + + public void testCompositeContextSet() throws Exception { + // TODO implement + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponentNegativeMetadataTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponentNegativeMetadataTestCase.java new file mode 100644 index 0000000000..dfd62c8c53 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponentNegativeMetadataTestCase.java @@ -0,0 +1,49 @@ +/* + * 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.core.implementation.java; + +import junit.framework.TestCase; + + +/** + * Performs rudimentary negative testing by using malformed metadata on a POJO + * + * @version $Rev $Date + */ +public class JavaAtomicComponentNegativeMetadataTestCase extends TestCase { + + /** + * Tests that a pojo with <code>@ComponentName</code> specified on a non-String type generates an error. + * <p/> + * <strong>NB:</strong> the test assumes an error with a message containing "@ComponentName" is generated + */ + public void testBadNameType() throws Exception { + // TODO implement + } + + /** + * Tests that a pojo with <code>@Context</code> specified on a non-CompositeContext type generates an error. + * <p/> + * <strong>NB:</strong> the test assumes an error with a message containing "@Context" is generated + */ + public void testContextType() throws Exception { + // TODO implement + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaBuilderPropertyTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaBuilderPropertyTestCase.java new file mode 100644 index 0000000000..5788526942 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaBuilderPropertyTestCase.java @@ -0,0 +1,139 @@ +/* + * 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.core.implementation.java; + +import java.net.URI; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.ScopeRegistry; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.PropertyValue; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; +import org.apache.tuscany.core.injection.SingletonObjectFactory; +import org.easymock.EasyMock; + +/** + * Verifies that the java component builder handles configured properties correctly + * + * @version $Rev$ $Date$ + */ +public class JavaBuilderPropertyTestCase extends TestCase { + private DeploymentContext deploymentContext; + private Component parent; + private ScopeRegistry registry; + + @SuppressWarnings("unchecked") + public void testPropertyHandling() throws Exception { + JavaComponentBuilder builder = new JavaComponentBuilder(); + builder.setScopeRegistry(registry); + PojoComponentType<ServiceDefinition, ReferenceDefinition, JavaMappedProperty<?>> type = + new PojoComponentType<ServiceDefinition, ReferenceDefinition, JavaMappedProperty<?>>(); + JavaMappedProperty<String> property = new JavaMappedProperty<String>(); + property.setName("test"); + property.setDefaultValueFactory(new SingletonObjectFactory<String>("foo")); + property.setMember(JavaBuilderPropertyTestCase.Foo.class.getMethod("setTest", String.class)); + type.add(property); + type.setConstructorDefinition(new ConstructorDefinition<Foo>(Foo.class.getConstructor((Class[]) null))); + type.setImplementationScope(Scope.STATELESS); + JavaImplementation impl = new JavaImplementation(Foo.class, type); + ComponentDefinition<JavaImplementation> definition = new ComponentDefinition<JavaImplementation>(impl); + definition.setUri(URI.create("component")); + PropertyValue propertyValue = new PropertyValue(property.getName(), property.getDefaultValueFactory()); + definition.getPropertyValues().put(property.getName(), propertyValue); + AtomicComponent component = builder.build(definition, deploymentContext); + JavaBuilderPropertyTestCase.Foo foo = (JavaBuilderPropertyTestCase.Foo) component.createInstance(); + assertEquals("foo", foo.getTest()); + } + + public void testIntPropertyHandling() throws Exception { + JavaComponentBuilder builder = new JavaComponentBuilder(); + builder.setScopeRegistry(registry); + PojoComponentType<ServiceDefinition, ReferenceDefinition, JavaMappedProperty<?>> type = + new PojoComponentType<ServiceDefinition, ReferenceDefinition, JavaMappedProperty<?>>(); + JavaMappedProperty<Integer> property = new JavaMappedProperty<Integer>(); + property.setName("test"); + property.setDefaultValueFactory(new SingletonObjectFactory<Integer>(1)); + property.setMember(JavaBuilderPropertyTestCase.FooInt.class.getMethod("setTest", Integer.TYPE)); + type.add(property); + type.setConstructorDefinition(new ConstructorDefinition<FooInt>(FooInt.class.getConstructor((Class[]) null))); + type.setImplementationScope(Scope.STATELESS); + JavaImplementation impl = new JavaImplementation(Foo.class, type); + ComponentDefinition<JavaImplementation> definition = new ComponentDefinition<JavaImplementation>(impl); + definition.setUri(URI.create("component")); + ObjectFactory<Integer> defaultValueFactory = property.getDefaultValueFactory(); + PropertyValue<Integer> propertyValue = new PropertyValue<Integer>(property.getName(), defaultValueFactory); + definition.getPropertyValues().put(property.getName(), propertyValue); + AtomicComponent component = builder.build(definition, deploymentContext); + FooInt foo = (FooInt) component.createInstance(); + assertEquals(1, foo.getTest()); + } + + protected void setUp() throws Exception { + super.setUp(); + deploymentContext = EasyMock.createMock(DeploymentContext.class); + EasyMock.replay(deploymentContext); + parent = EasyMock.createNiceMock(Component.class); + ScopeContainer mockContainer = EasyMock.createNiceMock(ScopeContainer.class); + EasyMock.replay(mockContainer); + registry = EasyMock.createMock(ScopeRegistry.class); + EasyMock.expect(registry.getScopeContainer(EasyMock.isA(Scope.class))).andReturn(mockContainer); + EasyMock.replay(registry); + } + + private static class Foo { + private String test; + + public Foo() { + } + + public String getTest() { + return test; + } + + public void setTest(String test) { + this.test = test; + } + } + + private static class FooInt { + private int test; + + public FooInt() { + } + + public int getTest() { + return test; + } + + public void setTest(int test) { + this.test = test; + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderConversationIDTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderConversationIDTestCase.java new file mode 100644 index 0000000000..0993db0afc --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderConversationIDTestCase.java @@ -0,0 +1,81 @@ +/*
+ * 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.core.implementation.java;
+
+import java.lang.reflect.Field;
+import java.net.URI;
+
+import org.osoa.sca.annotations.ConversationID;
+
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev: 473859 $ $Date: 2006-11-11 22:31:55 -0500 (Sat, 11 Nov 2006) $
+ */
+public class JavaComponentBuilderConversationIDTestCase extends TestCase {
+
+ @SuppressWarnings("unchecked")
+ public void testResourceInjection() throws Exception {
+ ScopeContainer container = EasyMock.createNiceMock(ScopeContainer.class);
+ ScopeRegistry registry = EasyMock.createMock(ScopeRegistry.class);
+ EasyMock.expect(registry.getScopeContainer(Scope.STATELESS)).andReturn(container);
+ EasyMock.replay(registry);
+ JavaComponentBuilder builder = new JavaComponentBuilder();
+ builder.setScopeRegistry(registry);
+ WorkContext workContext = new WorkContextImpl();
+ workContext.setIdentifier(Scope.CONVERSATION, "convID");
+ builder.setWorkContext(workContext);
+
+ ConstructorDefinition<Foo> ctorDef = new ConstructorDefinition<Foo>(Foo.class.getConstructor());
+ PojoComponentType type = new PojoComponentType();
+ Field field = Foo.class.getDeclaredField("conversationID");
+ type.setConversationIDMember(field);
+ type.setImplementationScope(Scope.STATELESS);
+ type.setConstructorDefinition(ctorDef);
+
+ JavaImplementation impl = new JavaImplementation(Foo.class, type);
+ URI uri = URI.create("foo");
+ ComponentDefinition<JavaImplementation> definition = new ComponentDefinition<JavaImplementation>(uri, impl);
+ JavaAtomicComponent component = (JavaAtomicComponent) builder.build(definition, null);
+ Foo foo = (Foo) component.createInstance();
+ assertEquals("convID", foo.conversationID);
+ }
+
+ private static class Foo {
+
+ @ConversationID
+ protected String conversationID;
+
+ public Foo() {
+ }
+
+ }
+}
+
+
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderMetadataTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderMetadataTestCase.java new file mode 100644 index 0000000000..16d8518cfe --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderMetadataTestCase.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.core.implementation.java; + +import java.lang.reflect.Constructor; +import java.net.URI; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceContract; + +import junit.framework.TestCase; +import org.apache.tuscany.core.implementation.composite.CompositeComponentImpl; +import org.apache.tuscany.core.mock.component.Source; +import org.apache.tuscany.core.mock.component.SourceImpl; +import org.apache.tuscany.core.mock.component.Target; +import org.easymock.EasyMock; + +/** + * Verifies component type metadata is properly applied to the component + * + * @version $$Rev$$ $$Date$$ + */ +public class JavaComponentBuilderMetadataTestCase extends TestCase { + private DeploymentContext deploymentContext; + private Constructor<SourceImpl> constructor; + private Component parent; + private PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type; + private ComponentDefinition<JavaImplementation> definition; + private ScopeContainer scopeContainer; + + public void testInitLevel() throws Exception { + type.setInitLevel(1); + JavaComponentBuilder builder = new JavaComponentBuilder(); + JavaAtomicComponent component = (JavaAtomicComponent) builder.build(definition, deploymentContext); + assertEquals(1, component.getInitLevel()); + } + + public void testMaxAge() throws Exception { + type.setMaxAge(100); + JavaComponentBuilder builder = new JavaComponentBuilder(); + JavaAtomicComponent component = (JavaAtomicComponent) builder.build(definition, deploymentContext); + assertEquals(100, component.getMaxAge()); + } + + public void testMaxIdleTime() throws Exception { + type.setMaxIdleTime(100); + JavaComponentBuilder builder = new JavaComponentBuilder(); + JavaAtomicComponent component = (JavaAtomicComponent) builder.build(definition, deploymentContext); + assertEquals(100, component.getMaxIdleTime()); + } + + public void testNoMaxAgeNoMaxIdleTime() throws Exception { + JavaComponentBuilder builder = new JavaComponentBuilder(); + JavaAtomicComponent component = (JavaAtomicComponent) builder.build(definition, deploymentContext); + assertEquals(-1, component.getMaxAge()); + assertEquals(-1, component.getMaxIdleTime()); + } + + public void testScope() throws Exception { + JavaComponentBuilder builder = new JavaComponentBuilder(); + JavaAtomicComponent component = (JavaAtomicComponent) builder.build(definition, deploymentContext); + component.setScopeContainer(scopeContainer); + assertEquals(Scope.COMPOSITE, component.getScope()); + } + + protected void setUp() throws Exception { + super.setUp(); + parent = new CompositeComponentImpl(URI.create("parent")); + constructor = SourceImpl.class.getConstructor((Class[]) null); + createDeploymentContext(); + createComponentDefinitionAndType(); + } + + + private void createDeploymentContext() { + scopeContainer = EasyMock.createMock(ScopeContainer.class); + scopeContainer.start(); + scopeContainer.stop(); + scopeContainer.register(EasyMock.isA(AtomicComponent.class)); + EasyMock.expectLastCall().atLeastOnce(); + EasyMock.expect(scopeContainer.getScope()).andReturn(Scope.COMPOSITE).atLeastOnce(); + EasyMock.replay(scopeContainer); + deploymentContext = EasyMock.createMock(DeploymentContext.class); + EasyMock.replay(deploymentContext); + } + + private void createComponentDefinitionAndType() throws Exception { + type = new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + type.setImplementationScope(Scope.COMPOSITE); + JavaMappedReference reference = new JavaMappedReference(); + reference.setUri(URI.create("#target")); + reference.setMember(SourceImpl.class.getMethod("setTarget", Target.class)); + type.add(reference); + ServiceContract<?> contract = new JavaServiceContract(Source.class); + JavaMappedService serviceDefinition = new JavaMappedService(); + serviceDefinition.setUri(URI.create("component#Source")); + serviceDefinition.setServiceContract(contract); + type.add(serviceDefinition); + type.setConstructorDefinition(new ConstructorDefinition<SourceImpl>(constructor)); + JavaImplementation sourceImpl = new JavaImplementation(SourceImpl.class, type); + definition = new ComponentDefinition<JavaImplementation>(sourceImpl); + definition.setUri(URI.create("component")); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderReferenceTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderReferenceTestCase.java new file mode 100644 index 0000000000..3021ccb4c6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderReferenceTestCase.java @@ -0,0 +1,145 @@ +/* + * 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.core.implementation.java; + +import java.lang.reflect.Constructor; +import java.net.URI; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; +import org.apache.tuscany.spi.wire.ProxyService; + +import junit.framework.TestCase; +import org.apache.tuscany.core.implementation.composite.CompositeComponentImpl; +import org.apache.tuscany.core.mock.component.Source; +import org.apache.tuscany.core.mock.component.SourceImpl; +import org.apache.tuscany.core.mock.component.Target; +import org.apache.tuscany.core.wire.jdk.JDKProxyService; +import org.easymock.EasyMock; +import org.easymock.IAnswer; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class JavaComponentBuilderReferenceTestCase extends TestCase { + private DeploymentContext deploymentContext; + private ProxyService proxyService; + private Constructor<SourceImpl> constructor; + private Component parent; + private Wire wire; + private ScopeContainer scopeContainer; + + public void testBuildReference() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> sourceType = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + sourceType.setImplementationScope(Scope.COMPOSITE); + JavaMappedReference reference = new JavaMappedReference(); + reference.setUri(URI.create("#target")); + reference.setMember(SourceImpl.class.getMethod("setTarget", Target.class)); + sourceType.add(reference); + ServiceContract<?> contract = new JavaServiceContract(Source.class); + JavaMappedService serviceDefinition = new JavaMappedService(); + serviceDefinition.setUri(URI.create("#Source")); + serviceDefinition.setServiceContract(contract); + sourceType.add(serviceDefinition); + sourceType.setConstructorDefinition(new ConstructorDefinition<SourceImpl>(constructor)); + JavaImplementation sourceImpl = new JavaImplementation(SourceImpl.class, sourceType); + ComponentDefinition<JavaImplementation> definition = new ComponentDefinition<JavaImplementation>(sourceImpl); + definition.setUri(URI.create("component")); + JavaComponentBuilder builder = new JavaComponentBuilder(); + builder.setProxyService(proxyService); + JavaAtomicComponent component = (JavaAtomicComponent) builder.build(definition, deploymentContext); + component.setScopeContainer(scopeContainer); + component.attachWire(wire); + deploymentContext.getCompositeScope().start(); + component.start(); + + Source source = (Source) component.getTargetInstance(); + assertNotNull(source.getTarget()); + component.stop(); + } + + protected void setUp() throws Exception { + super.setUp(); + proxyService = new JDKProxyService(); + parent = new CompositeComponentImpl(URI.create("parent")); + constructor = SourceImpl.class.getConstructor((Class[]) null); + createDeploymentContext(); + createWire(); + } + + + private void createDeploymentContext() throws Exception { + scopeContainer = EasyMock.createMock(ScopeContainer.class); + scopeContainer.start(); + scopeContainer.stop(); + scopeContainer.register(EasyMock.isA(AtomicComponent.class)); + EasyMock.expectLastCall().atLeastOnce(); + EasyMock.expect(scopeContainer.getScope()).andReturn(Scope.COMPOSITE).atLeastOnce(); + scopeContainer.getInstance(EasyMock.isA(AtomicComponent.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { + private Map<AtomicComponent, Object> cache = new HashMap<AtomicComponent, Object>(); + + public Object answer() throws Throwable { + AtomicComponent component = (AtomicComponent) EasyMock.getCurrentArguments()[0]; + Object instance = cache.get(component); + if (instance == null) { + instance = component.createInstance(); + cache.put(component, instance); + } + return instance; + } + }).anyTimes(); + EasyMock.replay(scopeContainer); + deploymentContext = EasyMock.createMock(DeploymentContext.class); + EasyMock.expect(deploymentContext.getCompositeScope()).andReturn(scopeContainer).atLeastOnce(); + EasyMock.replay(deploymentContext); + } + + private void createWire() { + Map<Operation<?>, InvocationChain> chains = Collections.emptyMap(); + wire = EasyMock.createMock(Wire.class); + EasyMock.expect(wire.getSourceUri()).andReturn(URI.create("#target")).atLeastOnce(); + EasyMock.expect(wire.getInvocationChains()).andReturn(chains).atLeastOnce(); + EasyMock.expect(wire.isOptimizable()).andReturn(false); + JavaServiceContract targetContract = new JavaServiceContract(Target.class); + targetContract.setConversational(false); + EasyMock.expect(wire.getSourceContract()).andReturn(targetContract).atLeastOnce(); + EasyMock.replay(wire); + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderResourceTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderResourceTestCase.java new file mode 100644 index 0000000000..abfbbe108d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderResourceTestCase.java @@ -0,0 +1,81 @@ +/* + * 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.core.implementation.java; + +import java.net.URI; + +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.ScopeRegistry; +import org.apache.tuscany.spi.host.ResourceHost; +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.Resource; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class JavaComponentBuilderResourceTestCase extends TestCase { + + @SuppressWarnings("unchecked") + public void testResourceInjection() throws Exception { + ScopeContainer container = EasyMock.createNiceMock(ScopeContainer.class); + ScopeRegistry registry = EasyMock.createMock(ScopeRegistry.class); + EasyMock.expect(registry.getScopeContainer(Scope.STATELESS)).andReturn(container); + EasyMock.replay(registry); + ResourceHost host = EasyMock.createMock(ResourceHost.class); + EasyMock.expect(host.resolveResource(EasyMock.eq(String.class))).andReturn("result"); + EasyMock.replay(host); + JavaComponentBuilder builder = new JavaComponentBuilder(); + builder.setHost(host); + builder.setScopeRegistry(registry); + ConstructorDefinition<Foo> ctorDef = new ConstructorDefinition<Foo>(Foo.class.getConstructor()); + PojoComponentType type = new PojoComponentType(); + Resource resource = new Resource("resource", String.class, Foo.class.getDeclaredField("resource")); + type.add(resource); + type.setImplementationScope(Scope.STATELESS); + type.setConstructorDefinition(ctorDef); + JavaImplementation impl = new JavaImplementation(Foo.class, type); + URI uri = URI.create("foo"); + ComponentDefinition<JavaImplementation> definition = new ComponentDefinition<JavaImplementation>(uri, impl); + Wire resourceWire = EasyMock.createMock(Wire.class); + EasyMock.expect(resourceWire.getTargetInstance()).andReturn("result"); + EasyMock.replay(resourceWire); + + JavaAtomicComponent component = (JavaAtomicComponent) builder.build(definition, null); + Foo foo = (Foo) component.createInstance(); + assertEquals("result", foo.resource); + } + + private static class Foo { + + protected String resource; + + public Foo() { + } + + } +} + + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentTypeLoaderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentTypeLoaderTestCase.java new file mode 100644 index 0000000000..92e8946d6f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentTypeLoaderTestCase.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.core.implementation.java; + +import java.net.URL; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.IntrospectionRegistry; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.loader.LoaderRegistry; + +import junit.framework.TestCase; +import org.easymock.EasyMock; +import org.easymock.IAnswer; + +/** + * @version $Rev$ $Date$ + */ +public class JavaComponentTypeLoaderTestCase extends TestCase { + + @SuppressWarnings("unchecked") + public void testPojoComponentTypeCreatedForIntrospection() throws Exception { + IntrospectionRegistry registry = EasyMock.createMock(IntrospectionRegistry.class); + registry.introspect( + (Class) EasyMock.isNull(), + EasyMock.isA(PojoComponentType.class), + (DeploymentContext) EasyMock.isNull()); + EasyMock.expectLastCall().andStubAnswer(new IAnswer() { + public Object answer() throws Throwable { + return EasyMock.getCurrentArguments()[2]; + } + }); + EasyMock.replay(registry); + JavaComponentTypeLoader loader = new JavaComponentTypeLoader(null, registry); + loader.loadByIntrospection(new JavaImplementation(), null); + EasyMock.verify(registry); + } + + @SuppressWarnings("unchecked") + public void testPojoComponentTypeCreatedForSideFileLoadAndReturned() throws Exception { + LoaderRegistry registry = EasyMock.createMock(LoaderRegistry.class); + registry.load( + EasyMock.isA(PojoComponentType.class), + (URL) EasyMock.isNull(), + EasyMock.eq(PojoComponentType.class), + (DeploymentContext) EasyMock.isNull()); + EasyMock.expectLastCall().andStubAnswer(new IAnswer() { + public Object answer() throws Throwable { + return EasyMock.getCurrentArguments()[0]; + } + }); + EasyMock.replay(registry); + JavaComponentTypeLoader loader = new JavaComponentTypeLoader(registry, null); + assertEquals(PojoComponentType.class, loader.loadFromSidefile(null, null).getClass()); + EasyMock.verify(registry); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaReferenceWireTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaReferenceWireTestCase.java new file mode 100644 index 0000000000..fdf293db9b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaReferenceWireTestCase.java @@ -0,0 +1,155 @@ +/* + * 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.core.implementation.java; + +import java.lang.reflect.Constructor; +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; +import org.apache.tuscany.spi.wire.ProxyService; + +import junit.framework.TestCase; +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.injection.PojoObjectFactory; +import org.easymock.EasyMock; +import org.easymock.IAnswer; + +/** + * Validates wiring from a Java atomic context + * + * @version $$Rev$$ $$Date$$ + */ +public class JavaReferenceWireTestCase extends TestCase { + + @SuppressWarnings({"unchecked"}) + public void testReferenceSet() throws Exception { + ScopeContainer scope = createMock(); + scope.start(); + final Target target = new TargetImpl(); + PojoConfiguration configuration = new PojoConfiguration(); + configuration.addReferenceSite("target", SourceImpl.class.getMethod("setTarget", Target.class)); + Constructor<SourceImpl> ctr = SourceImpl.class.getConstructor(); + configuration.setInstanceFactory(new PojoObjectFactory<SourceImpl>(ctr)); + Wire wire = EasyMock.createMock(Wire.class); + wire.getInvocationChains(); + EasyMock.expectLastCall().andReturn(new HashMap<Operation<?>, InvocationChain>()).atLeastOnce(); + URI uri = URI.create("#target"); + EasyMock.expect(wire.getSourceUri()).andReturn(uri).atLeastOnce(); + EasyMock.expect(wire.isOptimizable()).andReturn(false); + EasyMock.replay(wire); + ProxyService service = EasyMock.createMock(ProxyService.class); + EasyMock.expect(service.createProxy(EasyMock.eq(Target.class), EasyMock.eq(wire), EasyMock.isA(Map.class))) + .andAnswer(new IAnswer<Target>() { + public Target answer() throws Throwable { + Wire wire = (Wire) EasyMock.getCurrentArguments()[1]; + wire.getInvocationChains(); + return target; + } + + }).atLeastOnce(); + EasyMock.replay(service); + configuration.setProxyService(service); + configuration.setName(new URI("source")); + JavaAtomicComponent component = new JavaAtomicComponent(configuration); + component.setScopeContainer(scope); + component.attachWire(wire); + component.start(); + Source source = (Source) component.getTargetInstance(); + assertSame(target, source.getTarget()); + scope.stop(); + EasyMock.verify(wire); + EasyMock.verify(scope); + EasyMock.verify(service); + } + + private ScopeContainer createMock() throws TargetException { + ScopeContainer scope = EasyMock.createMock(ScopeContainer.class); + scope.start(); + scope.stop(); + scope.register(EasyMock.isA(AtomicComponent.class)); + EasyMock.expectLastCall().atLeastOnce(); + EasyMock.expect(scope.getScope()).andReturn(Scope.COMPOSITE).atLeastOnce(); + scope.getInstance(EasyMock.isA(AtomicComponent.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { + private Map<AtomicComponent, Object> cache = new HashMap<AtomicComponent, Object>(); + + public Object answer() throws Throwable { + AtomicComponent component = (AtomicComponent) EasyMock.getCurrentArguments()[0]; + Object instance = cache.get(component); + if (instance == null) { + instance = component.createInstance(); + cache.put(component, instance); + } + return instance; + } + }).anyTimes(); + EasyMock.replay(scope); + return scope; + } + + private interface Source { + Target getTarget(); + } + + private static class SourceImpl implements Source { + private Target target; + + public SourceImpl() { + } + + public Target getTarget() { + return target; + } + + public void setTarget(Target target) { + this.target = target; + } + } + + private interface Target { + + String getString(); + + void setString(String val); + } + + private static class TargetImpl implements Target { + private String string; + + public TargetImpl() { + } + + public String getString() { + return string; + } + + public void setString(String string) { + this.string = string; + } + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerBasicInvocationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerBasicInvocationTestCase.java new file mode 100644 index 0000000000..6ab6d7dbeb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerBasicInvocationTestCase.java @@ -0,0 +1,188 @@ +/* + * 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.core.implementation.java; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.extension.ExecutionMonitor; +import org.apache.tuscany.spi.model.Scope; +import static org.apache.tuscany.spi.wire.TargetInvoker.NONE; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.easymock.classextension.EasyMock; + +public class JavaTargetInvokerBasicInvocationTestCase extends TestCase { + private Method echoMethod; + private Method arrayMethod; + private Method nullParamMethod; + private Method primitiveMethod; + private Method checkedMethod; + private Method runtimeMethod; + private Wire wire; + private WorkContext context; + private ExecutionMonitor monitor; + + public JavaTargetInvokerBasicInvocationTestCase(String arg0) { + super(arg0); + } + + public void setUp() throws Exception { + echoMethod = TestBean.class.getDeclaredMethod("echo", String.class); + arrayMethod = TestBean.class.getDeclaredMethod("arrayEcho", String[].class); + nullParamMethod = TestBean.class.getDeclaredMethod("nullParam", (Class[]) null); + primitiveMethod = TestBean.class.getDeclaredMethod("primitiveEcho", Integer.TYPE); + checkedMethod = TestBean.class.getDeclaredMethod("checkedException", (Class[]) null); + runtimeMethod = TestBean.class.getDeclaredMethod("runtimeException", (Class[]) null); + wire = EasyMock.createNiceMock(Wire.class); + context = EasyMock.createNiceMock(WorkContext.class); + monitor = EasyMock.createNiceMock(ExecutionMonitor.class); + assertNotNull(echoMethod); + assertNotNull(checkedMethod); + assertNotNull(runtimeMethod); + } + + public void testObjectInvoke() throws Throwable { + TestBean bean = new TestBean(); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(bean); + EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(echoMethod, component, context); + Object ret = invoker.invokeTarget("foo", NONE); + assertEquals("foo", ret); + } + + public void testArrayInvoke() throws Throwable { + TestBean bean = new TestBean(); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(bean); + EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(arrayMethod, component, context); + + String[] args = new String[]{"foo", "bar"}; + Object ret = invoker.invokeTarget(new Object[]{args}, NONE); + String[] retA = (String[]) ret; + assertNotNull(retA); + assertEquals(2, retA.length); + assertEquals("foo", retA[0]); + assertEquals("bar", retA[1]); + } + + public void testNullInvoke() throws Throwable { + TestBean bean = new TestBean(); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(bean); + EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(nullParamMethod, component, context); + Object ret = invoker.invokeTarget(null, NONE); + String retS = (String) ret; + assertEquals("foo", retS); + } + + public void testPrimitiveInvoke() throws Throwable { + TestBean bean = new TestBean(); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(bean); + EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(primitiveMethod, component, context); + Object ret = invoker.invokeTarget(new Integer[]{1}, NONE); + Integer retI = (Integer) ret; + assertEquals(1, retI.intValue()); + } + + public void testInvokeCheckedException() throws Throwable { + TestBean bean = new TestBean(); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(bean); + EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(checkedMethod, component, context); + try { + invoker.invokeTarget(null, NONE); + } catch (InvocationTargetException e) { + if (e.getCause() != null && TestException.class.equals(e.getCause().getClass())) { + return; + } + } catch (Throwable e) { + //ok + } + fail(TestException.class.getName() + " should have been thrown"); + } + + public void testInvokeRuntimeException() throws Throwable { + TestBean bean = new TestBean(); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(bean); + EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(runtimeMethod, component, context); + try { + invoker.invokeTarget(null, NONE); + } catch (InvocationTargetException e) { + if (e.getCause() != null && e.getCause() instanceof TestRuntimeException) { + return; + } + } + fail(TestException.class.getName() + " should have been thrown"); + } + + private class TestBean { + + public String echo(String msg) throws Exception { + assertEquals("foo", msg); + return msg; + } + + public String[] arrayEcho(String[] msg) throws Exception { + assertNotNull(msg); + assertEquals(2, msg.length); + assertEquals("foo", msg[0]); + assertEquals("bar", msg[1]); + return msg; + } + + public String nullParam() throws Exception { + return "foo"; + } + + public int primitiveEcho(int i) throws Exception { + return i; + } + + public void checkedException() throws TestException { + throw new TestException(); + } + + public void runtimeException() throws TestRuntimeException { + throw new TestRuntimeException(); + } + } + + public class TestException extends Exception { + } + + public class TestRuntimeException extends RuntimeException { + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerMediationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerMediationTestCase.java new file mode 100644 index 0000000000..096c7f9aba --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerMediationTestCase.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.core.implementation.java; + +import java.lang.reflect.Method; + +import static org.apache.tuscany.spi.wire.TargetInvoker.NONE; +import org.apache.tuscany.spi.model.Scope; + +import junit.framework.TestCase; +import org.easymock.classextension.EasyMock; + +/** + * Tests invoking on a different interface from the one actually implemented by the target + * + * @version $Rev$ $Date$ + */ +public class JavaTargetInvokerMediationTestCase extends TestCase { + + private Method hello; + + public void setUp() throws Exception { + hello = Hello.class.getMethod("hello", String.class); + } + + public void testMediation() throws Exception { + Target target = EasyMock.createMock(Target.class); + EasyMock.expect(target.hello("foo")).andReturn("foo"); + EasyMock.replay(target); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(target); + EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(hello, component, null, null); + assertEquals("foo", invoker.invokeTarget("foo", NONE)); + } + + public interface Hello { + String hello(String message) throws Exception; + } + + private interface Target { + String hello(String message); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerNonBlockingInvocationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerNonBlockingInvocationTestCase.java new file mode 100644 index 0000000000..4f5d2a1ff3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerNonBlockingInvocationTestCase.java @@ -0,0 +1,225 @@ +/* + * 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.core.implementation.java; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.extension.ExecutionMonitor; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; +import static org.apache.tuscany.spi.wire.TargetInvoker.NONE; + +import junit.framework.TestCase; +import org.easymock.classextension.EasyMock; + +/** + * Verifies dispatching invocations to a Java implementation instance + * + * @version $Rev$ $Date$ + */ +public class JavaTargetInvokerNonBlockingInvocationTestCase extends TestCase { + + private Method echoMethod; + private Method arrayMethod; + private Method nullParamMethod; + private Method primitiveMethod; + private Method checkedMethod; + private Method runtimeMethod; + private WorkContext context; + private ExecutionMonitor monitor; + + public JavaTargetInvokerNonBlockingInvocationTestCase(String arg0) { + super(arg0); + } + + public void testInvoke() throws Exception { + AsyncTarget target = EasyMock.createMock(AsyncTarget.class); + target.invoke(); + EasyMock.expectLastCall().once(); + EasyMock.replay(target); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(target); + EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(component); + ExecutionMonitor monitor = EasyMock.createMock(ExecutionMonitor.class); + EasyMock.replay(monitor); + + Message msg = new MessageImpl(); + Object id = new Object(); + msg.setMessageId(id); + + WorkContext context = EasyMock.createMock(WorkContext.class); + context.setCorrelationId(id); + EasyMock.replay(context); + Method method = AsyncTarget.class.getMethod("invoke"); + method.setAccessible(true); + JavaTargetInvoker invoker = new JavaTargetInvoker(method, component, context); + invoker.invoke(msg); + EasyMock.verify(target); + EasyMock.verify(component); + } + + public void setUp() throws Exception { + echoMethod = TestBean.class.getDeclaredMethod("echo", String.class); + arrayMethod = TestBean.class.getDeclaredMethod("arrayEcho", String[].class); + nullParamMethod = TestBean.class.getDeclaredMethod("nullParam", (Class[]) null); + primitiveMethod = TestBean.class.getDeclaredMethod("primitiveEcho", Integer.TYPE); + checkedMethod = TestBean.class.getDeclaredMethod("checkedException", (Class[]) null); + runtimeMethod = TestBean.class.getDeclaredMethod("runtimeException", (Class[]) null); + context = EasyMock.createNiceMock(WorkContext.class); + monitor = EasyMock.createNiceMock(ExecutionMonitor.class); + assertNotNull(echoMethod); + assertNotNull(checkedMethod); + assertNotNull(runtimeMethod); + } + + public void testObjectInvoke() throws Throwable { + TestBean bean = new TestBean(); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(bean); + EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(echoMethod, component, context); + Object ret = invoker.invokeTarget("foo", NONE); + assertEquals("foo", ret); + } + + public void testArrayInvoke() throws Throwable { + TestBean bean = new TestBean(); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(bean); + EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(arrayMethod, component, context); + + String[] args = new String[]{"foo", "bar"}; + Object ret = invoker.invokeTarget(new Object[]{args}, NONE); + String[] retA = (String[]) ret; + assertNotNull(retA); + assertEquals(2, retA.length); + assertEquals("foo", retA[0]); + assertEquals("bar", retA[1]); + } + + public void testNullInvoke() throws Throwable { + TestBean bean = new TestBean(); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(bean); + EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(nullParamMethod, component, context); + Object ret = invoker.invokeTarget(null, NONE); + String retS = (String) ret; + assertEquals("foo", retS); + } + + public void testPrimitiveInvoke() throws Throwable { + TestBean bean = new TestBean(); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(bean); + EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(primitiveMethod, component, context); + Object ret = invoker.invokeTarget(new Integer[]{1}, NONE); + Integer retI = (Integer) ret; + assertEquals(1, retI.intValue()); + } + + public void testInvokeCheckedException() throws Throwable { + TestBean bean = new TestBean(); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(bean); + EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(checkedMethod, component, context); + try { + invoker.invokeTarget(null, NONE); + } catch (InvocationTargetException e) { + if (e.getCause() != null && TestException.class.equals(e.getCause().getClass())) { + return; + } + } catch (Throwable e) { + //ok + } + fail(TestException.class.getName() + " should have been thrown"); + } + + public void testInvokeRuntimeException() throws Throwable { + TestBean bean = new TestBean(); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(bean); + EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(runtimeMethod, component, context); + try { + invoker.invokeTarget(null, NONE); + } catch (InvocationTargetException e) { + if (e.getCause() != null && e.getCause() instanceof TestRuntimeException) { + return; + } + } + fail(TestException.class.getName() + " should have been thrown"); + } + + private class TestBean { + + public String echo(String msg) throws Exception { + assertEquals("foo", msg); + return msg; + } + + public String[] arrayEcho(String[] msg) throws Exception { + assertNotNull(msg); + assertEquals(2, msg.length); + assertEquals("foo", msg[0]); + assertEquals("bar", msg[1]); + return msg; + } + + public String nullParam() throws Exception { + return "foo"; + } + + public int primitiveEcho(int i) throws Exception { + return i; + } + + public void checkedException() throws TestException { + throw new TestException(); + } + + public void runtimeException() throws TestRuntimeException { + throw new TestRuntimeException(); + } + } + + public class TestException extends Exception { + } + + public class TestRuntimeException extends RuntimeException { + } + + public interface AsyncTarget { + void invoke(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerSequenceTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerSequenceTestCase.java new file mode 100644 index 0000000000..5edddeb94d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerSequenceTestCase.java @@ -0,0 +1,117 @@ +/* + * 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.core.implementation.java; + +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; +import org.apache.tuscany.spi.wire.TargetInvoker; + +import junit.framework.TestCase; +import org.easymock.classextension.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class JavaTargetInvokerSequenceTestCase extends TestCase { + + /** + * Verifies an invocation marked as non-conversational has an existing or new instance returned + */ + public void testNoSequence() throws Exception { + Foo foo = EasyMock.createMock(Foo.class); + foo.invoke(); + EasyMock.replay(foo); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(foo); + EasyMock.expect(component.getScope()).andReturn(Scope.CONVERSATION); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(Foo.class.getMethod("invoke"), component, null, null); + Message msg = new MessageImpl(); + msg.setConversationSequence(TargetInvoker.NONE); + invoker.invoke(msg); + EasyMock.verify(foo); + EasyMock.verify(component); + } + + /** + * Verifies that an invocation marked as starting a conversation has a new instance returned + */ + public void testStartSequence() throws Exception { + Foo foo = EasyMock.createMock(Foo.class); + foo.invoke(); + EasyMock.replay(foo); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(foo); + EasyMock.expect(component.getScope()).andReturn(Scope.CONVERSATION); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(Foo.class.getMethod("invoke"), component, null, null); + Message msg = new MessageImpl(); + msg.setConversationSequence(TargetInvoker.START); + invoker.invoke(msg); + EasyMock.verify(foo); + EasyMock.verify(component); + } + + /** + * Verifies that an invocation marked as continuing a conversation has an associated instance returned + */ + public void testContinueSequence() throws Exception { + Foo foo = EasyMock.createMock(Foo.class); + foo.invoke(); + EasyMock.replay(foo); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getAssociatedTargetInstance()).andReturn(foo); + EasyMock.expect(component.getScope()).andReturn(Scope.CONVERSATION); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(Foo.class.getMethod("invoke"), component, null, null); + Message msg = new MessageImpl(); + msg.setConversationSequence(TargetInvoker.CONTINUE); + invoker.invoke(msg); + EasyMock.verify(foo); + EasyMock.verify(component); + } + + /** + * Verifies that an invocation marked as ending a conversation has an associated instance returned and it is removed + * following the dispatch to the instance + */ + public void testEndSequence() throws Exception { + Foo foo = EasyMock.createMock(Foo.class); + foo.invoke(); + EasyMock.replay(foo); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getAssociatedTargetInstance()).andReturn(foo); + EasyMock.expect(component.getScope()).andReturn(Scope.CONVERSATION); + component.removeInstance(); + component.destroy(EasyMock.eq(foo)); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(Foo.class.getMethod("invoke"), component, null, null); + Message msg = new MessageImpl(); + msg.setConversationSequence(TargetInvoker.END); + invoker.invoke(msg); + EasyMock.verify(foo); + EasyMock.verify(component); + } + + + private interface Foo { + void invoke(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerStatelessDestroyTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerStatelessDestroyTestCase.java new file mode 100644 index 0000000000..fc53337d54 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerStatelessDestroyTestCase.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.core.implementation.java; + +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.model.Scope; + +import junit.framework.TestCase; +import org.easymock.classextension.EasyMock; + +public class JavaTargetInvokerStatelessDestroyTestCase extends TestCase { + + public JavaTargetInvokerStatelessDestroyTestCase(String arg0) { + super(arg0); + } + + public void testDestroy() throws Exception { + Method echoMethod = Echo.class.getDeclaredMethod("echo", String.class); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(new JavaTargetInvokerStatelessDestroyTestCase.Echo()); + EasyMock.expect(component.getScope()).andReturn(Scope.STATELESS); + component.destroy(EasyMock.isA(Echo.class)); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(echoMethod, component, null, null); + invoker.setCacheable(false); + assertEquals("foo", invoker.invokeTarget("foo", JavaTargetInvoker.NONE)); + EasyMock.verify(component); + } + + public static class Echo { + public String echo(String message) throws Exception { + return message; + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerTestCase.java new file mode 100644 index 0000000000..246e023eaa --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerTestCase.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.core.implementation.java; + +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.model.Scope; + +import junit.framework.TestCase; +import org.easymock.classextension.EasyMock; + +public class JavaTargetInvokerTestCase extends TestCase { + + public JavaTargetInvokerTestCase(String arg0) { + super(arg0); + } + + public void testInvoke() throws Exception { + Method echoMethod = Echo.class.getDeclaredMethod("echo", String.class); + JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(new Echo()); + EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.replay(component); + JavaTargetInvoker invoker = new JavaTargetInvoker(echoMethod, component, null, null); + invoker.setCacheable(false); + assertEquals("foo", invoker.invokeTarget("foo", JavaTargetInvoker.NONE)); + EasyMock.verify(component); + } + + public static class Echo { + public String echo(String message) throws Exception { + return message; + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/MultiplicityTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/MultiplicityTestCase.java new file mode 100644 index 0000000000..ba478c9634 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/MultiplicityTestCase.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.core.implementation.java; + +import junit.framework.TestCase; + + +/** + * Tests wires that are configured with a multiplicity + * + * @version $Rev$ $Date$ + */ +public class MultiplicityTestCase extends TestCase { + + public void testMultiplicity() throws Exception { + // TODO implement + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/ResourceInjectionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/ResourceInjectionTestCase.java new file mode 100644 index 0000000000..de0ec0331e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/ResourceInjectionTestCase.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.core.implementation.java; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.host.ResourceHost; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.injection.PojoObjectFactory; +import org.apache.tuscany.core.injection.ResourceObjectFactory; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ResourceInjectionTestCase extends TestCase { + + public void testResourceMemberInjection() throws Exception { + ScopeContainer containter = EasyMock.createNiceMock(ScopeContainer.class); + Constructor<Foo> ctor = Foo.class.getConstructor(); + Field field = Foo.class.getDeclaredField("resource"); + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setName(new URI("component")); + configuration.setInstanceFactory(new PojoObjectFactory<Foo>(ctor)); + configuration.addResourceSite("bar", field); + JavaAtomicComponent component = new JavaAtomicComponent(configuration); + component.setScopeContainer(containter); + + Wire wire = EasyMock.createMock(Wire.class); + EasyMock.expect(wire.getTargetInstance()).andReturn("result"); + EasyMock.replay(wire); + + ResourceHost host = EasyMock.createMock(ResourceHost.class); + EasyMock.expect(host.resolveResource(EasyMock.eq(String.class))).andReturn("result"); + EasyMock.replay(host); + + ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, false, host); + component.addResourceFactory("bar", factory); + + Foo foo = (Foo) component.createInstance(); + assertEquals("result", foo.resource); + } + + + public void testResourceConstructorInjection() throws Exception { + ScopeContainer containter = EasyMock.createNiceMock(ScopeContainer.class); + Constructor<FooConstructor> ctor = FooConstructor.class.getConstructor(String.class); + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setName(new URI("component")); + configuration.setInstanceFactory(new PojoObjectFactory<FooConstructor>(ctor)); + List<String> ctorNames = new ArrayList<String>(); + ctorNames.add("bar"); + configuration.setConstructorParamNames(ctorNames); + JavaAtomicComponent component = new JavaAtomicComponent(configuration); + component.setScopeContainer(containter); + + Wire wire = EasyMock.createMock(Wire.class); + EasyMock.expect(wire.getTargetInstance()).andReturn("result"); + EasyMock.replay(wire); + ResourceHost host = EasyMock.createMock(ResourceHost.class); + EasyMock.expect(host.resolveResource(EasyMock.eq(String.class))).andReturn("result"); + EasyMock.replay(host); + + ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, false, host); + component.addResourceFactory("bar", factory); + + FooConstructor foo = (FooConstructor) component.createInstance(); + assertEquals("result", foo.resource); + } + + public static class Foo { + protected String resource; + + public Foo() { + } + + } + + public static class FooConstructor { + protected String resource; + + public FooConstructor(String resource) { + this.resource = resource; + } + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/integration/CallbackInvocationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/integration/CallbackInvocationTestCase.java new file mode 100644 index 0000000000..9ed9cab9b2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/integration/CallbackInvocationTestCase.java @@ -0,0 +1,347 @@ +/* + * 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.core.implementation.java.integration; + +import java.lang.reflect.Method; +import java.net.URI; +import java.net.URISyntaxException; + +import org.osoa.sca.NoRegisteredCallbackException; +import org.osoa.sca.annotations.Callback; + +import org.apache.tuscany.spi.builder.Connector; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.ReferenceTarget; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.services.work.WorkScheduler; + +import junit.framework.TestCase; +import org.apache.tuscany.core.builder.ConnectorImpl; +import org.apache.tuscany.core.component.ComponentManager; +import org.apache.tuscany.core.component.ComponentManagerImpl; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.component.scope.CompositeScopeContainer; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.implementation.java.JavaAtomicComponent; +import org.apache.tuscany.core.implementation.java.JavaComponentBuilder; +import org.apache.tuscany.core.implementation.java.JavaImplementation; +import org.apache.tuscany.core.wire.jdk.JDKProxyService; +import static org.easymock.EasyMock.createMock; +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 org.easymock.IAnswer; + +/** + * Verifies callback integration scenarios with Java components. + * + * @version $Rev$ $Date$ + */ +public class CallbackInvocationTestCase extends TestCase { + private ScopeContainer container; + private DeploymentContext context; + private JavaComponentBuilder builder; + private WorkScheduler scheduler; + private WorkContext workContext; + private ComponentManager componentManager; + private Connector connector; + + /** + * Verifies callbacks between two Java component implementations: wire creation, connection, injection of callback + * proxy, and invocation + */ + public void testComponentToComponentCallback() throws Exception { + ComponentDefinition<JavaImplementation> targetDefinition = createTarget(); + JavaAtomicComponent targetComponent = (JavaAtomicComponent) builder.build(targetDefinition, context); + targetComponent.setScopeContainer(container); + container.register(targetComponent); + componentManager.register(targetComponent); + ComponentDefinition<JavaImplementation> sourceDefinition = createSource(URI.create("fooClient")); + JavaAtomicComponent clientComponent = (JavaAtomicComponent) builder.build(sourceDefinition, context); + clientComponent.setScopeContainer(container); + container.register(clientComponent); + componentManager.register(clientComponent); + connector.connect(sourceDefinition); + targetComponent.start(); + clientComponent.start(); + FooClient client = (FooClient) clientComponent.getTargetInstance(); + client.invoke(); + assertTrue(client.invoked); + client.invokeMultiCallback(); + assertTrue(client.count == 2); + } + + /** + * Verifies exception is thrown when callback is not implemented + */ + public void testCallbackNotRegistered() throws Exception { + // JFM temporarily commenting out as implementation needs to be spec compliant + } + + /** + * Verifies a callback in response to an invocation from two different client components is routed back to the + * appropriate client. + */ + public void testTwoSourceComponentToComponentCallback() throws Exception { + ComponentDefinition<JavaImplementation> targetDefinition = createTarget(); + JavaAtomicComponent targetComponent = + (JavaAtomicComponent) builder.build(targetDefinition, context); + targetComponent.setScopeContainer(container); + container.register(targetComponent); + componentManager.register(targetComponent); + + ComponentDefinition<JavaImplementation> sourceDefinition1 = createSource(URI.create("client1")); + ComponentDefinition<JavaImplementation> sourceDefinition2 = createSource(URI.create("client2")); + JavaAtomicComponent clientComponent1 = (JavaAtomicComponent) builder.build(sourceDefinition1, context); + clientComponent1.setScopeContainer(container); + container.register(clientComponent1); + componentManager.register(clientComponent1); + JavaAtomicComponent clientComponent2 = (JavaAtomicComponent) builder.build(sourceDefinition2, context); + clientComponent2.setScopeContainer(container); + container.register(clientComponent2); + componentManager.register(clientComponent2); + + connector.connect(sourceDefinition1); + connector.connect(sourceDefinition2); + targetComponent.start(); + + FooClient client1 = (FooClient) clientComponent1.getTargetInstance(); + client1.invoke(); + assertTrue(client1.invoked); + FooClient client2 = (FooClient) clientComponent2.getTargetInstance(); + client2.invoke(); + assertTrue(client2.invoked); + } + + + private ComponentDefinition<JavaImplementation> createTarget() throws NoSuchMethodException, + InvalidServiceContractException { + ConstructorDefinition<FooImpl> ctorDef = new ConstructorDefinition<FooImpl>(FooImpl.class.getConstructor()); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + type.setConstructorDefinition(ctorDef); + type.setImplementationScope(Scope.COMPOSITE); + Method method = FooImpl.class.getMethod("setCallback", FooCallback.class); + JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl(); + ServiceContract<?> contract = registry.introspect(Foo.class); + contract.setCallbackClass(FooCallback.class); + contract.setCallbackName("callback"); + JavaMappedService mappedService = new JavaMappedService(URI.create("Foo"), contract, false, "callback", method); + type.getServices().put("Foo", mappedService); + + JavaImplementation impl = new JavaImplementation(FooImpl.class, type); + impl.setComponentType(type); + impl.setImplementationClass(FooImpl.class); + return new ComponentDefinition<JavaImplementation>(URI.create("foo"), impl); + } + + private ComponentDefinition<JavaImplementation> createSource(URI name) + throws NoSuchMethodException, URISyntaxException, InvalidServiceContractException { + ConstructorDefinition<FooClient> ctorDef = + new ConstructorDefinition<FooClient>(FooClient.class.getConstructor()); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + type.setConstructorDefinition(ctorDef); + type.setImplementationScope(Scope.COMPOSITE); + Method method = FooClient.class.getMethod("setFoo", Foo.class); + JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl(); + ServiceContract<?> contract = registry.introspect(Foo.class); + contract.setCallbackClass(FooCallback.class); + contract.setCallbackName("callback"); + JavaMappedReference mappedReference = new JavaMappedReference(URI.create(name + "#" + "foo"), contract, method); + type.getReferences().put("foo", mappedReference); + ReferenceTarget refTarget = new ReferenceTarget(); + refTarget.setReferenceName(URI.create(name + "#" + "foo")); + refTarget.getTargets().add(new URI("foo")); + JavaImplementation impl = new JavaImplementation(FooClient.class, type); + impl.setComponentType(type); + impl.setImplementationClass(FooClient.class); + ComponentDefinition<JavaImplementation> def = new ComponentDefinition<JavaImplementation>(name, impl); + def.getReferenceTargets().put("foo", refTarget); + return def; + } + + private ComponentDefinition<JavaImplementation> createPlainSource(URI name) + throws NoSuchMethodException, URISyntaxException, InvalidServiceContractException { + ConstructorDefinition<FooPlainClient> ctorDef = + new ConstructorDefinition<FooPlainClient>(FooPlainClient.class.getConstructor()); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + type.setConstructorDefinition(ctorDef); + type.setImplementationScope(Scope.COMPOSITE); + Method method = FooPlainClient.class.getMethod("setFoo", Foo.class); + JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl(); + ServiceContract<?> contract = registry.introspect(Foo.class); + contract.setCallbackClass(FooCallback.class); + contract.setCallbackName("callback"); + JavaMappedReference mappedReference = new JavaMappedReference(URI.create(name + "#" + "foo"), contract, method); + type.getReferences().put("foo", mappedReference); + ReferenceTarget refTarget = new ReferenceTarget(); + refTarget.setReferenceName(URI.create(name + "#" + "foo")); + refTarget.getTargets().add(new URI("foo")); + JavaImplementation impl = new JavaImplementation(FooPlainClient.class, type); + ComponentDefinition<JavaImplementation> def = new ComponentDefinition<JavaImplementation>(name, impl); + def.getReferenceTargets().put("foo", refTarget); + return def; + } + + @Callback(FooCallback.class) + public static interface Foo { + void call(); + + void callMultiCallback(); + + void callFromPlain(); + } + + public static class FooImpl implements Foo { + private FooCallback callback; + + public FooImpl() { + } + + @Callback + public void setCallback(FooCallback callback) { + this.callback = callback; + } + + public void call() { + callback.callback(); + } + + public void callMultiCallback() { + callback.multiCallback(); + callback.multiCallback(); + } + + public void callFromPlain() { + try { + callback.callback(); + fail(); + } catch (NoRegisteredCallbackException e) { + // expected + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + + public static class FooClient implements FooCallback { + + private Foo foo; + private boolean invoked; + private int count; + + public FooClient() { + } + + public void setFoo(Foo foo) { + this.foo = foo; + } + + public void callback() { + if (invoked) { + fail(); + } + invoked = true; + } + + public void multiCallback() { + count++; + } + + public void invoke() { + foo.call(); + } + + public void invokeMultiCallback() { + foo.callMultiCallback(); + } + } + + public interface FooCallback { + void callback(); + + void multiCallback(); + } + + public static class FooPlainClient /* implements FooCallback */ { // do NOT implement the callback + + private Foo foo; + + public FooPlainClient() { + } + + public void setFoo(Foo foo) { + this.foo = foo; + } + + public void invoke() { + foo.callFromPlain(); + } + + public void callback() { + + } + + public void multiCallback() { + + } + } + + protected void setUp() throws Exception { + super.setUp(); + componentManager = new ComponentManagerImpl(); + connector = new ConnectorImpl(null, componentManager, scheduler, workContext); + container = new CompositeScopeContainer(null); + container.start(); + context = createMock(DeploymentContext.class); + context.getCompositeScope(); + expectLastCall().andReturn(container).anyTimes(); + replay(context); + + scheduler = createMock(WorkScheduler.class); + scheduler.scheduleWork(isA(Runnable.class)); + expectLastCall().andStubAnswer(new IAnswer<Object>() { + public Object answer() throws Throwable { + Runnable runnable = (Runnable) getCurrentArguments()[0]; + runnable.run(); + return null; + } + }); + replay(scheduler); + + builder = new JavaComponentBuilder(); + workContext = new WorkContextImpl(); + builder.setWorkContext(workContext); + builder.setProxyService(new JDKProxyService(workContext)); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/integration/WireToScopedJavaTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/integration/WireToScopedJavaTestCase.java new file mode 100644 index 0000000000..d389041de7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/java/integration/WireToScopedJavaTestCase.java @@ -0,0 +1,212 @@ +/* + * 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.core.implementation.java.integration; + +import java.net.URI; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; + +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.component.TargetInvokerCreationException; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; +import org.apache.tuscany.spi.wire.ProxyService; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.component.event.ComponentStart; +import org.apache.tuscany.core.component.event.ComponentStop; +import org.apache.tuscany.core.component.event.HttpSessionEnd; +import org.apache.tuscany.core.component.event.HttpSessionStart; +import org.apache.tuscany.core.component.event.RequestEnd; +import org.apache.tuscany.core.component.event.RequestStart; +import org.apache.tuscany.core.component.scope.CompositeScopeContainer; +import org.apache.tuscany.core.component.scope.HttpSessionScopeContainer; +import org.apache.tuscany.core.component.scope.RequestScopeContainer; +import org.apache.tuscany.core.component.scope.StatelessScopeContainer; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.implementation.java.JavaAtomicComponent; +import org.apache.tuscany.core.injection.PojoObjectFactory; +import org.apache.tuscany.core.mock.component.Target; +import org.apache.tuscany.core.mock.component.TargetImpl; +import org.apache.tuscany.core.wire.InvocationChainImpl; +import org.apache.tuscany.core.wire.WireImpl; +import org.apache.tuscany.core.wire.jdk.JDKProxyService; + +/** + * Validates wiring from a wire to Java atomic component by scope + * + * @version $$Rev$$ $$Date$$ + */ +public class WireToScopedJavaTestCase extends TestCase { + private WorkContext workContext = new WorkContextImpl(); + private ProxyService proxyService = new JDKProxyService(new WorkContextImpl()); + + public void testToStatelessScope() throws Exception { + StatelessScopeContainer scope = new StatelessScopeContainer(workContext, null); + scope.start(); + final Wire wire = getWire(scope); + Target service = proxyService.createProxy(Target.class, wire); + assertNotNull(service); + service.setString("foo"); + assertEquals(null, service.getString()); + scope.stop(); + } + + public void testToRequestScope() throws Exception { + final RequestScopeContainer scope = new RequestScopeContainer(workContext, null); + scope.start(); + + scope.onEvent(new RequestStart(this)); + + final Wire wire = getWire(scope); + Target service = proxyService.createProxy(Target.class, wire); + assertNotNull(service); + service.setString("foo"); + + // another request + Executor executor = Executors.newSingleThreadExecutor(); + FutureTask<Void> future = new FutureTask<Void>(new Runnable() { + public void run() { + scope.onEvent(new RequestStart(this)); + Target service2 = proxyService.createProxy(Target.class, wire); + Target target2 = proxyService.createProxy(Target.class, wire); + assertEquals(null, service2.getString()); + service2.setString("bar"); + assertEquals("bar", service2.getString()); + assertEquals("bar", target2.getString()); + scope.onEvent(new RequestEnd(this)); + } + }, null); + executor.execute(future); + future.get(); + + assertEquals("foo", service.getString()); + scope.onEvent(new RequestEnd(this)); + scope.stop(); + } + + public void testToSessionScope() throws Exception { + HttpSessionScopeContainer scope = new HttpSessionScopeContainer(workContext, null); + scope.start(); + Object session1 = new Object(); + workContext.setIdentifier(Scope.SESSION, session1); + scope.onEvent(new HttpSessionStart(this, session1)); + + final Wire wire = getWire(scope); + Target service = proxyService.createProxy(Target.class, wire); + Target target = proxyService.createProxy(Target.class, wire); + assertNotNull(service); + service.setString("foo"); + assertEquals("foo", service.getString()); + assertEquals("foo", target.getString()); + + workContext.clearIdentifier(Scope.SESSION); + + //second session + Object session2 = new Object(); + workContext.setIdentifier(Scope.SESSION, session2); + scope.onEvent(new HttpSessionStart(this, session2)); + + Target service2 = proxyService.createProxy(Target.class, wire); + assertNotNull(service2); + assertNull(service2.getString()); + Target target2 = proxyService.createProxy(Target.class, wire); + service2.setString("bar"); + assertEquals("bar", service2.getString()); + assertEquals("bar", target2.getString()); + + scope.onEvent(new HttpSessionEnd(this, session2)); + workContext.clearIdentifier(Scope.SESSION); + + workContext.setIdentifier(Scope.SESSION, session1); + assertEquals("foo", service.getString()); + + scope.onEvent(new HttpSessionEnd(this, session1)); + + scope.stop(); + } + + public void testToCompositeScope() throws Exception { + CompositeScopeContainer scope = new CompositeScopeContainer(null); + scope.start(); + scope.onEvent(new ComponentStart(this, null)); + final Wire wire = getWire(scope); + Target service = proxyService.createProxy(Target.class, wire); + Target target = proxyService.createProxy(Target.class, wire); + assertNotNull(service); + service.setString("foo"); + assertEquals("foo", service.getString()); + assertEquals("foo", target.getString()); + scope.onEvent(new ComponentStop(this, null)); + scope.stop(); + } + + private Wire getWire(ScopeContainer scope) throws Exception { + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setImplementationClass(TargetImpl.class); + configuration.setInstanceFactory(new PojoObjectFactory<TargetImpl>(TargetImpl.class.getConstructor())); + configuration.setWorkContext(workContext); + configuration.setName(new URI("source")); + configuration.setName(new URI("target")); + + JavaAtomicComponent target = new JavaAtomicComponent(configuration); + target.setScopeContainer(scope); + + Wire wire = createWire("target#Target", Target.class, target); + + target.start(); + return wire; + } + + private static <T> Wire createWire(String targetName, Class<T> interfaze, JavaAtomicComponent target) + throws InvalidServiceContractException, TargetInvokerCreationException { + Wire wire = new WireImpl(); + JavaServiceContract contract = new JavaServiceContract(interfaze); + contract.setConversational(false); + wire.setSourceContract(contract); + createChains(interfaze, wire); + wire.setTargetUri(URI.create(targetName)); + wire.setSourceUri(URI.create("component#ref")); + for (InvocationChain chain : wire.getInvocationChains().values()) { + chain.setTargetInvoker(target.createTargetInvoker("target", chain.getOperation())); + } + return wire; + } + + private static void createChains(Class<?> interfaze, Wire wire) + throws InvalidServiceContractException { + JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl(); + ServiceContract<?> contract = registry.introspect(interfaze); + for (Operation operation : contract.getOperations().values()) { + InvocationChain chain = new InvocationChainImpl(operation); + wire.addInvocationChain(operation, chain); + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/AllowsPassByReferenceProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/AllowsPassByReferenceProcessorTestCase.java new file mode 100644 index 0000000000..08e5b2315c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/AllowsPassByReferenceProcessorTestCase.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.core.implementation.processor;
+
+import org.osoa.sca.annotations.AllowsPassByReference;
+
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev: 452761 $ $Date: 2006-10-04 12:03:20 +0530 (Wed, 04 Oct 2006) $
+ */
+public class AllowsPassByReferenceProcessorTestCase extends TestCase {
+
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type;
+ AllowsPassByReferenceProcessor processor;
+
+ public void testClassAnnotation() throws Exception {
+// processor.visitClass(Foo.class, type, null);
+// assertEquals(true, type.isAllowsPassByReference());
+//
+// processor.visitClass(Bar.class, type, null);
+// assertEquals(false, type.isAllowsPassByReference());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ type = new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor = new AllowsPassByReferenceProcessor();
+ }
+
+ @AllowsPassByReference
+ private class Foo {
+ }
+
+ //no annotation
+ private class Bar {
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessorExtensibilityTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessorExtensibilityTestCase.java new file mode 100644 index 0000000000..f82d0f6f21 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessorExtensibilityTestCase.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.core.implementation.processor; + +import java.lang.reflect.Constructor; + +import org.osoa.sca.annotations.Property; + +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; + +/** + * Verifies the constructor processor works when parameters are marked with custom extension annotations + * + * @version $Rev$ $Date$ + */ +public class ConstructorProcessorExtensibilityTestCase extends TestCase { + private ConstructorProcessor processor = + new ConstructorProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl())); + + public void testProcessFirst() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Foo> ctor1 = Foo.class.getConstructor(String.class, String.class); + processor.visitConstructor(ctor1, type, null); + assertEquals("foo", type.getConstructorDefinition().getInjectionNames().get(0)); + } + + /** + * Verifies the constructor processor can be called after another processor has evaluated the constructor and found + * an annotation + * + * @throws Exception + */ + public void testProcessLast() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Foo> ctor1 = Foo.class.getConstructor(String.class, String.class); + ConstructorDefinition<Foo> definition = new ConstructorDefinition<Foo>(ctor1); + definition.getInjectionNames().add(""); + definition.getInjectionNames().add("mybar"); + type.setConstructorDefinition(definition); + processor.visitConstructor(ctor1, type, null); + assertEquals("foo", type.getConstructorDefinition().getInjectionNames().get(0)); + } + + + private @interface Bar { + + } + + private static class Foo { + @org.osoa.sca.annotations.Constructor + public Foo(@Property(name = "foo") String foo, @Bar String bar) { + + } + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessorTestCase.java new file mode 100644 index 0000000000..c6add2cae2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessorTestCase.java @@ -0,0 +1,167 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.implementation.processor; + +import java.lang.reflect.Constructor; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.model.Multiplicity; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; + +/** + * @version $Rev$ $Date$ + */ +public class ConstructorProcessorTestCase extends TestCase { + private ConstructorProcessor processor = + new ConstructorProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl())); + + public void testDuplicateConstructor() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + try { + processor.visitClass(BadFoo.class, type, null); + fail(); + } catch (DuplicateConstructorException e) { + // expected + } + } + + public void testConstructorAnnotation() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Foo> ctor1 = Foo.class.getConstructor(String.class); + processor.visitConstructor(ctor1, type, null); + assertEquals("foo", type.getConstructorDefinition().getInjectionNames().get(0)); + } + + public void testNoAnnotation() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<NoAnnotation> ctor1 = NoAnnotation.class.getConstructor(); + processor.visitConstructor(ctor1, type, null); + assertNull(type.getConstructorDefinition()); + } + + public void testBadAnnotation() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<BadAnnotation> ctor1 = BadAnnotation.class.getConstructor(String.class, Foo.class); + try { + processor.visitConstructor(ctor1, type, null); + fail(); + } catch (InvalidConstructorException e) { + // expected + } + } + + public void testMixedParameters() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Mixed> ctor1 = Mixed.class.getConstructor(String.class, String.class, String.class); + processor.visitConstructor(ctor1, type, null); + assertEquals("_ref0", type.getConstructorDefinition().getInjectionNames().get(0)); + assertEquals("foo", type.getConstructorDefinition().getInjectionNames().get(1)); + assertEquals("bar", type.getConstructorDefinition().getInjectionNames().get(2)); + } + + private static class BadFoo { + + @org.osoa.sca.annotations.Constructor("foo") + public BadFoo(String foo) { + + } + + @org.osoa.sca.annotations.Constructor({"foo", "bar"}) + public BadFoo(String foo, String bar) { + + } + } + + private static class Foo { + @org.osoa.sca.annotations.Constructor("foo") + public Foo(String foo) { + + } + } + + private static class NoAnnotation { + public NoAnnotation() { + } + } + + private static class BadAnnotation { + @org.osoa.sca.annotations.Constructor("foo") + public BadAnnotation(String foo, Foo ref) { + } + } + + + public static final class Mixed { + @org.osoa.sca.annotations.Constructor + public Mixed(@Reference String param1, + @Property(name = "foo")String param2, + @Reference(name = "bar")String param3) { + } + } + + public static final class Multiple { + @org.osoa.sca.annotations.Constructor + public Multiple(@Reference Collection<String> param1, + @Property(name = "foo")String[] param2, + @Reference(name = "bar", required = true)List<String> param3, + @Property(name = "abc")Set<String> param4, + @Reference(name = "xyz")String[] param5) { + } + } + + public void testMultiplicity() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Multiple> ctor1 = + Multiple.class.getConstructor(Collection.class, String[].class, List.class, Set.class, String[].class); + processor.visitConstructor(ctor1, type, null); + JavaMappedReference ref0 = type.getReferences().get("_ref0"); + assertNotNull(ref0); + assertEquals(Multiplicity.ZERO_N, ref0.getMultiplicity()); + JavaMappedReference ref1 = type.getReferences().get("bar"); + assertNotNull(ref1); + assertEquals(Multiplicity.ONE_N, ref1.getMultiplicity()); + JavaMappedReference ref2 = type.getReferences().get("xyz"); + assertNotNull(ref2); + assertEquals(Multiplicity.ZERO_N, ref2.getMultiplicity()); + JavaMappedProperty prop1 = type.getProperties().get("foo"); + assertNotNull(prop1); + assertTrue(prop1.isMany()); + JavaMappedProperty prop2 = type.getProperties().get("abc"); + assertNotNull(prop2); + assertTrue(prop2.isMany()); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorPropertyTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorPropertyTestCase.java new file mode 100644 index 0000000000..c3f1eec6c0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorPropertyTestCase.java @@ -0,0 +1,169 @@ +/* + * 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.core.implementation.processor; + +import java.lang.reflect.Constructor; +import java.util.List; + +import org.osoa.sca.annotations.Property; + +import org.apache.tuscany.spi.implementation.java.DuplicatePropertyException; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; + +/** + * @version $Rev$ $Date$ + */ +public class ConstructorPropertyTestCase extends TestCase { + + ConstructorProcessor processor = + new ConstructorProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl())); + + public void testProperty() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Foo> ctor = Foo.class.getConstructor(String.class); + processor.visitConstructor(ctor, type, null); + JavaMappedProperty<?> property = type.getProperties().get("myProp"); + assertTrue(property.isRequired()); + assertEquals("myProp", property.getName()); + } + + public void testTwoPropertiesSameType() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Foo> ctor = Foo.class.getConstructor(String.class, String.class); + processor.visitConstructor(ctor, type, null); + assertNotNull(type.getProperties().get("myProp1")); + assertNotNull(type.getProperties().get("myProp2")); + } + + public void testDuplicateProperty() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<BadFoo> ctor = BadFoo.class.getConstructor(String.class, String.class); + try { + processor.visitConstructor(ctor, type, null); + fail(); + } catch (DuplicatePropertyException e) { + // expected + } + } + + public void testNoName() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<BadFoo> ctor = BadFoo.class.getConstructor(String.class); + try { + processor.visitConstructor(ctor, type, null); + fail(); + } catch (InvalidPropertyException e) { + // expected + } + } + + public void testNamesOnConstructor() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Foo> ctor = Foo.class.getConstructor(Integer.class); + processor.visitConstructor(ctor, type, null); + assertNotNull(type.getProperties().get("myProp")); + } + + public void testInvalidNumberOfNames() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<BadFoo> ctor = BadFoo.class.getConstructor(Integer.class, Integer.class); + try { + processor.visitConstructor(ctor, type, null); + fail(); + } catch (InvalidPropertyException e) { + // expected + } + } + + public void testNoMatchingNames() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<BadFoo> ctor = BadFoo.class.getConstructor(List.class, List.class); + try { + processor.visitConstructor(ctor, type, null); + fail(); + } catch (InvalidConstructorException e) { + // expected + } + } + +// public void testMultiplicityRequired() throws Exception { + // TODO multiplicity +// } + + private static class Foo { + + @org.osoa.sca.annotations.Constructor() + public Foo(@Property(name = "myProp", required = true)String prop) { + + } + + @org.osoa.sca.annotations.Constructor("myProp") + public Foo(@Property Integer prop) { + + } + + @org.osoa.sca.annotations.Constructor() + public Foo(@Property(name = "myProp1")String prop1, @Property(name = "myProp2")String prop2) { + + } + + @org.osoa.sca.annotations.Constructor() + public Foo(@Property List prop) { + + } + } + + private static class BadFoo { + + @org.osoa.sca.annotations.Constructor() + public BadFoo(@Property(name = "myProp")String prop1, @Property(name = "myProp")String prop2) { + + } + + @org.osoa.sca.annotations.Constructor() + public BadFoo(@Property String prop) { + + } + + @org.osoa.sca.annotations.Constructor("myProp") + public BadFoo(@Property Integer prop, @Property Integer prop2) { + + } + + @org.osoa.sca.annotations.Constructor({"myRef", "myRef2"}) + public BadFoo(@Property List ref, @Property(name = "myOtherRef")List ref2) { + + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorReferenceTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorReferenceTestCase.java new file mode 100644 index 0000000000..067a23a096 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorReferenceTestCase.java @@ -0,0 +1,176 @@ +/* + * 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.core.implementation.processor; + +import java.lang.reflect.Constructor; +import java.util.List; + +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; + +/** + * @version $Rev$ $Date$ + */ +public class ConstructorReferenceTestCase extends TestCase { + private ConstructorProcessor processor; + + public void testReference() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Foo> ctor = Foo.class.getConstructor(String.class); + processor.visitConstructor(ctor, type, null); + JavaMappedReference reference = type.getReferences().get("myRef"); + assertTrue(reference.isRequired()); + assertEquals("#myRef", reference.getUri().toString()); + } + + public void testTwoReferencesSameType() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Foo> ctor = Foo.class.getConstructor(String.class, String.class); + processor.visitConstructor(ctor, type, null); + assertNotNull(type.getReferences().get("myRef1")); + assertNotNull(type.getReferences().get("myRef2")); + } + + public void testDuplicateProperty() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<BadFoo> ctor = BadFoo.class.getConstructor(String.class, String.class); + try { + processor.visitConstructor(ctor, type, null); + fail(); + } catch (DuplicateReferenceException e) { + // expected + } + } + + public void testNoName() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<NoNameFoo> ctor = NoNameFoo.class.getConstructor(String.class); + processor.visitConstructor(ctor, type, null); + assertNotNull(type.getReferences().get("_ref0")); + } + + public void testNamesOnConstructor() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Foo> ctor = Foo.class.getConstructor(Integer.class); + processor.visitConstructor(ctor, type, null); + assertNotNull(type.getReferences().get("myRef")); + } + + public void testInvalidNumberOfNames() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<BadFoo> ctor = BadFoo.class.getConstructor(Integer.class, Integer.class); + try { + processor.visitConstructor(ctor, type, null); + fail(); + } catch (InvalidReferenceException e) { + // expected + } + } + + public void testNoMatchingNames() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<BadFoo> ctor = BadFoo.class.getConstructor(List.class, List.class); + try { + processor.visitConstructor(ctor, type, null); + fail(); + } catch (InvalidConstructorException e) { + // expected + } + } + + protected void setUp() throws Exception { + super.setUp(); + processor = + new ConstructorProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl())); + } + +// public void testMultiplicityRequired() throws Exception { + // TODO multiplicity +// } + + private static class Foo { + + @org.osoa.sca.annotations.Constructor() + public Foo(@Reference(name = "myRef", required = true)String prop) { + + } + + @org.osoa.sca.annotations.Constructor() + public Foo(@Reference(name = "myRef1")String prop1, @Reference(name = "myRef2")String prop2) { + + } + + @org.osoa.sca.annotations.Constructor("myRef") + public Foo(@Reference Integer prop) { + + } + + @org.osoa.sca.annotations.Constructor() + public Foo(@Reference List prop) { + + } + } + + private static class NoNameFoo { + + @org.osoa.sca.annotations.Constructor + public NoNameFoo(@Reference String prop) { + + } + } + + private static class BadFoo { + + @org.osoa.sca.annotations.Constructor + public BadFoo(@Reference(name = "myRef")String prop1, @Reference(name = "myRef")String prop2) { + + } + + @org.osoa.sca.annotations.Constructor + public BadFoo(@Reference String prop) { + + } + + @org.osoa.sca.annotations.Constructor("myRef") + public BadFoo(@Reference Integer ref, @Reference Integer ref2) { + + } + + @org.osoa.sca.annotations.Constructor({"myRef", "myRef2"}) + public BadFoo(@Reference List ref, @Reference(name = "myOtherRef")List ref2) { + + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorResourceTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorResourceTestCase.java new file mode 100644 index 0000000000..6272b5216e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorResourceTestCase.java @@ -0,0 +1,166 @@ +/* + * 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.core.implementation.processor; + +import java.lang.reflect.Constructor; +import java.util.List; + +import org.apache.tuscany.api.annotation.Resource; + +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; + +/** + * @version $Rev$ $Date$ + */ +public class ConstructorResourceTestCase extends TestCase { + + ConstructorProcessor processor = + new ConstructorProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl())); + + public void testResource() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Foo> ctor = Foo.class.getConstructor(String.class); + processor.visitConstructor(ctor, type, null); + org.apache.tuscany.spi.implementation.java.Resource resource = type.getResources().get("myResource"); + assertFalse(resource.isOptional()); + } + + public void testTwoResourcesSameType() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Foo> ctor = Foo.class.getConstructor(String.class, String.class); + processor.visitConstructor(ctor, type, null); + assertNotNull(type.getResources().get("myResource1")); + assertNotNull(type.getResources().get("myResource2")); + } + + public void testDuplicateResource() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<BadFoo> ctor = BadFoo.class.getConstructor(String.class, String.class); + try { + processor.visitConstructor(ctor, type, null); + fail(); + } catch (DuplicateResourceException e) { + // expected + } + } + + public void testNoName() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<ConstructorResourceTestCase.BadFoo> ctor = + ConstructorResourceTestCase.BadFoo.class.getConstructor(String.class); + try { + processor.visitConstructor(ctor, type, null); + fail(); + } catch (InvalidResourceException e) { + // expected + } + } + + public void testNamesOnConstructor() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Foo> ctor = Foo.class.getConstructor(Integer.class); + processor.visitConstructor(ctor, type, null); + assertNotNull(type.getResources().get("myResource")); + } + + public void testInvalidNumberOfNames() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<ConstructorResourceTestCase.BadFoo> ctor = + ConstructorResourceTestCase.BadFoo.class.getConstructor(Integer.class, Integer.class); + try { + processor.visitConstructor(ctor, type, null); + fail(); + } catch (InvalidResourceException e) { + // expected + } + } + + public void testNoMatchingNames() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<ConstructorResourceTestCase.BadFoo> ctor = + ConstructorResourceTestCase.BadFoo.class.getConstructor(List.class, List.class); + try { + processor.visitConstructor(ctor, type, null); + fail(); + } catch (InvalidConstructorException e) { + // expected + } + } + + private static class Foo { + + @org.osoa.sca.annotations.Constructor + public Foo(@Resource(name = "myResource") String resource) { + + } + + @org.osoa.sca.annotations.Constructor("myResource") + public Foo(@Resource Integer resource) { + + } + + @org.osoa.sca.annotations.Constructor + public Foo(@Resource(name = "myResource1") String res1, @Resource(name = "myResource2") String res2) { + + } + + @org.osoa.sca.annotations.Constructor + public Foo(@Resource List res) { + + } + } + + private static class BadFoo { + + @org.osoa.sca.annotations.Constructor + public BadFoo(@Resource(name = "myResource") String res1, @Resource(name = "myResource") String res2) { + + } + + @org.osoa.sca.annotations.Constructor + public BadFoo(@Resource String res) { + + } + + @org.osoa.sca.annotations.Constructor("myProp") + public BadFoo(@Resource Integer res, @Resource Integer res2) { + + } + + @org.osoa.sca.annotations.Constructor({"myRes", "myRes2"}) + public BadFoo(@Resource List res, @Resource(name = "myOtherRes") List res2) { + + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ContextProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ContextProcessorTestCase.java new file mode 100644 index 0000000000..c0bf24e5fd --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ContextProcessorTestCase.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.core.implementation.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.osoa.sca.ComponentContext; +import org.osoa.sca.RequestContext; +import org.osoa.sca.annotations.Context; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ContextProcessorTestCase extends TestCase { + private ContextProcessor processor; + private Component composite; + + // FIXME: resurrect to test ComponentContext injection +/* + public void testCompositeContextMethod() throws Exception { + Method method = Foo.class.getMethod("setContext", ComponentContext.class); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitMethod(composite, method, type, null); + assertNotNull(type.getResources().get("context")); + } +*/ + + // FIXME: resurrect to test ComponentContext injection +/* + public void testCompositeContextField() throws Exception { + Field field = Foo.class.getDeclaredField("context"); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitField(composite, field, type, null); + assertNotNull(type.getResources().get("context")); + } +*/ + + public void testRequestContextMethod() throws Exception { + Method method = Foo.class.getMethod("setRequestContext", RequestContext.class); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitMethod(method, type, null); + assertNotNull(type.getResources().get("requestContext")); + } + + public void testRequestContextField() throws Exception { + Field field = Foo.class.getDeclaredField("requestContext"); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitField(field, type, null); + assertNotNull(type.getResources().get("requestContext")); + } + + public void testInvalidParamType() throws Exception { + Method method = Foo.class.getMethod("setContext", String.class); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + try { + processor.visitMethod(method, type, null); + fail(); + } catch (UnknownContextTypeException e) { + // expected + } + } + + public void testInvalidParamTypeField() throws Exception { + Field field = Foo.class.getDeclaredField("badContext"); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + try { + processor.visitField(field, type, null); + fail(); + } catch (UnknownContextTypeException e) { + // expected + } + } + + + public void testInvalidParamNum() throws Exception { + Method method = Foo.class.getMethod("setContext", ComponentContext.class, String.class); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + try { + processor.visitMethod(method, type, null); + fail(); + } catch (IllegalContextException e) { + // expected + } + } + + public void testInvalidNoParams() throws Exception { + Method method = Foo.class.getMethod("setContext"); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + try { + processor.visitMethod(method, type, null); + fail(); + } catch (IllegalContextException e) { + // expected + } + } + + public void testNoContext() throws Exception { + Method method = Foo.class.getMethod("noContext", ComponentContext.class); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitMethod(method, type, null); + assertEquals(0, type.getResources().size()); + } + + public void testNoContextField() throws Exception { + Field field = Foo.class.getDeclaredField("noContext"); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitField(field, type, null); + assertEquals(0, type.getResources().size()); + } + + protected void setUp() throws Exception { + super.setUp(); + processor = new ContextProcessor(); + processor.setWorkContext(EasyMock.createNiceMock(WorkContext.class)); + composite = EasyMock.createNiceMock(Component.class); + } + + private class Foo { + @Context + protected ComponentContext context; + + @Context + protected Object badContext; + + protected ComponentContext noContext; + + @Context + protected RequestContext requestContext; + + @Context + public void setContext(ComponentContext context) { + + } + + @Context + public void setContext(String context) { + + } + + @Context + public void setContext(ComponentContext context, String string) { + + } + + @Context + public void setContext() { + + } + + public void noContext(ComponentContext context) { + + } + + @Context + public void setRequestContext(RequestContext requestContext) { + this.requestContext = requestContext; + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConversationProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConversationProcessorTestCase.java new file mode 100644 index 0000000000..45149a1327 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConversationProcessorTestCase.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.core.implementation.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.osoa.sca.annotations.ConversationAttributes; +import org.osoa.sca.annotations.ConversationID; +import org.osoa.sca.annotations.Scope; + +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class ConversationProcessorTestCase extends TestCase { + private ConversationProcessor processor = new ConversationProcessor(); + + public void testMaxIdleTime() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitClass(FooMaxIdle.class, type, null); + assertEquals(10000L, type.getMaxIdleTime()); + assertEquals(-1, type.getMaxAge()); + } + + public void testMaxAge() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitClass(FooMaxAge.class, type, null); + assertEquals(10000L, type.getMaxAge()); + assertEquals(-1, type.getMaxIdleTime()); + } + + public void testBadFooBoth() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + try { + processor.visitClass(BadFooBoth.class, type, null); + fail(); + } catch (InvalidConversationalImplementation e) { + // expected + } + } + + public void testImplicitScope() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitClass(ImplicitFooScope.class, type, null); + assertEquals(org.apache.tuscany.spi.model.Scope.CONVERSATION, type.getImplementationScope()); + } + + public void testBadFooScope() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + try { + processor.visitClass(BadFooScope.class, type, null); + fail(); + } catch (InvalidConversationalImplementation e) { + // expected + } + } + + public void testJustConversation() throws Exception { + // TODO do we want these semantics + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitClass(FooJustConversation.class, type, null); + assertEquals(org.apache.tuscany.spi.model.Scope.CONVERSATION, type.getImplementationScope()); + assertEquals(-1, type.getMaxAge()); + assertEquals(-1, type.getMaxIdleTime()); + } + + public void testSetConversationIDField() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Field field = FooWithConversationIDField.class.getDeclaredField("conversationID"); + processor.visitField(field, type, null); + assertNotNull(type.getConversationIDMember()); + assertEquals(field, type.getConversationIDMember()); + } + + public void testSetConversationIDMethod() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Method method = FooWithConversationIDMethod.class.getDeclaredMethods()[0]; + processor.visitMethod(method, type, null); + assertNotNull(type.getConversationIDMember()); + assertEquals(method, type.getConversationIDMember()); + } + + @Scope("CONVERSATION") + @ConversationAttributes(maxIdleTime = "10 seconds") + private class FooMaxIdle { + } + + @Scope("CONVERSATION") + @ConversationAttributes(maxAge = "10 seconds") + private class FooMaxAge { + } + + @Scope("CONVERSATION") + @ConversationAttributes(maxAge = "10 seconds", maxIdleTime = "10 seconds") + private class BadFooBoth { + } + + @ConversationAttributes(maxAge = "10 seconds") + private class ImplicitFooScope { + } + + @Scope("STATELESS") + @ConversationAttributes(maxAge = "10 seconds") + private class BadFooScope { + } + + @ConversationAttributes + private class FooJustConversation { + } + + private class FooWithConversationIDField { + @ConversationID + private String conversationID; + } + + private class FooWithConversationIDMethod { + @ConversationID + void setConversationID(String conversationID) { + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConvertTimeMillisTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConvertTimeMillisTestCase.java new file mode 100644 index 0000000000..556416a797 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConvertTimeMillisTestCase.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.core.implementation.processor; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class ConvertTimeMillisTestCase extends TestCase { + private MockProcessor registy; + + public void testConvertSeconds() throws Exception { + assertEquals(10000L, registy.convertTimeMillis("10 seconds")); + assertEquals(10000L, registy.convertTimeMillis("10 SECONDS")); + try { + registy.convertTimeMillis("10seconds"); + fail(); + } catch (NumberFormatException e) { + // expected + } + } + + public void testConvertMinutes() throws Exception { + assertEquals(600000L, registy.convertTimeMillis("10 minutes")); + assertEquals(600000L, registy.convertTimeMillis("10 MINUTES")); + try { + registy.convertTimeMillis("10minutes"); + fail(); + } catch (NumberFormatException e) { + // expected + } + } + + public void testConvertHours() throws Exception { + assertEquals(36000000L, registy.convertTimeMillis("10 hours")); + assertEquals(36000000L, registy.convertTimeMillis("10 HOURS")); + try { + registy.convertTimeMillis("10hours"); + fail(); + } catch (NumberFormatException e) { + // expected + } + } + + public void testConvertDays() throws Exception { + assertEquals(864000000L, registy.convertTimeMillis("10 days")); + assertEquals(864000000L, registy.convertTimeMillis("10 DAYS")); + try { + registy.convertTimeMillis("10days"); + fail(); + } catch (NumberFormatException e) { + // expected + } + } + + public void testConvertYears() throws Exception { + assertEquals(315569260000L, registy.convertTimeMillis("10 years")); + assertEquals(315569260000L, registy.convertTimeMillis("10 YEARS")); + try { + registy.convertTimeMillis("10years"); + fail(); + } catch (NumberFormatException e) { + // expected + } + } + + public void testConvertDefault() throws Exception { + assertEquals(10000L, registy.convertTimeMillis("10 ")); + assertEquals(10000L, registy.convertTimeMillis("10")); + } + + public void testInvalid() throws Exception { + try { + registy.convertTimeMillis("foo"); + fail(); + } catch (NumberFormatException e) { + // expected + } + } + + protected void setUp() throws Exception { + super.setUp(); + registy = new MockProcessor(); + } + + private class MockProcessor extends ConversationProcessor { + + @Override + protected long convertTimeMillis(String expr) throws NumberFormatException { + return super.convertTimeMillis(expr); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/DestroyProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/DestroyProcessorTestCase.java new file mode 100644 index 0000000000..c4a4861d50 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/DestroyProcessorTestCase.java @@ -0,0 +1,100 @@ +/* + * 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.core.implementation.processor; + +import java.lang.reflect.Method; + +import org.osoa.sca.annotations.Destroy; + +import org.apache.tuscany.spi.implementation.java.JavaMappedService; + +import junit.framework.TestCase; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; + +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; + +/** + * @version $Rev$ $Date$ + */ +public class DestroyProcessorTestCase extends TestCase { + + public void testDestroy() throws Exception { + DestroyProcessor processor = new DestroyProcessor(); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Method method = Foo.class.getMethod("destroy"); + processor.visitMethod(method, type, null); + assertNotNull(type.getDestroyMethod()); + } + + public void testBadDestroy() throws Exception { + DestroyProcessor processor = new DestroyProcessor(); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Method method = Bar.class.getMethod("badDestroy", String.class); + try { + processor.visitMethod(method, type, null); + fail(); + } catch (IllegalDestructorException e) { + // expected + } + } + + public void testTwoDestroy() throws Exception { + DestroyProcessor processor = new DestroyProcessor(); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Method method = Bar.class.getMethod("destroy"); + Method method2 = Bar.class.getMethod("destroy2"); + processor.visitMethod(method, type, null); + try { + processor.visitMethod(method2, type, null); + fail(); + } catch (DuplicateDestructorException e) { + // expected + } + } + + + private class Foo { + + @Destroy + public void destroy() { + } + } + + + private class Bar { + + @Destroy + public void destroy() { + } + + @Destroy + public void destroy2() { + } + + @Destroy + public void badDestroy(String foo) { + } + + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/EagerInitProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/EagerInitProcessorTestCase.java new file mode 100644 index 0000000000..292f44c3bd --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/EagerInitProcessorTestCase.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.implementation.processor; + +import org.osoa.sca.annotations.EagerInit; + +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class EagerInitProcessorTestCase extends TestCase { + + public void testNoLevel() throws ProcessingException { + EagerInitProcessor processor = new EagerInitProcessor(); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitClass(Level.class, type, null); + assertEquals(50, type.getInitLevel()); + } + + public void testSubclass() throws ProcessingException { + EagerInitProcessor processor = new EagerInitProcessor(); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitClass(SubClass.class, type, null); + assertEquals(50, type.getInitLevel()); + } + + @EagerInit + private class Level { + } + + private class SubClass extends Level { + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicAndPropertyTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicAndPropertyTestCase.java new file mode 100644 index 0000000000..7827e47872 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicAndPropertyTestCase.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.core.implementation.processor; + +import java.lang.reflect.Constructor; + +import org.osoa.sca.annotations.Property; + +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; + +/** + * @version $Rev$ $Date$ + */ +public class HeuristicAndPropertyTestCase extends TestCase { + + private PropertyProcessor propertyProcessor; + private HeuristicPojoProcessor heuristicProcessor; + + /** + * Verifies the property and heuristic processors don't collide + */ + @SuppressWarnings("unchecked") + public void testPropertyProcessorWithHeuristicProcessor() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor ctor = Foo.class.getConstructor(String.class); + type.setConstructorDefinition(new ConstructorDefinition(ctor)); + propertyProcessor.visitConstructor(ctor, type, null); + heuristicProcessor.visitEnd(Foo.class, type, null); + assertEquals(1, type.getProperties().size()); + assertNotNull(type.getProperties().get("foo")); + } + + protected void setUp() throws Exception { + super.setUp(); + ImplementationProcessorServiceImpl service = + new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl()); + propertyProcessor = new PropertyProcessor(service); + heuristicProcessor = new HeuristicPojoProcessor(service); + } + + public static class Foo { + public Foo(@Property(name = "foo") String prop) { + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicConstructorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicConstructorTestCase.java new file mode 100644 index 0000000000..45fe6be68f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicConstructorTestCase.java @@ -0,0 +1,297 @@ +/* + * 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.core.implementation.processor; + +import java.net.URI; + +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Remotable; + +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.model.ServiceContract; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; + +/** + * @version $Rev$ $Date$ + */ +public class HeuristicConstructorTestCase extends TestCase { + + private HeuristicPojoProcessor processor = + new HeuristicPojoProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl())); + + /** + * Verifies a single constructor is chosen with a parameter as the type + */ + public void testSingleConstructorWithParam() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + JavaMappedProperty<String> prop = new JavaMappedProperty<String>(); + prop.setName("foo"); + prop.setJavaType(String.class); + type.getProperties().put("foo", prop); + processor.visitEnd(Foo1.class, type, null); + assertNotNull(type.getConstructorDefinition().getConstructor()); + assertEquals("foo", type.getConstructorDefinition().getInjectionNames().get(0)); + } + + /** + * Verifies a single constructor is chosen with a reference as the type + */ + public void testSingleConstructorWithRef() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + JavaMappedReference ref = new JavaMappedReference(); + ref.setUri(URI.create("#foo")); + ServiceContract contract = new JavaServiceContract(String.class); + ref.setServiceContract(contract); + type.getReferences().put("foo", ref); + processor.visitEnd(Foo1.class, type, null); + assertNotNull(type.getConstructorDefinition().getConstructor()); + assertEquals("foo", type.getConstructorDefinition().getInjectionNames().get(0)); + } + + /** + * Verifies a single constructor is chosen with a property and a reference as the type + */ + public void testSingleConstructorWithPropRef() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + + JavaMappedProperty<String> prop = new JavaMappedProperty<String>(); + prop.setName("foo"); + prop.setJavaType(String.class); + type.getProperties().put("foo", prop); + + JavaMappedReference ref = new JavaMappedReference(); + ref.setUri(URI.create("#ref")); + ServiceContract contract = new JavaServiceContract(Foo1.class); + ref.setServiceContract(contract); + type.getReferences().put("ref", ref); + processor.visitEnd(Foo2.class, type, null); + assertNotNull(type.getConstructorDefinition().getConstructor()); + assertEquals(2, type.getConstructorDefinition().getInjectionNames().size()); + } + + + public void testSingleConstructorResolvableParam() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitEnd(Foo5.class, type, null); + assertEquals(String.class, type.getProperties().get("string").getJavaType()); + } + + public void testSingleConstructorResolvableRef() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitEnd(Foo6.class, type, null); + assertEquals(Ref.class, + type.getReferences().get("heuristicconstructortestcase$ref").getServiceContract().getInterfaceClass()); + } + + public void testSingleConstructorAmbiguousRef() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + JavaMappedReference ref = new JavaMappedReference(); + ref.setUri(URI.create("#ref")); + ServiceContract contract = new JavaServiceContract(Foo1.class); + ref.setServiceContract(contract); + type.getReferences().put("ref", ref); + JavaMappedReference ref2 = new JavaMappedReference(); + ref2.setUri(URI.create("#ref2")); + ref2.setServiceContract(contract); + type.getReferences().put("ref2", ref2); + try { + processor.visitEnd(Foo4.class, type, null); + fail(); + } catch (AmbiguousConstructorException e) { + // expected + } + } + + public void testConstructorPropertyAnnotatedParamsOnly() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitEnd(Foo7.class, type, null); + assertNotNull(type.getProperties().get("myProp")); + } + + public void testConstructorReferenceAnnotatedParamsOnly() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitEnd(Foo8.class, type, null); + assertNotNull(type.getReferences().get("myRef")); + } + + @SuppressWarnings("unchecked") + public void testDefaultConstructor() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitEnd(Foo3.class, type, null); + assertNotNull(type.getConstructorDefinition().getConstructor()); + } + + public void testSameTypesButAnnotated() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitEnd(Foo12.class, type, null); + assertEquals(2, type.getProperties().size()); + assertNotNull(type.getProperties().get("prop1")); + assertNotNull(type.getProperties().get("prop2")); + } + + /** + * Verifies processing executes with additional extension annotations + */ + public void testRandomAnnotation() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitEnd(Foo11.class, type, null); + assertEquals(1, type.getProperties().size()); + assertNotNull(type.getProperties().get("prop1")); + } + + public void testPrivateConstructor() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + try { + processor.visitEnd(Foo14.class, type, null); + fail(); + } catch (NoConstructorException e) { + // expected + } + } + + + public void testMultipleConstructors() throws Exception { + // throw new UnsupportedOperationException("Finish heuristic multiple constructors - Foo10"); + } + + + public static class Foo1 { + public Foo1(String val) { + } + } + + public static class Foo2 { + public Foo2(String val, Foo1 ref) { + } + } + + public static class Foo3 { + } + + public static class Foo4 { + public Foo4(Foo1 ref) { + } + } + + public static class Prop { + + } + + @Remotable + public static interface Ref { + + } + + public static class Foo5 { + public Foo5(String val) { + } + } + + public static class Foo6 { + public Foo6(Ref ref) { + } + } + + public static class Foo7 { + public Foo7(@Property(name = "myProp")String prop) { + } + } + + + public static class Foo8 { + public Foo8(@Reference(name = "myRef")String ref) { + } + } + + public static class Foo9 { + public Foo9(@Reference(name = "myRef")String ref) { + } + } + + public static class Foo10 { + + public Foo10() { + } + + public Foo10(String prop) { + } + + public Foo10(@Property(name = "prop1")String prop1, @Property(name = "prop2")String prop2) { + + } + } + + public static class Foo11 { + + public Foo11(@Property(name = "prop1")String prop, @Baz String baz) { + } + } + + public static class Foo12 { + + public Foo12(@Property(name = "prop1")String prop, @Property(name = "prop2")String baz) { + } + } + + public @interface Baz { + + } + + public static class Foo13 { + public Foo13(@Reference String foo) { + } + } + + public static final class Foo14 { + private Foo14() { + } + } + + public static final class Foo15 { + public Foo15(@Reference String param1, @Reference String param2) { + } + } + + public static final class Foo16 { + public Foo16(@Reference String param1, + @Property(name = "foo")String param2, + @Reference(name = "bar")String param3) { + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicPojoProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicPojoProcessorTestCase.java new file mode 100644 index 0000000000..9863960c1e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicPojoProcessorTestCase.java @@ -0,0 +1,396 @@ +/* + * 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.core.implementation.processor; + +import java.lang.reflect.Constructor; +import java.net.URI; +import java.util.Collection; +import java.util.List; + +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Remotable; +import org.osoa.sca.annotations.Service; + +import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension; +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; + +/** + * Verfies component type information is properly introspected from an unadorned POJO according to the SCA Java Client + * and Implementation Model Specification + * + * @version $Rev$ $Date$ + */ +public class HeuristicPojoProcessorTestCase extends TestCase { + + private HeuristicPojoProcessor processor = + new HeuristicPojoProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl())); + + /** + * Verifies a single service interface is computed when only one interface is implemented + */ + public void testSingleInterface() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<SingleInterfaceImpl> ctor = SingleInterfaceImpl.class.getConstructor(); + type.setConstructorDefinition(new ConstructorDefinition<SingleInterfaceImpl>(ctor)); + processor.visitEnd(SingleInterfaceImpl.class, type, null); + assertEquals(1, type.getServices().size()); + assertEquals(PropertyInterface.class, + type.getServices().get(PropertyInterface.class.getSimpleName()) + .getServiceContract().getInterfaceClass()); + assertTrue(type.getProperties().isEmpty()); + assertTrue(type.getReferences().isEmpty()); + } + + /** + * Verifies property and reference setters are computed + */ + public void testPropertyReference() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<SingleInterfaceWithPropertyReferenceImpl> ctor = + SingleInterfaceWithPropertyReferenceImpl.class.getConstructor(); + type.setConstructorDefinition(new ConstructorDefinition<SingleInterfaceWithPropertyReferenceImpl>(ctor)); + processor.visitEnd(SingleInterfaceWithPropertyReferenceImpl.class, type, null); + assertEquals(1, type.getServices().size()); + assertEquals(Interface1.class, + type.getServices().get(Interface1.class.getSimpleName()) + .getServiceContract().getInterfaceClass()); + assertEquals(1, type.getProperties().size()); + assertEquals(ComplexProperty.class, type.getProperties().get("property").getJavaType()); + assertEquals(1, type.getReferences().size()); + assertEquals(Ref.class, type.getReferences().get("reference").getServiceContract().getInterfaceClass()); + } + + /** + * Verifies that a property setter is not introspected if an analogous operation is in the service interface + */ + public void testPropertySetterInInterface() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<SingleInterfaceImpl> ctor = SingleInterfaceImpl.class.getConstructor(); + type.setConstructorDefinition(new ConstructorDefinition<SingleInterfaceImpl>(ctor)); + processor.visitEnd(SingleInterfaceImpl.class, type, null); + assertEquals(0, type.getProperties().size()); + } + + /** + * Verifies that a reference setter is not introspected if an analogous operation is in the service interface + */ + public void testReferenceSetterInInterface() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<RefInterfaceImpl> ctor = RefInterfaceImpl.class.getConstructor(); + type.setConstructorDefinition(new ConstructorDefinition<RefInterfaceImpl>(ctor)); + processor.visitEnd(RefInterfaceImpl.class, type, null); + assertEquals(0, type.getReferences().size()); + } + + /** + * Verifies collection generic types or array types are introspected as references according to spec rules + */ + public void testReferenceCollectionType() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<ReferenceCollectionImpl> ctor = ReferenceCollectionImpl.class.getConstructor(); + type.setConstructorDefinition(new ConstructorDefinition<ReferenceCollectionImpl>(ctor)); + processor.visitEnd(ReferenceCollectionImpl.class, type, null); + assertEquals(0, type.getProperties().size()); + assertEquals(4, type.getReferences().size()); + } + + /** + * Verifies collection generic types or array types are introspected as properties according to spec rules + */ + public void testPropertyCollectionType() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<PropertyCollectionImpl> ctor = PropertyCollectionImpl.class.getConstructor(); + type.setConstructorDefinition(new ConstructorDefinition<PropertyCollectionImpl>(ctor)); + processor.visitEnd(PropertyCollectionImpl.class, type, null); + assertEquals(0, type.getReferences().size()); + assertEquals(4, type.getProperties().size()); + } + + /** + * Verifies references are calculated when the type marked with is @Remotable + */ + public void testRemotableRef() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<RemotableRefImpl> ctor = RemotableRefImpl.class.getConstructor(); + type.setConstructorDefinition(new ConstructorDefinition<RemotableRefImpl>(ctor)); + processor.visitEnd(RemotableRefImpl.class, type, null); + assertEquals(2, type.getReferences().size()); + assertEquals(0, type.getProperties().size()); + } + + public void testParentInterface() throws ProcessingException, NoSuchMethodException { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Child> ctor = Child.class.getConstructor(); + type.setConstructorDefinition(new ConstructorDefinition<Child>(ctor)); + processor.visitEnd(Child.class, type, null); + assertTrue(type.getServices().containsKey(Interface1.class.getSimpleName())); + } + + /** + * Verifies a service inteface is calculated when only props and refs are given + */ + public void testExcludedPropertyAndReference() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + JavaMappedReference ref = new JavaMappedReference(); + ref.setUri(URI.create("#reference")); + type.add(ref); + JavaMappedReference ref2 = new JavaMappedReference(); + ref2.setUri(URI.create("#reference2")); + type.add(ref2); + JavaMappedProperty<?> prop1 = new JavaMappedProperty(); + prop1.setName("string1"); + type.add(prop1); + JavaMappedProperty<?> prop2 = new JavaMappedProperty(); + prop2.setName("string2"); + type.add(prop2); + processor.visitEnd(MockService.class, type, null); + assertEquals(1, type.getServices().size()); + } + + public void testProtectedRemotableRefField() throws ProcessingException, NoSuchMethodException { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<ProtectedRemotableRefFieldImpl> ctor = ProtectedRemotableRefFieldImpl.class.getConstructor(); + type.setConstructorDefinition(new ConstructorDefinition<ProtectedRemotableRefFieldImpl>(ctor)); + processor.visitEnd(ProtectedRemotableRefFieldImpl.class, type, null); + assertNotNull(type.getReferences().get("otherRef")); + } + + public void testProtectedRemotableRefMethod() throws ProcessingException, NoSuchMethodException { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<ProtectedRemotableRefMethodImpl> ctor = ProtectedRemotableRefMethodImpl.class.getConstructor(); + type.setConstructorDefinition(new ConstructorDefinition<ProtectedRemotableRefMethodImpl>(ctor)); + processor.visitEnd(ProtectedRemotableRefMethodImpl.class, type, null); + assertNotNull(type.getReferences().get("otherRef")); + } + + public void testSetDataTypes() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<PropertyIntTypeOnConstructor> ctor = PropertyIntTypeOnConstructor.class.getConstructor(int.class); + type.setConstructorDefinition(new ConstructorDefinition<PropertyIntTypeOnConstructor>(ctor)); + processor.visitEnd(ProtectedRemotableRefMethodImpl.class, type, null); + org.apache.tuscany.spi.model.Property<?> foo = type.getProperties().get("foo"); + assertEquals(int.class, foo.getJavaType()); + assertEquals(SimpleTypeMapperExtension.XSD_INT, foo.getXmlType()); + } + + private static class PropertyIntTypeOnConstructor { + private int foo; + + public PropertyIntTypeOnConstructor(@Property(name = "foo")int foo) { + this.foo = foo; + } + + public int getFoo() { + return foo; + } + } + + private interface PropertyInterface { + void setString1(String val); + } + + private interface Interface1 { + } + + private static class Parent implements Interface1 { + + } + + private static class Child extends Parent { + public Child() { + } + + } + + private static class SingleInterfaceImpl implements PropertyInterface { + public SingleInterfaceImpl() { + } + + public void setString1(String val) { + } + + } + + private interface HeuristicServiceInterface { + void fooOperation(String ref); + + void setInvalid1(); // No parameter + + void setInvalid2(String str, int i); // More than one parameter + + String setInvalid3(String str); // return should be void + } + + public static class MockService implements PropertyInterface, RefInterface, HeuristicServiceInterface { + + @Property + public void setString1(String val) { + } + + @Property + public void setString2(String val) { + } + + @Reference + public void setReference(Ref ref) { + } + + @Reference + public void setReference2(Ref ref) { + } + + public void fooOperation(String ref) { + + } + + public void setInvalid1() { + } + + public void setInvalid2(String str, int i) { + } + + public String setInvalid3(String str) { + return null; + } + + } + + @Service + private interface Ref { + } + + private class ComplexProperty { + } + + private interface RefInterface { + void setReference(Ref ref); + } + + private static class RefInterfaceImpl implements RefInterface { + public RefInterfaceImpl() { + } + + public void setReference(Ref ref) { + } + } + + private static class SingleInterfaceWithPropertyReferenceImpl implements Interface1 { + public SingleInterfaceWithPropertyReferenceImpl() { + } + + public void setReference(Ref ref) { + } + + public void setProperty(ComplexProperty prop) { + } + } + + private static class ReferenceCollectionImpl implements Interface1 { + public ReferenceCollectionImpl() { + } + + public void setCollectionReference(Collection<Ref> ref) { + } + + public void setNonGenericCollectionReference(Collection ref) { + } + + public void setListReference(List<Ref> ref) { + } + + public void setArrayReference(Ref[] ref) { + } + } + + private static class PropertyCollectionImpl implements Interface1 { + public PropertyCollectionImpl() { + } + + public void setCollectionProperty(Collection<ComplexProperty> prop) { + } + + public void setCollectionProperty2(Collection<String> prop) { + } + + public void setArrayProperty(ComplexProperty[] prop) { + } + + public void setArrayProperty2(String[] prop) { + } + } + + @Remotable + private interface RemotableRef { + } + + private static class RemotableRefImpl implements Interface1 { + protected RemotableRef otherRef; + + public RemotableRefImpl() { + } + + public void setRef(RemotableRef ref) { + + } + } + + private static class ProtectedRemotableRefFieldImpl implements Interface1 { + protected RemotableRef otherRef; + + public ProtectedRemotableRefFieldImpl() { + } + + public ProtectedRemotableRefFieldImpl(RemotableRef otherRef) { + this.otherRef = otherRef; + } + + } + + private static class ProtectedRemotableRefMethodImpl implements Interface1 { + public ProtectedRemotableRefMethodImpl() { + } + + protected void setOtherRef(RemotableRef otherRef) { + } + + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeutisticExtensibleConstructorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeutisticExtensibleConstructorTestCase.java new file mode 100644 index 0000000000..ed2fea8c41 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeutisticExtensibleConstructorTestCase.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.core.implementation.processor; + +import java.lang.reflect.Constructor; +import java.util.List; + +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; + +/** + * Verifies constructors that have extensible annotation types, i.e. that have parameters marked by annotations which + * are themselves processed by some other implementation processor + * + * @version $Rev$ $Date$ + */ +public class HeutisticExtensibleConstructorTestCase extends TestCase { + + private HeuristicPojoProcessor processor = + new HeuristicPojoProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl())); + + /** + * Verifies heuristic processing can be called priot to an extension annotation processors being called. + */ + public void testBarAnnotationProcessedFirst() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Foo> ctor = Foo.class.getConstructor(String.class, String.class); + ConstructorDefinition<Foo> definition = new ConstructorDefinition<Foo>(ctor); + type.setConstructorDefinition(definition); + JavaMappedProperty property = new JavaMappedProperty(); + property.setName("myBar"); + definition.getInjectionNames().add("myBar"); + type.getProperties().put("myBar", property); + processor.visitEnd(Foo.class, type, null); + assertEquals(2, type.getProperties().size()); + } + + /** + * Verifies heuristic processing can be called before an extension annotation processors is called. + * <p/> + * For example, given: + * <pre> Foo(@Bar String prop, @org.osoa.sca.annotations.Property(name = "foo") String prop2)</pre> + * <p/> + * Heuristic evaluation of @Property can occur prior to another implementation processor evaluating @Bar + * + * @throws Exception + */ + public void testBarAnnotationProcessedLast() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitEnd(Foo.class, type, null); + + // now simulate process the bar impl + ConstructorDefinition<?> definition = type.getConstructorDefinition(); + List<String> injectionNames = definition.getInjectionNames(); + injectionNames.remove(0); + injectionNames.add(0, "mybar"); + type.getProperties().put("mybar", new JavaMappedProperty<String>()); + + assertEquals(2, type.getProperties().size()); + assertEquals("foo", definition.getInjectionNames().get(1)); + } + + /** + * Verifies heuristic processing can be called before an extension annotation processors is called with the + * extension parameter in a middle position. Specifically, verifies that the heuristic processor updates injection + * names and preserves their ordering. + */ + public void testBarAnnotationProcessedFirstInMiddle() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Foo2> ctor = Foo2.class.getConstructor(String.class, String.class, String.class); + ConstructorDefinition<Foo2> definition = new ConstructorDefinition<Foo2>(ctor); + type.setConstructorDefinition(definition); + // insert placeholder for first param, which would be done by a processor + definition.getInjectionNames().add(""); + JavaMappedProperty property = new JavaMappedProperty(); + property.setName("myBar"); + definition.getInjectionNames().add("myBar"); + type.getProperties().put("myBar", property); + processor.visitEnd(Foo2.class, type, null); + assertEquals("baz", definition.getInjectionNames().get(0)); + assertEquals(2, type.getProperties().size()); + assertEquals(1, type.getReferences().size()); + } + + public @interface Bar { + + } + + public static class Foo { + public Foo(@Bar String prop, @org.osoa.sca.annotations.Property(name = "foo") String prop2) { + } + } + + public static class Foo2 { + public Foo2(@org.osoa.sca.annotations.Reference(name = "baz") String prop1, + @Bar String prop2, + @org.osoa.sca.annotations.Property(name = "foo") String prop3) { + } + } + + +} + + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceTestCase.java new file mode 100644 index 0000000000..9f340ccd11 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceTestCase.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.core.implementation.processor; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; + +import org.osoa.sca.annotations.Callback; +import org.osoa.sca.annotations.Conversational; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Remotable; + +import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.model.ServiceContract; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; + +/** + * @version $Rev$ $Date$ + */ +public class ImplementationProcessorServiceTestCase extends TestCase { + + private ImplementationProcessorService implService = + new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl()); + + public void testCreateConversationalService() throws Exception { + JavaMappedService service = implService.createService(Foo.class); + assertTrue(Foo.class.equals(service.getServiceContract().getInterfaceClass())); + assertTrue(service.isRemotable()); + assertTrue(service.getServiceContract().isConversational()); + ServiceContract serviceContract = service.getServiceContract(); + assertTrue(Bar.class.equals(serviceContract.getCallbackClass())); + assertTrue("ImplementationProcessorServiceTestCase$Bar".equals(serviceContract.getCallbackName())); + } + + public void testCreateDefaultService() throws Exception { + JavaMappedService service = implService.createService(Baz.class); + assertTrue(Baz.class.equals(service.getServiceContract().getInterfaceClass())); + assertTrue(!service.isRemotable()); + assertFalse(service.getServiceContract().isConversational()); + } + + public void testProcessParamProperty() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<PropertyClass> ctor = PropertyClass.class.getConstructor(int.class); + Annotation[] paramAnnotations = ctor.getParameterAnnotations()[0]; + List<String> injectionNames = new ArrayList<String>(); + String[] names = new String[]{"foo"}; + implService.processParam(int.class, + ctor.getGenericParameterTypes()[0], + paramAnnotations, + names, + 0, + type, + injectionNames); + org.apache.tuscany.spi.model.Property<?> property = type.getProperties().get("foo"); + assertEquals(int.class, property.getJavaType()); + assertEquals(SimpleTypeMapperExtension.XSD_INT, property.getXmlType()); + } + + + @Conversational + @Callback(Bar.class) + @Remotable + public interface Foo { + + } + + public interface Bar { + + } + + public interface Baz { + + } + + public static class PropertyClass { + private int foo; + + public PropertyClass(@Property(name = "foo")int foo) { + this.foo = foo; + } + + public int getFoo() { + return foo; + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceUniqueTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceUniqueTestCase.java new file mode 100644 index 0000000000..da45ed2d46 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceUniqueTestCase.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.implementation.processor; + +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; + +/** + * @version $Rev$ $Date$ + */ +public class ImplementationProcessorServiceUniqueTestCase extends TestCase { + + private ImplementationProcessorService service = + new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl()); + + public void testUniquess1() throws Exception { + Class[] classes = new Class[2]; + classes[0] = String.class; + classes[1] = Integer.class; + assertTrue(service.areUnique(classes)); + } + + public void testUniquess2() throws Exception { + Class[] classes = new Class[2]; + classes[0] = String.class; + classes[1] = String.class; + assertFalse(service.areUnique(classes)); + } + + public void testUniquess3() throws Exception { + Class[] classes = new Class[1]; + classes[0] = String.class; + assertTrue(service.areUnique(classes)); + } + + public void testUniquess4() throws Exception { + Class[] classes = new Class[3]; + classes[0] = String.class; + classes[1] = Integer.class; + classes[2] = String.class; + assertFalse(service.areUnique(classes)); + } + + public void testUniquess5() throws Exception { + Class[] classes = new Class[0]; + assertTrue(service.areUnique(classes)); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/InitProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/InitProcessorTestCase.java new file mode 100644 index 0000000000..ee3a0d83d1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/InitProcessorTestCase.java @@ -0,0 +1,98 @@ +/* + * 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.core.implementation.processor; + +import java.lang.reflect.Method; + +import org.osoa.sca.annotations.Init; + +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class InitProcessorTestCase extends TestCase { + + public void testInit() throws Exception { + InitProcessor processor = new InitProcessor(); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Method method = InitProcessorTestCase.Foo.class.getMethod("init"); + processor.visitMethod(method, type, null); + assertNotNull(type.getInitMethod()); + assertEquals(0, type.getInitLevel()); + } + + public void testBadInit() throws Exception { + InitProcessor processor = new InitProcessor(); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Method method = InitProcessorTestCase.Bar.class.getMethod("badInit", String.class); + try { + processor.visitMethod(method, type, null); + fail(); + } catch (IllegalInitException e) { + // expected + } + } + + public void testTwoInit() throws Exception { + InitProcessor processor = new InitProcessor(); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Method method = InitProcessorTestCase.Bar.class.getMethod("init"); + Method method2 = InitProcessorTestCase.Bar.class.getMethod("init2"); + processor.visitMethod(method, type, null); + try { + processor.visitMethod(method2, type, null); + fail(); + } catch (DuplicateInitException e) { + // expected + } + } + + + private class Foo { + @Init + public void init() { + } + } + + + private class Bar { + @Init + public void init() { + } + + @Init + public void init2() { + } + + @Init + public void badInit(String foo) { + } + + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/MonitorProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/MonitorProcessorTestCase.java new file mode 100644 index 0000000000..c3683399ca --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/MonitorProcessorTestCase.java @@ -0,0 +1,180 @@ +/* + * 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.core.implementation.processor; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Map; + +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.IllegalPropertyException; + +import junit.framework.TestCase; +import org.apache.tuscany.api.annotation.Monitor; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.injection.SingletonObjectFactory; +import org.apache.tuscany.host.MonitorFactory; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class MonitorProcessorTestCase extends TestCase { + + private MonitorProcessor processor; + private MonitorFactory monitorFactory; + + public void testSetter() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Method method = Foo.class.getMethod("setMonitor", Foo.class); + EasyMock.expect(monitorFactory.getMonitor(EasyMock.eq(Foo.class))).andReturn(null); + EasyMock.replay(monitorFactory); + processor.visitMethod(method, type, null); + Map<String, JavaMappedProperty<?>> properties = type.getProperties(); + assertTrue(properties.get("monitor").getDefaultValueFactory() instanceof SingletonObjectFactory); + EasyMock.verify(monitorFactory); + } + + + public void testBadSetter() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Method method = BadMonitor.class.getMethod("setMonitor"); + try { + processor.visitMethod(method, type, null); + fail(); + } catch (IllegalPropertyException e) { + // expected + } + } + + public void testField() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Field field = Foo.class.getDeclaredField("bar"); + EasyMock.expect(monitorFactory.getMonitor(EasyMock.eq(Foo.class))).andReturn(null); + EasyMock.replay(monitorFactory); + processor.visitField(field, type, null); + Map<String, JavaMappedProperty<?>> properties = type.getProperties(); + assertTrue(properties.get("bar").getDefaultValueFactory() instanceof SingletonObjectFactory); + EasyMock.verify(monitorFactory); + } + + public void testConstructor() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Bar> ctor = Bar.class.getConstructor(BazMonitor.class); + EasyMock.expect(monitorFactory.getMonitor(EasyMock.eq(BazMonitor.class))).andReturn(null); + EasyMock.replay(monitorFactory); + processor.visitConstructor(ctor, type, null); + Map<String, JavaMappedProperty<?>> properties = type.getProperties(); + assertTrue( + properties.get(BazMonitor.class.getName()).getDefaultValueFactory() instanceof SingletonObjectFactory); + EasyMock.verify(monitorFactory); + } + + /** + * Verifies calling the monitor processor to evaluate a constructor can be done after a property parameter is + * processed + */ + public void testConstructorAfterProperty() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Bar> ctor = Bar.class.getConstructor(String.class, BazMonitor.class); + EasyMock.expect(monitorFactory.getMonitor(EasyMock.eq(BazMonitor.class))).andReturn(null); + EasyMock.replay(monitorFactory); + ConstructorDefinition<Bar> definition = new ConstructorDefinition<Bar>(ctor); + JavaMappedProperty prop = new JavaMappedProperty(); + definition.getInjectionNames().add("prop"); + type.setConstructorDefinition(definition); + type.getProperties().put("prop", prop); + processor.visitConstructor(ctor, type, null); + Map<String, JavaMappedProperty<?>> properties = type.getProperties(); + assertEquals(BazMonitor.class.getName(), definition.getInjectionNames().get(1)); + assertEquals(2, type.getProperties().size()); + String name = BazMonitor.class.getName(); + assertTrue(properties.get(name).getDefaultValueFactory() instanceof SingletonObjectFactory); + EasyMock.verify(monitorFactory); + } + + /** + * Verifies calling the monitor processor to evaluate a constructor can be done before a property parameter is + * processed + */ + public void testConstructorBeforeProperty() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + Constructor<Bar> ctor = Bar.class.getConstructor(String.class, BazMonitor.class); + EasyMock.expect(monitorFactory.getMonitor(EasyMock.eq(BazMonitor.class))).andReturn(null); + EasyMock.replay(monitorFactory); + processor.visitConstructor(ctor, type, null); + Map<String, JavaMappedProperty<?>> properties = type.getProperties(); + ConstructorDefinition definition = type.getConstructorDefinition(); + assertEquals(2, definition.getInjectionNames().size()); + assertEquals(BazMonitor.class.getName(), definition.getInjectionNames().get(1)); + String name = BazMonitor.class.getName(); + assertTrue(properties.get(name).getDefaultValueFactory() instanceof SingletonObjectFactory); + EasyMock.verify(monitorFactory); + } + + protected void setUp() throws Exception { + super.setUp(); + monitorFactory = EasyMock.createMock(MonitorFactory.class); + JavaInterfaceProcessorRegistryImpl registry = new JavaInterfaceProcessorRegistryImpl(); + ImplementationProcessorServiceImpl processor = new ImplementationProcessorServiceImpl(registry); + this.processor = new MonitorProcessor(monitorFactory, processor); + } + + private class Foo { + + @Monitor + protected Foo bar; + + @Monitor + public void setMonitor(Foo foo) { + } + } + + + private class BadMonitor { + + @Monitor + public void setMonitor() { + } + } + + private interface BazMonitor { + + } + + private static class Bar { + + public Bar(@Monitor BazMonitor monitor) { + } + + public Bar(String prop, @Monitor BazMonitor monitor) { + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/PropertyProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/PropertyProcessorTestCase.java new file mode 100644 index 0000000000..b91a33f6f0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/PropertyProcessorTestCase.java @@ -0,0 +1,208 @@ +/* + * 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.core.implementation.processor; + +import java.util.Collection; +import java.util.List; + +import org.osoa.sca.annotations.Property; + +import org.apache.tuscany.spi.implementation.java.DuplicatePropertyException; +import org.apache.tuscany.spi.implementation.java.IllegalPropertyException; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; + +/** + * @version $Rev$ $Date$ + */ +public class PropertyProcessorTestCase extends TestCase { + + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type; + PropertyProcessor processor; + + public void testMethodAnnotation() throws Exception { + processor.visitMethod(Foo.class.getMethod("setFoo", String.class), type, null); + assertNotNull(type.getProperties().get("foo")); + } + + public void testMethodRequired() throws Exception { + processor.visitMethod(Foo.class.getMethod("setFooRequired", String.class), type, null); + JavaMappedProperty prop = type.getProperties().get("fooRequired"); + assertNotNull(prop); + assertTrue(prop.isRequired()); + } + + public void testMethodName() throws Exception { + processor.visitMethod(Foo.class.getMethod("setBarMethod", String.class), type, null); + assertNotNull(type.getProperties().get("bar")); + } + + public void testFieldAnnotation() throws Exception { + processor.visitField(Foo.class.getDeclaredField("baz"), type, null); + assertNotNull(type.getProperties().get("baz")); + } + + public void testFieldRequired() throws Exception { + processor.visitField(Foo.class.getDeclaredField("bazRequired"), type, null); + JavaMappedProperty prop = type.getProperties().get("bazRequired"); + assertNotNull(prop); + assertTrue(prop.isRequired()); + } + + public void testFieldName() throws Exception { + processor.visitField(Foo.class.getDeclaredField("bazField"), type, null); + assertNotNull(type.getProperties().get("theBaz")); + } + + public void testDuplicateFields() throws Exception { + processor.visitField(Bar.class.getDeclaredField("dup"), type, null); + try { + processor.visitField(Bar.class.getDeclaredField("baz"), type, null); + fail(); + } catch (DuplicatePropertyException e) { + // expected + } + } + + public void testDuplicateMethods() throws Exception { + processor.visitMethod(Bar.class.getMethod("dupMethod", String.class), type, null); + try { + processor.visitMethod(Bar.class.getMethod("dupSomeMethod", String.class), type, null); + fail(); + } catch (DuplicatePropertyException e) { + // expected + } + } + + public void testInvalidProperty() throws Exception { + try { + processor.visitMethod(Bar.class.getMethod("badMethod"), type, null); + fail(); + } catch (IllegalPropertyException e) { + // expected + } + } + + protected void setUp() throws Exception { + super.setUp(); + type = new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + JavaInterfaceProcessorRegistryImpl registry = new JavaInterfaceProcessorRegistryImpl(); + processor = new PropertyProcessor(new ImplementationProcessorServiceImpl(registry)); + } + + private class Foo { + + @Property + protected String baz; + @Property(required = true) + protected String bazRequired; + @Property(name = "theBaz") + protected String bazField; + + @Property + public void setFoo(String string) { + } + + @Property(required = true) + public void setFooRequired(String string) { + } + + @Property(name = "bar") + public void setBarMethod(String string) { + } + + } + + private class Bar { + + @Property + protected String dup; + + @Property(name = "dup") + protected String baz; + + @Property + public void dupMethod(String s) { + } + + @Property(name = "dupMethod") + public void dupSomeMethod(String s) { + } + + @Property + public void badMethod() { + } + + } + + private class Multiple { + @Property + protected List<String> refs1; + + @Property + protected String[] refs2; + + @Property + public void setRefs3(String[] refs) { + } + + @Property + public void setRefs4(Collection<String> refs) { + } + + } + + public void testMultiplicityCollection() throws Exception { + processor.visitField(Multiple.class.getDeclaredField("refs1"), type, null); + JavaMappedProperty prop = type.getProperties().get("refs1"); + assertNotNull(prop); + assertSame(String.class, prop.getJavaType()); + assertTrue(prop.isMany()); + } + + public void testMultiplicityArray() throws Exception { + processor.visitField(Multiple.class.getDeclaredField("refs2"), type, null); + JavaMappedProperty prop = type.getProperties().get("refs2"); + assertNotNull(prop); + assertSame(String.class, prop.getJavaType()); + assertTrue(prop.isMany()); + } + + public void testMultiplicityArrayMethod() throws Exception { + processor.visitMethod(Multiple.class.getMethod("setRefs3", String[].class), type, null); + JavaMappedProperty prop = type.getProperties().get("refs3"); + assertNotNull(prop); + assertSame(String.class, prop.getJavaType()); + assertTrue(prop.isMany()); + } + + public void testMultiplicityCollectionMethod() throws Exception { + processor.visitMethod(Multiple.class.getMethod("setRefs4", Collection.class), type, null); + JavaMappedProperty prop = type.getProperties().get("refs4"); + assertNotNull(prop); + assertSame(String.class, prop.getJavaType()); + assertTrue(prop.isMany()); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ReferenceProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ReferenceProcessorTestCase.java new file mode 100644 index 0000000000..7ee40f3eb2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ReferenceProcessorTestCase.java @@ -0,0 +1,232 @@ +/* + * 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.core.implementation.processor; + +import java.util.Collection; +import java.util.List; + +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.model.Multiplicity; +import org.apache.tuscany.spi.model.ServiceContract; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; + +/** + * @version $Rev$ $Date$ + */ +public class ReferenceProcessorTestCase extends TestCase { + + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + ReferenceProcessor processor = new ReferenceProcessor(new JavaInterfaceProcessorRegistryImpl()); + + public void testMethodAnnotation() throws Exception { + processor.visitMethod(ReferenceProcessorTestCase.Foo.class.getMethod("setFoo", Ref.class), type, null); + JavaMappedReference reference = type.getReferences().get("foo"); + assertNotNull(reference); + ServiceContract contract = reference.getServiceContract(); + assertEquals(Ref.class, contract.getInterfaceClass()); + assertEquals("ReferenceProcessorTestCase$Ref", contract.getInterfaceName()); + } + + public void testMethodRequired() throws Exception { + processor.visitMethod( + ReferenceProcessorTestCase.Foo.class.getMethod("setFooRequired", Ref.class), + type, + null); + JavaMappedReference prop = type.getReferences().get("fooRequired"); + assertNotNull(prop); + assertTrue(prop.isRequired()); + } + + public void testMethodName() throws Exception { + processor.visitMethod( + ReferenceProcessorTestCase.Foo.class.getMethod("setBarMethod", Ref.class), + type, + null); + assertNotNull(type.getReferences().get("bar")); + } + + public void testFieldAnnotation() throws Exception { + processor.visitField(ReferenceProcessorTestCase.Foo.class.getDeclaredField("baz"), type, null); + JavaMappedReference reference = type.getReferences().get("baz"); + assertNotNull(reference); + ServiceContract contract = reference.getServiceContract(); + assertEquals(Ref.class, contract.getInterfaceClass()); + assertEquals("ReferenceProcessorTestCase$Ref", contract.getInterfaceName()); + } + + public void testFieldRequired() throws Exception { + processor.visitField(ReferenceProcessorTestCase.Foo.class.getDeclaredField("bazRequired"), type, null); + JavaMappedReference prop = type.getReferences().get("bazRequired"); + assertNotNull(prop); + assertTrue(prop.isRequired()); + } + + public void testFieldName() throws Exception { + processor.visitField(ReferenceProcessorTestCase.Foo.class.getDeclaredField("bazField"), type, null); + assertNotNull(type.getReferences().get("theBaz")); + } + + public void testDuplicateFields() throws Exception { + processor.visitField(ReferenceProcessorTestCase.Bar.class.getDeclaredField("dup"), type, null); + try { + processor.visitField(ReferenceProcessorTestCase.Bar.class.getDeclaredField("baz"), type, null); + fail(); + } catch (DuplicateReferenceException e) { + // expected + } + } + + public void testDuplicateMethods() throws Exception { + processor.visitMethod(ReferenceProcessorTestCase.Bar.class.getMethod("dupMethod", Ref.class), type, null); + try { + processor.visitMethod( + ReferenceProcessorTestCase.Bar.class.getMethod("dupSomeMethod", Ref.class), + type, + null); + fail(); + } catch (DuplicateReferenceException e) { + // expected + } + } + + public void testInvalidProperty() throws Exception { + try { + processor.visitMethod(ReferenceProcessorTestCase.Bar.class.getMethod("badMethod"), type, null); + fail(); + } catch (IllegalReferenceException e) { + // expected + } + } + + protected void setUp() throws Exception { + super.setUp(); + type = new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor = new ReferenceProcessor(new JavaInterfaceProcessorRegistryImpl()); + } + + private interface Ref { + } + + private class Foo { + + @Reference + protected Ref baz; + @Reference(required = true) + protected Ref bazRequired; + @Reference(name = "theBaz") + protected Ref bazField; + + @Reference + public void setFoo(Ref ref) { + } + + @Reference(required = true) + public void setFooRequired(Ref ref) { + } + + @Reference(name = "bar") + public void setBarMethod(Ref ref) { + } + + } + + private class Bar { + + @Reference + protected Ref dup; + + @Reference(name = "dup") + protected Ref baz; + + @Reference + public void dupMethod(Ref s) { + } + + @Reference(name = "dupMethod") + public void dupSomeMethod(Ref s) { + } + + @Reference + public void badMethod() { + } + + } + + private class Multiple { + @Reference(required = true) + protected List<Ref> refs1; + + @Reference(required = false) + protected Ref[] refs2; + + @Reference(required = true) + public void setRefs3(Ref[] refs) { + } + + @Reference(required = false) + public void setRefs4(Collection<Ref> refs) { + } + + } + + public void testMultiplicity1ToN() throws Exception { + processor.visitField(Multiple.class.getDeclaredField("refs1"), type, null); + JavaMappedReference prop = type.getReferences().get("refs1"); + assertNotNull(prop); + assertSame(Ref.class, prop.getServiceContract().getInterfaceClass()); + assertEquals(Multiplicity.ONE_N, prop.getMultiplicity()); + assertTrue(prop.isRequired()); + } + + public void testMultiplicityTo0ToN() throws Exception { + processor.visitField(Multiple.class.getDeclaredField("refs2"), type, null); + JavaMappedReference prop = type.getReferences().get("refs2"); + assertNotNull(prop); + assertSame(Ref.class, prop.getServiceContract().getInterfaceClass()); + assertEquals(Multiplicity.ZERO_N, prop.getMultiplicity()); + assertFalse(prop.isRequired()); + } + + public void testMultiplicity1ToNMethod() throws Exception { + processor.visitMethod(Multiple.class.getMethod("setRefs3", Ref[].class), type, null); + JavaMappedReference prop = type.getReferences().get("refs3"); + assertNotNull(prop); + assertSame(Ref.class, prop.getServiceContract().getInterfaceClass()); + assertEquals(Multiplicity.ONE_N, prop.getMultiplicity()); + assertTrue(prop.isRequired()); + } + + public void testMultiplicity0ToNMethod() throws Exception { + processor.visitMethod(Multiple.class.getMethod("setRefs4", Collection.class), type, null); + JavaMappedReference prop = type.getReferences().get("refs4"); + assertNotNull(prop); + assertSame(Ref.class, prop.getServiceContract().getInterfaceClass()); + assertEquals(Multiplicity.ZERO_N, prop.getMultiplicity()); + assertFalse(prop.isRequired()); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ResourceProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ResourceProcessorTestCase.java new file mode 100644 index 0000000000..25c1a14be6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ResourceProcessorTestCase.java @@ -0,0 +1,117 @@ +/* + * 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.core.implementation.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.Resource; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class ResourceProcessorTestCase extends TestCase { + + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type; + ResourceProcessor processor = new ResourceProcessor(); + + public void testVisitField() throws Exception { + Field field = Foo.class.getDeclaredField("bar"); + processor.visitField(field, type, null); + Resource resource = type.getResources().get("bar"); + assertFalse(resource.isOptional()); + assertNull(resource.getMappedName()); + assertEquals(field.getType(), resource.getType()); + } + + public void testVisitMethod() throws Exception { + Method method = Foo.class.getMethod("setBar", Bar.class); + processor.visitMethod(method, type, null); + Resource resource = type.getResources().get("bar"); + assertFalse(resource.isOptional()); + assertNull(resource.getMappedName()); + assertEquals(method.getParameterTypes()[0], resource.getType()); + } + + public void testVisitNamedMethod() throws Exception { + Method method = Foo.class.getMethod("setBar2", Bar.class); + processor.visitMethod(method, type, null); + Resource resource = type.getResources().get("someName"); + assertFalse(resource.isOptional()); + assertEquals("mapped", resource.getMappedName()); + } + + public void testVisitBadMethod() throws Exception { + Method method = Foo.class.getMethod("setBad"); + try { + processor.visitMethod(method, type, null); + fail(); + } catch (IllegalResourceException e) { + // expected + } + } + + public void testDuplicateResources() throws Exception { + Field field = Foo.class.getDeclaredField("bar"); + processor.visitField(field, type, null); + try { + processor.visitField(field, type, null); + fail(); + } catch (DuplicateResourceException e) { + //expected + } + } + + protected void setUp() throws Exception { + super.setUp(); + type = new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + } + + private class Foo { + + @org.apache.tuscany.api.annotation.Resource + protected Bar bar; + + @org.apache.tuscany.api.annotation.Resource(optional = true) + protected Bar barNotRequired; + + @org.apache.tuscany.api.annotation.Resource + public void setBar(Bar bar) { + } + + @org.apache.tuscany.api.annotation.Resource(name = "someName", mappedName = "mapped") + public void setBar2(Bar bar) { + } + + @org.apache.tuscany.api.annotation.Resource + public void setBad() { + } + + } + + private interface Bar { + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ScopeProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ScopeProcessorTestCase.java new file mode 100644 index 0000000000..f8fa73b0f5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ScopeProcessorTestCase.java @@ -0,0 +1,128 @@ +/* + * 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.core.implementation.processor; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; +import org.apache.tuscany.spi.model.Scope; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ScopeProcessorTestCase extends TestCase { + + Component parent; + + public void testCompositeScope() throws ProcessingException { + ScopeProcessor processor = new ScopeProcessor(); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + + processor.visitClass(Composite.class, type, null); + assertEquals(Scope.COMPOSITE, type.getImplementationScope()); + } + + public void testSessionScope() throws ProcessingException { + ScopeProcessor processor = new ScopeProcessor(); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitClass(Session.class, type, null); + assertEquals(Scope.SESSION, type.getImplementationScope()); + } + + public void testConversationalScope() throws ProcessingException { + ScopeProcessor processor = new ScopeProcessor(); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitClass(Conversation.class, type, null); + assertEquals(Scope.CONVERSATION, type.getImplementationScope()); + } + + public void testRequestScope() throws ProcessingException { + ScopeProcessor processor = new ScopeProcessor(); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitClass(Request.class, type, null); + assertEquals(Scope.REQUEST, type.getImplementationScope()); + } + + public void testSystemScope() throws ProcessingException { + ScopeProcessor processor = new ScopeProcessor(); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitClass(System.class, type, null); + assertEquals(Scope.SYSTEM, type.getImplementationScope()); + } + + public void testStatelessScope() throws ProcessingException { + ScopeProcessor processor = new ScopeProcessor(); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitClass(Stateless.class, type, null); + assertEquals(Scope.STATELESS, type.getImplementationScope()); + } + + public void testNoScope() throws ProcessingException { + ScopeProcessor processor = new ScopeProcessor(); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitClass(None.class, type, null); + assertEquals(Scope.STATELESS, type.getImplementationScope()); + } + + protected void setUp() throws Exception { + super.setUp(); + parent = EasyMock.createNiceMock(Component.class); + } + + @org.osoa.sca.annotations.Scope("COMPOSITE") + private class Composite { + } + + @org.osoa.sca.annotations.Scope("SESSION") + private class Session { + } + + @org.osoa.sca.annotations.Scope("CONVERSATION") + private class Conversation { + } + + @org.osoa.sca.annotations.Scope("REQUEST") + private class Request { + } + + @org.osoa.sca.annotations.Scope("SYSTEM") + private class System { + } + + @org.osoa.sca.annotations.Scope("STATELESS") + private class Stateless { + } + + private class None { + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ServiceCallbackTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ServiceCallbackTestCase.java new file mode 100644 index 0000000000..b198bd730b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ServiceCallbackTestCase.java @@ -0,0 +1,166 @@ +/* + * 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.core.implementation.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.osoa.sca.annotations.Callback; +import org.osoa.sca.annotations.Service; + +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.idl.java.IllegalCallbackException; + +/** + * @version $Rev$ $Date$ + */ +public class ServiceCallbackTestCase extends TestCase { + + ServiceProcessor processor = + new ServiceProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl())); + + public void testMethodCallbackInterface() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitClass(FooImpl.class, type, null); + JavaMappedService service = type.getServices().get(Foo.class.getSimpleName()); + assertNotNull(service); + Method method = FooImpl.class.getMethod("setCallback", FooCallback.class); + processor.visitMethod(method, type, null); + assertEquals(method, service.getCallbackMember()); + } + + public void testFieldCallbackInterface() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitClass(FooImpl.class, type, null); + JavaMappedService service = type.getServices().get(Foo.class.getSimpleName()); + assertNotNull(service); + Field field = FooImpl.class.getDeclaredField("callback"); + processor.visitField(field, type, null); + assertEquals(field, service.getCallbackMember()); + } + + public void testMethodDoesNotMatchCallback() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitClass(BadBarImpl.class, type, null); + Method method = BadBarImpl.class.getMethod("setWrongInterfaceCallback", String.class); + try { + processor.visitMethod(method, type, null); + fail(); + } catch (IllegalCallbackReferenceException e) { + // expected + } + } + + public void testNoParamCallback() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitClass(BadBarImpl.class, type, null); + Method method = BadBarImpl.class.getMethod("setNoParamCallback"); + try { + processor.visitMethod(method, type, null); + fail(); + } catch (IllegalCallbackReferenceException e) { + // expected + } + } + + public void testFieldDoesNotMatchCallback() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitClass(BadBarImpl.class, type, null); + Field field = BadBarImpl.class.getDeclaredField("wrongInterfaceCallback"); + try { + processor.visitField(field, type, null); + fail(); + } catch (IllegalCallbackReferenceException e) { + // expected + } + } + + public void testBadCallbackInterfaceAnnotation() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + try { + processor.visitClass(BadFooImpl.class, type, null); + fail(); + } catch (ProcessingException e) { + // expected + assertTrue(e.getCause() instanceof IllegalCallbackException); + } + } + + @Callback(FooCallback.class) + private interface Foo { + + } + + private interface FooCallback { + + } + + @Service(Foo.class) + private static class FooImpl implements Foo { + + @Callback + protected FooCallback callback; + + @Callback + public void setCallback(FooCallback cb) { + + } + } + + private static class BadBarImpl implements Foo { + @Callback + protected String wrongInterfaceCallback; + + @Callback + public void setWrongInterfaceCallback(String cb) { + + } + + @Callback + public void setNoParamCallback() { + + } + + } + + @Callback + private interface BadFoo { + + } + + @Service(BadFoo.class) + private static class BadFooImpl implements BadFoo { + + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ServiceProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ServiceProcessorTestCase.java new file mode 100644 index 0000000000..3d3ce498c9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/processor/ServiceProcessorTestCase.java @@ -0,0 +1,151 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.implementation.processor; + +import org.osoa.sca.annotations.Callback; +import org.osoa.sca.annotations.Remotable; +import org.osoa.sca.annotations.Service; + +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.model.ServiceContract; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; + +/** + * @version $Rev$ $Date$ + */ +public class ServiceProcessorTestCase extends TestCase { + private ServiceProcessor processor; + private PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type; + + public void testMultipleInterfaces() throws Exception { + processor.visitClass(FooMultiple.class, type, null); + assertEquals(2, type.getServices().size()); + JavaMappedService service = type.getServices().get(Baz.class.getSimpleName()); + ServiceContract contract = service.getServiceContract(); + assertEquals(Baz.class, contract.getInterfaceClass()); + assertEquals(Bar.class, contract.getCallbackClass()); + assertEquals("ServiceProcessorTestCase$Bar", contract.getCallbackName()); + assertNotNull(type.getServices().get(Bar.class.getSimpleName())); + } + + public void testSingleInterfaces() throws Exception { + processor.visitClass(FooSingle.class, type, null); + assertEquals(1, type.getServices().size()); + assertNotNull(type.getServices().get(Baz.class.getSimpleName())); + } + + public void testMultipleNoService() throws Exception { + processor.visitClass(FooMultipleNoService.class, type, null); + assertEquals(0, type.getServices().size()); + } + + /** + * Verifies a service with a callback annotation is recognized + */ + public void testMultipleWithCallbackAnnotation() throws Exception { + processor.visitClass(FooMultipleWithCalback.class, type, null); + assertEquals(1, type.getServices().size()); + } + + public void testRemotableNoService() throws Exception { + processor.visitClass(FooRemotableNoService.class, type, null); + assertEquals(1, type.getServices().size()); + JavaMappedService service = type.getServices().get(BazRemotable.class.getSimpleName()); + ServiceContract contract = service.getServiceContract(); + assertEquals(BazRemotable.class, contract.getInterfaceClass()); + } + + public void testNonInterface() throws Exception { + try { + processor.visitClass(BadImpl.class, type, null); + fail(); + } catch (InvalidServiceType e) { + //expected + } + } + + public void testNoInterfaces() throws Exception { + try { + processor.visitClass(BadDefinition.class, type, null); + fail(); + } catch (IllegalServiceDefinitionException e) { + //expected + } + } + + protected void setUp() throws Exception { + super.setUp(); + JavaInterfaceProcessorRegistryImpl registry = new JavaInterfaceProcessorRegistryImpl(); + processor = new ServiceProcessor(new ImplementationProcessorServiceImpl(registry)); + type = new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + } + + @Callback(Bar.class) + private interface Baz { + } + + private interface Bar { + } + + private interface Bar2 { + } + + @Remotable + private interface BazRemotable { + } + + @Service(interfaces = {Baz.class, Bar.class}) + private class FooMultiple implements Baz, Bar { + + } + + @Service(Baz.class) + private class FooSingle implements Baz, Bar { + + } + + private class FooMultipleNoService implements Bar, Bar2 { + + } + + private class FooMultipleWithCalback implements Baz, Bar { + + } + + private class FooRemotableNoService implements BazRemotable, Bar { + + } + + @Service(FooSingle.class) + private class BadImpl extends FooSingle { + + } + + + @Service() + private class BadDefinition extends FooSingle { + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/system/builder/SystemComponentBuilderResourceTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/system/builder/SystemComponentBuilderResourceTestCase.java new file mode 100644 index 0000000000..8cfbc2c627 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/system/builder/SystemComponentBuilderResourceTestCase.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.core.implementation.system.builder; + +import java.lang.reflect.Field; +import java.net.URI; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.ScopeRegistry; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.host.ResourceHost; +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.Resource; +import org.apache.tuscany.spi.model.ComponentDefinition; +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; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.implementation.system.model.SystemImplementation; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class SystemComponentBuilderResourceTestCase extends TestCase { + + @SuppressWarnings("unchecked") + public void testResourceInjection() throws Exception { + ScopeContainer container = EasyMock.createNiceMock(ScopeContainer.class); + DeploymentContext ctx = EasyMock.createNiceMock(DeploymentContext.class); + ScopeRegistry registry = EasyMock.createMock(ScopeRegistry.class); + EasyMock.expect(registry.getScopeContainer(Scope.STATELESS)).andReturn(container); + EasyMock.replay(registry); + ResourceHost host = EasyMock.createMock(ResourceHost.class); + EasyMock.expect(host.resolveResource(EasyMock.eq(String.class))).andReturn("result"); + EasyMock.replay(host); + SystemComponentBuilder builder = new SystemComponentBuilder(); + builder.setScopeRegistry(registry); + builder.setHost(host); + ConstructorDefinition<Foo> ctorDef = new ConstructorDefinition<SystemComponentBuilderResourceTestCase.Foo>( + SystemComponentBuilderResourceTestCase.Foo.class.getConstructor()); + PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + Field member = Foo.class.getDeclaredField("resource"); + Resource<String> resource = new Resource<String>("resource", String.class, member); + type.add(resource); + type.setImplementationScope(Scope.STATELESS); + type.setConstructorDefinition(ctorDef); + SystemImplementation impl = new SystemImplementation(); + impl.setImplementationClass(SystemComponentBuilderResourceTestCase.Foo.class); + impl.setComponentType(type); + ComponentDefinition<SystemImplementation> definition = + new ComponentDefinition<SystemImplementation>(URI.create("foo"), impl); + + Wire wire = EasyMock.createMock(Wire.class); + EasyMock.expect(wire.getTargetInstance()).andReturn("result"); + EasyMock.replay(wire); + + AtomicComponent component = builder.build(definition, ctx); + SystemComponentBuilderResourceTestCase.Foo foo = + (SystemComponentBuilderResourceTestCase.Foo) component.createInstance(); + assertEquals("result", foo.resource); + } + + private static class Foo { + + protected String resource; + + public Foo() { + } + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentTestCase.java new file mode 100644 index 0000000000..02fac67c2c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentTestCase.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.core.implementation.system.component; + +import java.net.URI; + +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.injection.EventInvoker; +import org.apache.tuscany.core.injection.MethodEventInvoker; +import org.apache.tuscany.core.injection.PojoObjectFactory; +import org.apache.tuscany.core.injection.SingletonObjectFactory; +import org.easymock.EasyMock; + +/** + * Verifies a system atomic component can be started and initialized + * + * @version $$Rev$$ $$Date$$ + */ +public class SystemAtomicComponentTestCase extends TestCase { + + private EventInvoker<Object> initInvoker; + private EventInvoker<Object> destroyInvoker; + + public void testDefaultCreationAndInit() throws Exception { + PojoObjectFactory<Foo> factory = new PojoObjectFactory<Foo>(Foo.class.getConstructor((Class[]) null)); + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setInstanceFactory(factory); + configuration.setInitInvoker(initInvoker); + configuration.setName(new URI("foo")); + SystemAtomicComponentImpl component = new SystemAtomicComponentImpl(configuration); + Foo foo = (Foo) component.createInstance(); + component.init(foo); + assertTrue(foo.initialized); + } + + public void testDestroy() throws Exception { + PojoObjectFactory<Foo> factory = new PojoObjectFactory<Foo>(Foo.class.getConstructor((Class[]) null)); + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setInstanceFactory(factory); + configuration.setDestroyInvoker(destroyInvoker); + configuration.setName(new URI("foo")); + SystemAtomicComponentImpl component = new SystemAtomicComponentImpl(configuration); + Foo foo = (Foo) component.createInstance(); + component.destroy(foo); + assertTrue(foo.destroyed); + } + + public void testReferenceAndPropertyConstructor() throws Exception { + PojoObjectFactory<Bar> factory = new PojoObjectFactory<Bar>(Bar.class.getConstructor(String.class, Foo.class)); + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setInstanceFactory(factory); + configuration.setInitInvoker(initInvoker); + configuration.addConstructorParamName("foo"); + configuration.addConstructorParamType(String.class); + configuration.addConstructorParamName("ref"); + configuration.addConstructorParamType(Foo.class); + configuration.setName(new URI("foo")); + SystemAtomicComponentImpl component = new SystemAtomicComponentImpl(configuration); + component.addPropertyFactory("foo", new SingletonObjectFactory<String>("baz")); + Foo target = new Foo(); + Wire wire = EasyMock.createMock(Wire.class); + EasyMock.expect(wire.getTargetInstance()).andReturn(target); + URI uri = URI.create("#ref"); + EasyMock.expect(wire.getSourceUri()).andReturn(uri).anyTimes(); + EasyMock.replay(wire); + component.attachWire(wire); + Bar bar = (Bar) component.createInstance(); + assertEquals("baz", bar.foo); + assertEquals(target, bar.ref); + EasyMock.verify(wire); + } + + protected void setUp() throws Exception { + super.setUp(); + initInvoker = new MethodEventInvoker<Object>(Foo.class.getMethod("init")); + destroyInvoker = new MethodEventInvoker<Object>(Foo.class.getMethod("destroy")); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + public static class Foo { + private boolean initialized; + private boolean destroyed; + + public void init() { + initialized = true; + } + + public void destroy() { + destroyed = true; + } + } + + public static class Bar { + + private String foo; + private Foo ref; + + public Bar(String foo, Foo ref) { + this.foo = foo; + this.ref = ref; + } + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentWireInvocationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentWireInvocationTestCase.java new file mode 100644 index 0000000000..23685aaa9e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentWireInvocationTestCase.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.core.implementation.system.component; + +import java.net.URI; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.scope.CompositeScopeContainer; +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.injection.PojoObjectFactory; +import org.apache.tuscany.core.mock.component.Source; +import org.apache.tuscany.core.mock.component.SourceImpl; +import org.apache.tuscany.core.mock.component.Target; +import org.apache.tuscany.core.mock.component.TargetImpl; +import org.easymock.EasyMock; + +/** + * Tests reference wires are injected properly into system component instances + * + * @version $$Rev$$ $$Date$$ + */ +public class SystemAtomicComponentWireInvocationTestCase extends TestCase { + + public void testWireResolution() throws Exception { + CompositeScopeContainer scope = new CompositeScopeContainer(null); + scope.start(); + Target target = new TargetImpl(); + PojoConfiguration configuration = new PojoConfiguration(); + configuration.addReferenceSite("setTarget", SourceImpl.class.getMethod("setTarget", Target.class)); + configuration.setInstanceFactory(new PojoObjectFactory<SourceImpl>(SourceImpl.class.getConstructor())); + configuration.setName(new URI("source")); + AtomicComponent component = new SystemAtomicComponentImpl(configuration); + component.setScopeContainer(scope); + Wire wire = EasyMock.createMock(Wire.class); + URI uri = URI.create("#setTarget"); + EasyMock.expect(wire.getSourceUri()).andReturn(uri).atLeastOnce(); + EasyMock.expect(wire.getTargetInstance()).andReturn(target); + EasyMock.replay(wire); + component.attachWire(wire); + component.start(); + assertSame(((Source) component.getTargetInstance()).getTarget(), target); + EasyMock.verify(wire); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/system/loader/SystemComponentTypeLoaderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/system/loader/SystemComponentTypeLoaderTestCase.java new file mode 100644 index 0000000000..9a3272cf2e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/system/loader/SystemComponentTypeLoaderTestCase.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.core.implementation.system.loader; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.implementation.java.ProcessingException; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.implementation.IntrospectionRegistryImpl; +import org.apache.tuscany.core.implementation.processor.ConstructorProcessor; +import org.apache.tuscany.core.implementation.processor.DestroyProcessor; +import org.apache.tuscany.core.implementation.processor.HeuristicPojoProcessor; +import org.apache.tuscany.core.implementation.processor.ImplementationProcessorServiceImpl; +import org.apache.tuscany.core.implementation.processor.InitProcessor; +import org.apache.tuscany.core.implementation.processor.PropertyProcessor; +import org.apache.tuscany.core.implementation.processor.ReferenceProcessor; +import org.apache.tuscany.core.implementation.processor.ScopeProcessor; +import org.apache.tuscany.core.implementation.processor.ServiceProcessor; +import org.apache.tuscany.core.implementation.system.model.SystemImplementation; +import org.apache.tuscany.core.mock.component.BasicInterface; +import org.apache.tuscany.core.mock.component.BasicInterfaceImpl; +import org.apache.tuscany.core.monitor.NullMonitorFactory; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class SystemComponentTypeLoaderTestCase extends TestCase { + private SystemComponentTypeLoader loader; + + public void testIntrospectUnannotatedClass() throws ProcessingException { + Component parent = EasyMock.createNiceMock(Component.class); + SystemImplementation impl = new SystemImplementation(BasicInterfaceImpl.class); + PojoComponentType<?, ?, ?> componentType = loader.loadByIntrospection(impl, null); + ServiceDefinition service = componentType.getServices().get(BasicInterface.class.getSimpleName()); + assertEquals(BasicInterface.class, service.getServiceContract().getInterfaceClass()); + Property<?> property = componentType.getProperties().get("publicProperty"); + assertEquals(String.class, property.getJavaType()); + ReferenceDefinition referenceDefinition = componentType.getReferences().get("protectedReference"); + assertEquals(BasicInterface.class, referenceDefinition.getServiceContract().getInterfaceClass()); + } + + protected void setUp() throws Exception { + super.setUp(); + JavaInterfaceProcessorRegistryImpl interfaceProcessorRegistry = new JavaInterfaceProcessorRegistryImpl(); + ImplementationProcessorService service = + new ImplementationProcessorServiceImpl(interfaceProcessorRegistry); + IntrospectionRegistryImpl registry = new IntrospectionRegistryImpl(); + registry.setMonitor(new NullMonitorFactory().getMonitor(IntrospectionRegistryImpl.Monitor.class)); + registry.registerProcessor(new ConstructorProcessor(service)); + registry.registerProcessor(new DestroyProcessor()); + registry.registerProcessor(new InitProcessor()); + registry.registerProcessor(new ScopeProcessor()); + registry.registerProcessor(new PropertyProcessor(service)); + registry.registerProcessor(new ReferenceProcessor(interfaceProcessorRegistry)); + registry.registerProcessor(new ServiceProcessor(service)); + registry.registerProcessor(new HeuristicPojoProcessor(service)); + loader = new SystemComponentTypeLoader(registry); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/system/loader/SystemImplementationLoaderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/system/loader/SystemImplementationLoaderTestCase.java new file mode 100644 index 0000000000..3dce59e42a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/implementation/system/loader/SystemImplementationLoaderTestCase.java @@ -0,0 +1,106 @@ +/* + * 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.core.implementation.system.loader; + +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.UnrecognizedElementException; + +import junit.framework.TestCase; +import org.apache.tuscany.core.implementation.system.model.SystemImplementation; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class SystemImplementationLoaderTestCase extends TestCase { + + public static final QName SYSTEM_IMPLEMENTATION = + new QName("http://tuscany.apache.org/xmlns/sca/system/2.0-alpha", "implementation.system"); + + public void testLoad() throws Exception { + LoaderRegistry registry = EasyMock.createNiceMock(LoaderRegistry.class); + EasyMock.replay(registry); + DeploymentContext context = EasyMock.createMock(DeploymentContext.class); + EasyMock.expect(context.getClassLoader()).andReturn(getClass().getClassLoader()); + EasyMock.replay(context); + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getName()).andReturn(SYSTEM_IMPLEMENTATION); + EasyMock.expect(reader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("class"))) + .andReturn(getClass().getName()); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.replay(reader); + SystemImplementationLoader loader = new SystemImplementationLoader(registry); + SystemImplementation impl = loader.load(null, reader, context); + assertEquals(getClass(), impl.getImplementationClass()); + EasyMock.verify(reader); + EasyMock.verify(context); + } + + public void testUnrecognizedElement() throws Exception { + LoaderRegistry registry = EasyMock.createNiceMock(LoaderRegistry.class); + EasyMock.replay(registry); + DeploymentContext context = EasyMock.createMock(DeploymentContext.class); + EasyMock.expect(context.getClassLoader()).andReturn(getClass().getClassLoader()); + EasyMock.replay(context); + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getName()).andReturn(SYSTEM_IMPLEMENTATION).atLeastOnce(); + EasyMock.expect(reader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("class"))) + .andReturn(getClass().getName()); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.START_ELEMENT); + EasyMock.expect(reader.getLocation()).andReturn(new MockLocation()); + EasyMock.replay(reader); + SystemImplementationLoader loader = new SystemImplementationLoader(registry); + try { + loader.load(null, reader, context); + fail(); + } catch (UnrecognizedElementException e) { + // expected + } + } + + private class MockLocation implements Location { + + public int getLineNumber() { + return 0; + } + + public int getColumnNumber() { + return 0; + } + + public int getCharacterOffset() { + return 0; + } + + public String getPublicId() { + return null; + } + + public String getSystemId() { + return null; + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/CallbackWireObjectFactoryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/CallbackWireObjectFactoryTestCase.java new file mode 100644 index 0000000000..9032d091a3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/CallbackWireObjectFactoryTestCase.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.core.injection; + +import java.util.List; +import java.util.ArrayList; + +import org.apache.tuscany.spi.wire.Wire; +import org.apache.tuscany.spi.wire.ProxyService; + +import junit.framework.TestCase; +import org.easymock.EasyMock; +import static org.easymock.EasyMock.createMock; + +/** + * @version $Rev$ $Date$ + */ +public class CallbackWireObjectFactoryTestCase extends TestCase { + + @SuppressWarnings({"unchecked"}) + public void testCreateInstance() throws Exception { + ProxyService service = createMock(ProxyService.class); + Foo foo = new Foo() { + }; + EasyMock.expect(service.createCallbackProxy(EasyMock.eq(Foo.class), EasyMock.isA(List.class))).andReturn(foo); + EasyMock.replay(service); + List<Wire> wires = new ArrayList<Wire>(); + CallbackWireObjectFactory factory = new CallbackWireObjectFactory(Foo.class, service, wires); + assertEquals(foo, factory.getInstance()); + EasyMock.verify(service); + } + + private interface Foo { + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/FieldInjectorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/FieldInjectorTestCase.java new file mode 100644 index 0000000000..d31347f7e6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/FieldInjectorTestCase.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.core.injection; + +import java.lang.reflect.Field; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class FieldInjectorTestCase extends TestCase { + + protected Field protectedField; + + public void testIllegalAccess() throws Exception { + FieldInjector<Foo> injector = new FieldInjector<Foo>(protectedField, new SingletonObjectFactory<String>("foo")); + Foo foo = new Foo(); + injector.inject(foo); + assertEquals("foo", foo.hidden); + } + + + protected void setUp() throws Exception { + super.setUp(); + protectedField = Foo.class.getDeclaredField("hidden"); + } + + private class Foo { + private String hidden; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/JNDIObjectFactoryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/JNDIObjectFactoryTestCase.java new file mode 100644 index 0000000000..91214fd02d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/JNDIObjectFactoryTestCase.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.core.injection; + +import javax.naming.Context; +import javax.naming.NamingException; + +import org.apache.tuscany.spi.ObjectCreationException; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class JNDIObjectFactoryTestCase extends TestCase { + + public void testGetInstance() throws Exception { + Context ctx = EasyMock.createMock(Context.class); + EasyMock.expect(ctx.lookup(EasyMock.eq("foo"))).andReturn(new Foo()); + EasyMock.replay(ctx); + JNDIObjectFactory<Foo> factory = new JNDIObjectFactory<Foo>(ctx, "foo"); + assertTrue(factory.getInstance() instanceof Foo); // must do an instanceof b/c of type erasure + EasyMock.verify(ctx); + } + + public void testGetInstanceError() throws Exception { + Context ctx = EasyMock.createMock(Context.class); + EasyMock.expect(ctx.lookup(EasyMock.eq("foo"))).andThrow(new NamingException()); + EasyMock.replay(ctx); + JNDIObjectFactory<Foo> factory = new JNDIObjectFactory<Foo>(ctx, "foo"); + try { + factory.getInstance(); + fail(); + } catch (ObjectCreationException e) { + //expected + } + EasyMock.verify(ctx); + } + + + private class Foo { + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/MethodEventInvokerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/MethodEventInvokerTestCase.java new file mode 100644 index 0000000000..3bb882da2d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/MethodEventInvokerTestCase.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.injection; + +import java.lang.reflect.Method; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class MethodEventInvokerTestCase extends TestCase { + private Method privateMethod; + private Method exceptionMethod; + + public void testIllegalAccess() throws Exception { + MethodEventInvoker<MethodEventInvokerTestCase.Foo> injector = new MethodEventInvoker<Foo>(privateMethod); + try { + injector.invokeEvent(new Foo()); + fail(); + } catch (AssertionError e) { + // expected + } + } + + public void testException() throws Exception { + MethodEventInvoker<MethodEventInvokerTestCase.Foo> injector = new MethodEventInvoker<Foo>(exceptionMethod); + try { + injector.invokeEvent(new Foo()); + fail(); + } catch (RuntimeException e) { + // expected + } + } + + protected void setUp() throws Exception { + super.setUp(); + privateMethod = MethodEventInvokerTestCase.Foo.class.getDeclaredMethod("hidden"); + exceptionMethod = MethodEventInvokerTestCase.Foo.class.getDeclaredMethod("exception"); + + } + + private class Foo { + + public void foo() { + } + + private void hidden() { + } + + public void exception() { + throw new RuntimeException(); + } + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/MethodInjectorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/MethodInjectorTestCase.java new file mode 100644 index 0000000000..b21ba4ccfa --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/MethodInjectorTestCase.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.core.injection; + +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.ObjectFactory; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class MethodInjectorTestCase extends TestCase { + private Method fooMethod; + private Method privateMethod; + private Method exceptionMethod; + + public void testIllegalArgument() throws Exception { + ObjectFactory<Object> factory = new SingletonObjectFactory<Object>(new Object()); + MethodInjector<Foo> injector = new MethodInjector<Foo>(fooMethod, factory); + try { + injector.inject(new Foo()); + fail(); + } catch (ObjectCreationException e) { + // expected + } + } + + public void testException() throws Exception { + ObjectFactory<Object> factory = new SingletonObjectFactory<Object>("foo"); + MethodInjector<Foo> injector = new MethodInjector<Foo>(exceptionMethod, factory); + try { + injector.inject(new Foo()); + fail(); + } catch (RuntimeException e) { + // expected + } + } + + protected void setUp() throws Exception { + super.setUp(); + fooMethod = Foo.class.getMethod("foo", String.class); + privateMethod = Foo.class.getDeclaredMethod("hidden", String.class); + exceptionMethod = Foo.class.getDeclaredMethod("exception", String.class); + + } + + private class Foo { + + public void foo(String bar) { + } + + private void hidden(String bar) { + } + + public void exception(String bar) { + throw new RuntimeException(); + } + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/PojoObjectFactoryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/PojoObjectFactoryTestCase.java new file mode 100644 index 0000000000..f68f34b22f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/PojoObjectFactoryTestCase.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.core.injection; + +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.spi.ObjectFactory; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class PojoObjectFactoryTestCase extends TestCase { + + private Constructor<Foo> ctor; + + public void testConstructorInjection() throws Exception { + List<ObjectFactory> initializers = new ArrayList<ObjectFactory>(); + initializers.add(new SingletonObjectFactory<String>("foo")); + PojoObjectFactory<Foo> factory = new PojoObjectFactory<Foo>(ctor, initializers); + Foo foo = factory.getInstance(); + assertEquals("foo", foo.foo); + } + + /** + * Verifies null parameters can be passed to a constructor. This is valid when a reference is optional during + * constructor injection + */ + public void testConstructorInjectionOptionalParam() throws Exception { + List<ObjectFactory> initializers = new ArrayList<ObjectFactory>(); + initializers.add(null); + PojoObjectFactory<Foo> factory = new PojoObjectFactory<Foo>(ctor, initializers); + Foo foo = factory.getInstance(); + assertNull(foo.foo); + } + + public void testConstructorInitializerInjection() throws Exception { + PojoObjectFactory<Foo> factory = new PojoObjectFactory<Foo>(ctor); + factory.setInitializerFactory(0, new SingletonObjectFactory<String>("foo")); + Foo foo = factory.getInstance(); + assertEquals("foo", foo.foo); + } + + protected void setUp() throws Exception { + super.setUp(); + ctor = Foo.class.getConstructor(String.class); + } + + private static class Foo { + + private String foo; + + public Foo(String foo) { + this.foo = foo; + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/RequestContextObjectFactoryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/RequestContextObjectFactoryTestCase.java new file mode 100644 index 0000000000..a1a41bbada --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/RequestContextObjectFactoryTestCase.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.core.injection; + +import org.apache.tuscany.spi.component.WorkContext; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class RequestContextObjectFactoryTestCase extends TestCase { + + public void testInstanceCreate() { + WorkContext workContext = EasyMock.createNiceMock(WorkContext.class); + RequestContextObjectFactory factory = new RequestContextObjectFactory(workContext); + assertNotNull(factory.getInstance()); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/ResourceObjectFactoryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/ResourceObjectFactoryTestCase.java new file mode 100644 index 0000000000..cf8bbc6818 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/ResourceObjectFactoryTestCase.java @@ -0,0 +1,91 @@ +/* + * 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.core.injection; + +import org.apache.tuscany.spi.host.ResourceHost; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ResourceObjectFactoryTestCase extends TestCase { + + public void testResolveFromHostByType() throws Exception { + ResourceHost host = EasyMock.createMock(ResourceHost.class); + EasyMock.expect(host.resolveResource(EasyMock.eq(String.class))).andReturn("foo"); + EasyMock.replay(host); + ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, false, host); + assertEquals("foo", factory.getInstance()); + EasyMock.verify(host); + } + + public void testResolveFromHostByName() throws Exception { + ResourceHost host = EasyMock.createMock(ResourceHost.class); + EasyMock.expect(host.resolveResource(EasyMock.eq(String.class), + EasyMock.eq("sca://localhost/bar"))).andReturn("foo"); + EasyMock.replay(host); + ResourceObjectFactory<String> factory = + new ResourceObjectFactory<String>(String.class, "sca://localhost/bar", false, host); + assertEquals("foo", factory.getInstance()); + EasyMock.verify(host); + } + + + public void testResolveFromParentThenResolveFromHostNotFound() throws Exception { + ResourceHost host = EasyMock.createMock(ResourceHost.class); + EasyMock.expect(host.resolveResource(EasyMock.eq(String.class))).andReturn(null); + EasyMock.replay(host); + ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, true, host); + assertNull(factory.getInstance()); + EasyMock.verify(host); + } + + public void testResolveByTypeNotFound() throws Exception { + ResourceHost host = EasyMock.createMock(ResourceHost.class); + EasyMock.expect(host.resolveResource(EasyMock.eq(String.class))).andReturn(null); + EasyMock.replay(host); + + Wire wire = EasyMock.createMock(Wire.class); + EasyMock.expect(wire.getTargetInstance()).andReturn(null); + EasyMock.replay(wire); + + ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, false, host); + try { + factory.getInstance(); + fail(); + } catch (ResourceNotFoundException e) { + //expected + } + EasyMock.verify(host); + } + + public void testResolveByTypeNotFoundOptional() throws Exception { + ResourceHost host = EasyMock.createMock(ResourceHost.class); + EasyMock.expect(host.resolveResource(EasyMock.eq(String.class))).andReturn(null); + EasyMock.replay(host); + ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, true, host); + assertNull(factory.getInstance()); + EasyMock.verify(host); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/SingletonObjectFactoryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/SingletonObjectFactoryTestCase.java new file mode 100644 index 0000000000..876e68d5b3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/injection/SingletonObjectFactoryTestCase.java @@ -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. + */ +package org.apache.tuscany.core.injection; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class SingletonObjectFactoryTestCase extends TestCase { + + public void testSingleton() throws Exception { + Object o = new Object(); + SingletonObjectFactory<Object> factory = new SingletonObjectFactory<Object>(o); + assertEquals(o, factory.getInstance()); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/conversation/AbstractConversationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/conversation/AbstractConversationTestCase.java new file mode 100644 index 0000000000..95f51c1183 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/conversation/AbstractConversationTestCase.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.core.integration.conversation; + +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.services.store.StoreMonitor; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.component.scope.ConversationalScopeContainer; +import org.apache.tuscany.core.services.store.memory.MemoryStore; +import org.easymock.classextension.EasyMock; + +/** + * Provides helper methods for setting up a partial runtime for conversational test cases. + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractConversationTestCase extends TestCase { + protected ScopeContainer container; + protected MemoryStore store; + protected WorkContext workContext; + + protected void createRuntime() { + workContext = new WorkContextImpl(); + store = new MemoryStore(EasyMock.createNiceMock(StoreMonitor.class)); + container = new ConversationalScopeContainer(store, workContext, null); + } + + protected void initializeRuntime() { + store.init(); + container.start(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationIdleExpireTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationIdleExpireTestCase.java new file mode 100644 index 0000000000..b42ebf2a69 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationIdleExpireTestCase.java @@ -0,0 +1,149 @@ +/* + * 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.core.integration.conversation; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.net.URI; + +import org.osoa.sca.annotations.Conversational; +import org.osoa.sca.annotations.EndsConversation; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.TargetNotFoundException; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; + +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.implementation.java.JavaAtomicComponent; +import org.apache.tuscany.core.injection.PojoObjectFactory; +import org.apache.tuscany.core.integration.mock.MockFactory; +import org.apache.tuscany.core.wire.jdk.JDKInvocationHandler; +import org.easymock.classextension.EasyMock; + +/** + * Verifies conversational resources are cleaned up if the maximum idle time is exceeded + * + * @version $Rev$ $Date$ + */ +public class ConversationIdleExpireTestCase extends AbstractConversationTestCase { + protected AtomicComponent target; + private JDKInvocationHandler handler; + private FooImpl targetInstance; + private Method operation1; + private Method operation2; + private final Object mutex = new Object(); + + public void testConversationExpire() throws Throwable { + workContext.setIdentifier(org.apache.tuscany.spi.model.Scope.CONVERSATION, "12345A"); + // start the conversation + handler.invoke(operation1, null); + // verify the instance was persisted + assertEquals(targetInstance, store.readRecord(target, "12345A")); + synchronized (mutex) { + mutex.wait(100); + } + // verify the instance was expired + assertNull(store.readRecord(target, "12345A")); + // continue the conversation - should throw an error + try { + handler.invoke(operation2, null); + fail(); + } catch (TargetNotFoundException e) { + // expected + } + } + + + protected void setUp() throws Exception { + super.setUp(); + createRuntime(); + store.setReaperInterval(10); + initializeRuntime(); + + targetInstance = EasyMock.createMock(FooImpl.class); + targetInstance.operation1(); + targetInstance.operation2(); + targetInstance.end(); + EasyMock.replay(targetInstance); + target = createTarget(); + + Wire wire = MockFactory.createWire("foo", Foo.class); + for (InvocationChain chain : wire.getInvocationChains().values()) { + chain.setTargetInvoker(target.createTargetInvoker("target", chain.getOperation())); + } + handler = new JDKInvocationHandler(Foo.class, wire, workContext); + operation1 = Foo.class.getMethod("operation1"); + operation2 = Foo.class.getMethod("operation2"); + } + + protected void tearDown() throws Exception { + super.tearDown(); + container.stop(); + store.destroy(); + } + + private JavaAtomicComponent createTarget() throws Exception { + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setName(new URI("target")); + configuration.setMaxIdleTime(50); + configuration.setInstanceFactory(new MockPojoFactory(FooImpl.class.getConstructor())); + configuration.setImplementationClass(FooImpl.class); + JavaAtomicComponent component = new JavaAtomicComponent(configuration); + component.setScopeContainer(container); + component.start(); + return component; + } + + private class MockPojoFactory extends PojoObjectFactory<FooImpl> { + public MockPojoFactory(Constructor<FooImpl> ctr) { + super(ctr); + } + + public FooImpl getInstance() throws ObjectCreationException { + return targetInstance; + } + } + + @Conversational + public static interface Foo { + + void operation1(); + + void operation2(); + + @EndsConversation + void end(); + + } + + public static class FooImpl implements Foo { + + public void operation1() { + } + + public void operation2() { + } + + @EndsConversation + public void end() { + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationMaxAgeExpireTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationMaxAgeExpireTestCase.java new file mode 100644 index 0000000000..a237687b1b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationMaxAgeExpireTestCase.java @@ -0,0 +1,154 @@ +/* + * 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.core.integration.conversation; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.net.URI; + +import org.osoa.sca.annotations.Conversational; +import org.osoa.sca.annotations.EndsConversation; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.TargetNotFoundException; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; + +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.implementation.java.JavaAtomicComponent; +import org.apache.tuscany.core.injection.PojoObjectFactory; +import org.apache.tuscany.core.integration.mock.MockFactory; +import org.apache.tuscany.core.wire.jdk.JDKInvocationHandler; +import org.easymock.classextension.EasyMock; + +/** + * Verifies conversational resources are cleaned up if the maximum age is exceeded + * + * @version $Rev$ $Date$ + */ +public class ConversationMaxAgeExpireTestCase extends AbstractConversationTestCase { + protected AtomicComponent target; + private JDKInvocationHandler handler; + private FooImpl targetInstance; + private Method operation1; + private Method operation2; + private final Object mutex = new Object(); + + public void testConversationExpire() throws Throwable { + workContext.setIdentifier(org.apache.tuscany.spi.model.Scope.CONVERSATION, "12345A"); + // start the conversation + handler.invoke(operation1, null); + // verify the instance was persisted + assertEquals(targetInstance, store.readRecord(target, "12345A")); + synchronized (mutex) { + mutex.wait(100); + } + // verify the instance was expired + assertNull(store.readRecord(target, "12345A")); + // continue the conversation - should throw an error + try { + handler.invoke(operation2, null); + fail(); + } catch (TargetNotFoundException e) { + // expected + } + } + + + protected void setUp() throws Exception { + super.setUp(); + createRuntime(); + store.setReaperInterval(10); + initializeRuntime(); + + targetInstance = EasyMock.createMock(FooImpl.class); + targetInstance.operation1(); + targetInstance.operation2(); + targetInstance.end(); + EasyMock.replay(targetInstance); + target = createTarget(); + // create source component mock + JavaAtomicComponent source = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(source.getUri()).andReturn(URI.create("source")).atLeastOnce(); + EasyMock.replay(source); + + Wire wire = MockFactory.createWire("foo", Foo.class); + for (InvocationChain chain : wire.getInvocationChains().values()) { + chain.setTargetInvoker(target.createTargetInvoker("target", chain.getOperation())); + } + handler = new JDKInvocationHandler(Foo.class, wire, workContext); + operation1 = Foo.class.getMethod("operation1"); + operation2 = Foo.class.getMethod("operation2"); + } + + protected void tearDown() throws Exception { + super.tearDown(); + container.stop(); + store.destroy(); + } + + private AtomicComponent createTarget() throws Exception { + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setName(new URI("target")); + configuration.setMaxAge(50); + Constructor<FooImpl> ctor = FooImpl.class.getConstructor(); + configuration.setInstanceFactory(new ConversationMaxAgeExpireTestCase.MockPojoFactory(ctor)); + configuration.setImplementationClass(FooImpl.class); + JavaAtomicComponent component = new JavaAtomicComponent(configuration); + component.setScopeContainer(container); + component.start(); + return component; + } + + private class MockPojoFactory extends PojoObjectFactory<FooImpl> { + public MockPojoFactory(Constructor<FooImpl> ctr) { + super(ctr); + } + + public FooImpl getInstance() throws ObjectCreationException { + return targetInstance; + } + } + + @Conversational + public static interface Foo { + + void operation1(); + + void operation2(); + + @EndsConversation + void end(); + + } + + public static class FooImpl implements Foo { + + public void operation1() { + } + + public void operation2() { + } + + @EndsConversation + public void end() { + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationStartStopEndTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationStartStopEndTestCase.java new file mode 100644 index 0000000000..a7815a3cd6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationStartStopEndTestCase.java @@ -0,0 +1,148 @@ +/* + * 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.core.integration.conversation; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.net.URI; + +import org.osoa.sca.annotations.Conversational; +import org.osoa.sca.annotations.EndsConversation; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.component.AtomicComponent; +import static org.apache.tuscany.spi.model.Scope.CONVERSATION; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; + +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.implementation.java.JavaAtomicComponent; +import org.apache.tuscany.core.injection.PojoObjectFactory; +import org.apache.tuscany.core.integration.mock.MockFactory; +import org.apache.tuscany.core.wire.jdk.JDKInvocationHandler; +import org.easymock.classextension.EasyMock; + +/** + * Verifies start, continue and end conversation invocations are processed properly. Checks that a target instance is + * properly instantiated and persisted in the store. Additionally verifies that invocations are dispatched to a target + * instance, and that start, continue, and end operations are performed correctly. Finally, verfies that the target + * instance is removed from the store when the conversation ends. + * + * @version $Rev$ $Date$ + */ +public class ConversationStartStopEndTestCase extends AbstractConversationTestCase { + protected AtomicComponent target; + private FooImpl targetInstance; + private JDKInvocationHandler handler; + private Method operation1; + private Method operation2; + private Method endOperation; + + public void testConversationStartContinueEnd() throws Throwable { + workContext.setIdentifier(CONVERSATION, "12345A"); + // start the conversation + handler.invoke(operation1, null); + // verify the instance was persisted + assertEquals(targetInstance, store.readRecord(target, "12345A")); + // continue the conversation + handler.invoke(operation2, null); + // verify the instance was persisted + assertEquals(targetInstance, store.readRecord(target, "12345A")); + // end the conversation + handler.invoke(endOperation, null); + workContext.clearIdentifier(CONVERSATION); + EasyMock.verify(targetInstance); + // verify the store has removed the instance + assertNull(store.readRecord(target, "12345A")); + } + + + protected void setUp() throws Exception { + super.setUp(); + createRuntime(); + initializeRuntime(); + targetInstance = EasyMock.createMock(FooImpl.class); + targetInstance.operation1(); + targetInstance.operation2(); + targetInstance.end(); + EasyMock.replay(targetInstance); + // create target component mock + target = createAtomicComponent(); + Wire wire = MockFactory.createWire("foo", Foo.class); + for (InvocationChain chain : wire.getInvocationChains().values()) { + chain.setTargetInvoker(target.createTargetInvoker("foo", chain.getOperation())); + } + handler = new JDKInvocationHandler(Foo.class, wire, workContext); + operation1 = Foo.class.getMethod("operation1"); + operation2 = Foo.class.getMethod("operation2"); + endOperation = Foo.class.getMethod("end"); + } + + protected void tearDown() throws Exception { + super.tearDown(); + container.stop(); + store.destroy(); + } + + private JavaAtomicComponent createAtomicComponent() throws Exception { + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setName(new URI("target")); + configuration.setInstanceFactory(new MockPojoFactory(FooImpl.class.getConstructor())); + configuration.setImplementationClass(FooImpl.class); + JavaAtomicComponent component = new JavaAtomicComponent(configuration); + component.setScopeContainer(container); + component.start(); + return component; + } + + private class MockPojoFactory extends PojoObjectFactory<FooImpl> { + public MockPojoFactory(Constructor<FooImpl> ctr) { + super(ctr); + } + + public FooImpl getInstance() throws ObjectCreationException { + return targetInstance; + } + } + + @Conversational + public static interface Foo { + + void operation1(); + + void operation2(); + + @EndsConversation + void end(); + + } + + public static class FooImpl implements Foo { + + public void operation1() { + } + + public void operation2() { + } + + @EndsConversation + public void end() { + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/implementation/IntrospectionRegistryIntegrationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/implementation/IntrospectionRegistryIntegrationTestCase.java new file mode 100644 index 0000000000..a726609073 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/implementation/IntrospectionRegistryIntegrationTestCase.java @@ -0,0 +1,131 @@ +/* + * 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.core.integration.implementation; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.apache.tuscany.api.annotation.Resource; + +import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.JavaMappedReference; +import org.apache.tuscany.spi.implementation.java.JavaMappedService; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import static org.apache.tuscany.spi.model.Scope.COMPOSITE; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.implementation.IntrospectionRegistryImpl; +import org.apache.tuscany.core.implementation.processor.DestroyProcessor; +import org.apache.tuscany.core.implementation.processor.ImplementationProcessorServiceImpl; +import org.apache.tuscany.core.implementation.processor.InitProcessor; +import org.apache.tuscany.core.implementation.processor.PropertyProcessor; +import org.apache.tuscany.core.implementation.processor.ReferenceProcessor; +import org.apache.tuscany.core.implementation.processor.ResourceProcessor; +import org.apache.tuscany.core.implementation.processor.ScopeProcessor; +import org.apache.tuscany.core.monitor.NullMonitorFactory; + +/** + * Sanity check of the <code>IntegrationRegistry</code> to verify operation with processors + * + * @version $Rev$ $Date$ + */ +public class IntrospectionRegistryIntegrationTestCase extends TestCase { + + private IntrospectionRegistryImpl registry; + + public void testSimpleComponentTypeParsing() throws Exception { + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + registry.introspect(Foo.class, type, null); + assertEquals(Foo.class.getMethod("init"), type.getInitMethod()); + assertEquals(Foo.class.getMethod("destroy"), type.getDestroyMethod()); + assertEquals(COMPOSITE, type.getImplementationScope()); + assertEquals(Foo.class.getMethod("setBar", String.class), type.getProperties().get("bar").getMember()); + assertEquals(Foo.class.getMethod("setTarget", Foo.class), type.getReferences().get("target").getMember()); + assertEquals(Foo.class.getMethod("setResource", Foo.class), type.getResources().get("resource").getMember()); + } + + protected void setUp() throws Exception { + super.setUp(); + registry = new IntrospectionRegistryImpl(); + registry.setMonitor(new NullMonitorFactory().getMonitor(IntrospectionRegistryImpl.Monitor.class)); + registry.registerProcessor(new DestroyProcessor()); + registry.registerProcessor(new InitProcessor()); + registry.registerProcessor(new ScopeProcessor()); + JavaInterfaceProcessorRegistryImpl interfaceProcessorRegistry = new JavaInterfaceProcessorRegistryImpl(); + ImplementationProcessorService service = new ImplementationProcessorServiceImpl(interfaceProcessorRegistry); + registry.registerProcessor(new PropertyProcessor(service)); + registry.registerProcessor(new ReferenceProcessor(interfaceProcessorRegistry)); + registry.registerProcessor(new ResourceProcessor()); + } + + @Scope("COMPOSITE") + private static class Foo { + protected Foo target; + protected String bar; + protected Foo resource; + private boolean initialized; + private boolean destroyed; + + + @Init + public void init() { + if (initialized) { + fail(); + } + initialized = true; + } + + @Destroy + public void destroy() { + if (destroyed) { + fail(); + } + destroyed = true; + } + + public Foo getTarget() { + return target; + } + + @Reference + public void setTarget(Foo target) { + this.target = target; + } + + public String getBar() { + return bar; + } + + @Property + public void setBar(String bar) { + this.bar = bar; + } + + @Resource + public void setResource(Foo resource) { + this.resource = resource; + } + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/implementation/system/builder/SystemBuilderPropertyTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/implementation/system/builder/SystemBuilderPropertyTestCase.java new file mode 100644 index 0000000000..c95b26b094 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/implementation/system/builder/SystemBuilderPropertyTestCase.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.core.integration.implementation.system.builder; + +import java.net.URI; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.ConstructorDefinition; +import org.apache.tuscany.spi.implementation.java.JavaMappedProperty; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; +import org.apache.tuscany.core.implementation.system.builder.SystemComponentBuilder; +import org.apache.tuscany.core.implementation.system.model.SystemImplementation; +import org.apache.tuscany.core.injection.SingletonObjectFactory; +import org.easymock.EasyMock; + +/** + * Verifies that the system builder handles configured properties correctly + * + * @version $Rev$ $Date$ + */ +public class SystemBuilderPropertyTestCase extends TestCase { + + DeploymentContext deploymentContext; + Component parent; + + @SuppressWarnings("unchecked") + public void testPropertyHandling() throws Exception { + SystemComponentBuilder builder = new SystemComponentBuilder(); + PojoComponentType<ServiceDefinition, ReferenceDefinition, JavaMappedProperty<?>> type = + new PojoComponentType<ServiceDefinition, ReferenceDefinition, JavaMappedProperty<?>>(); + type.setConstructorDefinition(new ConstructorDefinition<Foo>(Foo.class.getConstructor((Class[]) null))); + JavaMappedProperty<String> property = new JavaMappedProperty<String>(); + property.setName("test"); + property.setDefaultValueFactory(new SingletonObjectFactory<String>("foo")); + property.setMember(Foo.class.getMethod("setTest", String.class)); + type.add(property); + SystemImplementation impl = new SystemImplementation(); + impl.setComponentType(type); + impl.setImplementationClass(Foo.class); + ComponentDefinition<SystemImplementation> definition = new ComponentDefinition<SystemImplementation>(impl); + definition.setUri(URI.create("component")); + AtomicComponent component = builder.build(definition, deploymentContext); + Foo foo = (Foo) component.createInstance(); + assertEquals("foo", foo.getTest()); + } + + protected void setUp() throws Exception { + super.setUp(); + deploymentContext = EasyMock.createMock(DeploymentContext.class); + parent = EasyMock.createNiceMock(Component.class); + } + + private static class Foo { + private String test; + + public Foo() { + } + + public String getTest() { + return test; + } + + public void setTest(String test) { + this.test = test; + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/mock/MockFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/mock/MockFactory.java new file mode 100644 index 0000000000..b98d197a20 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/mock/MockFactory.java @@ -0,0 +1,209 @@ +/* + * 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.core.integration.mock; + +import java.lang.reflect.Member; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; +import org.apache.tuscany.spi.wire.ProxyService; + +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.implementation.PojoConfiguration; +import org.apache.tuscany.core.implementation.java.JavaAtomicComponent; +import org.apache.tuscany.core.injection.PojoObjectFactory; +import org.apache.tuscany.core.wire.InvocationChainImpl; +import org.apache.tuscany.core.wire.InvokerInterceptor; +import org.apache.tuscany.core.wire.WireImpl; +import org.apache.tuscany.core.wire.jdk.JDKProxyService; + +/** + * @version $$Rev$$ $$Date$$ + */ +public final class MockFactory { + + private static final ProxyService PROXY_SERVICE = new JDKProxyService(new WorkContextImpl()); + private static final JavaInterfaceProcessorRegistry REGISTRY = new JavaInterfaceProcessorRegistryImpl(); + + private MockFactory() { + } + + /** + * Wires two components together where the reference interface is the same as target service + */ + public static Map<String, AtomicComponent> createWiredComponents(String sourceName, + Class<?> sourceClass, + ScopeContainer sourceScope, + Map<String, Member> members, + String targetName, + Class<?> targetService, + Class<?> targetClass, + ScopeContainer targetScope) throws Exception { + return createWiredComponents(sourceName, + sourceClass, + targetService, + sourceScope, + null, + members, + targetName, + targetClass, + targetScope + ); + + } + + @SuppressWarnings("unchecked") + public static Map<String, AtomicComponent> createWiredComponents(String sourceName, Class<?> sourceClass, + Class<?> sourceReferenceClass, + ScopeContainer sourceScope, + Interceptor sourceHeadInterceptor, + Map<String, Member> members, + String targetName, + Class<?> targetClass, + ScopeContainer targetScope + ) + throws Exception { + + JavaAtomicComponent targetComponent = + createJavaComponent(targetName, targetScope, targetClass); + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setInstanceFactory(new PojoObjectFactory(sourceClass.getConstructor())); + configuration.setProxyService(PROXY_SERVICE); + for (Map.Entry<String, Member> entry : members.entrySet()) { + configuration.addReferenceSite(entry.getKey(), entry.getValue()); + } + configuration.setWorkContext(new WorkContextImpl()); + configuration.setName(new URI(sourceName)); + JavaAtomicComponent sourceComponent = new JavaAtomicComponent(configuration); + sourceComponent.setScopeContainer(sourceScope); + Wire wire = createWire(targetName, sourceReferenceClass, sourceHeadInterceptor); + for (InvocationChain chain : wire.getInvocationChains().values()) { + chain.setTargetInvoker(targetComponent.createTargetInvoker(targetName, chain.getOperation())); + } + sourceComponent.attachWire(wire); + targetScope.register(targetComponent); + sourceScope.register(sourceComponent); + Map<String, AtomicComponent> components = new HashMap<String, AtomicComponent>(); + components.put(sourceName, sourceComponent); + components.put(targetName, targetComponent); + return components; + } + + + /** + * Wires two components using a multiplicity reference + */ + @SuppressWarnings("unchecked") + public static Map<String, AtomicComponent> createWiredMultiplicity(String sourceName, Class<?> sourceClass, + Class<?> sourceReferenceClass, + ScopeContainer sourceScope, + String targetName, Class<?> targetService, + Class<?> targetClass, + Map<String, Member> members, + ScopeContainer targetScope) throws Exception { + JavaAtomicComponent targetComponent = + createJavaComponent(targetName, targetScope, targetClass); + String serviceName = targetService.getName().substring(targetService.getName().lastIndexOf('.') + 1); + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setInstanceFactory(new PojoObjectFactory(sourceClass.getConstructor())); + configuration.setProxyService(PROXY_SERVICE); + for (Map.Entry<String, Member> entry : members.entrySet()) { + configuration.addReferenceSite(entry.getKey(), entry.getValue()); + } + configuration.setWorkContext(new WorkContextImpl()); + configuration.setName(new URI(sourceName)); + + JavaAtomicComponent sourceComponent = new JavaAtomicComponent(configuration); + sourceComponent.setScopeContainer(sourceScope); + Wire wire = createWire(targetName, sourceReferenceClass, null); + wire.setTargetUri(URI.create(targetName + "#" + serviceName)); + for (InvocationChain chain : wire.getInvocationChains().values()) { + chain.setTargetInvoker(targetComponent.createTargetInvoker("target", chain.getOperation())); + } + List<Wire> wires = new ArrayList<Wire>(); + wires.add(wire); + sourceComponent.attachWires(wires); + targetScope.register(targetComponent); + sourceScope.register(sourceComponent); + + Map<String, AtomicComponent> components = new HashMap<String, AtomicComponent>(); + components.put(sourceName, sourceComponent); + components.put(targetName, targetComponent); + return components; + } + + public static <T> Wire createWire(String serviceName, Class<T> interfaze) + throws InvalidServiceContractException { + return createWire(serviceName, interfaze, null); + } + + public static <T> Wire createWire(String serviceName, Class<T> interfaze, Interceptor interceptor) + throws InvalidServiceContractException { + Wire wire = new WireImpl(); + ServiceContract<?> contract = REGISTRY.introspect(interfaze); + wire.setSourceContract(contract); + wire.setSourceUri(URI.create("#" + serviceName)); + createChains(interfaze, interceptor, wire); + return wire; + } + + @SuppressWarnings("unchecked") + private static <T> JavaAtomicComponent createJavaComponent(String name, ScopeContainer scope, Class<T> clazz) + throws NoSuchMethodException, URISyntaxException { + PojoConfiguration configuration = new PojoConfiguration(); + configuration.setImplementationClass(clazz); + configuration.setInstanceFactory(new PojoObjectFactory(clazz.getConstructor())); + configuration.setProxyService(PROXY_SERVICE); + configuration.setWorkContext(new WorkContextImpl()); + configuration.setName(new URI(name)); + JavaAtomicComponent component = new JavaAtomicComponent(configuration); + component.setScopeContainer(scope); + return component; + } + + private static void createChains(Class<?> interfaze, Interceptor interceptor, Wire wire) + throws InvalidServiceContractException { + + ServiceContract<?> contract = REGISTRY.introspect(interfaze); + for (Operation<?> method : contract.getOperations().values()) { + InvocationChain chain = new InvocationChainImpl(method); + if (interceptor != null) { + chain.addInterceptor(interceptor); + } + // add tail interceptor + chain.addInterceptor(new InvokerInterceptor()); + wire.addInvocationChain(method, chain); + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/scope/ScopeReferenceTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/scope/ScopeReferenceTestCase.java new file mode 100644 index 0000000000..51d4e86260 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/scope/ScopeReferenceTestCase.java @@ -0,0 +1,785 @@ +/* + * 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.core.integration.scope; + +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; + +import org.apache.tuscany.spi.component.AtomicComponent; +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.model.Scope; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.component.event.ComponentStart; +import org.apache.tuscany.core.component.event.ComponentStop; +import org.apache.tuscany.core.component.event.HttpSessionEnd; +import org.apache.tuscany.core.component.event.HttpSessionStart; +import org.apache.tuscany.core.component.event.RequestEnd; +import org.apache.tuscany.core.component.event.RequestStart; +import org.apache.tuscany.core.component.scope.CompositeScopeContainer; +import org.apache.tuscany.core.component.scope.HttpSessionScopeContainer; +import org.apache.tuscany.core.component.scope.RequestScopeContainer; +import org.apache.tuscany.core.component.scope.StatelessScopeContainer; +import org.apache.tuscany.core.integration.mock.MockFactory; +import org.apache.tuscany.core.mock.component.Source; +import org.apache.tuscany.core.mock.component.SourceImpl; +import org.apache.tuscany.core.mock.component.Target; +import org.apache.tuscany.core.mock.component.TargetImpl; +import org.apache.tuscany.core.util.JavaIntrospectionHelper; + +/** + * Tests scoping is properly handled for service references + * + * @version $Rev$ $Date$ + */ +public class ScopeReferenceTestCase extends TestCase { + private Map<String, Member> members; + + /** + * Tests a composite-to-composite scoped wire + */ + public void testCompositeToComposite() throws Exception { + ScopeContainer scope = new CompositeScopeContainer(null); + scope.start(); + + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", + SourceImpl.class, + scope, members, + "target", + Target.class, + TargetImpl.class, + scope); + scope.onEvent(new ComponentStart(this, null)); + AtomicComponent sourceComponent = contexts.get("source"); + AtomicComponent targetComponent = contexts.get("target"); + Source source = (Source) sourceComponent.getTargetInstance(); + Target target = (Target) targetComponent.getTargetInstance(); + assertNull(source.getTarget().getString()); + assertNull(target.getString()); + target.setString("foo"); + assertTrue(Proxy.isProxyClass(source.getTarget().getClass())); + assertEquals("foo", source.getTarget().getString()); + scope.onEvent(new ComponentStop(this, null)); + scope.stop(); + } + + /** + * Tests a composite-to-session scoped wire is setup properly by the runtime + */ + public void testCompositeToSession() throws Exception { + WorkContext ctx = new WorkContextImpl(); + ScopeContainer compositeScope = new CompositeScopeContainer(null); + compositeScope.start(); + ScopeContainer sessionScope = new HttpSessionScopeContainer(ctx, null); + sessionScope.start(); + + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class, + compositeScope, members, "target", Target.class, TargetImpl.class, sessionScope); + compositeScope.onEvent(new ComponentStart(this, null)); + Object session1 = new Object(); + ctx.setIdentifier(Scope.SESSION, session1); + sessionScope.onEvent(new HttpSessionStart(this, session1)); + AtomicComponent sourceComponent = contexts.get("source"); + AtomicComponent targetComponent = contexts.get("target"); + Source source = (Source) sourceComponent.getTargetInstance(); + Target target = (Target) targetComponent.getTargetInstance(); + assertNull(source.getTarget().getString()); + assertNull(target.getString()); + target.setString("foo"); + assertTrue(Proxy.isProxyClass(source.getTarget().getClass())); + assertEquals("foo", source.getTarget().getString()); + ctx.clearIdentifier(Scope.SESSION); + sessionScope.onEvent(new HttpSessionEnd(this, session1)); + + //second session + Object session2 = new Object(); + ctx.setIdentifier(Scope.SESSION, session2); + sessionScope.onEvent(new HttpSessionStart(this, session2)); + + Target target2 = (Target) targetComponent.getTargetInstance(); + assertFalse("foo".equals(target2.getString())); + + assertFalse("foo".equals(source.getTarget().getString())); + source.getTarget().setString("bar"); + assertEquals("bar", target2.getString()); + assertEquals("bar", source.getTarget().getString()); + sessionScope.onEvent(new HttpSessionEnd(this, session2)); + + ctx.clearIdentifier(Scope.SESSION); + compositeScope.onEvent(new ComponentStop(this, null)); + sessionScope.stop(); + compositeScope.stop(); + } + + /** + * Tests a composite-to-request scoped wire + */ + public void testCompositeToRequest() throws Exception { + WorkContext ctx = new WorkContextImpl(); + ScopeContainer compositeScope = new CompositeScopeContainer(null); + compositeScope.start(); + final ScopeContainer requestScope = new RequestScopeContainer(ctx, null); + requestScope.start(); + + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class, + compositeScope, members, "target", Target.class, TargetImpl.class, requestScope); + compositeScope.onEvent(new ComponentStart(this, null)); + requestScope.onEvent(new RequestStart(this)); + + AtomicComponent sourceComponent = contexts.get("source"); + final AtomicComponent targetComponent = contexts.get("target"); + final Source source = (Source) sourceComponent.getTargetInstance(); + Target target = (Target) targetComponent.getTargetInstance(); + assertNull(source.getTarget().getString()); + assertNull(target.getString()); + target.setString("foo"); + assertTrue(Proxy.isProxyClass(source.getTarget().getClass())); + assertEquals("foo", source.getTarget().getString()); + + // spin off another request + Executor executor = Executors.newSingleThreadExecutor(); + FutureTask<Void> future = new FutureTask<Void>(new Runnable() { + public void run() { + requestScope.onEvent(new RequestStart(this)); + Target target2 = null; + try { + target2 = (Target) targetComponent.getTargetInstance(); + } catch (TargetException e) { + fail(e.getMessage()); + } + assertFalse("foo".equals(target2.getString())); + assertFalse("foo".equals(source.getTarget().getString())); + source.getTarget().setString("bar"); + assertEquals("bar", target2.getString()); + assertEquals("bar", source.getTarget().getString()); + requestScope.onEvent(new RequestEnd(this)); + } + }, null); + executor.execute(future); + future.get(); + assertEquals("foo", source.getTarget().getString()); + requestScope.onEvent(new RequestEnd(this)); + compositeScope.onEvent(new ComponentStop(this, null)); + requestScope.stop(); + compositeScope.stop(); + } + + /** + * Tests a composite-to-stateless scoped wire is setup properly by the runtime + */ + public void testCompositeToStateless() throws Exception { + WorkContext ctx = new WorkContextImpl(); + ScopeContainer compositeScope = new CompositeScopeContainer(null); + compositeScope.start(); + ScopeContainer statelessScope = new StatelessScopeContainer(ctx, null); + statelessScope.start(); + + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class, + compositeScope, members, "target", Target.class, TargetImpl.class, statelessScope); + compositeScope.onEvent(new ComponentStart(this, null)); + + AtomicComponent sourceComponent = contexts.get("source"); + AtomicComponent targetComponent = contexts.get("target"); + Source source = (Source) sourceComponent.getTargetInstance(); + Target target = (Target) targetComponent.getTargetInstance(); + assertTrue(Proxy.isProxyClass(source.getTarget().getClass())); + assertNull(source.getTarget().getString()); + assertNull(target.getString()); + target.setString("foo"); + assertFalse("foo".equals(source.getTarget().getString())); + Target target2 = (Target) targetComponent.getTargetInstance(); + assertFalse("foo".equals(target2.getString())); + source.getTarget().setString("bar"); + assertFalse("bar".equals(source.getTarget().getString())); + compositeScope.onEvent(new ComponentStop(this, null)); + compositeScope.stop(); + statelessScope.stop(); + } + + + /** + * Tests a session-to-session scoped wire + */ + public void testSessionToSession() throws Exception { + WorkContext ctx = new WorkContextImpl(); + ScopeContainer sessionScope = new HttpSessionScopeContainer(ctx, null); + sessionScope.start(); + + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class, + sessionScope, members, "target", Target.class, TargetImpl.class, sessionScope); + + Object session1 = new Object(); + ctx.setIdentifier(Scope.SESSION, session1); + sessionScope.onEvent(new HttpSessionStart(this, session1)); + AtomicComponent sourceComponent = contexts.get("source"); + AtomicComponent targetComponent = contexts.get("target"); + Source source = (Source) sourceComponent.getTargetInstance(); + Target target = (Target) targetComponent.getTargetInstance(); + source.getTarget().setString("foo"); + source.getTarget().setString("foo"); + assertEquals("foo", target.getString()); + + ctx.clearIdentifier(Scope.SESSION); + sessionScope.onEvent(new HttpSessionEnd(this, session1)); + + //second session + Object session2 = new Object(); + ctx.setIdentifier(Scope.SESSION, session2); + sessionScope.onEvent(new HttpSessionStart(this, session2)); + + Source source2 = (Source) sourceComponent.getTargetInstance(); + assertNotNull(source2); + Target target2 = (Target) targetComponent.getTargetInstance(); + + assertNotNull(target2); + assertNull(target2.getString()); + assertEquals(null, source2.getTarget().getString()); + source2.getTarget().setString("baz"); + assertEquals("baz", source2.getTarget().getString()); + assertEquals("baz", target2.getString()); + ctx.clearIdentifier(Scope.SESSION); + sessionScope.onEvent(new HttpSessionEnd(this, session2)); + sessionScope.stop(); + } + + + /** + * Tests a session-to-composite scoped wire + */ + public void testSessionToComposite() throws Exception { + WorkContext ctx = new WorkContextImpl(); + ScopeContainer compositeScope = new CompositeScopeContainer(null); + compositeScope.start(); + ScopeContainer sessionScope = new HttpSessionScopeContainer(ctx, null); + sessionScope.start(); + + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class, + sessionScope, members, "target", Target.class, TargetImpl.class, compositeScope); + compositeScope.onEvent(new ComponentStart(this, null)); + Object session1 = new Object(); + ctx.setIdentifier(Scope.SESSION, session1); + sessionScope.onEvent(new HttpSessionStart(this, session1)); + AtomicComponent sourceComponent = contexts.get("source"); + AtomicComponent targetComponent = contexts.get("target"); + Source source = (Source) sourceComponent.getTargetInstance(); + Target target = (Target) targetComponent.getTargetInstance(); + assertNull(source.getTarget().getString()); + assertNull(target.getString()); + target.setString("foo"); + assertTrue(Proxy.isProxyClass(source.getTarget().getClass())); + assertEquals("foo", source.getTarget().getString()); + ctx.clearIdentifier(Scope.SESSION); + sessionScope.onEvent(new HttpSessionEnd(this, session1)); + + //second session + Object session2 = new Object(); + ctx.setIdentifier(Scope.SESSION, session2); + sessionScope.onEvent(new HttpSessionStart(this, session2)); + + Target target2 = (Target) targetComponent.getTargetInstance(); + Source source2 = (Source) sourceComponent.getTargetInstance(); + assertEquals("foo", target2.getString()); + assertEquals("foo", source2.getTarget().getString()); + source2.getTarget().setString("baz"); + assertEquals("baz", source2.getTarget().getString()); + assertEquals("baz", target2.getString()); + assertEquals("baz", target.getString()); + ctx.clearIdentifier(Scope.SESSION); + sessionScope.onEvent(new HttpSessionEnd(this, session2)); + compositeScope.stop(); + sessionScope.stop(); + } + + /** + * Tests a session-to-request scoped wire is setup properly by the runtime + */ + public void testSessionToRequest() throws Exception { + WorkContext ctx = new WorkContextImpl(); + final ScopeContainer requestScope = new RequestScopeContainer(ctx, null); + requestScope.start(); + ScopeContainer sessionScope = new HttpSessionScopeContainer(ctx, null); + sessionScope.start(); + + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class, + sessionScope, members, "target", Target.class, TargetImpl.class, requestScope); + Object session1 = new Object(); + ctx.setIdentifier(Scope.SESSION, session1); + sessionScope.onEvent(new HttpSessionStart(this, session1)); + requestScope.onEvent(new RequestStart(this)); + AtomicComponent sourceComponent = contexts.get("source"); + final AtomicComponent targetComponent = contexts.get("target"); + final Source source = (Source) sourceComponent.getTargetInstance(); + Target target = (Target) targetComponent.getTargetInstance(); + assertNull(source.getTarget().getString()); + assertNull(target.getString()); + target.setString("foo"); + assertTrue(Proxy.isProxyClass(source.getTarget().getClass())); + assertEquals("foo", source.getTarget().getString()); + + // spin off another request + Executor executor = Executors.newSingleThreadExecutor(); + FutureTask<Void> future = new FutureTask<Void>(new Runnable() { + public void run() { + requestScope.onEvent(new RequestStart(this)); + Target target2 = null; + try { + target2 = (Target) targetComponent.getTargetInstance(); + } catch (TargetException e) { + fail(e.getMessage()); + } + assertFalse("foo".equals(target2.getString())); + assertFalse("foo".equals(source.getTarget().getString())); + source.getTarget().setString("bar"); + assertEquals("bar", target2.getString()); + assertEquals("bar", source.getTarget().getString()); + requestScope.onEvent(new RequestEnd(this)); + } + }, null); + executor.execute(future); + future.get(); + assertEquals("foo", source.getTarget().getString()); + requestScope.onEvent(new RequestEnd(this)); + ctx.clearIdentifier(Scope.SESSION); + sessionScope.onEvent(new HttpSessionEnd(this, session1)); + requestScope.stop(); + sessionScope.stop(); + } + + + /** + * Tests a session-to-stateless scoped wire is setup properly by the runtime + */ + public void testSessionToStateless() throws Exception { + WorkContext ctx = new WorkContextImpl(); + ScopeContainer sessionScope = new HttpSessionScopeContainer(ctx, null); + sessionScope.start(); + ScopeContainer statelessScope = new StatelessScopeContainer(ctx, null); + statelessScope.start(); + + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class, + sessionScope, members, "target", Target.class, TargetImpl.class, statelessScope); + + Object session1 = new Object(); + ctx.setIdentifier(Scope.SESSION, session1); + sessionScope.onEvent(new HttpSessionStart(this, session1)); + + AtomicComponent sourceComponent = contexts.get("source"); + AtomicComponent targetComponent = contexts.get("target"); + Source source = (Source) sourceComponent.getTargetInstance(); + Target target = (Target) targetComponent.getTargetInstance(); + assertTrue(Proxy.isProxyClass(source.getTarget().getClass())); + assertNull(source.getTarget().getString()); + assertNull(target.getString()); + target.setString("foo"); + assertFalse("foo".equals(source.getTarget().getString())); + Target target2 = (Target) targetComponent.getTargetInstance(); + assertFalse("foo".equals(target2.getString())); + source.getTarget().setString("bar"); + assertFalse("bar".equals(source.getTarget().getString())); + + ctx.clearIdentifier(Scope.SESSION); + sessionScope.onEvent(new HttpSessionEnd(this, session1)); + sessionScope.stop(); + statelessScope.stop(); + } + + /** + * Tests a request-to-request scoped wire is setup properly by the runtime + */ + public void testRequestToRequest() throws Exception { + WorkContext ctx = new WorkContextImpl(); + final ScopeContainer requestScope = new RequestScopeContainer(ctx, null); + requestScope.start(); + + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class, + requestScope, members, "target", Target.class, TargetImpl.class, requestScope); + requestScope.onEvent(new RequestStart(this)); + + final AtomicComponent sourceComponent = contexts.get("source"); + final AtomicComponent targetComponent = contexts.get("target"); + Source source = (Source) sourceComponent.getTargetInstance(); + Target target = (Target) targetComponent.getTargetInstance(); + assertNull(source.getTarget().getString()); + assertNull(target.getString()); + target.setString("foo"); + assertTrue(Proxy.isProxyClass(source.getTarget().getClass())); + assertEquals("foo", source.getTarget().getString()); + + // spin off another request + Executor executor = Executors.newSingleThreadExecutor(); + FutureTask<Void> future = new FutureTask<Void>(new Runnable() { + public void run() { + requestScope.onEvent(new RequestStart(this)); + Source source2 = null; + Target target2 = null; + try { + source2 = (Source) sourceComponent.getTargetInstance(); + target2 = (Target) targetComponent.getTargetInstance(); + } catch (TargetException e) { + fail(e.getMessage()); + } + assertFalse("foo".equals(target2.getString())); + assertFalse("foo".equals(source2.getTarget().getString())); + source2.getTarget().setString("bar"); + assertEquals("bar", target2.getString()); + assertEquals("bar", source2.getTarget().getString()); + requestScope.onEvent(new RequestEnd(this)); + } + }, null); + executor.execute(future); + future.get(); + requestScope.onEvent(new RequestEnd(this)); + requestScope.stop(); + } + + /** + * Tests a request-to-composite scoped wire + */ + public void testRequestToComposite() throws Exception { + WorkContext ctx = new WorkContextImpl(); + final ScopeContainer requestScope = new RequestScopeContainer(ctx, null); + final ScopeContainer compositeScope = new CompositeScopeContainer(null); + requestScope.start(); + compositeScope.start(); + compositeScope.onEvent(new ComponentStart(this, null)); + + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class, + requestScope, members, "target", Target.class, TargetImpl.class, compositeScope); + requestScope.onEvent(new RequestStart(this)); + + final AtomicComponent sourceComponent = contexts.get("source"); + final AtomicComponent targetComponent = contexts.get("target"); + Source source = (Source) sourceComponent.getTargetInstance(); + Target target = (Target) targetComponent.getTargetInstance(); + assertNull(source.getTarget().getString()); + assertNull(target.getString()); + target.setString("foo"); + assertTrue(Proxy.isProxyClass(source.getTarget().getClass())); + assertEquals("foo", source.getTarget().getString()); + + // spin off another request + Executor executor = Executors.newSingleThreadExecutor(); + FutureTask<Void> future = new FutureTask<Void>(new Runnable() { + public void run() { + requestScope.onEvent(new RequestStart(this)); + Source source2 = null; + Target target2 = null; + try { + source2 = (Source) sourceComponent.getTargetInstance(); + target2 = (Target) targetComponent.getTargetInstance(); + } catch (TargetException e) { + fail(e.getMessage()); + } + assertEquals("foo", target2.getString()); + assertEquals("foo", source2.getTarget().getString()); + source2.getTarget().setString("bar"); + assertEquals("bar", target2.getString()); + assertEquals("bar", source2.getTarget().getString()); + requestScope.onEvent(new RequestEnd(this)); + } + }, null); + executor.execute(future); + future.get(); + assertEquals("bar", target.getString()); + + requestScope.onEvent(new RequestEnd(this)); + requestScope.stop(); + compositeScope.onEvent(new ComponentStop(this, null)); + compositeScope.stop(); + } + + /** + * Tests a request-to-session scoped wire is setup properly by the runtime + */ + public void testRequestToSession() throws Exception { + WorkContext ctx = new WorkContextImpl(); + final ScopeContainer requestScope = new RequestScopeContainer(ctx, null); + final ScopeContainer sessionScope = new HttpSessionScopeContainer(ctx, null); + requestScope.start(); + sessionScope.start(); + + Object session1 = new Object(); + ctx.setIdentifier(Scope.SESSION, session1); + sessionScope.onEvent(new HttpSessionStart(this, session1)); + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class, + requestScope, members, "target", Target.class, TargetImpl.class, sessionScope); + + final AtomicComponent sourceComponent = contexts.get("source"); + final AtomicComponent targetComponent = contexts.get("target"); + requestScope.onEvent(new RequestStart(this)); + Source source = (Source) sourceComponent.getTargetInstance(); + Target target = (Target) targetComponent.getTargetInstance(); + assertNull(source.getTarget().getString()); + assertNull(target.getString()); + target.setString("foo"); + assertTrue(Proxy.isProxyClass(source.getTarget().getClass())); + assertEquals("foo", source.getTarget().getString()); + + // spin off another request + Executor executor = Executors.newSingleThreadExecutor(); + FutureTask<Void> future = new FutureTask<Void>(new Runnable() { + public void run() { + requestScope.onEvent(new RequestStart(this)); + Source source2 = null; + Target target2 = null; + try { + source2 = (Source) sourceComponent.getTargetInstance(); + target2 = (Target) targetComponent.getTargetInstance(); + } catch (TargetException e) { + fail(e.getMessage()); + } + assertEquals("foo", target2.getString()); + assertEquals("foo", source2.getTarget().getString()); + source2.getTarget().setString("bar"); + assertEquals("bar", target2.getString()); + assertEquals("bar", source2.getTarget().getString()); + requestScope.onEvent(new RequestEnd(this)); + } + }, null); + executor.execute(future); + future.get(); + assertEquals("bar", target.getString()); + + requestScope.onEvent(new RequestEnd(this)); + requestScope.stop(); + ctx.clearIdentifier(Scope.SESSION); + sessionScope.onEvent(new HttpSessionEnd(this, session1)); + sessionScope.stop(); + } + + + /** + * Tests a request-to-stateless scoped wire is setup properly by the runtime + */ + public void testRequestToStateless() throws Exception { + WorkContext ctx = new WorkContextImpl(); + ScopeContainer requestScope = new RequestScopeContainer(ctx, null); + requestScope.start(); + ScopeContainer statelessScope = new StatelessScopeContainer(ctx, null); + statelessScope.start(); + + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class, + requestScope, members, "target", Target.class, TargetImpl.class, statelessScope); + + AtomicComponent sourceComponent = contexts.get("source"); + AtomicComponent targetComponent = contexts.get("target"); + requestScope.onEvent(new RequestStart(this)); + Source source = (Source) sourceComponent.getTargetInstance(); + Target target = (Target) targetComponent.getTargetInstance(); + assertTrue(Proxy.isProxyClass(source.getTarget().getClass())); + assertNull(source.getTarget().getString()); + assertNull(target.getString()); + target.setString("foo"); + assertFalse("foo".equals(source.getTarget().getString())); + Target target2 = (Target) targetComponent.getTargetInstance(); + assertFalse("foo".equals(target2.getString())); + source.getTarget().setString("bar"); + assertFalse("bar".equals(source.getTarget().getString())); + requestScope.onEvent(new RequestEnd(this)); + requestScope.stop(); + statelessScope.stop(); + } + + + /** + * Tests a stateless-to-stateless scoped wire is setup properly by the runtime + */ + public void testStatelessToStateless() throws Exception { + WorkContext ctx = new WorkContextImpl(); + ScopeContainer statelessScope = new StatelessScopeContainer(ctx, null); + statelessScope.start(); + + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class, + statelessScope, members, "target", Target.class, TargetImpl.class, statelessScope); + + AtomicComponent sourceComponent = contexts.get("source"); + AtomicComponent targetComponent = contexts.get("target"); + Source source = (Source) sourceComponent.getTargetInstance(); + Target target = (Target) targetComponent.getTargetInstance(); + assertTrue(Proxy.isProxyClass(source.getTarget().getClass())); + assertNull(source.getTarget().getString()); + assertNull(target.getString()); + target.setString("foo"); + assertFalse("foo".equals(source.getTarget().getString())); + Target target2 = (Target) targetComponent.getTargetInstance(); + assertFalse("foo".equals(target2.getString())); + source.getTarget().setString("bar"); + assertFalse("bar".equals(source.getTarget().getString())); + statelessScope.stop(); + } + + /** + * Tests a stateless-to-request scoped wire is setup properly by the runtime + */ + public void testStatelessToRequest() throws Exception { + WorkContext ctx = new WorkContextImpl(); + final ScopeContainer requestScope = new RequestScopeContainer(ctx, null); + requestScope.start(); + ScopeContainer statelessScope = new StatelessScopeContainer(ctx, null); + statelessScope.start(); + + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class, + statelessScope, members, "target", Target.class, TargetImpl.class, requestScope); + requestScope.onEvent(new RequestStart(this)); + AtomicComponent sourceComponent = contexts.get("source"); + final AtomicComponent targetComponent = contexts.get("target"); + final Source source = (Source) sourceComponent.getTargetInstance(); + Target target = (Target) targetComponent.getTargetInstance(); + assertNull(source.getTarget().getString()); + assertNull(target.getString()); + target.setString("foo"); + assertTrue(Proxy.isProxyClass(source.getTarget().getClass())); + assertEquals("foo", source.getTarget().getString()); + + // spin off another request + Executor executor = Executors.newSingleThreadExecutor(); + FutureTask<Void> future = new FutureTask<Void>(new Runnable() { + public void run() { + requestScope.onEvent(new RequestStart(this)); + Target target2 = null; + try { + target2 = (Target) targetComponent.getTargetInstance(); + } catch (TargetException e) { + fail(e.getMessage()); + } + assertFalse("foo".equals(target2.getString())); + assertFalse("foo".equals(source.getTarget().getString())); + source.getTarget().setString("bar"); + assertEquals("bar", target2.getString()); + assertEquals("bar", source.getTarget().getString()); + requestScope.onEvent(new RequestEnd(this)); + } + }, null); + executor.execute(future); + future.get(); + requestScope.stop(); + statelessScope.stop(); + } + + /** + * Tests a stateless-to-session scoped wire is setup properly by the runtime + */ + public void testStatelessToSession() throws Exception { + WorkContext ctx = new WorkContextImpl(); + ScopeContainer statelessScope = new StatelessScopeContainer(ctx, null); + statelessScope.start(); + ScopeContainer sessionScope = new HttpSessionScopeContainer(ctx, null); + sessionScope.start(); + + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class, + statelessScope, members, "target", Target.class, TargetImpl.class, sessionScope); + Object session1 = new Object(); + ctx.setIdentifier(Scope.SESSION, session1); + sessionScope.onEvent(new HttpSessionStart(this, session1)); + AtomicComponent sourceComponent = contexts.get("source"); + AtomicComponent targetComponent = contexts.get("target"); + Source source = (Source) sourceComponent.getTargetInstance(); + Target target = (Target) targetComponent.getTargetInstance(); + assertNull(source.getTarget().getString()); + assertNull(target.getString()); + target.setString("foo"); + assertTrue(Proxy.isProxyClass(source.getTarget().getClass())); + assertEquals("foo", source.getTarget().getString()); + ctx.clearIdentifier(Scope.SESSION); + sessionScope.onEvent(new HttpSessionEnd(this, session1)); + + //second session + Object session2 = new Object(); + ctx.setIdentifier(Scope.SESSION, session2); + sessionScope.onEvent(new HttpSessionStart(this, session2)); + + Target target2 = (Target) targetComponent.getTargetInstance(); + assertFalse("foo".equals(target2.getString())); + + assertFalse("foo".equals(source.getTarget().getString())); + source.getTarget().setString("bar"); + assertEquals("bar", target2.getString()); + assertEquals("bar", source.getTarget().getString()); + sessionScope.onEvent(new HttpSessionEnd(this, session2)); + + ctx.clearIdentifier(Scope.SESSION); + sessionScope.stop(); + statelessScope.stop(); + } + + + /** + * Tests a stateless-to-composite scoped wire is setup properly by the runtime + */ + public void testStatelessToComposite() throws Exception { + WorkContext ctx = new WorkContextImpl(); + ScopeContainer statelessScope = new StatelessScopeContainer(ctx, null); + statelessScope.start(); + ScopeContainer compositeScope = new CompositeScopeContainer(null); + compositeScope.start(); + + Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class, + statelessScope, members, "target", Target.class, TargetImpl.class, compositeScope); + compositeScope.onEvent(new ComponentStart(this, null)); + AtomicComponent sourceComponent = contexts.get("source"); + AtomicComponent targetComponent = contexts.get("target"); + Source source = (Source) sourceComponent.getTargetInstance(); + Target target = (Target) targetComponent.getTargetInstance(); + assertNull(source.getTarget().getString()); + assertNull(target.getString()); + target.setString("foo"); + assertTrue(Proxy.isProxyClass(source.getTarget().getClass())); + assertEquals("foo", source.getTarget().getString()); + + //second session + Object session2 = new Object(); + ctx.setIdentifier(Scope.SESSION, session2); + compositeScope.onEvent(new HttpSessionStart(this, session2)); + + Target target2 = (Target) targetComponent.getTargetInstance(); + assertEquals("foo", target2.getString()); + + assertEquals("foo", source.getTarget().getString()); + source.getTarget().setString("bar"); + assertEquals("bar", target2.getString()); + assertEquals("bar", source.getTarget().getString()); + + compositeScope.onEvent(new ComponentStop(this, null)); + compositeScope.stop(); + statelessScope.stop(); + } + + protected void setUp() throws Exception { + super.setUp(); + members = new HashMap<String, Member>(); + Method[] methods = SourceImpl.class.getMethods(); + for (Method method : methods) { + if (method.getName().startsWith("set")) { + members.put(JavaIntrospectionHelper.toPropertyName(method.getName()), method); + } + } + } + + +} + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/wire/DifferentInterfaceWireTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/wire/DifferentInterfaceWireTestCase.java new file mode 100644 index 0000000000..7588e377b4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/wire/DifferentInterfaceWireTestCase.java @@ -0,0 +1,136 @@ +/* + * 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.core.integration.wire; + +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.TargetException; +import org.apache.tuscany.spi.model.Scope; + +import junit.framework.TestCase; +import org.apache.tuscany.core.integration.mock.MockFactory; +import org.apache.tuscany.core.mock.component.OtherTarget; +import org.apache.tuscany.core.mock.component.OtherTargetImpl; +import org.apache.tuscany.core.mock.component.Target; +import org.apache.tuscany.core.mock.component.SourceImpl; +import org.apache.tuscany.core.mock.component.Source; +import org.easymock.EasyMock; +import org.easymock.IAnswer; + + +/** + * Tests wires that have different interfaces on the source and target side + * + * @version $Rev$ $Date$ + */ +public class DifferentInterfaceWireTestCase extends TestCase { + + public void testDifferentInterfaceInjection() throws Exception { + Map<String, Member> members = new HashMap<String, Member>(); + Method m = SourceImpl.class.getMethod("setTarget", Target.class); + members.put("target", m); + ScopeContainer scope = createMock(); + scope.start(); + Map<String, AtomicComponent> contexts = + MockFactory.createWiredComponents("source", + SourceImpl.class, + Target.class, + scope, + null, + members, + "target", + OtherTargetImpl.class, + scope + ); + AtomicComponent sourceComponent = contexts.get("source"); + Source source = (Source) sourceComponent.getTargetInstance(); + Target target = source.getTarget(); + assertTrue(Proxy.isProxyClass(target.getClass())); + assertNotNull(target); + scope.stop(); + EasyMock.verify(scope); + } + + public void testDifferentInterfaceMultiplicityInjection() throws Exception { + Map<String, Member> members = new HashMap<String, Member>(); + Method m = SourceImpl.class.getMethod("setTargets", List.class); + members.put("target", m); + ScopeContainer scope = createMock(); + scope.start(); + Map<String, AtomicComponent> components = MockFactory.createWiredMultiplicity("source", + SourceImpl.class, + Target.class, + scope, + "target", + OtherTarget.class, + OtherTargetImpl.class, + members, + scope); + AtomicComponent sourceComponent = components.get("source"); + Source source = (Source) sourceComponent.getTargetInstance(); + List<Target> targets = source.getTargets(); + assertEquals(1, targets.size()); + Target target = targets.get(0); + target.setString("foo"); + assertEquals("foo", target.getString()); + assertTrue(Proxy.isProxyClass(target.getClass())); + scope.stop(); + EasyMock.verify(scope); + } + + protected void setUp() throws Exception { + super.setUp(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + private ScopeContainer createMock() throws TargetException { + ScopeContainer scope = EasyMock.createMock(ScopeContainer.class); + scope.start(); + scope.stop(); + scope.register(EasyMock.isA(AtomicComponent.class)); + EasyMock.expectLastCall().atLeastOnce(); + EasyMock.expect(scope.getScope()).andReturn(Scope.COMPOSITE).atLeastOnce(); + scope.getInstance(EasyMock.isA(AtomicComponent.class)); + EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { + private Map<AtomicComponent, Object> cache = new HashMap<AtomicComponent, Object>(); + + public Object answer() throws Throwable { + AtomicComponent component = (AtomicComponent) EasyMock.getCurrentArguments()[0]; + Object instance = cache.get(component); + if (instance == null) { + instance = component.createInstance(); + cache.put(component, instance); + } + return instance; + } + }).anyTimes(); + EasyMock.replay(scope); + return scope; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/wire/ReferenceInjectionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/wire/ReferenceInjectionTestCase.java new file mode 100644 index 0000000000..a3ac4dea65 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/wire/ReferenceInjectionTestCase.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.core.integration.wire; + +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ScopeContainer; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.scope.CompositeScopeContainer; +import org.apache.tuscany.core.integration.mock.MockFactory; +import org.apache.tuscany.core.mock.component.Source; +import org.apache.tuscany.core.mock.component.SourceImpl; +import org.apache.tuscany.core.mock.component.Target; +import org.apache.tuscany.core.mock.component.TargetImpl; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class ReferenceInjectionTestCase extends TestCase { + private Map<String, Member> members; + + public void testProxiedReferenceInjection() throws Exception { + ScopeContainer scope = new CompositeScopeContainer(null); + scope.start(); + Map<String, AtomicComponent> components = MockFactory.createWiredComponents("source", + SourceImpl.class, + scope, + members, + "target", + Target.class, + TargetImpl.class, + scope); + AtomicComponent sourceComponent = components.get("source"); + Source source = (Source) sourceComponent.getTargetInstance(); + Target target = source.getTarget(); + assertTrue(Proxy.isProxyClass(target.getClass())); + + assertNotNull(target); + scope.stop(); + } + + protected void setUp() throws Exception { + super.setUp(); + members = new HashMap<String, Member>(); + Method m = SourceImpl.class.getMethod("setTarget", Target.class); + members.put("target", m); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/wire/oneway/OneWayWireToJavaInvocationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/wire/oneway/OneWayWireToJavaInvocationTestCase.java new file mode 100644 index 0000000000..df0d3700b6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/integration/wire/oneway/OneWayWireToJavaInvocationTestCase.java @@ -0,0 +1,126 @@ +/* + * 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.core.integration.wire.oneway; + +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.concurrent.CountDownLatch; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.extension.ExecutionMonitor; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.services.work.WorkScheduler; +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; +import org.apache.tuscany.spi.wire.TargetInvoker; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.implementation.java.JavaAtomicComponent; +import org.apache.tuscany.core.implementation.java.JavaTargetInvoker; +import org.apache.tuscany.core.services.work.jsr237.Jsr237WorkScheduler; +import org.apache.tuscany.core.services.work.jsr237.workmanager.ThreadPoolWorkManager; +import org.apache.tuscany.core.wire.InvocationChainImpl; +import org.apache.tuscany.core.wire.InvokerInterceptor; +import org.apache.tuscany.core.wire.NonBlockingInterceptor; +import org.easymock.classextension.EasyMock; + +/** + * Verifies non-blocking invocations are properly made through a wire to a Java component + * + * @version $Rev$ $Date$ + */ +public class OneWayWireToJavaInvocationTestCase extends TestCase { + private WorkScheduler scheduler; + private WorkContext context; + private CountDownLatch latch; + private InvocationChain ochain; + private JavaTargetInvoker invoker; + private JavaAtomicComponent component; + private AsyncTarget target; + + public void testOneWay() throws Exception { + MessageImpl msg = new MessageImpl(); + msg.setTargetInvoker(invoker); + ochain.getHeadInterceptor().invoke(msg); + latch.await(); + EasyMock.verify(target); + EasyMock.verify(component); + } + + protected void setUp() throws Exception { + super.setUp(); + latch = new CountDownLatch(1); + context = new WorkContextImpl(); + scheduler = new Jsr237WorkScheduler(new ThreadPoolWorkManager(1)); + target = EasyMock.createMock(AsyncTarget.class); + target.invoke(); + EasyMock.expectLastCall().once(); + EasyMock.replay(target); + component = EasyMock.createMock(JavaAtomicComponent.class); + EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE); + EasyMock.expect(component.getTargetInstance()).andReturn(target); + EasyMock.replay(component); + Method method = AsyncTarget.class.getMethod("invoke"); + method.setAccessible(true); + ExecutionMonitor monitor = EasyMock.createNiceMock(ExecutionMonitor.class); + invoker = new JavaTargetInvoker(method, component, context); + Operation<Type> operation = new Operation<Type>("invoke", null, null, null, false, null, TargetInvoker.NONE); + ochain = new InvocationChainImpl(operation); + NonBlockingInterceptor bridgeInterceptor = new NonBlockingInterceptor(scheduler, context); + ochain.addInterceptor(bridgeInterceptor); + InvocationChain ichain = new InvocationChainImpl(operation); + WaitInterceptor waitInterceptor = new WaitInterceptor(); + InvokerInterceptor invokerInterceptor = new InvokerInterceptor(); + ichain.addInterceptor(waitInterceptor); + ichain.addInterceptor(invokerInterceptor); + bridgeInterceptor.setNext(waitInterceptor); + ochain.setTargetInvoker(invoker); + } + + public interface AsyncTarget { + void invoke(); + } + + + private class WaitInterceptor implements Interceptor { + private Interceptor next; + + public Message invoke(Message msg) { + msg = next.invoke(msg); + latch.countDown(); + return msg; + } + + public Interceptor getNext() { + return next; + } + + public void setNext(Interceptor next) { + this.next = next; + } + + public boolean isOptimizable() { + return false; + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderNoBindingTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderNoBindingTestCase.java new file mode 100644 index 0000000000..52136d0d72 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderNoBindingTestCase.java @@ -0,0 +1,103 @@ +/* + * 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.core.loader; + +import java.net.URI; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamReader; + +import static org.osoa.sca.Constants.SCA_NS; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; +import org.apache.tuscany.core.implementation.java.JavaImplementation; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ComponentLoaderNoBindingTestCase extends TestCase { + private static final QName COMPONENT = new QName(SCA_NS, "component"); + private ComponentLoader loader; + private XMLStreamReader reader; + private ServiceDefinition service; + private ReferenceDefinition reference; + private DeploymentContext ctx; + + public void testNoServiceBinding() throws Exception { + loader.load(null, reader, ctx); + assert service.getBindings().isEmpty(); + } + + public void testNoReferenceBinding() throws Exception { + loader.load(null, reader, ctx); + assert reference.getBindings().isEmpty(); + } + + protected void setUp() throws Exception { + super.setUp(); + URI componentId = URI.create("sca://localhost/parent/"); + service = new ServiceDefinition(); + service.setUri(URI.create("service")); + reference = new ReferenceDefinition(); + reference.setUri(URI.create("#ref")); + PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + type.add(service); + type.add(reference); + JavaImplementation impl = new JavaImplementation(null, type); + LoaderRegistry registry = EasyMock.createMock(LoaderRegistry.class); + EasyMock.expect(registry.load( + (ModelObject) EasyMock.isNull(), + EasyMock.isA(XMLStreamReader.class), + EasyMock.isA(DeploymentContext.class))).andReturn(impl); + registry.loadComponentType( + EasyMock.isA(Implementation.class), + EasyMock.isA(DeploymentContext.class)); + EasyMock.replay(registry); + loader = new ComponentLoader(registry, null); + reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getName()).andReturn(COMPONENT).atLeastOnce(); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.expect(reader.getAttributeValue(null, "name")).andReturn("foo"); + EasyMock.expect(reader.getAttributeValue(null, "initLevel")).andReturn("0"); + EasyMock.expect(reader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("autowire"))) + .andReturn(null); + EasyMock.expect(reader.nextTag()).andReturn(1); + EasyMock.replay(reader); + ctx = EasyMock.createMock(DeploymentContext.class); + EasyMock.expect(ctx.getClassLoader()).andReturn(null); + EasyMock.expect(ctx.isAutowire()).andReturn(false); + EasyMock.expect(ctx.getScdlLocation()).andReturn(null); + EasyMock.expect(ctx.getComponentId()).andReturn(componentId); + EasyMock.replay(ctx); + + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderNoReferenceTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderNoReferenceTestCase.java new file mode 100644 index 0000000000..55c51d5c12 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderNoReferenceTestCase.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.core.loader; + +import java.net.URI; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import static org.osoa.sca.Constants.SCA_NS; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.UndefinedReferenceException; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; +import org.apache.tuscany.core.implementation.java.JavaImplementation; +import org.easymock.EasyMock; +import static org.easymock.EasyMock.isNull; + +/** + * @version $Rev$ $Date$ + */ +public class ComponentLoaderNoReferenceTestCase extends TestCase { + private static final QName COMPONENT = new QName(SCA_NS, "component"); + private static final QName REFERENCE = new QName(SCA_NS, "reference"); + private static final String NAME = "testComponent"; + private ComponentLoader loader; + private XMLStreamReader reader; + private DeploymentContext ctx; + + /** + * Verifies an error is thrown when an attempt to configure a non-existent reference in SCDL is made + */ + public void testNoReferenceOnComponentType() throws LoaderException, XMLStreamException { + try { + loader.load(null, reader, ctx); + fail(); + } catch (UndefinedReferenceException e) { + // expected + } + } + + protected void setUp() throws Exception { + super.setUp(); + URI componentId = URI.create("sca://localhost/parent/"); + PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + JavaImplementation impl = new JavaImplementation(null, type); + reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getName()).andReturn(COMPONENT); + EasyMock.expect(reader.getAttributeValue((String) EasyMock.isNull(), EasyMock.isA(String.class))) + .andReturn(NAME); + EasyMock.expect(reader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("initLevel"))) + .andReturn(null); + EasyMock.expect(reader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("autowire"))) + .andReturn(null); + EasyMock.expect(reader.getAttributeValue(EasyMock.isA(String.class), EasyMock.isA(String.class))) + .andReturn(null); + EasyMock.expect(reader.nextTag()).andReturn(0); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.START_ELEMENT); + EasyMock.expect(reader.getName()).andReturn(REFERENCE); + EasyMock.expect(reader.getAttributeValue((String) isNull(), EasyMock.eq("name"))) + .andReturn("noreference"); + EasyMock.expect(reader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("autowire"))) + .andReturn(null); + EasyMock.expect(reader.getAttributeValue(null, "target")).andReturn("text"); + + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.replay(reader); + LoaderRegistry mockRegistry = EasyMock.createMock(LoaderRegistry.class); + mockRegistry.loadComponentType( + EasyMock.isA(Implementation.class), + EasyMock.isA(DeploymentContext.class)); + EasyMock.expect(mockRegistry.load( + (ModelObject) isNull(), + EasyMock.isA(XMLStreamReader.class), + EasyMock.isA(DeploymentContext.class))).andReturn(impl); + EasyMock.replay(mockRegistry); + loader = new ComponentLoader(mockRegistry, null); + ctx = EasyMock.createMock(DeploymentContext.class); + EasyMock.expect(ctx.getClassLoader()).andReturn(null); + EasyMock.expect(ctx.isAutowire()).andReturn(false); + EasyMock.expect(ctx.getScdlLocation()).andReturn(null); + EasyMock.expect(ctx.getComponentId()).andReturn(componentId); + EasyMock.replay(ctx); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderPropertyTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderPropertyTestCase.java new file mode 100644 index 0000000000..c6f65481b7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderPropertyTestCase.java @@ -0,0 +1,81 @@ +/* + * 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.core.loader; + +import javax.xml.stream.XMLStreamException; + +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.MissingRequiredPropertyException; +import org.apache.tuscany.spi.loader.PropertyObjectFactory; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; +import org.apache.tuscany.core.implementation.java.JavaImplementation; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ComponentLoaderPropertyTestCase extends TestCase { + + private TestLoader loader; + + /** + * Verifies that an optional property not cofigured in an assembly will avoid having a PropertyValue created for it + * so that the runtime does not erroneously inject null values + */ + public void testOptionalPropertyNotConfigured() throws LoaderException, XMLStreamException { + PojoComponentType<?, ?, Property<?>> type = + new PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + Property property = new Property(); + property.setName("name"); + type.add(property); + JavaImplementation impl = new JavaImplementation(null, type); + impl.setComponentType(type); + ComponentDefinition<Implementation<?>> defn = new ComponentDefinition<Implementation<?>>(impl); + loader.populatePropertyValues(defn); + assertTrue(defn.getPropertyValues().isEmpty()); + } + + protected void setUp() throws Exception { + super.setUp(); + LoaderRegistry mockRegistry = EasyMock.createMock(LoaderRegistry.class); + PropertyObjectFactory mockPropertyFactory = EasyMock.createMock(PropertyObjectFactory.class); + loader = new TestLoader(mockRegistry, mockPropertyFactory); + } + + private class TestLoader extends ComponentLoader { + + public TestLoader(LoaderRegistry registry, PropertyObjectFactory propertyFactory) { + super(registry, propertyFactory); + } + + @Override + public void populatePropertyValues(ComponentDefinition<Implementation<?>> componentDefinition) + throws MissingRequiredPropertyException { + super.populatePropertyValues(componentDefinition); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderRefTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderRefTestCase.java new file mode 100644 index 0000000000..07ef7d6348 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderRefTestCase.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.core.loader; + +import java.net.URI; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ReferenceTarget; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; +import org.apache.tuscany.core.implementation.java.JavaImplementation; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ComponentLoaderRefTestCase extends TestCase { + private ComponentLoader loader; + private final URI componentId = URI.create("sca://localhost/parent/"); + private DeploymentContext context; + + public void testLoadReferenceNoFragment() throws LoaderException, XMLStreamException { + PojoComponentType<?, MockReferenceDefinition, Property<?>> type = + new PojoComponentType<ServiceDefinition, MockReferenceDefinition, Property<?>>(); + MockReferenceDefinition reference = new MockReferenceDefinition(); + reference.setUri(URI.create("#reference")); + type.add(reference); + JavaImplementation impl = new JavaImplementation(); + impl.setComponentType(type); + ComponentDefinition<?> definition = new ComponentDefinition<JavaImplementation>(impl); + definition.setUri(URI.create("component")); + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getAttributeValue(null, "name")).andReturn("reference"); + EasyMock.expect(reader.getAttributeValue(null, "target")).andReturn("target"); + EasyMock.expect(reader.getAttributeValue(null, "autowire")).andReturn(null); + EasyMock.replay(reader); + loader.loadReference(reader, definition, context); + ReferenceTarget target = definition.getReferenceTargets().get("reference"); + assertEquals(1, target.getTargets().size()); + URI uri = target.getTargets().get(0); + assertEquals(componentId.resolve("target"), uri); + assertNull(uri.getFragment()); + EasyMock.verify(reader); + } + + public void testLoadReferenceWithFragment() throws LoaderException, XMLStreamException { + PojoComponentType<?, MockReferenceDefinition, Property<?>> type = + new PojoComponentType<ServiceDefinition, MockReferenceDefinition, Property<?>>(); + MockReferenceDefinition reference = new MockReferenceDefinition(); + reference.setUri(URI.create("#reference")); + type.add(reference); + JavaImplementation impl = new JavaImplementation(); + impl.setComponentType(type); + ComponentDefinition<?> definition = new ComponentDefinition<JavaImplementation>(impl); + definition.setUri(URI.create("component")); + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getAttributeValue(null, "name")).andReturn("reference"); + EasyMock.expect(reader.getAttributeValue(null, "target")).andReturn("target/fragment"); + EasyMock.expect(reader.getAttributeValue(null, "autowire")).andReturn(null); + EasyMock.replay(reader); + loader.loadReference(reader, definition, context); + ReferenceTarget target = definition.getReferenceTargets().get("reference"); + assertEquals(1, target.getTargets().size()); + URI uri = target.getTargets().get(0); + assertEquals(componentId.resolve("target#fragment"), uri); + EasyMock.verify(reader); + } + + public void testLoadReferenceWithMultipleTargetUris() throws LoaderException, XMLStreamException { + PojoComponentType<?, MockReferenceDefinition, Property<?>> type = + new PojoComponentType<ServiceDefinition, MockReferenceDefinition, Property<?>>(); + MockReferenceDefinition reference = new MockReferenceDefinition(); + reference.setUri(URI.create("#reference")); + type.add(reference); + JavaImplementation impl = new JavaImplementation(); + impl.setComponentType(type); + ComponentDefinition<?> definition = new ComponentDefinition<JavaImplementation>(impl); + definition.setUri(URI.create("component")); + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getAttributeValue(null, "name")).andReturn("reference"); + EasyMock.expect(reader.getAttributeValue(null, "target")).andReturn("target1/fragment1 target2/fragment2"); + EasyMock.expect(reader.getAttributeValue(null, "autowire")).andReturn(null); + EasyMock.replay(reader); + loader.loadReference(reader, definition, context); + ReferenceTarget target = definition.getReferenceTargets().get("reference"); + assertEquals(2, target.getTargets().size()); + URI uri1 = target.getTargets().get(0); + assertEquals(componentId.resolve("target1#fragment1"), uri1); + URI uri2 = target.getTargets().get(1); + assertEquals(componentId.resolve("target2#fragment2"), uri2); + EasyMock.verify(reader); + } + + public void testLoadReferenceAutowire() throws LoaderException, XMLStreamException { + PojoComponentType<?, MockReferenceDefinition, Property<?>> type = + new PojoComponentType<ServiceDefinition, MockReferenceDefinition, Property<?>>(); + MockReferenceDefinition reference = new MockReferenceDefinition(); + reference.setUri(URI.create("#reference")); + type.add(reference); + JavaImplementation impl = new JavaImplementation(); + impl.setComponentType(type); + ComponentDefinition<?> definition = new ComponentDefinition<JavaImplementation>(impl); + definition.setUri(URI.create("component")); + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getAttributeValue(null, "name")).andReturn("reference"); + EasyMock.expect(reader.getAttributeValue(null, "target")).andReturn("target/fragment"); + EasyMock.expect(reader.getAttributeValue(null, "autowire")).andReturn("true"); + EasyMock.replay(reader); + loader.loadReference(reader, definition, context); + ReferenceTarget target = definition.getReferenceTargets().get("reference"); + assertTrue(target.isAutowire()); + EasyMock.verify(reader); + } + + + + protected void setUp() throws Exception { + super.setUp(); + LoaderRegistry mockRegistry = EasyMock.createMock(LoaderRegistry.class); + loader = new ComponentLoader(mockRegistry, null); + Component parent = EasyMock.createNiceMock(Component.class); + EasyMock.expect(parent.getUri()).andReturn(componentId).atLeastOnce(); + EasyMock.replay(parent); + + context = EasyMock.createMock(DeploymentContext.class); + EasyMock.expect(context.getComponentId()).andReturn(componentId); + EasyMock.replay(context); + } + + private class MockReferenceDefinition extends ReferenceDefinition { + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderTestCase.java new file mode 100644 index 0000000000..f13fbe67e3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderTestCase.java @@ -0,0 +1,245 @@ +/* + * 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.core.loader; + +import java.net.URI; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import static org.osoa.sca.Constants.SCA_NS; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.PropertyObjectFactory; +import org.apache.tuscany.spi.loader.UnrecognizedElementException; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; +import org.apache.tuscany.core.implementation.java.JavaImplementation; +import org.easymock.EasyMock; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.isNull; +import static org.easymock.EasyMock.replay; +import org.easymock.IAnswer; + +/** + * @version $Rev$ $Date$ + */ +public class ComponentLoaderTestCase extends TestCase { + private static final QName COMPONENT = new QName(SCA_NS, "component"); + private static final String COMPONENT_NAME = "sca://localhost/parent/"; + private static final String NAME = "testComponent"; + private JavaImplementation impl; + + private XMLStreamReader mockReader; + private LoaderRegistry mockRegistry; + private PropertyObjectFactory mockPropertyFactory; + private ComponentLoader loader; + private Component parent; + private DeploymentContext ctx; + private URI componentId; + + public void testEmptyComponent() throws LoaderException, XMLStreamException { + EasyMock.expect(mockReader.getName()).andReturn(COMPONENT).atLeastOnce(); + EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.isA(String.class))) + .andReturn(NAME); + EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("initLevel"))) + .andReturn(null); + EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("autowire"))) + .andReturn(null); + EasyMock.expect(mockReader.getAttributeValue(EasyMock.isA(String.class), EasyMock.isA(String.class))) + .andReturn(null); + EasyMock.expect(mockReader.nextTag()).andReturn(0); + EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.replay(mockReader); + mockRegistry.loadComponentType( + EasyMock.isA(Implementation.class), + EasyMock.isA(DeploymentContext.class)); + EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() { + @SuppressWarnings("unchecked") + public Object answer() throws Throwable { + Implementation impl = (Implementation) EasyMock.getCurrentArguments()[0]; + impl.setComponentType(new PojoComponentType()); + return impl; + } + }); + + EasyMock.expect(mockRegistry.load( + (ModelObject) isNull(), + EasyMock.eq(mockReader), + EasyMock.isA(DeploymentContext.class))).andReturn(impl); + EasyMock.replay(mockRegistry); + ComponentDefinition component = loader.load(null, mockReader, ctx); + assertEquals(COMPONENT_NAME + NAME, component.getUri().toString()); + assertNull(component.getInitLevel()); + } + + public void testAutowire() throws LoaderException, XMLStreamException { + EasyMock.expect(mockReader.getName()).andReturn(COMPONENT).atLeastOnce(); + EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.isA(String.class))) + .andReturn(NAME); + EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("initLevel"))) + .andReturn(null); + EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("autowire"))) + .andReturn("true"); + EasyMock.expect(mockReader.nextTag()).andReturn(0); + EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.replay(mockReader); + + mockRegistry.loadComponentType( + EasyMock.isA(Implementation.class), + EasyMock.isA(DeploymentContext.class)); + + EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() { + @SuppressWarnings("unchecked") + public Object answer() throws Throwable { + Implementation impl = (Implementation) EasyMock.getCurrentArguments()[0]; + impl.setComponentType(new PojoComponentType()); + return impl; + } + }); + EasyMock.expect(mockRegistry.load( + (ModelObject) isNull(), + EasyMock.eq(mockReader), + EasyMock.isA(DeploymentContext.class))).andReturn(impl); + EasyMock.replay(mockRegistry); + + ComponentDefinition component = loader.load(null, mockReader, ctx); + + assertTrue(component.getAutowire()); + } + + public void testInitValue20() throws LoaderException, XMLStreamException { + EasyMock.expect(mockReader.getName()).andReturn(COMPONENT).atLeastOnce(); + EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.isA(String.class))) + .andReturn(NAME); + EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("initLevel"))) + .andReturn("20"); + EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("autowire"))) + .andReturn(null); + EasyMock.expect(mockReader.nextTag()).andReturn(0); + EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.replay(mockReader); + + mockRegistry.loadComponentType( + EasyMock.isA(Implementation.class), + EasyMock.isA(DeploymentContext.class)); + + EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() { + @SuppressWarnings("unchecked") + public Object answer() throws Throwable { + Implementation impl = (Implementation) EasyMock.getCurrentArguments()[0]; + impl.setComponentType(new PojoComponentType()); + return impl; + } + }); + EasyMock.expect(mockRegistry.load( + (ModelObject) isNull(), + EasyMock.eq(mockReader), + EasyMock.isA(DeploymentContext.class))).andReturn(impl); + EasyMock.replay(mockRegistry); + + ComponentDefinition component = loader.load(null, mockReader, ctx); + assertEquals(COMPONENT_NAME + NAME, component.getUri().toString()); + assertEquals(Integer.valueOf(20), component.getInitLevel()); + } + + public void testLoadPropertyWithSource() throws LoaderException, XMLStreamException { + PojoComponentType<?, ?, Property<?>> type = + new PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + Property property = new Property(); + property.setName("name"); + type.add(property); + JavaImplementation impl = new JavaImplementation(); + impl.setComponentType(type); + ComponentDefinition<?> defn = new ComponentDefinition<JavaImplementation>(impl); + XMLStreamReader reader = createMock(XMLStreamReader.class); + expect(reader.getAttributeValue(null, "name")).andReturn("name"); + expect(reader.getAttributeValue(null, "source")).andReturn("$source"); + expect(reader.getAttributeValue(null, "file")).andReturn(null); + expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + replay(reader); + loader.loadProperty(reader, defn, null); + assertEquals("$source", defn.getPropertyValues().get("name").getSource()); + EasyMock.verify(reader); + } + + public void testUnrecognizedElement() throws LoaderException, XMLStreamException { + EasyMock.expect(mockReader.getName()).andReturn(COMPONENT); + EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.isA(String.class))) + .andReturn(NAME); + EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("initLevel"))) + .andReturn(null); + EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("autowire"))) + .andReturn(null); + EasyMock.expect(mockReader.getAttributeValue(EasyMock.isA(String.class), EasyMock.isA(String.class))) + .andReturn(null); + EasyMock.expect(mockReader.nextTag()).andReturn(0); + EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.START_ELEMENT); + EasyMock.expect(mockReader.getName()).andReturn(new QName("foo", "bar")); + EasyMock.replay(mockReader); + mockRegistry.loadComponentType( + EasyMock.isA(Implementation.class), + EasyMock.isA(DeploymentContext.class)); + + EasyMock.expect(mockRegistry.load( + (ModelObject) isNull(), + EasyMock.eq(mockReader), + EasyMock.isA(DeploymentContext.class))).andReturn(impl); + EasyMock.replay(mockRegistry); + try { + loader.load(null, mockReader, ctx); + fail(); + } catch (UnrecognizedElementException e) { + // expected + } + } + + protected void setUp() throws Exception { + super.setUp(); + componentId = URI.create(COMPONENT_NAME); + impl = new JavaImplementation(); + mockReader = EasyMock.createMock(XMLStreamReader.class); + mockRegistry = EasyMock.createMock(LoaderRegistry.class); + mockPropertyFactory = EasyMock.createMock(PropertyObjectFactory.class); + loader = new ComponentLoader(mockRegistry, mockPropertyFactory); + parent = EasyMock.createNiceMock(Component.class); + URI uri = URI.create("foo"); + EasyMock.expect(parent.getUri()).andReturn(uri).atLeastOnce(); + EasyMock.replay(parent); + + ctx = EasyMock.createMock(DeploymentContext.class); + EasyMock.expect(ctx.isAutowire()).andReturn(false); + EasyMock.expect(ctx.getClassLoader()).andReturn(null); + EasyMock.expect(ctx.getScdlLocation()).andReturn(null); + EasyMock.expect(ctx.getComponentId()).andReturn(componentId); + EasyMock.replay(ctx); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderValidationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderValidationTestCase.java new file mode 100644 index 0000000000..fdfdaeaa7f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderValidationTestCase.java @@ -0,0 +1,169 @@ +/* + * 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.core.loader; + +import java.net.URI; +import javax.xml.stream.XMLStreamException; + +import org.apache.tuscany.spi.implementation.java.PojoComponentType; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.MissingReferenceException; +import org.apache.tuscany.spi.loader.PropertyObjectFactory; +import org.apache.tuscany.spi.loader.ReferenceMultiplicityViolationException; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.Multiplicity; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ReferenceTarget; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; +import org.apache.tuscany.core.implementation.java.JavaImplementation; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ComponentLoaderValidationTestCase extends TestCase { + + private ComponentLoaderValidationTestCase.TestLoader loader; + + public void testValidation() throws LoaderException, XMLStreamException { + PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + ReferenceDefinition refDefinition = new ReferenceDefinition(); + refDefinition.setUri(URI.create("#name")); + type.add(refDefinition); + JavaImplementation impl = new JavaImplementation(null, type); + ComponentDefinition<Implementation<?>> defn = new ComponentDefinition<Implementation<?>>(impl); + ReferenceTarget target = new ReferenceTarget(); + target.setReferenceName(URI.create("#name")); + defn.add(target); + loader.validate(defn); + } + + public void testReferenceNotSet() throws LoaderException, XMLStreamException { + PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + ReferenceDefinition refDefinition = new ReferenceDefinition(); + refDefinition.setUri(URI.create("#name")); + refDefinition.setRequired(true); + type.add(refDefinition); + JavaImplementation impl = new JavaImplementation(null, type); + ComponentDefinition<Implementation<?>> defn = new ComponentDefinition<Implementation<?>>(impl); + try { + loader.validate(defn); + fail(); + } catch (MissingReferenceException e) { + // expected + } + } + + public void testNotRequiredReference() throws LoaderException, XMLStreamException { + PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + ReferenceDefinition refDefinition = new ReferenceDefinition(); + refDefinition.setUri(URI.create("#name")); + refDefinition.setRequired(false); + type.add(refDefinition); + JavaImplementation impl = new JavaImplementation(null, type); + ComponentDefinition<Implementation<?>> defn = new ComponentDefinition<Implementation<?>>(impl); + loader.validate(defn); + } + + public void testReferenceMultiplicity() throws LoaderException, XMLStreamException { + PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new PojoComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + ReferenceDefinition refDefinition = new ReferenceDefinition(); + URI uri = URI.create("#r1"); + refDefinition.setUri(uri); + refDefinition.setRequired(true); + refDefinition.setMultiplicity(Multiplicity.ONE_N); + type.add(refDefinition); + JavaImplementation impl = new JavaImplementation(null, type); + ComponentDefinition<Implementation<?>> defn = new ComponentDefinition<Implementation<?>>(impl); + ReferenceTarget target = new ReferenceTarget(); + target.setReferenceName(uri); + target.addTarget(URI.create("c1")); + target.addTarget(URI.create("c2")); + defn.add(target); + loader.validate(defn); + + refDefinition.setMultiplicity(Multiplicity.ZERO_ONE); + try { + loader.validate(defn); + fail(); + } catch (ReferenceMultiplicityViolationException e) { + // Expected + } + + refDefinition.setMultiplicity(Multiplicity.ZERO_N); + loader.validate(defn); + + refDefinition.setMultiplicity(Multiplicity.ONE_ONE); + try { + loader.validate(defn); + fail(); + } catch (ReferenceMultiplicityViolationException e) { + // Expected + } + + target.getTargets().clear(); + refDefinition.setMultiplicity(Multiplicity.ONE_ONE); + try { + loader.validate(defn); + fail(); + } catch (ReferenceMultiplicityViolationException e) { + // Expected + } + refDefinition.setMultiplicity(Multiplicity.ONE_N); + try { + loader.validate(defn); + fail(); + } catch (ReferenceMultiplicityViolationException e) { + // Expected + } + refDefinition.setMultiplicity(Multiplicity.ZERO_N); + loader.validate(defn); + refDefinition.setMultiplicity(Multiplicity.ZERO_ONE); + loader.validate(defn); + + } + + protected void setUp() throws Exception { + super.setUp(); + LoaderRegistry mockRegistry = EasyMock.createMock(LoaderRegistry.class); + PropertyObjectFactory mockPropertyFactory = EasyMock.createMock(PropertyObjectFactory.class); + loader = new ComponentLoaderValidationTestCase.TestLoader(mockRegistry, mockPropertyFactory); + } + + private class TestLoader extends ComponentLoader { + + public TestLoader(LoaderRegistry registry, PropertyObjectFactory propertyFactory) { + super(registry, propertyFactory); + } + + @Override + protected void validate(ComponentDefinition<Implementation<?>> definition) throws LoaderException { + super.validate(definition); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentTypeElementLoaderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentTypeElementLoaderTestCase.java new file mode 100644 index 0000000000..9948019b7b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ComponentTypeElementLoaderTestCase.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.core.loader; + +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamReader; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ComponentTypeElementLoaderTestCase extends TestCase { + + public void testSpecializedComponentTypePassedIn() throws Exception { + ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + ComponentTypeElementLoader loader = new ComponentTypeElementLoader(null); + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getName()).andReturn(ComponentTypeElementLoader.COMPONENT_TYPE); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.replay(reader); + // verify that the exact component type instance is returned. Some StAXElementLoader implementations may chose + // to copy the original instance but ComponentTypeElementLoader does not since it has no knowledge of the + // specialized instance + ModelObject object = loader.load(type, reader, null); + assertEquals(object, type); + } + + public void testComponentTypePassedAsContext() throws Exception { + ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + LoaderRegistry registry = EasyMock.createMock(LoaderRegistry.class); + EasyMock.expect(registry.load( + EasyMock.isA(ComponentType.class), + EasyMock.isA(XMLStreamReader.class), + (DeploymentContext) EasyMock.isNull())).andReturn(type); + EasyMock.replay(registry); + ComponentTypeElementLoader loader = new ComponentTypeElementLoader(registry); + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getName()).andReturn(ComponentTypeElementLoader.COMPONENT_TYPE); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.START_ELEMENT); + EasyMock.expect(reader.getName()).andReturn(new QName("foo", "foo")); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.replay(reader); + + loader.load(type, reader, null); + EasyMock.verify(registry); + } + + public void testNonSpecializedComponentTypePassedIn() throws Exception { + ComponentTypeElementLoader loader = new ComponentTypeElementLoader(null); + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.getName()).andReturn(ComponentTypeElementLoader.COMPONENT_TYPE); + EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.replay(reader); + ModelObject object = loader.load(null, reader, null); + assertEquals(ComponentType.class, object.getClass()); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/DependencyLoaderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/DependencyLoaderTestCase.java new file mode 100644 index 0000000000..41b56d2bab --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/DependencyLoaderTestCase.java @@ -0,0 +1,124 @@ +/* + * 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.core.loader; + +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.UnrecognizedElementException; + +import junit.framework.TestCase; +import org.easymock.EasyMock; +import org.apache.tuscany.core.implementation.composite.Dependency; + +/** + * @version $Rev$ $Date$ + */ +public class DependencyLoaderTestCase extends TestCase { + private static final String NS = "http://tuscany.apache.org/xmlns/sca/2.0-alpha"; + private static final QName DEPENDENCY = new QName(NS, "dependency"); + private static final QName GROUP = new QName(NS, "group"); + private static final QName NAME = new QName(NS, "name"); + private static final QName VERSION = new QName(NS, "version"); + private static final QName CLASSIFIER = new QName(NS, "classifier"); + private static final QName TYPE = new QName(NS, "type"); + + public void testLoad() throws Exception { + LoaderRegistry registry = EasyMock.createNiceMock(LoaderRegistry.class); + EasyMock.replay(registry); + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.nextTag()).andReturn(XMLStreamConstants.START_ELEMENT); + EasyMock.expect(reader.getName()).andReturn(GROUP); + EasyMock.expect(reader.getElementText()).andReturn("group"); + EasyMock.expect(reader.nextTag()).andReturn(XMLStreamConstants.START_ELEMENT); + EasyMock.expect(reader.getName()).andReturn(NAME); + EasyMock.expect(reader.getElementText()).andReturn("name"); + EasyMock.expect(reader.nextTag()).andReturn(XMLStreamConstants.START_ELEMENT); + EasyMock.expect(reader.getName()).andReturn(VERSION); + EasyMock.expect(reader.getElementText()).andReturn("1"); + EasyMock.expect(reader.nextTag()).andReturn(XMLStreamConstants.START_ELEMENT); + EasyMock.expect(reader.getName()).andReturn(CLASSIFIER); + EasyMock.expect(reader.getElementText()).andReturn("classifier"); + EasyMock.expect(reader.nextTag()).andReturn(XMLStreamConstants.START_ELEMENT); + EasyMock.expect(reader.getName()).andReturn(TYPE); + EasyMock.expect(reader.getElementText()).andReturn("type"); + EasyMock.expect(reader.nextTag()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.replay(reader); + DependencyLoader loader = new DependencyLoader(registry); + Dependency dependency = loader.load(null, reader, null); + assertEquals("group", dependency.getArtifact().getGroup()); + assertEquals("name", dependency.getArtifact().getName()); + assertEquals("1", dependency.getArtifact().getVersion()); + assertEquals("classifier", dependency.getArtifact().getClassifier()); + assertEquals("type", dependency.getArtifact().getType()); + } + + public void testLoaderRegister() { + LoaderRegistry registry = EasyMock.createMock(LoaderRegistry.class); + registry.registerLoader(EasyMock.eq(DEPENDENCY), EasyMock.isA(DependencyLoader.class)); + EasyMock.replay(registry); + DependencyLoader loader = new DependencyLoader(registry); + loader.start(); + EasyMock.verify(registry); + } + + public void testUnrecognizedElement() throws Exception { + LoaderRegistry registry = EasyMock.createNiceMock(LoaderRegistry.class); + EasyMock.replay(registry); + XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class); + EasyMock.expect(reader.nextTag()).andReturn(XMLStreamConstants.START_ELEMENT); + EasyMock.expect(reader.getName()).andReturn(new QName("foo", "bar")); + EasyMock.expect(reader.getElementText()).andReturn("foo"); + EasyMock.expect(reader.getLocation()).andReturn(new MockLocation()); + EasyMock.replay(reader); + DependencyLoader loader = new DependencyLoader(registry); + try { + loader.load(null, reader, null); + fail(); + } catch (UnrecognizedElementException e) { + // expected + } + } + + private class MockLocation implements Location { + + public int getLineNumber() { + return 0; + } + + public int getColumnNumber() { + return 0; + } + + public int getCharacterOffset() { + return 0; + } + + public String getPublicId() { + return null; + } + + public String getSystemId() { + return null; + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/IncludeLoaderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/IncludeLoaderTestCase.java new file mode 100644 index 0000000000..671c3a74d9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/IncludeLoaderTestCase.java @@ -0,0 +1,176 @@ +/* + * 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.core.loader; + +import java.net.URI; +import java.net.URL; +import javax.xml.namespace.QName; +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import junit.framework.TestCase; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.eq; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.isA; +import static org.easymock.EasyMock.isNull; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import org.osoa.sca.Constants; + +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.MissingIncludeException; +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.Include; +import org.apache.tuscany.spi.model.ModelObject; + +/** + * @version $Rev$ $Date$ + */ +public class IncludeLoaderTestCase extends TestCase { + private static final QName INCLUDE = new QName(Constants.SCA_NS, "include"); + + private LoaderRegistry registry; + private IncludeLoader loader; + private XMLStreamReader reader; + private DeploymentContext context; + private URL base; + private URL includeURL; + private ClassLoader cl; + private URI componentId; + + public void testNoLocation() throws LoaderException, XMLStreamException { + String name = "foo"; + expect(reader.getName()).andReturn(INCLUDE); + expect(reader.getAttributeValue(null, "name")).andReturn(name); + expect(reader.getAttributeValue(null, "scdlLocation")).andReturn(null); + expect(reader.getAttributeValue(null, "scdlResource")).andReturn(null); + expect(reader.next()).andReturn(END_ELEMENT); + + expect(context.getClassLoader()).andReturn(cl); + replay(registry, reader, context); + + try { + loader.load(null, reader, context); + fail(); + } catch (MissingIncludeException e) { + // OK expected + } + verify(registry, reader, context); + } + + public void testWithAbsoluteScdlLocation() throws LoaderException, XMLStreamException { + String name = "foo"; + expect(reader.getName()).andReturn(INCLUDE); + expect(reader.getAttributeValue(null, "name")).andReturn(name); + expect(reader.getAttributeValue(null, "scdlLocation")).andReturn("http://example.com/include.scdl"); + expect(reader.getAttributeValue(null, "scdlResource")).andReturn(null); + expect(reader.next()).andReturn(END_ELEMENT); + + expect(context.getScdlLocation()).andReturn(base); + expect(context.getClassLoader()).andReturn(cl); + expect(context.isAutowire()).andReturn(false); + expect(context.getComponentId()).andReturn(componentId); + + expect(registry.load( + (ModelObject) isNull(), + eq(includeURL), + eq(CompositeComponentType.class), + isA(DeploymentContext.class))) + .andReturn(null); + replay(registry, reader, context); + + Include include = loader.load(null, reader, context); + assertEquals(name, include.getName()); + assertEquals(includeURL, include.getScdlLocation()); + verify(registry, reader, context); + } + + public void testWithRelativeScdlLocation() throws LoaderException, XMLStreamException { + String name = "foo"; + expect(reader.getName()).andReturn(INCLUDE); + expect(reader.getAttributeValue(null, "name")).andReturn(name); + expect(reader.getAttributeValue(null, "scdlLocation")).andReturn("include.scdl"); + expect(reader.getAttributeValue(null, "scdlResource")).andReturn(null); + expect(reader.next()).andReturn(END_ELEMENT); + + expect(context.getScdlLocation()).andReturn(base); + expect(context.getClassLoader()).andReturn(cl); + expect(context.isAutowire()).andReturn(false); + expect(context.getComponentId()).andReturn(componentId); + + expect(registry.load( + (ModelObject) isNull(), + eq(includeURL), + eq(CompositeComponentType.class), + isA(DeploymentContext.class))) + .andReturn(null); + replay(registry, reader, context); + + Include include = loader.load(null, reader, context); + assertEquals(name, include.getName()); + assertEquals(includeURL, include.getScdlLocation()); + verify(registry, reader, context); + } + + public void testWithScdlResource() throws LoaderException, XMLStreamException { + String name = "foo"; + String resource = "org/apache/tuscany/core/loader/test-include.scdl"; + includeURL = cl.getResource(resource); + assertNotNull(includeURL); + + expect(reader.getName()).andReturn(INCLUDE); + expect(reader.getAttributeValue(null, "name")).andReturn(name); + expect(reader.getAttributeValue(null, "scdlLocation")).andReturn(null); + expect(reader.getAttributeValue(null, "scdlResource")).andReturn(resource); + expect(reader.next()).andReturn(END_ELEMENT); + + expect(context.getClassLoader()).andReturn(cl); + expect(context.isAutowire()).andReturn(false); + expect(context.getComponentId()).andReturn(componentId); + + expect(registry.load( + (ModelObject) isNull(), + eq(includeURL), + eq(CompositeComponentType.class), + isA(DeploymentContext.class))) + .andReturn(null); + replay(registry, reader, context); + + Include include = loader.load(null, reader, context); + assertEquals(name, include.getName()); + assertEquals(includeURL, include.getScdlLocation()); + verify(registry, reader, context); + } + + protected void setUp() throws Exception { + super.setUp(); + registry = createMock(LoaderRegistry.class); + reader = createMock(XMLStreamReader.class); + context = createMock(DeploymentContext.class); + cl = getClass().getClassLoader(); + base = new URL("http://example.com/test.scdl"); + includeURL = new URL("http://example.com/include.scdl"); + loader = new IncludeLoader(registry); + componentId = URI.create("sca://localhost/parent/"); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/JNDIPropertyFactoryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/JNDIPropertyFactoryTestCase.java new file mode 100644 index 0000000000..fb5bfd32d3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/JNDIPropertyFactoryTestCase.java @@ -0,0 +1,81 @@ +/* + * 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.core.loader; + +import java.lang.reflect.Type; +import java.util.Hashtable; +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.spi.InitialContextFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import org.apache.tuscany.spi.model.PropertyValue; + +import junit.framework.TestCase; +import org.apache.tuscany.core.injection.JNDIObjectFactory; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class JNDIPropertyFactoryTestCase extends TestCase { + + public void testCreate() throws Exception { + String old = System.getProperty(Context.INITIAL_CONTEXT_FACTORY); + try { + System.setProperty(Context.INITIAL_CONTEXT_FACTORY, MockInitialContextFactory.class.getName()); + JNDIPropertyFactory factory = new JNDIPropertyFactory(); + Element element = EasyMock.createMock(Element.class); + EasyMock.expect(element.getTextContent()).andReturn("foo"); + EasyMock.replay(element); + Document doc = EasyMock.createMock(Document.class); + EasyMock.expect(doc.getDocumentElement()).andReturn(element); + EasyMock.replay(doc); + PropertyValue<?> value = new MockPropertyValue<Type>(); + value.setValue(doc); + JNDIObjectFactory<?> jndiFactory = (JNDIObjectFactory<?>) factory.createObjectFactory(null, value); + assertEquals("bar", jndiFactory.getInstance()); + } finally { + System.clearProperty(Context.INITIAL_CONTEXT_FACTORY); + if (old != null) { + System.setProperty(Context.INITIAL_CONTEXT_FACTORY, old); + } + } + + } + + private class MockPropertyValue<T> extends PropertyValue<T> { + + } + + public static class MockInitialContextFactory implements InitialContextFactory { + public MockInitialContextFactory() { + } + + public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException { + Context context = EasyMock.createMock(Context.class); + EasyMock.expect(context.lookup("foo")).andReturn("bar"); + EasyMock.replay(context); + return context; + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/LoaderExceptionFormatterTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/LoaderExceptionFormatterTestCase.java new file mode 100644 index 0000000000..49c53935dc --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/LoaderExceptionFormatterTestCase.java @@ -0,0 +1,47 @@ +/* + * 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.core.loader; + +import java.io.PrintWriter; +import java.io.StringWriter; + +import org.apache.tuscany.spi.loader.LoaderException; + +import junit.framework.TestCase; +import org.easymock.EasyMock; +import org.apache.tuscany.host.monitor.FormatterRegistry; + +/** + * @version $Rev$ $Date$ + */ +public class LoaderExceptionFormatterTestCase extends TestCase { + + public void testLog() { + FormatterRegistry registry = EasyMock.createNiceMock(FormatterRegistry.class); + LoaderExceptionFormatter formatter = new LoaderExceptionFormatter(registry); + LoaderException e = new LoaderException("test"); + StringWriter writer = new StringWriter(); + PrintWriter pw = new PrintWriter(writer); + formatter.write(pw, e); + pw.close(); + assertTrue(!"message".equals(writer.toString())); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/PolicySetLoaderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/PolicySetLoaderTestCase.java new file mode 100644 index 0000000000..2b3acc9d92 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/PolicySetLoaderTestCase.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.core.loader; + +import java.util.Collection; +import java.util.Iterator; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import javax.xml.stream.XMLStreamReader; + +import static org.osoa.sca.Constants.SCA_NS; + +import org.apache.tuscany.spi.model.IntentMap; +import org.apache.tuscany.spi.model.PolicySet; +import org.apache.tuscany.spi.model.Qualifier; + +import junit.framework.TestCase; + +public class PolicySetLoaderTestCase extends TestCase { + private static final QName POLICYSET = new QName(SCA_NS, "policySet"); + + public void testLoader() throws Exception { + PolicySetLoader loader = new PolicySetLoader(null); + XMLInputFactory factory = XMLInputFactory.newInstance(); + XMLStreamReader reader = factory.createXMLStreamReader(this.getClass().getResourceAsStream("TestPolicy.scdl")); + while (true) { + int state = reader.next(); + if (START_ELEMENT == state && reader.getName().equals(POLICYSET)) { + break; + } + } + PolicySet policySet = loader.load(null, reader, null); + assertNotNull(policySet); + assertEquals(2, policySet.getAppliedArtifacts().size()); + assertTrue(policySet.getAppliedArtifacts().contains(new QName(SCA_NS, "binding.ws"))); + assertTrue(policySet.getAppliedArtifacts().contains(new QName(SCA_NS, "binding.jms"))); + Collection<IntentMap> intentMaps = policySet.getIntentMaps(); + assertEquals(1, intentMaps.size()); + IntentMap intentMap = intentMaps.iterator().next(); + assertEquals("transport", intentMap.getDefaultProvideIntent()); + assertTrue(intentMap.getProvideIntents().contains("sec.confidentiality")); + Collection<Qualifier> qualifiers = intentMap.getQualifiers(); + assertEquals(2, qualifiers.size()); + Iterator qit = qualifiers.iterator(); + Qualifier qualifier1 = (Qualifier) qit.next(); + assertEquals(2, qualifier1.getWsPolicyAttachments().size()); + assertEquals("transport", qualifier1.getName()); + Qualifier qualifier2 = (Qualifier) qit.next(); + assertEquals("message", qualifier2.getName()); + IntentMap messageMap = qualifier2.getIntentMap(); + assertEquals(2, messageMap.getQualifiers().size()); + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/PropertyParsingTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/PropertyParsingTestCase.java new file mode 100644 index 0000000000..eb732d9f74 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/PropertyParsingTestCase.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.core.loader; + +import java.io.StringReader; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class PropertyParsingTestCase extends TestCase { + private XMLInputFactory xmlFactory; + private DocumentBuilder docBuilder; + private Element root; + + public void testComplexProperty() throws XMLStreamException { + String xml = "<property xmlns:foo='http://foo.com'>" + + "<foo:a>aValue</foo:a>" + + "<foo:b>InterestingURI</foo:b>" + + "</property>"; + + XMLStreamReader reader = getReader(xml); + PropertyUtils.loadPropertyValue(reader, root); + NodeList childNodes = root.getChildNodes(); + assertEquals(2, childNodes.getLength()); + + Element e = (Element) childNodes.item(0); + assertEquals("http://foo.com", e.getNamespaceURI()); + assertEquals("a", e.getLocalName()); + assertEquals("aValue", e.getTextContent()); + e = (Element) childNodes.item(1); + assertEquals("http://foo.com", e.getNamespaceURI()); + assertEquals("b", e.getLocalName()); + assertEquals("InterestingURI", e.getTextContent()); + } + + public XMLStreamReader getReader(String xml) throws XMLStreamException { + XMLStreamReader reader = xmlFactory.createXMLStreamReader(new StringReader(xml)); + reader.next(); + return reader; + } + + protected void setUp() throws Exception { + super.setUp(); + xmlFactory = XMLInputFactory.newInstance(); + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + docBuilder = docFactory.newDocumentBuilder(); + Document doc = docBuilder.newDocument(); + root = doc.createElement("value"); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ReferenceLoaderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ReferenceLoaderTestCase.java new file mode 100644 index 0000000000..3d4bcaf195 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ReferenceLoaderTestCase.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.core.loader; + +import java.net.URI; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.osoa.sca.Constants; + +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.model.BindingDefinition; +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.ModelObject; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * Verifies loading of a reference definition from an XML-based assembly + * + * @version $Rev$ $Date$ + */ +public class ReferenceLoaderTestCase extends TestCase { + private static final QName REFERENCE = new QName(Constants.SCA_NS, "reference"); + private static final String COMPONENT_NAME = "sca://someComponent"; + private URI componentId; + private ReferenceLoader loader; + private XMLStreamReader mockReader; + private LoaderRegistry mockRegistry; + private DeploymentContext ctx; + + public void testWithNoInterface() throws LoaderException, XMLStreamException { + String name = "referenceDefinition"; + EasyMock.expect(mockReader.getName()).andReturn(REFERENCE).anyTimes(); + EasyMock.expect(mockReader.getAttributeValue(null, "name")).andReturn(name); + EasyMock.expect(mockReader.getAttributeValue(null, "multiplicity")).andReturn("0..1"); + EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.expect(mockReader.getName()).andReturn(REFERENCE).anyTimes(); + EasyMock.replay(mockReader); + ReferenceDefinition referenceDefinition = loader.load(null, mockReader, ctx); + assertNotNull(referenceDefinition); + assertEquals(COMPONENT_NAME + "#" + name, referenceDefinition.getUri().toString()); + } + + public void testComponentTypeService() throws LoaderException, XMLStreamException { + String name = "reference"; + EasyMock.expect(mockReader.getName()).andReturn(REFERENCE).anyTimes(); + EasyMock.expect(mockReader.getAttributeValue(null, "name")).andReturn(name); + EasyMock.expect(mockReader.getAttributeValue(null, "multiplicity")).andReturn("0..1"); + EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.expect(mockReader.getName()).andReturn(REFERENCE).anyTimes(); + EasyMock.replay(mockReader); + ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + ReferenceDefinition referenceDefinition = loader.load(type, mockReader, ctx); + assertTrue(ReferenceDefinition.class.equals(referenceDefinition.getClass())); + } + + public void testMultipleBindings() throws LoaderException, XMLStreamException { + String name = "referenceDefinition"; + EasyMock.expect(mockReader.getName()).andReturn(REFERENCE).anyTimes(); + EasyMock.expect(mockReader.getAttributeValue(null, "name")).andReturn(name); + EasyMock.expect(mockReader.getAttributeValue(null, "multiplicity")).andReturn("0..1"); + EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.START_ELEMENT).times(2); + EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.expect(mockReader.getName()).andReturn(REFERENCE).anyTimes(); + EasyMock.replay(mockReader); + + BindingDefinition binding = new BindingDefinition() { + }; + EasyMock.expect(mockRegistry.load( + (ModelObject) EasyMock.isNull(), + EasyMock.eq(mockReader), + EasyMock.isA(DeploymentContext.class))) + .andReturn(binding).times(2); + EasyMock.replay(mockRegistry); + + ReferenceDefinition referenceDefinition = loader.load(null, mockReader, ctx); + assertEquals(2, referenceDefinition.getBindings().size()); + } + + public void testWithInterface() throws LoaderException, XMLStreamException { + String name = "referenceDefinition"; + ServiceContract sc = new ServiceContract() { + }; + EasyMock.expect(mockReader.getName()).andReturn(REFERENCE).anyTimes(); + EasyMock.expect(mockReader.getAttributeValue(null, "name")).andReturn(name); + EasyMock.expect(mockReader.getAttributeValue(null, "multiplicity")).andReturn("0..1"); + EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.START_ELEMENT); + EasyMock.expect(mockRegistry.load(null, mockReader, ctx)).andReturn(sc); + EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + + EasyMock.replay(mockReader); + EasyMock.replay(mockRegistry); + + ReferenceDefinition referenceDefinition = loader.load(null, mockReader, ctx); + assertNotNull(referenceDefinition); + assertEquals(COMPONENT_NAME + "#" + name, referenceDefinition.getUri().toString()); + assertSame(sc, referenceDefinition.getServiceContract()); + } + + protected void setUp() throws Exception { + super.setUp(); + componentId = URI.create(COMPONENT_NAME); + mockReader = EasyMock.createStrictMock(XMLStreamReader.class); + mockRegistry = EasyMock.createMock(LoaderRegistry.class); + loader = new ReferenceLoader(mockRegistry); + ctx = EasyMock.createMock(DeploymentContext.class); + EasyMock.expect(ctx.getComponentId()).andReturn(componentId); + EasyMock.replay(ctx); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ServiceLoaderPromoteTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ServiceLoaderPromoteTestCase.java new file mode 100644 index 0000000000..335d9f5aa9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ServiceLoaderPromoteTestCase.java @@ -0,0 +1,86 @@ +/* + * 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.core.loader; + +import java.net.URI; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.osoa.sca.Constants; + +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.model.ServiceDefinition; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ServiceLoaderPromoteTestCase extends TestCase { + private static final QName SERVICE = new QName(Constants.SCA_NS, "service"); + private static final String COMPONENT_NAME = "sca://domain/someComponent/"; + private URI componentId; + private ServiceLoader loader; + private XMLStreamReader mockReader; + private DeploymentContext ctx; + + public void testReferenceNoFragment() throws LoaderException, XMLStreamException { + String name = "serviceDefinition"; + EasyMock.expect(mockReader.getName()).andReturn(SERVICE); + EasyMock.expect(mockReader.getAttributeValue(null, "name")).andReturn(name); + EasyMock.expect(mockReader.getAttributeValue(null, "promote")).andReturn("target"); + EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.expect(mockReader.getName()).andReturn(SERVICE); + EasyMock.replay(mockReader); + ServiceDefinition serviceDefinition = loader.load(null, mockReader, ctx); + assertNotNull(serviceDefinition); + assertEquals(COMPONENT_NAME + "target", serviceDefinition.getTarget().toString()); + } + + public void testReferenceWithFragment() throws LoaderException, XMLStreamException { + String name = "serviceDefinition"; + EasyMock.expect(mockReader.getName()).andReturn(SERVICE); + EasyMock.expect(mockReader.getAttributeValue(null, "name")).andReturn(name); + EasyMock.expect(mockReader.getAttributeValue(null, "promote")).andReturn("target/fragment"); + EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.END_ELEMENT); + EasyMock.expect(mockReader.getName()).andReturn(SERVICE); + EasyMock.replay(mockReader); + ServiceDefinition serviceDefinition = loader.load(null, mockReader, ctx); + assertNotNull(serviceDefinition); + assertEquals(COMPONENT_NAME + "target#fragment", serviceDefinition.getTarget().toString()); + } + + + protected void setUp() throws Exception { + super.setUp(); + mockReader = EasyMock.createStrictMock(XMLStreamReader.class); + LoaderRegistry mockRegistry = EasyMock.createMock(LoaderRegistry.class); + loader = new ServiceLoader(mockRegistry); + + componentId = URI.create(COMPONENT_NAME); + ctx = EasyMock.createMock(DeploymentContext.class); + EasyMock.expect(ctx.getComponentId()).andReturn(componentId); + EasyMock.replay(ctx); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ServiceLoaderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ServiceLoaderTestCase.java new file mode 100644 index 0000000000..b7cb8161c7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/ServiceLoaderTestCase.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.core.loader; + +import java.net.URI; +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.Constants.SCA_NS; + +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.model.BindingDefinition; +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.ServiceContract; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; +import org.easymock.EasyMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; + +/** + * Verifies loading of a service definition from an XML-based assembly + * + * @version $Rev$ $Date$ + */ +public class ServiceLoaderTestCase extends TestCase { + private static final QName SERVICE = new QName(SCA_NS, "service"); + //private static final QName REFERENCE = new QName(SCA_NS, "reference"); + private static final QName INTERFACE_JAVA = new QName(SCA_NS, "interface.java"); + private static final String PARENT_NAME = "sca://localhost/parent/"; + private ServiceLoader loader; + private DeploymentContext deploymentContext; + private XMLStreamReader mockReader; + private LoaderRegistry mockRegistry; + private URI componentId; + + public void testWithNoInterface() throws LoaderException, XMLStreamException { + String name = "serviceDefinition"; + expect(mockReader.getName()).andReturn(SERVICE).anyTimes(); + expect(mockReader.getAttributeValue(null, "name")).andReturn(name); + expect(mockReader.getAttributeValue(null, "promote")).andReturn(null); + expect(mockReader.next()).andReturn(END_ELEMENT); + expect(mockReader.getName()).andReturn(SERVICE).anyTimes(); + replay(mockReader); + ServiceDefinition serviceDefinition = loader.load(null, mockReader, deploymentContext); + assertNotNull(serviceDefinition); + assertEquals(PARENT_NAME + "#" + name, serviceDefinition.getUri().toString()); + } + + public void testComponentTypeService() throws LoaderException, XMLStreamException { + String name = "service"; + expect(mockReader.getName()).andReturn(SERVICE).anyTimes(); + expect(mockReader.getAttributeValue(null, "name")).andReturn(name); + expect(mockReader.getAttributeValue(null, "promote")).andReturn(null); + expect(mockReader.next()).andReturn(END_ELEMENT); + expect(mockReader.getName()).andReturn(SERVICE).anyTimes(); + replay(mockReader); + ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + ServiceDefinition serviceDefinition = loader.load(type, mockReader, deploymentContext); + assertTrue(ServiceDefinition.class.equals(serviceDefinition.getClass())); + } + + public void testMultipleBindings() throws LoaderException, XMLStreamException { + String name = "serviceDefinition"; + expect(mockReader.getName()).andReturn(SERVICE).anyTimes(); + expect(mockReader.getAttributeValue(null, "name")).andReturn(name); + expect(mockReader.getAttributeValue(null, "promote")).andReturn("component/target"); + expect(mockReader.next()).andReturn(START_ELEMENT); + expect(mockReader.next()).andReturn(START_ELEMENT); + expect(mockReader.next()).andReturn(END_ELEMENT); + expect(mockReader.getName()).andReturn(SERVICE).anyTimes(); + replay(mockReader); + + BindingDefinition binding = new BindingDefinition() { + }; + expect(mockRegistry.load(null, mockReader, deploymentContext)).andReturn(binding).times(2); + replay(mockRegistry); + + ServiceDefinition serviceDefinition = loader.load(null, mockReader, deploymentContext); + assertEquals(2, serviceDefinition.getBindings().size()); + } + + public void testWithInterface() throws LoaderException, XMLStreamException { + String name = "serviceDefinition"; + String target = "target"; + ServiceContract sc = new ServiceContract() { + }; + expect(mockReader.getName()).andReturn(SERVICE).anyTimes(); + expect(mockReader.getAttributeValue(null, "name")).andReturn(name); + expect(mockReader.getAttributeValue(null, "promote")).andReturn(target); + expect(mockReader.next()).andReturn(START_ELEMENT); + expect(mockRegistry.load(null, mockReader, deploymentContext)).andReturn(sc); + expect(mockReader.next()).andReturn(END_ELEMENT); + expect(mockReader.getName()).andReturn(SERVICE); + + replay(mockReader); + replay(mockRegistry); + + ServiceDefinition serviceDefinition = loader.load(null, mockReader, deploymentContext); + assertNotNull(serviceDefinition); + assertEquals(PARENT_NAME + "#" + name, serviceDefinition.getUri().toString()); + assertSame(sc, serviceDefinition.getServiceContract()); + } + + public void testWithNoReference() throws LoaderException, XMLStreamException { + String name = "serviceDefinition"; + ServiceContract sc = new ServiceContract() { + }; + expect(mockReader.getName()).andReturn(SERVICE).anyTimes(); + expect(mockReader.getAttributeValue(null, "name")).andReturn(name); + expect(mockReader.getAttributeValue(null, "promote")).andReturn(null); + expect(mockReader.next()).andReturn(START_ELEMENT); + expect(mockRegistry.load(null, mockReader, deploymentContext)).andReturn(sc); + expect(mockReader.next()).andReturn(END_ELEMENT); + expect(mockReader.getName()).andReturn(SERVICE); + + replay(mockReader); + replay(mockRegistry); + + ServiceDefinition serviceDefinition = loader.load(null, mockReader, deploymentContext); + assertNotNull(serviceDefinition); + assertEquals(PARENT_NAME + "#" + name, serviceDefinition.getUri().toString()); + assertSame(sc, serviceDefinition.getServiceContract()); + } + + protected void setUp() throws Exception { + super.setUp(); + mockReader = EasyMock.createStrictMock(XMLStreamReader.class); + mockRegistry = EasyMock.createMock(LoaderRegistry.class); + loader = new ServiceLoader(mockRegistry); + componentId = URI.create(PARENT_NAME); + deploymentContext = EasyMock.createMock(DeploymentContext.class); + EasyMock.expect(deploymentContext.getComponentId()).andReturn(componentId); + EasyMock.replay(deploymentContext); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/StAXLoaderRegistryImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/StAXLoaderRegistryImplTestCase.java new file mode 100644 index 0000000000..b98051f3f8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/StAXLoaderRegistryImplTestCase.java @@ -0,0 +1,131 @@ +/* + * 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.core.loader; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.StAXElementLoader; +import org.apache.tuscany.spi.loader.UnrecognizedElementException; +import org.apache.tuscany.spi.model.ModelObject; + +import junit.framework.TestCase; +import org.apache.tuscany.core.deployer.RootDeploymentContext; +import static org.easymock.EasyMock.isNull; +import org.easymock.classextension.EasyMock; + +/** + * Verifies the default loader registry + * + * @version $Rev$ $Date$ + */ +public class StAXLoaderRegistryImplTestCase extends TestCase { + private LoaderRegistryImpl registry; + private QName name; + private LoaderRegistryImpl.Monitor mockMonitor; + private StAXElementLoader<ModelObject> mockLoader; + private XMLStreamReader mockReader; + private DeploymentContext deploymentContext; + private ModelObject modelObject; + + public void testLoaderRegistration() { + mockMonitor.registeringLoader(EasyMock.eq(name)); + EasyMock.replay(mockMonitor); + registry.registerLoader(name, mockLoader); + EasyMock.verify(mockMonitor); + } + + public void testLoaderUnregistration() { + mockMonitor.unregisteringLoader(EasyMock.eq(name)); + EasyMock.replay(mockMonitor); + registry.unregisterLoader(name, (StAXElementLoader<ModelObject>) mockLoader); + EasyMock.verify(mockMonitor); + } + + public void testSuccessfulDispatch() throws LoaderException, XMLStreamException { + EasyMock.expect(mockReader.getName()).andReturn(name); + EasyMock.replay(mockReader); + mockMonitor.registeringLoader(EasyMock.eq(name)); + mockMonitor.elementLoad(EasyMock.eq(name)); + EasyMock.replay(mockMonitor); + EasyMock.expect(mockLoader.load( + (ModelObject) isNull(), + EasyMock.eq(mockReader), + EasyMock.eq(deploymentContext))).andReturn(modelObject); + EasyMock.replay(mockLoader); + registry.registerLoader(name, (StAXElementLoader<ModelObject>) mockLoader); + Component parent = EasyMock.createNiceMock(Component.class); + assertSame(modelObject, registry.load(null, mockReader, deploymentContext)); + EasyMock.verify(mockLoader); + EasyMock.verify(mockMonitor); + EasyMock.verify(mockReader); + + } + + public void testUnsuccessfulDispatch() throws LoaderException, XMLStreamException { + EasyMock.expect(mockReader.getName()).andReturn(name); + EasyMock.replay(mockReader); + mockMonitor.elementLoad(EasyMock.eq(name)); + EasyMock.replay(mockMonitor); + try { + registry.load(null, mockReader, deploymentContext); + fail(); + } catch (UnrecognizedElementException e) { + assertSame(name, e.getElement()); + } + EasyMock.verify(mockReader); + EasyMock.verify(mockMonitor); + } + + public void testPregivenModelObject() throws Exception { + EasyMock.expect(mockReader.getName()).andReturn(name); + EasyMock.replay(mockReader); + mockMonitor.registeringLoader(EasyMock.eq(name)); + mockMonitor.elementLoad(EasyMock.eq(name)); + EasyMock.replay(mockMonitor); + EasyMock.expect(mockLoader.load( + EasyMock.eq(modelObject), + EasyMock.eq(mockReader), + EasyMock.eq(deploymentContext))).andReturn(modelObject); + EasyMock.replay(mockLoader); + registry.registerLoader(name, (StAXElementLoader<ModelObject>) mockLoader); + Component parent = EasyMock.createNiceMock(Component.class); + assertSame(modelObject, registry.load(modelObject, mockReader, deploymentContext)); + EasyMock.verify(mockLoader); + } + + @SuppressWarnings("unchecked") + protected void setUp() throws Exception { + super.setUp(); + name = new QName("http://mock", "test"); + deploymentContext = new RootDeploymentContext(null, null, null, null, null, false); + mockMonitor = EasyMock.createMock(LoaderRegistryImpl.Monitor.class); + registry = new LoaderRegistryImpl(mockMonitor); + + mockLoader = EasyMock.createMock(StAXElementLoader.class); + mockReader = EasyMock.createMock(XMLStreamReader.class); + modelObject = new ModelObject() { + }; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/StringParserPropertyFactoryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/StringParserPropertyFactoryTestCase.java new file mode 100644 index 0000000000..4445dfad2c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/StringParserPropertyFactoryTestCase.java @@ -0,0 +1,128 @@ +/* + * 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.core.loader; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.PropertyValue; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class StringParserPropertyFactoryTestCase extends TestCase { + + private <T> PropertyValue<T> mock(String value) { + Document document = EasyMock.createMock(Document.class); + Element element = EasyMock.createMock(Element.class); + EasyMock.expect(document.getDocumentElement()).andReturn(element); + EasyMock.expect(element.getTextContent()).andReturn(value); + EasyMock.replay(document, element); + return new PropertyValue<T>(null, document); + } + + public void testInteger() throws Exception { + + StringParserPropertyFactory factory = new StringParserPropertyFactory(); + Property<Integer> property = new Property<Integer>(); + property.setJavaType(Integer.class); + PropertyValue<Integer> propertyValue = mock("1"); + ObjectFactory<Integer> oFactory = factory.createObjectFactory(property, propertyValue); + assertEquals(1, oFactory.getInstance().intValue()); + } + + public void testPrimitiveInt() throws Exception { + StringParserPropertyFactory factory = new StringParserPropertyFactory(); + Property<Integer> property = new Property<Integer>(); + property.setJavaType(Integer.TYPE); + PropertyValue<Integer> propertyValue = mock("1"); + ObjectFactory<Integer> oFactory = factory.createObjectFactory(property, propertyValue); + assertEquals(1, oFactory.getInstance().intValue()); + } + + public void testString() throws Exception { + StringParserPropertyFactory factory = new StringParserPropertyFactory(); + Property<String> property = new Property<String>(); + property.setJavaType(String.class); + PropertyValue<String> propertyValue = mock("1"); + ObjectFactory<String> oFactory = factory.createObjectFactory(property, propertyValue); + assertEquals("1", oFactory.getInstance()); + } + + public void testByteArray() throws Exception { + StringParserPropertyFactory factory = new StringParserPropertyFactory(); + Property<byte[]> property = new Property<byte[]>(); + property.setJavaType(byte[].class); + PropertyValue<byte[]> propertyValue = mock("1"); + ObjectFactory<byte[]> oFactory = factory.createObjectFactory(property, propertyValue); + byte[] result = oFactory.getInstance(); + byte[] expected = "1".getBytes(); + for (int i = 0; i < result.length; i++) { + byte b = result[i]; + if (b != expected[i]) { + fail(); + } + } + } + + public void testBoolean() throws Exception { + StringParserPropertyFactory factory = new StringParserPropertyFactory(); + Property<Boolean> property = new Property<Boolean>(); + property.setJavaType(Boolean.class); + PropertyValue<Boolean> propertyValue = mock("true"); + ObjectFactory<Boolean> oFactory = factory.createObjectFactory(property, propertyValue); + assertTrue(oFactory.getInstance()); + } + + public void testPrimitiveBoolean() throws Exception { + StringParserPropertyFactory factory = new StringParserPropertyFactory(); + Property<Boolean> property = new Property<Boolean>(); + property.setJavaType(Boolean.TYPE); + PropertyValue<Boolean> propertyValue = mock("true"); + ObjectFactory<Boolean> oFactory = factory.createObjectFactory(property, propertyValue); + assertTrue(oFactory.getInstance()); + } + + public void testStringConstructor() throws Exception { + StringParserPropertyFactory factory = new StringParserPropertyFactory(); + Property<Foo> property = new Property<Foo>(); + property.setJavaType(Foo.class); + PropertyValue<Foo> propertyValue = mock("test"); + ObjectFactory<Foo> oFactory = factory.createObjectFactory(property, propertyValue); + assertEquals("test", oFactory.getInstance().getFoo()); + } + + private static class Foo { + private String foo; + + public Foo(String foo) { + this.foo = foo; + } + + public String getFoo() { + return foo; + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/WireLoaderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/WireLoaderTestCase.java new file mode 100644 index 0000000000..75e455d5a8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/loader/WireLoaderTestCase.java @@ -0,0 +1,181 @@ +/*
+ * 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.core.loader;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+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.Constants.SCA_NS;
+
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.loader.InvalidWireException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.WireDefinition;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * @version $Rev: 471504 $ $Date: 2006-11-06 01:10:40 +0530 (Mon, 06 Nov 2006) $
+ */
+public class WireLoaderTestCase extends TestCase {
+ private static final QName WIRE = new QName(SCA_NS, "wire");
+ private static final QName SOURCE_URI = new QName(SCA_NS, "source.uri");
+ private static final QName TARGET_URI = new QName(SCA_NS, "target.uri");
+
+ private LoaderRegistry registry;
+ private WireLoader loader;
+ private XMLStreamReader reader;
+ private DeploymentContext context;
+ private Component composite;
+
+ public void testValidWire() throws LoaderException, XMLStreamException {
+ expect(reader.getName()).andReturn(WIRE);
+ expect(reader.next()).andReturn(START_ELEMENT);
+ expect(reader.getName()).andReturn(SOURCE_URI).times(1);
+ expect(reader.getElementText()).andReturn("source").times(1);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.next()).andReturn(START_ELEMENT);
+ expect(reader.getName()).andReturn(TARGET_URI).times(2);
+ expect(reader.getElementText()).andReturn("target").times(1);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.getName()).andReturn(WIRE).anyTimes();
+ replay(registry, reader, context);
+ WireDefinition wireDef = loader.load(null, reader, context);
+ assertNotNull(wireDef);
+ verify(registry, reader, context);
+ }
+
+ public void testInValidWireNoSourceElement() throws LoaderException, XMLStreamException {
+ expect(reader.getName()).andReturn(WIRE).times(1);
+ expect(reader.next()).andReturn(START_ELEMENT);
+ expect(reader.getName()).andReturn(TARGET_URI).times(2);
+ expect(reader.getElementText()).andReturn("target").times(1);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.getName()).andReturn(WIRE).anyTimes();
+ replay(registry, reader, context);
+ try {
+ loader.load(null, reader, context);
+ fail();
+ } catch (InvalidWireException e) {
+ //expected behaviour
+ }
+ verify(registry, reader, context);
+ }
+
+ public void testInValidWireNoTargetElement() throws LoaderException, XMLStreamException {
+ expect(reader.getName()).andReturn(WIRE).times(1);
+ expect(reader.next()).andReturn(START_ELEMENT);
+ expect(reader.getName()).andReturn(SOURCE_URI).times(1);
+ expect(reader.getElementText()).andReturn("source").times(1);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.getName()).andReturn(WIRE).anyTimes();
+ replay(registry, reader, context);
+ try {
+ loader.load(null, reader, context);
+ fail();
+ } catch (InvalidWireException e) {
+ //expected behaviour
+ }
+ verify(registry, reader, context);
+ }
+
+ public void testInValidWireNoSourceSpecified() throws LoaderException, XMLStreamException {
+ expect(reader.getName()).andReturn(WIRE).times(1);
+ expect(reader.next()).andReturn(START_ELEMENT);
+ expect(reader.getName()).andReturn(SOURCE_URI).times(1);
+ expect(reader.getElementText()).andReturn("").times(1);
+ replay(registry, reader, context);
+ try {
+ loader.load(null, reader, context);
+ fail();
+ } catch (InvalidWireException e) {
+ //expected behaviour
+ }
+ verify(registry, reader, context);
+ }
+
+ public void testInValidWireNoTargetSpecified() throws LoaderException, XMLStreamException {
+ expect(reader.getName()).andReturn(WIRE).times(1);
+ expect(reader.next()).andReturn(START_ELEMENT);
+ expect(reader.getName()).andReturn(SOURCE_URI).times(1);
+ expect(reader.getElementText()).andReturn("source").times(1);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.next()).andReturn(START_ELEMENT);
+ expect(reader.getName()).andReturn(TARGET_URI).times(2);
+ expect(reader.getElementText()).andReturn("").times(1);
+ expect(reader.getName()).andReturn(WIRE).anyTimes();
+ replay(registry, reader, context);
+ try {
+ loader.load(null, reader, context);
+ fail();
+ } catch (InvalidWireException e) {
+ //expected behaviour
+ }
+ verify(registry, reader, context);
+ }
+
+ public void testWireSourceAndTargetFragments() throws LoaderException, XMLStreamException {
+ expect(reader.getName()).andReturn(WIRE);
+ expect(reader.next()).andReturn(START_ELEMENT);
+ expect(reader.getName()).andReturn(SOURCE_URI).times(1);
+ expect(reader.getElementText()).andReturn("source/reference").times(1);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.next()).andReturn(START_ELEMENT);
+ expect(reader.getName()).andReturn(TARGET_URI).times(2);
+ expect(reader.getElementText()).andReturn("target/service").times(1);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.getName()).andReturn(WIRE).anyTimes();
+ replay(registry, reader, context);
+ WireDefinition wireDef = loader.load(null, reader, context);
+ assertNotNull(wireDef);
+ assertEquals("source", wireDef.getSource().getPath());
+ assertEquals("reference", wireDef.getSource().getFragment());
+ assertEquals("target", wireDef.getTarget().getPath());
+ assertEquals("service", wireDef.getTarget().getFragment());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ registry = createMock(LoaderRegistry.class);
+ reader = createMock(XMLStreamReader.class);
+ Location location = EasyMock.createNiceMock(Location.class);
+ EasyMock.replay(location);
+ EasyMock.expect(reader.getLocation()).andReturn(location).anyTimes();
+ context = createMock(DeploymentContext.class);
+ composite = createMock(Component.class);
+ loader = new WireLoader(registry);
+ }
+
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/marshaller/JavaPhysicalChangeSetMarshallerTest.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/marshaller/JavaPhysicalChangeSetMarshallerTest.java new file mode 100644 index 0000000000..3c65e231d2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/marshaller/JavaPhysicalChangeSetMarshallerTest.java @@ -0,0 +1,154 @@ +/* + * 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.core.marshaller; + +import java.io.InputStream; +import java.util.Set; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamReader; + +import junit.framework.TestCase; + +import org.apache.tuscany.core.marshaller.extensions.java.JavaPhysicalComponentDefinitionMarshaller; +import org.apache.tuscany.core.marshaller.extensions.java.JavaPhysicalReferenceDefinitionMarshaller; +import org.apache.tuscany.core.marshaller.extensions.java.JavaPhysicalServiceDefinitionMarshaller; +import org.apache.tuscany.core.model.physical.java.JavaPhysicalComponentDefinition; +import org.apache.tuscany.core.model.physical.java.JavaPhysicalReferenceDefinition; +import org.apache.tuscany.core.model.physical.java.JavaPhysicalServiceDefinition; +import org.apache.tuscany.spi.marshaller.ModelMarshallerRegistry; +import org.apache.tuscany.spi.model.physical.PhysicalChangeSet; +import org.apache.tuscany.spi.model.physical.PhysicalComponentDefinition; +import org.apache.tuscany.spi.model.physical.PhysicalOperationDefinition; +import org.apache.tuscany.spi.model.physical.PhysicalWireDefinition; + +/** + * Test case for Java physical change set marshaller. + * + * @version $Revision$ $Date$ + * + */ +public class JavaPhysicalChangeSetMarshallerTest extends TestCase { + + private ModelMarshallerRegistry registry; + + public JavaPhysicalChangeSetMarshallerTest(String arg0) { + super(arg0); + } + + public void setUp() { + + registry = new DefaultModelMarshallerRegistry(); + + AbstractMarshallerExtension<?>[] marshallers = new AbstractMarshallerExtension<?>[6]; + + marshallers[0] = new JavaPhysicalComponentDefinitionMarshaller(); + marshallers[1] = new JavaPhysicalServiceDefinitionMarshaller(); + marshallers[2] = new JavaPhysicalReferenceDefinitionMarshaller(); + marshallers[3] = new PhysicalOperationDefinitionMarshaller(); + marshallers[4] = new PhysicalWireDefinitionMarshaller(); + marshallers[5] = new PhysicalChangeSetMarshaller(); + + for (int i = 0; i < 6; i++) { + marshallers[i].setRegistry(registry); + } + + } + + public void testUnmarshall() throws Exception { + + ClassLoader cl = getClass().getClassLoader(); + InputStream inputStream = cl.getResourceAsStream("marshall/javaChangeSet.xml"); + XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream); + + reader.next(); + PhysicalChangeSet changeSet = (PhysicalChangeSet)registry.unmarshall(reader); + assertNotNull(changeSet); + Set<? extends PhysicalComponentDefinition> pcds = changeSet.getComponentDefinitions(); + assertEquals(2, pcds.size()); + for (PhysicalComponentDefinition pcd : pcds) { + + assertTrue(pcd instanceof JavaPhysicalComponentDefinition); + String componentId = pcd.getComponentId().toString(); + assertTrue("cmp1".equals(componentId) || "cmp2".equals(componentId)); + + JavaPhysicalComponentDefinition jpcd = (JavaPhysicalComponentDefinition)pcd; + + Set<JavaPhysicalReferenceDefinition> refs = jpcd.getReferences(); + assertEquals(1, refs.size()); + JavaPhysicalReferenceDefinition ref = refs.iterator().next(); + if ("cmp1".equals(componentId)) { + assertEquals("rf1", ref.getName()); + Set<PhysicalOperationDefinition> pods = ref.getOperations(); + assertEquals(1, pods.size()); + PhysicalOperationDefinition pod = pods.iterator().next(); + assertEquals("op2", pod.getName()); + } else { + assertEquals("rf2", ref.getName()); + Set<PhysicalOperationDefinition> pods = ref.getOperations(); + assertEquals(1, pods.size()); + PhysicalOperationDefinition pod = pods.iterator().next(); + assertEquals("op1", pod.getName()); + } + + Set<JavaPhysicalServiceDefinition> svs = jpcd.getServices(); + assertEquals(1, svs.size()); + JavaPhysicalServiceDefinition sv = svs.iterator().next(); + if ("cmp1".equals(componentId)) { + assertEquals("sv1", sv.getName()); + Set<PhysicalOperationDefinition> pods = sv.getOperations(); + assertEquals(1, pods.size()); + PhysicalOperationDefinition pod = pods.iterator().next(); + assertEquals("op1", pod.getName()); + } else { + assertEquals("sv2", sv.getName()); + Set<PhysicalOperationDefinition> pods = sv.getOperations(); + assertEquals(1, pods.size()); + PhysicalOperationDefinition pod = pods.iterator().next(); + assertEquals("op2", pod.getName()); + } + + } + + Set<PhysicalWireDefinition> pwds = changeSet.getWireDefinitions(); + + assertEquals(2, changeSet.getWireDefinitions().size()); + for (PhysicalWireDefinition pwd : pwds) { + + String sourceUri = pwd.getSourceUri().toString(); + String targetUri = pwd.getTargetUri().toString(); + + assertTrue(("cmp1#rf1".equals(sourceUri) && "cmp2#sv2".equals(targetUri)) + || ("cmp2#rf2".equals(sourceUri) && "cmp1#sv1" + .equals(targetUri))); + + Set<PhysicalOperationDefinition> pods = pwd.getOperations(); + assertEquals(1, pods.size()); + PhysicalOperationDefinition pod = pods.iterator().next(); + + if (sourceUri.equals("cmp1#rf1")) { + assertEquals("op2", pod.getName()); + } else { + assertEquals("op1", pod.getName()); + } + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/binding/MockServiceBinding.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/binding/MockServiceBinding.java new file mode 100644 index 0000000000..5fc4f84d90 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/binding/MockServiceBinding.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.core.mock.binding; + +import java.net.URI; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.component.AbstractSCAObject; +import org.apache.tuscany.spi.component.ServiceBinding; +import org.apache.tuscany.spi.component.TargetInvokerCreationException; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; + +/** + * @version $Rev$ $Date$ + */ +public class MockServiceBinding extends AbstractSCAObject implements ServiceBinding { + private Wire wire; + + public MockServiceBinding(URI uri) { + super(uri); + } + + public QName getBindingType() { + return null; + } + + public ServiceContract<?> getBindingServiceContract() { + return null; + } + + public Wire getWire() { + return wire; + } + + public void setWire(Wire wire) { + this.wire = wire; + } + + public TargetInvoker createTargetInvoker(String targetName, Operation operation) + throws TargetInvokerCreationException { + return null; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/AsyncTarget.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/AsyncTarget.java new file mode 100644 index 0000000000..653d5d7335 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/AsyncTarget.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.core.mock.component; + +import org.osoa.sca.annotations.OneWay; + +/** + * @version $Rev$ $Date$ + */ +public interface AsyncTarget { + @OneWay + void invoke(); + + int getCount(); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/BadContextPojo.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/BadContextPojo.java new file mode 100644 index 0000000000..066acc346d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/BadContextPojo.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.core.mock.component; + +import org.osoa.sca.annotations.Context; + +public class BadContextPojo { + + @Context + String context; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/BadNamePojo.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/BadNamePojo.java new file mode 100644 index 0000000000..77ec37f9e4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/BadNamePojo.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.core.mock.component; + +import org.osoa.sca.annotations.ComponentName; + +public class BadNamePojo { + @ComponentName + private int name; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/BasicInterface.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/BasicInterface.java new file mode 100644 index 0000000000..b7921c248f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/BasicInterface.java @@ -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. + */ +package org.apache.tuscany.core.mock.component; + +/** + * @version $Rev$ $Date$ + */ +public interface BasicInterface { + String returnsProperty(); + + BasicInterface returnsReference(); + + int returnsInt(); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/BasicInterfaceImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/BasicInterfaceImpl.java new file mode 100644 index 0000000000..f7d7bb38cf --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/BasicInterfaceImpl.java @@ -0,0 +1,66 @@ +/* + * 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.core.mock.component; + +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; + +/** + * @version $Rev$ $Date$ + */ +public class BasicInterfaceImpl implements BasicInterface { + + @Property + public String publicProperty; + + @Reference (required = false) + public BasicInterface publicReference; + + @Property + protected String protectedProperty; + + @Reference (required = false) + protected BasicInterface protectedReference; + + private String privateProperty; + + private BasicInterface privateReference; + + @Property + public void setPrivateProperty(String privateProperty) { + this.privateProperty = privateProperty; + } + + @Reference (required = false) + public void setPrivateReference(BasicInterface privateReference) { + this.privateReference = privateReference; + } + + public String returnsProperty() { + return privateProperty; + } + + public BasicInterface returnsReference() { + return privateReference; + } + + public int returnsInt() { + return 0; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeComponent.java new file mode 100644 index 0000000000..88b97216cd --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeComponent.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.core.mock.component; + +import org.osoa.sca.annotations.Scope; + +/** + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +public interface CompositeScopeComponent { + + //public boolean isInit(); +} + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeComponentImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeComponentImpl.java new file mode 100644 index 0000000000..93ee1f707a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeComponentImpl.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.mock.component; + +import org.osoa.sca.annotations.Scope; + + +/** + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +public class CompositeScopeComponentImpl implements + CompositeScopeComponent { + + private String foo; + + public void setFoo(String foo) { + this.foo = foo; + } + + public String getFoo() { + return foo; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeDestroyOnlyComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeDestroyOnlyComponent.java new file mode 100644 index 0000000000..16ce3b5569 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeDestroyOnlyComponent.java @@ -0,0 +1,36 @@ +/* + * 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.core.mock.component; + +import org.osoa.sca.annotations.Destroy; + +public class CompositeScopeDestroyOnlyComponent extends CompositeScopeComponentImpl { + + boolean destroyed; + + public boolean isDestroyed() { + return destroyed; + } + + @Destroy + public void destroy() { + destroyed = true; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeInitDestroyComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeInitDestroyComponent.java new file mode 100644 index 0000000000..05b938a87c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeInitDestroyComponent.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.mock.component; + +import org.osoa.sca.annotations.Destroy; + +public class CompositeScopeInitDestroyComponent extends CompositeScopeInitOnlyComponent { + + boolean destroyed; + + public boolean isDestroyed() { + return destroyed; + } + + @Destroy + public void destroy() { + if (destroyed) { + throw new AssertionError("Destroy called more than once"); + } + destroyed = true; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeInitOnlyComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeInitOnlyComponent.java new file mode 100644 index 0000000000..f9f80ca15c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeInitOnlyComponent.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.core.mock.component; + +import org.osoa.sca.annotations.Init; + +public class CompositeScopeInitOnlyComponent extends CompositeScopeComponentImpl { + + private boolean initialized; + // this value tests to ensure introspection can find the init() method even + // if a field is named the same. Ultimately, this should be in the introspection tests + private boolean init; + + public boolean isInitialized() { + return initialized; + } + + @Init + public void init() { + if (initialized) { + throw new AssertionError("Init called more than once"); + } + initialized = true; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeComponent.java new file mode 100644 index 0000000000..c71ac0586f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeComponent.java @@ -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.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * @version $Rev: 430937 $ $Date: 2006-08-11 21:17:56 -0400 (Fri, 11 Aug 2006) $
+ */
+@Scope("CONVERSATION")
+public interface ConversationalScopeComponent {
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeComponentImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeComponentImpl.java new file mode 100644 index 0000000000..5ea7278e1f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeComponentImpl.java @@ -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.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * @version $Rev: 430937 $ $Date: 2006-08-11 21:17:56 -0400 (Fri, 11 Aug 2006) $
+ */
+@Scope("CONVERSATION")
+public class ConversationalScopeComponentImpl implements ConversationalScopeComponent {
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeDestroyOnlyComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeDestroyOnlyComponent.java new file mode 100644 index 0000000000..8cea9efa49 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeDestroyOnlyComponent.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.core.mock.component;
+
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.Scope;
+
+@Scope("CONVERSATION")
+public class ConversationalScopeDestroyOnlyComponent extends ConversationalScopeComponentImpl {
+
+ boolean destroyed;
+
+ public boolean isDestroyed() {
+ return destroyed;
+ }
+
+ @Destroy
+ public void destroy() {
+ destroyed = true;
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeInitDestroyComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeInitDestroyComponent.java new file mode 100644 index 0000000000..40dbfedf2c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeInitDestroyComponent.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.core.mock.component;
+
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.Scope;
+
+@Scope("CONVERSATION")
+public class ConversationalScopeInitDestroyComponent
+ extends ConversationalScopeInitOnlyComponent {
+
+ private boolean destroyed;
+
+ public boolean isDestroyed() {
+ return destroyed;
+ }
+
+ @Destroy
+ public void destroy() {
+ destroyed = true;
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeInitOnlyComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeInitOnlyComponent.java new file mode 100644 index 0000000000..caaa0c39e7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeInitOnlyComponent.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.core.mock.component;
+
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Scope;
+
+@Scope("CONVERSATION")
+public class ConversationalScopeInitOnlyComponent
+ extends ConversationalScopeComponentImpl {
+
+ private boolean initialized;
+
+ public boolean isInitialized() {
+ return initialized;
+ }
+
+ @Init
+ public void init() {
+ initialized = true;
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderException.java new file mode 100644 index 0000000000..af257c226d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderException.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.mock.component; + +public class OrderException extends Exception { + + public OrderException() { + super(); + } + + public OrderException(String message) { + super(message); + } + + public OrderException(String message, Throwable cause) { + super(message, cause); + } + + public OrderException(Throwable cause) { + super(cause); + } + +} + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedDependentPojo.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedDependentPojo.java new file mode 100644 index 0000000000..2033f0eca5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedDependentPojo.java @@ -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. + */ +package org.apache.tuscany.core.mock.component; + +/** + * @version $$Rev$$ $$Date$$ + */ +public interface OrderedDependentPojo extends OrderedInitPojo { + + OrderedInitPojo getPojo(); + + void setPojo(OrderedInitPojo pojo); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedDependentPojoImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedDependentPojoImpl.java new file mode 100644 index 0000000000..439c3d143c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedDependentPojoImpl.java @@ -0,0 +1,36 @@ +/* + * 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.core.mock.component; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class OrderedDependentPojoImpl extends OrderedInitPojoImpl implements OrderedDependentPojo { + + private OrderedInitPojo pojo; + + public OrderedInitPojo getPojo() { + return pojo; + } + + public void setPojo(OrderedInitPojo pojo) { + this.pojo = pojo; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedEagerInitPojo.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedEagerInitPojo.java new file mode 100644 index 0000000000..1986952747 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedEagerInitPojo.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.mock.component; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.EagerInit; + +@Scope("COMPOSITE") +@EagerInit +public class OrderedEagerInitPojo { + + private static final Object LOCK = new Object(); + private static int numberInstantied; + private int initOrder; + + @Init + public void init() { + synchronized (LOCK) { + ++numberInstantied; + initOrder = numberInstantied; + } + } + + @Destroy + public void destroy() throws OrderException { + synchronized (LOCK) { + if (initOrder != numberInstantied) { + throw new OrderException("Instance shutdown done out of order"); + } + --numberInstantied; + } + } + + public int getNumberInstantiated() { + return numberInstantied; + } + + public int getInitOrder() { + return initOrder; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedInitPojo.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedInitPojo.java new file mode 100644 index 0000000000..0b891cfa42 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedInitPojo.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.core.mock.component; + +/** + * @version $$Rev$$ $$Date$$ + */ +public interface OrderedInitPojo { + int getNumberInstantiated(); + + int getInitOrder(); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedInitPojoImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedInitPojoImpl.java new file mode 100644 index 0000000000..a7063f6353 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedInitPojoImpl.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.core.mock.component; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Scope; + +@Scope("COMPOSITE") +public class OrderedInitPojoImpl implements OrderedInitPojo { + + private static final Object LOCK = new Object(); + private static int numberInstantied; + private int initOrder; + + public OrderedInitPojoImpl() { + } + + @Init + public void init() { + synchronized (LOCK) { + ++numberInstantied; + initOrder = numberInstantied; + } + } + + @Destroy + public void destroy() throws OrderException { + synchronized (LOCK) { + if (initOrder != numberInstantied) { + throw new OrderException("Instance shutdown done out of order"); + } + --numberInstantied; + } + } + + public int getNumberInstantiated() { + return numberInstantied; + } + + public int getInitOrder() { + return initOrder; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OtherTarget.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OtherTarget.java new file mode 100644 index 0000000000..0b897daa40 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OtherTarget.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.core.mock.component; + +/** + * Implementations are used in wiring tests + * + * @version $Rev$ $Date$ + */ +public interface OtherTarget { + + String getString(); + + void setString(String val); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OtherTargetImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OtherTargetImpl.java new file mode 100644 index 0000000000..a3b2bbf098 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/OtherTargetImpl.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.mock.component; + +/** + * A target used for testing wires with a different source and target interface + * + * @version $Rev$ $Date$ + */ +public class OtherTargetImpl implements OtherTarget { + + private String theString; + + public String getString() { + return theString; + } + + public void setString(String val) { + theString = val; + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeComponent.java new file mode 100644 index 0000000000..8c7dc107ee --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeComponent.java @@ -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. + */ +package org.apache.tuscany.core.mock.component; + +import org.osoa.sca.annotations.Scope; + +/** + * @version $Rev$ $Date$ + */ +@Scope("REQUEST") +public interface RequestScopeComponent { + +} + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeDestroyOnlyComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeDestroyOnlyComponent.java new file mode 100644 index 0000000000..5224ceda5f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeDestroyOnlyComponent.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.core.mock.component; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Scope; + +@Scope("REQUEST") +public class RequestScopeDestroyOnlyComponent extends SessionScopeComponentImpl { + + boolean destroyed; + + public boolean isDestroyed() { + return destroyed; + } + + @Destroy + public void destroy() { + destroyed = true; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeInitDestroyComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeInitDestroyComponent.java new file mode 100644 index 0000000000..38b188a4b5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeInitDestroyComponent.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.core.mock.component; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Scope; + +@Scope("REQUEST") +public class RequestScopeInitDestroyComponent extends SessionScopeInitOnlyComponent { + + boolean destroyed; + + public boolean isDestroyed() { + return destroyed; + } + + @Destroy + public void destroy() { + destroyed = true; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeInitOnlyComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeInitOnlyComponent.java new file mode 100644 index 0000000000..707f8ab50f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeInitOnlyComponent.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.mock.component; + +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Scope; + +@Scope("REQUEST") +public class RequestScopeInitOnlyComponent extends SessionScopeComponentImpl { + + private boolean initialized; + + public boolean isInitialized() { + return initialized; + } + + @Init + public void init() { + initialized = true; + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeComponent.java new file mode 100644 index 0000000000..827ba804f2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeComponent.java @@ -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. + */ +package org.apache.tuscany.core.mock.component; + +import org.osoa.sca.annotations.Scope; + +/** + * @version $Rev$ $Date$ + */ +@Scope("SESSION") +public interface SessionScopeComponent { + +} + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeComponentImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeComponentImpl.java new file mode 100644 index 0000000000..e547bf6113 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeComponentImpl.java @@ -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. + */ +package org.apache.tuscany.core.mock.component; + +import org.osoa.sca.annotations.Scope; + +/** + * @version $Rev$ $Date$ + */ +@Scope("SESSION") +public class SessionScopeComponentImpl implements + SessionScopeComponent { + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeInitDestroyComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeInitDestroyComponent.java new file mode 100644 index 0000000000..c11bd1bd49 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeInitDestroyComponent.java @@ -0,0 +1,36 @@ +/* + * 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.core.mock.component; + +import org.osoa.sca.annotations.Destroy; + +public class SessionScopeInitDestroyComponent extends SessionScopeInitOnlyComponent { + + private boolean destroyed; + + public boolean isDestroyed() { + return destroyed; + } + + @Destroy + public void destroy() { + destroyed = true; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeInitOnlyComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeInitOnlyComponent.java new file mode 100644 index 0000000000..095cc916ec --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeInitOnlyComponent.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.core.mock.component; + +import org.osoa.sca.annotations.Init; + +public class SessionScopeInitOnlyComponent extends SessionScopeComponentImpl { + + private boolean initialized; + + public boolean isInitialized() { + return initialized; + } + + @Init + public void init() { + initialized = true; + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SimpleTarget.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SimpleTarget.java new file mode 100644 index 0000000000..c78ba00a7a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SimpleTarget.java @@ -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. + */ +package org.apache.tuscany.core.mock.component; + +public interface SimpleTarget { + + String hello(String message) throws Exception; + + String goodbye(String message) throws Exception; + + String echo(String message) throws Exception; + +} + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SimpleTargetImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SimpleTargetImpl.java new file mode 100644 index 0000000000..634a07a401 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SimpleTargetImpl.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.core.mock.component; + +public class SimpleTargetImpl implements SimpleTarget { + + public SimpleTargetImpl() { + super(); + } + + public String hello(String message) throws Exception { + return message; + } + + public String goodbye(String message) throws Exception { + return message; + } + + public String echo(String message) throws Exception { + return message; + } + + +} + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/Source.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/Source.java new file mode 100644 index 0000000000..f7969f748b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/Source.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.core.mock.component; + +import java.util.List; + +/** + * Implementations are used in wiring tests + * + * @version $Rev$ $Date$ + */ +public interface Source { + + Target getTarget(); + + List<Target> getTargets(); + + List<Target> getTargetsThroughField(); + +} + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SourceImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SourceImpl.java new file mode 100644 index 0000000000..187e33b2bd --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/SourceImpl.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.core.mock.component; + +import java.util.List; + +/** + * Mock system component implementation used in wiring tests + * + * @version $Rev$ $Date$ + */ +public class SourceImpl implements Source { + + private Target target; + private List<Target> targets; + private List<Target> targetsThroughField; + private Target[] targetsArray; + + public void setTarget(Target target) { + this.target = target; + } + + public Target getTarget() { + return target; + } + + public List<Target> getTargets() { + return targets; + } + + public void setTargets(List<Target> targets) { + this.targets = targets; + } + + public List<Target> getTargetsThroughField() { + return targetsThroughField; + } + + public Target[] getArrayOfTargets() { + return targetsArray; + } + + public void setArrayOfTargets(Target[] targets) { + targetsArray = targets; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/StatelessComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/StatelessComponent.java new file mode 100644 index 0000000000..c16ac942a3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/StatelessComponent.java @@ -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. + */ +package org.apache.tuscany.core.mock.component; + +import org.osoa.sca.annotations.Scope; + +/** + * @version $Rev$ $Date$ + */ +@Scope("STATELESS") +public interface StatelessComponent { + +} + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/StatelessComponentImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/StatelessComponentImpl.java new file mode 100644 index 0000000000..64a23c12c8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/StatelessComponentImpl.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.core.mock.component; + +/** + * @version $Rev$ $Date$ + */ +public class StatelessComponentImpl implements + StatelessComponent { + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/Target.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/Target.java new file mode 100644 index 0000000000..778c14665d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/Target.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.mock.component; + +/** + * Implementations are used in wiring tests + * + * @version $Rev$ $Date$ + */ +public interface Target { + + String getString(); + + void setString(String val); +} + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/TargetImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/TargetImpl.java new file mode 100644 index 0000000000..037dd3a37c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/component/TargetImpl.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.core.mock.component; + +/** + * Mock system component implementation used in wiring tests + * + * @version $Rev$ $Date$ + */ +public class TargetImpl implements Target { + + private String theString; + + public String getString() { + return theString; + } + + public void setString(String val) { + theString = val; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/wire/MockStaticInvoker.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/wire/MockStaticInvoker.java new file mode 100644 index 0000000000..cdd0de7a6d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/wire/MockStaticInvoker.java @@ -0,0 +1,97 @@ +/* + * 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.core.mock.wire; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +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; + +/** + * Caches component instances that do not need to be resolved for every wire, e.g. an wire originating from a lesser + * scope intended for a target with a wider scope + * + * @version $Rev$ $Date$ + */ +public class MockStaticInvoker implements TargetInvoker { + + private Object instance; + private Method operation; + private boolean cacheable; + + + public MockStaticInvoker(Method operation, Object instance) { + this.operation = operation; + this.instance = instance; + } + + public boolean isCacheable() { + return cacheable; + } + + public void setCacheable(boolean cacheable) { + this.cacheable = cacheable; + } + + public boolean isOptimizable() { + return isCacheable(); + } + + public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException { + try { + if (payload != null && !payload.getClass().isArray()) { + return operation.invoke(instance, payload); + } else { + return operation.invoke(instance, (Object[]) payload); + } + } catch (IllegalAccessException e) { + throw new InvocationRuntimeException(e); + } + } + + public Message invoke(Message msg) throws InvocationRuntimeException { + try { + Object resp = invokeTarget(msg.getBody(), TargetInvoker.NONE); + msg.setBody(resp); + } catch (InvocationTargetException e) { + msg.setBodyWithFault(e.getCause()); + } catch (Throwable e) { + msg.setBodyWithFault(e); + } + return msg; + } + + public void setNext(Interceptor next) { + throw new IllegalStateException("This interceptor must be the last interceptor in an interceptor chain"); + } + + public Object clone() throws CloneNotSupportedException { + try { + MockStaticInvoker invoker = (MockStaticInvoker) super.clone(); + invoker.instance = this.instance; + invoker.operation = this.operation; + return invoker; + } catch (CloneNotSupportedException e) { + return null; // will not happen + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/wire/MockSyncInterceptor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/wire/MockSyncInterceptor.java new file mode 100644 index 0000000000..1fe2c027ab --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/wire/MockSyncInterceptor.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.core.mock.wire; + +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.Message; + +public class MockSyncInterceptor implements Interceptor { + + private int count; + + private Interceptor next; + + public MockSyncInterceptor() { + } + + public Message invoke(Message msg) { + ++count; + return next.invoke(msg); + } + + public int getCount() { + return count; + } + + public void setNext(Interceptor next) { + this.next = next; + } + + public Interceptor getNext() { + return next; + } + + public boolean isOptimizable() { + return false; + } + +} + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/wire/MockTargetInvoker.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/wire/MockTargetInvoker.java new file mode 100644 index 0000000000..3fcc75bdb4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/mock/wire/MockTargetInvoker.java @@ -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. + */ +package org.apache.tuscany.core.mock.wire; + +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.Message; + +import org.apache.tuscany.core.binding.local.AbstractLocalTargetInvoker; + +/** + * @version $Rev$ $Date$ + */ +public class MockTargetInvoker extends AbstractLocalTargetInvoker { + public Message invoke(Message msg) throws InvocationRuntimeException { + return null; + } +}
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/monitor/DefaultExceptionFormatterTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/monitor/DefaultExceptionFormatterTestCase.java new file mode 100644 index 0000000000..437e718206 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/monitor/DefaultExceptionFormatterTestCase.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.core.monitor; + +import java.io.PrintWriter; +import java.io.StringWriter; + +import junit.framework.TestCase; +import org.apache.tuscany.api.TuscanyException; +import org.apache.tuscany.api.TuscanyRuntimeException; + +/** + * @version $Rev$ $Date$ + */ +public class DefaultExceptionFormatterTestCase extends TestCase { + private DefaultExceptionFormatter formatter = new DefaultExceptionFormatter(); + + public void testTuscanyExceptionFormat() throws Exception { + StringWriter writer = new StringWriter(); + PrintWriter pw = new PrintWriter(writer); + TuscanyException e = new TuscanyException("somemessage") { + }; + formatter.write(pw, e); + assertTrue(writer.toString().indexOf("somemessage") >= 0); + } + + public void testTuscanyRuntimeExceptionFormat() throws Exception { + StringWriter writer = new StringWriter(); + PrintWriter pw = new PrintWriter(writer); + TuscanyRuntimeException e = new TuscanyRuntimeException("somemessage") { + }; + formatter.write(pw, e); + assertTrue(writer.toString().indexOf("somemessage") >= 0); + } + + public void testNormalExceptionFormat() throws Exception { + StringWriter writer = new StringWriter(); + PrintWriter pw = new PrintWriter(writer); + Exception e = new Exception(); + formatter.write(pw, e); // just verify there are no errors since no formatting needs to be doen + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/monitor/JavaLoggingTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/monitor/JavaLoggingTestCase.java new file mode 100644 index 0000000000..5fdf035c7a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/monitor/JavaLoggingTestCase.java @@ -0,0 +1,153 @@ +/* + * 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.core.monitor; + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +import org.apache.tuscany.api.annotation.LogLevel; +import org.apache.tuscany.host.MonitorFactory; + +import junit.framework.TestCase; + +/** + * Test case for the JavaLoggingMonitorFactory. + * + * @version $Rev$ $Date$ + */ +public class JavaLoggingTestCase extends TestCase { + private static final Logger LOGGER = Logger.getLogger(Monitor.class.getName()); + private static final MockHandler HANDLER = new MockHandler(); + + private MonitorFactory factory; + + /** + * Smoke test to ensure the LOGGER is working. + */ + public void testLogger() { + LOGGER.info("test"); + assertEquals(1, HANDLER.logs.size()); + } + + /** + * Test that no record is logged. + */ + public void testUnloggedEvent() { + Monitor mon = factory.getMonitor(Monitor.class); + mon.eventNotToLog(); + assertEquals(0, HANDLER.logs.size()); + } + + /** + * Test the correct record is written for an event with no arguments. + */ + public void testEventWithNoArgs() { + Monitor mon = factory.getMonitor(Monitor.class); + mon.eventWithNoArgs(); + assertEquals(1, HANDLER.logs.size()); + LogRecord record = HANDLER.logs.get(0); + assertEquals(Level.INFO, record.getLevel()); + assertEquals(LOGGER.getName(), record.getLoggerName()); + assertEquals(Monitor.class.getName() + "#eventWithNoArgs", record.getMessage()); + } + + /** + * Test the correct record is written for an event defined by annotation. + */ + public void testEventWithAnnotation() { + Monitor mon = factory.getMonitor(Monitor.class); + mon.eventWithAnnotation(); + assertEquals(1, HANDLER.logs.size()); + LogRecord record = HANDLER.logs.get(0); + assertEquals(Level.INFO, record.getLevel()); + assertEquals(LOGGER.getName(), record.getLoggerName()); + assertEquals(Monitor.class.getName() + "#eventWithAnnotation", record.getMessage()); + } + + /** + * Test the argument is logged. + */ + public void testEventWithOneArg() { + Monitor mon = factory.getMonitor(Monitor.class); + mon.eventWithOneArg("ARG"); + assertEquals(1, HANDLER.logs.size()); + LogRecord record = HANDLER.logs.get(0); + assertEquals(Monitor.class.getName() + "#eventWithOneArg", record.getMessage()); + } + + protected void setUp() throws Exception { + super.setUp(); + LOGGER.setUseParentHandlers(false); + LOGGER.addHandler(HANDLER); + HANDLER.flush(); + + String sourceClass = Monitor.class.getName(); + Properties levels = new Properties(); + levels.setProperty(sourceClass + "#eventWithNoArgs", "INFO"); + levels.setProperty(sourceClass + "#eventWithOneArg", "INFO"); + levels.setProperty(sourceClass + "#eventWithThrowable", "WARNING"); + factory = new JavaLoggingMonitorFactory(levels, Level.FINE, "TestMessages"); + } + + protected void tearDown() throws Exception { + LOGGER.removeHandler(HANDLER); + HANDLER.flush(); + super.tearDown(); + } + + /** + * Mock log HANDLER to capture records. + */ + public static class MockHandler extends Handler { + List<LogRecord> logs = new ArrayList<LogRecord>(); + + public void publish(LogRecord record) { + logs.add(record); + } + + public void flush() { + logs.clear(); + } + + public void close() throws SecurityException { + } + } + + @SuppressWarnings({"JavaDoc"}) + public static interface Monitor { + void eventNotToLog(); + + @LogLevel("INFO") + void eventWithNoArgs(); + + @LogLevel("INFO") + void eventWithOneArg(String msg); + + @LogLevel("WARNING") + void eventWithThrowable(Exception e); + + @LogLevel("INFO") + void eventWithAnnotation(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/policy/IntentRegistryImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/policy/IntentRegistryImplTestCase.java new file mode 100644 index 0000000000..de1c91b741 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/policy/IntentRegistryImplTestCase.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.core.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import javax.xml.namespace.QName; + +import static org.osoa.sca.Constants.SCA_NS; + +import org.apache.tuscany.spi.model.Intent; +import org.apache.tuscany.spi.model.IntentName; +import org.apache.tuscany.spi.policy.IntentRegistry; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class IntentRegistryImplTestCase extends TestCase { + private static final QName WS_BINDING = new QName(SCA_NS, "binding.ws"); + private static final QName JMS_BINDING = new QName(SCA_NS, "binding.jms"); + private IntentRegistry intentReg; + + @Override + protected void setUp() throws Exception { + intentReg = new IntentRegistryImpl(); + + Intent bodyintent = new Intent(new IntentName("sec.confidentiality/message/body"), "test"); + bodyintent.addAppliedArtifacts(WS_BINDING); + bodyintent.addAppliedArtifacts(JMS_BINDING); + intentReg.register(bodyintent); + + Intent headintent = new Intent(new IntentName("sec.confidentiality/message/head"), "test"); + headintent.addAppliedArtifacts(WS_BINDING); + headintent.addAppliedArtifacts(JMS_BINDING); + intentReg.register(headintent); + + Intent confidentialityintent = new Intent(new IntentName("sec.confidentiality"), "test"); + confidentialityintent.addAppliedArtifacts(WS_BINDING); + confidentialityintent.addAppliedArtifacts(JMS_BINDING); + intentReg.register(confidentialityintent); + + Intent messageintent = new Intent(new IntentName("sec.confidentiality/message"), null); + messageintent.addAppliedArtifacts(WS_BINDING); + messageintent.addAppliedArtifacts(JMS_BINDING); + intentReg.register(messageintent); + } + + @Override + protected void tearDown() throws Exception { + intentReg = null; + } + +// public void testGetQualifiedIntent() { +// List<IntentName> intentNameList = new ArrayList<IntentName>(); +// intentReg.get +// //intentReg.getConcretIntents(intentNameList, artifact) +// } + + public void testGetConcretIntents() { + Intent messageintent = new Intent(new IntentName("sec.confidentiality/transport"), null); + messageintent.addAppliedArtifacts(WS_BINDING); + messageintent.addAppliedArtifacts(JMS_BINDING); + intentReg.register(messageintent); + + Intent allintent = new Intent(new IntentName("sec.confidentiality/all"), null); + allintent.addAppliedArtifacts(WS_BINDING); + allintent.addRequriedIntents(new IntentName("sec.confidentiality/message")); + allintent.addRequriedIntents(new IntentName("sec.confidentiality/transport")); + + + intentReg.register(allintent); + List<IntentName> intents = new ArrayList<IntentName>(); + intents.add(new IntentName("sec.confidentiality/all")); + Collection<IntentName> concreteIntents = intentReg.inlineProfileIntent(intents, WS_BINDING); + assertEquals(2, concreteIntents.size()); + assertTrue(concreteIntents.contains(new IntentName("sec.confidentiality/message"))); + assertTrue(concreteIntents.contains(new IntentName("sec.confidentiality/transport"))); + //fail("Not yet implemented"); + } + + public void testGetQualifiedIntents() { + IntentName message = new IntentName("sec.confidentiality/message"); + Collection<IntentName> qualifiedIntents = intentReg.getQualifiedIntents(message, JMS_BINDING); + assertEquals(2, qualifiedIntents.size()); + assertTrue(qualifiedIntents.contains(new IntentName("sec.confidentiality/message/body"))); + assertTrue(qualifiedIntents.contains(new IntentName("sec.confidentiality/message/head"))); + assertFalse(qualifiedIntents.contains(new IntentName("sec.confidentiality/message"))); + assertFalse(qualifiedIntents.contains(new IntentName("sec.confidentiality"))); + } + + public void testIsApplicable() { + assertTrue(intentReg.isApplicable(new IntentName("sec.confidentiality/message"), WS_BINDING)); + assertFalse(intentReg.isApplicable(new IntentName("sec.confidentiality/transport"), WS_BINDING)); + assertFalse(intentReg.isApplicable(new IntentName("test.confidentiality/transport"), WS_BINDING)); + } + + public void testRegister() { + Intent messageintent = new Intent(new IntentName("sec.confidentiality/transport"), null); + messageintent.addAppliedArtifacts(WS_BINDING); + messageintent.addAppliedArtifacts(JMS_BINDING); + intentReg.register(messageintent); + assertTrue(intentReg.isApplicable(new IntentName("sec.confidentiality/transport"), WS_BINDING)); + assertTrue(intentReg.isApplicable(new IntentName("sec.confidentiality/transport"), JMS_BINDING)); + + } + + public void testIsQualifiedIntent() { + Intent messageintent = new Intent(new IntentName("sec.confidentiality/transport"), null); + messageintent.addAppliedArtifacts(WS_BINDING); + messageintent.addAppliedArtifacts(JMS_BINDING); + intentReg.register(messageintent); + Intent allintent = new Intent(new IntentName("sec.confidentiality/all"), null); + allintent.addAppliedArtifacts(WS_BINDING); + + assertTrue(intentReg.isQualifiedIntent(new IntentName("sec.confidentiality/transport"))); + assertTrue(intentReg.isQualifiedIntent(new IntentName("sec.confidentiality/message/body"))); + assertTrue(intentReg.isQualifiedIntent(new IntentName("sec.confidentiality/message/body"))); + assertFalse(intentReg.isQualifiedIntent(new IntentName("sec.confidentiality/message"))); + assertFalse(intentReg.isQualifiedIntent(new IntentName("sec.confidentiality"))); + } + + public void testUnRegister() { + Intent messageintent = new Intent(new IntentName("sec.confidentiality/transport"), null); + messageintent.addAppliedArtifacts(WS_BINDING); + messageintent.addAppliedArtifacts(JMS_BINDING); + intentReg.register(messageintent); + intentReg.unRegister(messageintent); + assertFalse(intentReg.isApplicable(new IntentName("sec.confidentiality/transport"), WS_BINDING)); + assertFalse(intentReg.isApplicable(new IntentName("sec.confidentiality/transport"), JMS_BINDING)); + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/policy/PolicyEngineImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/policy/PolicyEngineImplTestCase.java new file mode 100644 index 0000000000..f6db640e2b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/policy/PolicyEngineImplTestCase.java @@ -0,0 +1,140 @@ +/* + * 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.core.policy; + +import java.io.InputStream; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamReader; + +import static org.osoa.sca.Constants.SCA_NS; + +import org.apache.tuscany.spi.model.Intent; +import org.apache.tuscany.spi.model.IntentName; +import org.apache.tuscany.spi.model.PolicyModel; +import org.apache.tuscany.spi.model.PolicySet; +import org.apache.tuscany.spi.policy.IntentRegistry; +import org.apache.tuscany.spi.policy.PolicyEngine; +import org.apache.tuscany.spi.policy.PolicySetContainer; +import org.apache.tuscany.spi.policy.SCATypeManager; + +import junit.framework.TestCase; +import org.apache.tuscany.core.loader.PolicySetLoader; + +public class PolicyEngineImplTestCase extends TestCase { + private static final QName POLICYSET = new QName(SCA_NS, "policySet"); + private static final QName WS_BINDING = new QName(SCA_NS, "binding.ws"); + private IntentRegistry intentReg; + private PolicyEngine policyEngine; + + + public void testgetPolicy() throws Exception { + Collection<PolicyModel> policies = + policyEngine.getPolicy(new IntentName[]{new IntentName("sec.authentication/cert")}, null, WS_BINDING); + assertEquals(2, policies.size()); + policies = + policyEngine.getPolicy(new IntentName[]{new IntentName("sec.authentication/basic")}, null, WS_BINDING); + assertEquals(1, policies.size()); + + //test for unqualified intent with default value on intentMap + policies = policyEngine.getPolicy(new IntentName[]{new IntentName("sec.authentication")}, null, WS_BINDING); + assertEquals(2, policies.size()); + } + + @Override + protected void setUp() throws Exception { + PolicySetLoader loader = new PolicySetLoader(null); + XMLInputFactory factory = XMLInputFactory.newInstance(); + InputStream resourceAsStream = this.getClass().getResourceAsStream("PolicySet.scdl"); + XMLStreamReader reader = factory.createXMLStreamReader(resourceAsStream); + PolicySetContainerImpl psc = new PolicySetContainerImpl(); + while (true) { + int state = reader.next(); + if (state == XMLStreamConstants.END_DOCUMENT) { + break; + } + if (XMLStreamConstants.START_ELEMENT == state && reader.getName().equals(POLICYSET)) { + psc.addPolicySet(loader.load(null, reader, null)); + } + + } + resourceAsStream.close(); + intentReg = new IntentRegistryImpl(); + policyEngine = new PolicyEngineImpl(intentReg, psc, new SCATypeManagerImpl()); + + Intent bodyintent = new Intent(new IntentName("sec.confidentiality/message/body"), "test"); + bodyintent.addAppliedArtifacts(WS_BINDING); + intentReg.register(bodyintent); + + Intent allintent = new Intent(new IntentName("sec.confidentiality/message/all"), "test"); + allintent.addAppliedArtifacts(WS_BINDING); + intentReg.register(allintent); + + Intent confidentialityintent = new Intent(new IntentName("sec.confidentiality"), "test"); + confidentialityintent.addAppliedArtifacts(WS_BINDING); + intentReg.register(confidentialityintent); + + Intent messageintent = new Intent(new IntentName("sec.confidentiality/message"), null); + messageintent.addAppliedArtifacts(WS_BINDING); + intentReg.register(messageintent); + + Intent authintent = new Intent(new IntentName("sec.authentication"), null); + authintent.addAppliedArtifacts(WS_BINDING); + intentReg.register(authintent); + + Intent certintent = new Intent(new IntentName("sec.authentication/cert"), null); + certintent.addAppliedArtifacts(WS_BINDING); + intentReg.register(certintent); + + Intent basicintent = new Intent(new IntentName("sec.authentication/basic"), null); + basicintent.addAppliedArtifacts(WS_BINDING); + intentReg.register(basicintent); + + } + + private class PolicySetContainerImpl implements PolicySetContainer { + + private Map<QName, PolicySet> sets = new HashMap<QName, PolicySet>(); + + public Collection<PolicySet> getAllPolicySet() { + return sets.values(); + } + + public PolicySet getPolicySet(QName name) { + return sets.get(name); + } + + public void addPolicySet(PolicySet pset) { + sets.put(pset.getName(), pset); + } + + } + + private class SCATypeManagerImpl implements SCATypeManager { + + public boolean isTypeOf(QName subType, QName type) { + return subType.equals(type); + } + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/property/PropertyHelperTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/property/PropertyHelperTestCase.java new file mode 100644 index 0000000000..4f2e2fbf42 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/property/PropertyHelperTestCase.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.core.property; + +import java.net.URL; +import javax.xml.namespace.NamespaceContext; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +import org.apache.tuscany.spi.deployer.DeploymentContext; + +import junit.framework.TestCase; +import org.apache.tuscany.core.databinding.xml.String2Node; +import org.easymock.EasyMock; + +/** + * + */ +public class PropertyHelperTestCase extends TestCase { + private static final String IPO_XML = + "<?xml version=\"1.0\"?>" + "<ipo:purchaseOrder" + + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + + " xmlns:ipo=\"http://www.example.com/IPO\"" + + " xsi:schemaLocation=\"http://www.example.com/IPO ipo.xsd\"" + + " orderDate=\"1999-12-01\">" + + " <shipTo exportCode=\"1\" xsi:type=\"ipo:UKAddress\">" + + " <name>Helen Zoe</name>" + + " <street>47 Eden Street</street>" + + " <city>Cambridge</city>" + + " <postcode>CB1 1JR</postcode>" + + " </shipTo>" + + " <billTo xsi:type=\"ipo:USAddress\">" + + " <name>Robert Smith</name>" + + " <street>8 Oak Avenue</street>" + + " <city>Old Town</city>" + + " <state>PA</state>" + + " <zip>95819</zip>" + + " </billTo>" + + " <items>" + + " <item partNum=\"833-AA\">" + + " <productName>Lapis necklace</productName>" + + " <quantity>1</quantity>" + + " <USPrice>99.95</USPrice>" + + " <ipo:comment>Want this for the holidays</ipo:comment>" + + " <shipDate>1999-12-05</shipDate>" + + " </item>" + + " </items>" + + "</ipo:purchaseOrder>"; + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + } + + public void testXPath() throws Exception { + String2Node t = new String2Node(); + Node node = t.transform(IPO_XML, null); + + Document doc = PropertyHelper.evaluate(null, node, "/ipo:purchaseOrder/billTo"); + assertNotNull(doc); + + NamespaceContext context = EasyMock.createMock(NamespaceContext.class); + EasyMock.expect(context.getNamespaceURI("ipo")).andReturn("http://www.example.com/IPO").anyTimes(); + EasyMock.replay(context); + doc = PropertyHelper.evaluate(context, node, "/ipo:purchaseOrder/items"); + assertNotNull(doc); + doc = PropertyHelper.evaluate(context, node, "/ipo:purchaseOrder/billTo"); + assertNotNull(doc); + doc = PropertyHelper.evaluate(context, node, "/"); + assertNotNull(doc); + doc = PropertyHelper.evaluate(context, node, "/ipo:purchaseOrder/billTo1"); + assertNull(doc); + } + + public void testFile() throws Exception { + URL url = getClass().getResource("ipo.xml"); + Document doc = PropertyHelper.loadFromFile(url.toExternalForm(), null); + assertNotNull(doc); + + DeploymentContext context = EasyMock.createMock(DeploymentContext.class); + EasyMock.expect(context.getClassLoader()).andReturn(getClass().getClassLoader()); + EasyMock.replay(context); + doc = PropertyHelper.loadFromFile("org/apache/tuscany/core/property/ipo.xml", context); + assertNotNull(doc); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/property/SimplePropertyObjectFactoryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/property/SimplePropertyObjectFactoryTestCase.java new file mode 100644 index 0000000000..9ef1faccfe --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/property/SimplePropertyObjectFactoryTestCase.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.core.property; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.PropertyValue; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class SimplePropertyObjectFactoryTestCase extends TestCase { + + private <T> PropertyValue<T> mock(String value) { + Document document = EasyMock.createMock(Document.class); + Element element = EasyMock.createMock(Element.class); + EasyMock.expect(document.getDocumentElement()).andReturn(element); + EasyMock.expect(element.getTextContent()).andReturn(value); + EasyMock.replay(document, element); + return new PropertyValue<T>(null, document); + } + + public void testInteger() throws Exception { + + PropertyObjectFactoryImpl factory = new PropertyObjectFactoryImpl(); + Property<Integer> property = new Property<Integer>(); + property.setJavaType(Integer.class); + PropertyValue<Integer> propertyValue = mock("1"); + ObjectFactory<Integer> oFactory = factory.createObjectFactory(property, propertyValue); + assertEquals(1, oFactory.getInstance().intValue()); + } + + public void testPrimitiveInt() throws Exception { + PropertyObjectFactoryImpl factory = new PropertyObjectFactoryImpl(); + Property<Integer> property = new Property<Integer>(); + property.setJavaType(Integer.TYPE); + PropertyValue<Integer> propertyValue = mock("1"); + ObjectFactory<Integer> oFactory = factory.createObjectFactory(property, propertyValue); + assertEquals(1, oFactory.getInstance().intValue()); + } + + public void testString() throws Exception { + PropertyObjectFactoryImpl factory = new PropertyObjectFactoryImpl(); + Property<String> property = new Property<String>(); + property.setJavaType(String.class); + PropertyValue<String> propertyValue = mock("1"); + ObjectFactory<String> oFactory = factory.createObjectFactory(property, propertyValue); + assertEquals("1", oFactory.getInstance()); + } + + public void testByteArray() throws Exception { + PropertyObjectFactoryImpl factory = new PropertyObjectFactoryImpl(); + Property<byte[]> property = new Property<byte[]>(); + property.setJavaType(byte[].class); + PropertyValue<byte[]> propertyValue = mock("TWFu"); // BASE64 for "Man" + ObjectFactory<byte[]> oFactory = factory.createObjectFactory(property, propertyValue); + byte[] result = oFactory.getInstance(); + byte[] expected = "Man".getBytes(); + for (int i = 0; i < result.length; i++) { + byte b = result[i]; + if (b != expected[i]) { + fail(); + } + } + } + + public void testBoolean() throws Exception { + PropertyObjectFactoryImpl factory = new PropertyObjectFactoryImpl(); + Property<Boolean> property = new Property<Boolean>(); + property.setJavaType(Boolean.class); + PropertyValue<Boolean> propertyValue = mock("true"); + ObjectFactory<Boolean> oFactory = factory.createObjectFactory(property, propertyValue); + assertTrue(oFactory.getInstance()); + } + + public void testPrimitiveBoolean() throws Exception { + PropertyObjectFactoryImpl factory = new PropertyObjectFactoryImpl(); + Property<Boolean> property = new Property<Boolean>(); + property.setJavaType(Boolean.TYPE); + PropertyValue<Boolean> propertyValue = mock("true"); + ObjectFactory<Boolean> oFactory = factory.createObjectFactory(property, propertyValue); + assertTrue(oFactory.getInstance()); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/resolver/DefaultAutowireResolverTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/resolver/DefaultAutowireResolverTestCase.java new file mode 100644 index 0000000000..6d50489f18 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/resolver/DefaultAutowireResolverTestCase.java @@ -0,0 +1,177 @@ +/* + * 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.core.resolver; + +import java.net.URI; + +import org.apache.tuscany.spi.model.AtomicImplementation; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.ComponentType; +import org.apache.tuscany.spi.model.CompositeComponentType; +import org.apache.tuscany.spi.model.CompositeImplementation; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ReferenceTarget; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.model.ServiceDefinition; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class DefaultAutowireResolverTestCase extends TestCase { + private static final URI REFERENCE_URI = URI.create("source#ref"); + private static final URI TARGET_URI = URI.create("target#service"); + private DefaultAutowireResolver resolver; + + public void testAutowireAtomicToAtomic() throws Exception { + ComponentDefinition<CompositeImplementation> composite = createComposite("composite"); + CompositeComponentType<?, ?, ?> type = composite.getImplementation().getComponentType(); + ComponentDefinition<MockAtomicImpl> source = createSourceAtomic(Foo.class); + type.add(source); + ComponentDefinition<MockAtomicImpl> target = createTargetAtomic(Foo.class); + type.add(target); + resolver.resolve(null, composite); + ReferenceTarget refTarget = source.getReferenceTargets().get(REFERENCE_URI.getFragment()); + assertEquals(TARGET_URI, refTarget.getTargets().get(0)); + } + + public void testAutowireAtomicToAtomicRequiresSuperInterface() throws Exception { + ComponentDefinition<CompositeImplementation> composite = createComposite("composite"); + CompositeComponentType<?, ?, ?> type = composite.getImplementation().getComponentType(); + ComponentDefinition<MockAtomicImpl> source = createSourceAtomic(SuperFoo.class); + type.add(source); + ComponentDefinition<MockAtomicImpl> target = createTargetAtomic(Foo.class); + type.add(target); + resolver.resolve(null, composite); + ReferenceTarget refTarget = source.getReferenceTargets().get(REFERENCE_URI.getFragment()); + assertEquals(TARGET_URI, refTarget.getTargets().get(0)); + } + + public void testAutowireAtomicToAtomicRequiresSubInterface() throws Exception { + ComponentDefinition<CompositeImplementation> composite = createComposite("composite"); + CompositeComponentType<?, ?, ?> type = composite.getImplementation().getComponentType(); + ComponentDefinition<MockAtomicImpl> source = createSourceAtomic(Foo.class); + type.add(source); + ComponentDefinition<MockAtomicImpl> target = createTargetAtomic(SuperFoo.class); + type.add(target); + try { + resolver.resolve(null, composite); + fail(); + } catch (AutowireTargetNotFoundException e) { + // expected + } + } + + public void testAutowireAtomicToAtomicIncompatibleInterfaces() throws Exception { + ComponentDefinition<CompositeImplementation> composite = createComposite("composite"); + CompositeComponentType<?, ?, ?> type = composite.getImplementation().getComponentType(); + ComponentDefinition<MockAtomicImpl> source = createSourceAtomic(Foo.class); + type.add(source); + ComponentDefinition<MockAtomicImpl> target = createTargetAtomic(String.class); + type.add(target); + try { + resolver.resolve(null, composite); + fail(); + } catch (AutowireTargetNotFoundException e) { + // expected + } + } + + public void testNestedAutowireAtomicToAtomic() throws Exception { + ComponentDefinition<CompositeImplementation> composite = createComposite("composite"); + CompositeComponentType<?, ?, ?> type = composite.getImplementation().getComponentType(); + ComponentDefinition<MockAtomicImpl> source = createSourceAtomic(Foo.class); + type.add(source); + ComponentDefinition<MockAtomicImpl> target = createTargetAtomic(Foo.class); + type.add(target); + ComponentDefinition<CompositeImplementation> parent = createComposite("parent"); + parent.getImplementation().getComponentType().add(composite); + resolver.resolve(null, parent); + ReferenceTarget refTarget = source.getReferenceTargets().get(REFERENCE_URI.getFragment()); + assertEquals(TARGET_URI, refTarget.getTargets().get(0)); + } + + + protected void setUp() throws Exception { + super.setUp(); + resolver = new DefaultAutowireResolver(); + } + + private ComponentDefinition<CompositeImplementation> createComposite(String uri) { + URI parentUri = URI.create(uri); + CompositeComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new CompositeComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + CompositeImplementation impl = new CompositeImplementation(); + impl.setComponentType(type); + return new ComponentDefinition<CompositeImplementation>(parentUri, impl); + } + + private ComponentDefinition<MockAtomicImpl> createSourceAtomic(Class<?> requiredInterface) { + URI uri = URI.create("source"); + ServiceContract contract = new ServiceContract() { + }; + contract.setInterfaceClass(requiredInterface); + ReferenceDefinition reference = new ReferenceDefinition(URI.create("#ref"), contract); + reference.setRequired(true); + MockComponentType type = new MockComponentType(); + type.add(reference); + MockAtomicImpl impl = new MockAtomicImpl(); + impl.setComponentType(type); + ComponentDefinition<MockAtomicImpl> definition = new ComponentDefinition<MockAtomicImpl>(uri, impl); + ReferenceTarget target = new ReferenceTarget(); + target.setReferenceName(REFERENCE_URI); + target.setAutowire(true); + definition.add(target); + return definition; + } + + private ComponentDefinition<MockAtomicImpl> createTargetAtomic(Class<?> serviceInterface) { + URI uri = URI.create("target"); + ServiceDefinition service = new ServiceDefinition(); + service.setUri(URI.create("#service")); + ServiceContract contract = new ServiceContract() { + }; + contract.setInterfaceClass(serviceInterface); + service.setServiceContract(contract); + MockComponentType type = new MockComponentType(); + type.add(service); + MockAtomicImpl impl = new MockAtomicImpl(); + impl.setComponentType(type); + return new ComponentDefinition<MockAtomicImpl>(uri, impl); + } + + private class MockAtomicImpl extends AtomicImplementation<MockComponentType> { + + } + + private class MockComponentType extends ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> { + + } + + private interface SuperFoo { + + } + + private interface Foo extends SuperFoo { + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/artifact/LocalMavenRepositoryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/artifact/LocalMavenRepositoryTestCase.java new file mode 100644 index 0000000000..0efecb9302 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/artifact/LocalMavenRepositoryTestCase.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.core.services.artifact; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URL; + +import junit.framework.TestCase; + +import org.apache.tuscany.spi.services.artifact.Artifact; + +/** + * This testcase assumes that there is a maven repo in the default location. + * + * @version $Rev$ $Date$ + */ +public class LocalMavenRepositoryTestCase extends TestCase { + private static final String VERSION = "3.8.1"; + private LocalMavenRepository repo; + private Artifact artifact; + private String path; + + public void testPathWithNoClassifier() { + assertEquals(path, repo.getPath(artifact)); + } + + public void testPathWithClassifier() { + artifact.setClassifier("x86"); + path = "junit/junit/" + VERSION + "/junit-" + VERSION + "-x86.jar"; + assertEquals(path, repo.getPath(artifact)); + } + + public void testArtifactFoundInRepo() throws MalformedURLException, UnsupportedEncodingException { + String home = System.getProperty("user.home"); + File file = new File(home + "/.m2/repository", path); + repo.resolve(artifact); + assertEquals(file.toURI().toURL(), artifact.getUrl()); + } + + public void testArtifactNotFoundInRepo() throws MalformedURLException { + artifact.setClassifier("x86"); + repo.resolve(artifact); + assertNull(artifact.getUrl()); + } + + public void testNonNullURLIsUnmodified() throws MalformedURLException { + URL url = new URL("http://www.apache.org"); + artifact.setUrl(url); + repo.resolve(artifact); + assertSame(url, artifact.getUrl()); + } + + protected void setUp() throws Exception { + super.setUp(); + repo = new LocalMavenRepository(".m2/repository"); + + artifact = new Artifact(); + artifact.setGroup("junit"); + artifact.setName("junit"); + artifact.setVersion(VERSION); + artifact.setType("jar"); + path = "junit/junit/" + VERSION + "/junit-" + VERSION + ".jar"; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/AssemblyServiceImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/AssemblyServiceImplTestCase.java new file mode 100644 index 0000000000..357eee9f93 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/AssemblyServiceImplTestCase.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.core.services.deployment; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; + +import junit.framework.TestCase; +import org.easymock.classextension.EasyMock; + +import org.apache.tuscany.host.deployment.UnsupportedContentTypeException; + +/** + * @version $Rev$ $Date$ + */ +public class AssemblyServiceImplTestCase extends TestCase { + private AssemblyServiceImpl service; + + public void testApplyChangesWithNullURL() { + try { + service.applyChanges(null); + fail(); + } catch (IllegalArgumentException e) { + //ok + } catch (Throwable t) { + fail(); + } + } + + public void testApplyChangesWhenURLContentTypeIsNull() throws Exception { + final URLConnection urlConnection = EasyMock.createMock(URLConnection.class); + EasyMock.expect(urlConnection.getContentType()).andReturn(null); + EasyMock.replay(urlConnection); + URLStreamHandler handler = new MockURLStreamHandler(urlConnection); + + URL url = new URL(null, "file:/tmp/foo.xml", handler); + try { + service.applyChanges(url); + } catch (UnsupportedContentTypeException e) { + assertNull(e.getMessage()); + assertEquals(url.toString(), e.getIdentifier()); + EasyMock.verify(urlConnection); + } catch (Throwable t) { + fail(); + } + } + + public void testApplyChangesWithNullStream() { + try { + service.applyChanges(null, "xxx/xxx"); + fail(); + } catch (IllegalArgumentException e) { + //ok + } catch (Throwable t) { + fail(); + } + } + + public void testApplyChangesWithNullContentType() { + InputStream is = EasyMock.createMock(InputStream.class); + EasyMock.replay(is); + try { + service.applyChanges(is, null); + fail(); + } catch (IllegalArgumentException e) { + EasyMock.verify(is); + } catch (Throwable t) { + fail(); + } + } + + protected void setUp() throws Exception { + super.setUp(); + service = new AssemblyServiceImpl(); + } + + private static class MockURLStreamHandler extends URLStreamHandler { + private final URLConnection urlConnection; + + public MockURLStreamHandler(URLConnection urlConnection) { + this.urlConnection = urlConnection; + } + + protected URLConnection openConnection(URL url) throws IOException { + return urlConnection; + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/ContentTypeDescriberImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/ContentTypeDescriberImplTestCase.java new file mode 100644 index 0000000000..f163edea6d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/ContentTypeDescriberImplTestCase.java @@ -0,0 +1,49 @@ +/*
+ * 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.core.services.deployment;
+
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+public class ContentTypeDescriberImplTestCase extends TestCase {
+ private ContentTypeDescriberImpl contentTypeBuilder;
+
+ public void testResolveContentType() throws Exception {
+ URL artifactURL = getClass().getResource("test.scdl");
+ assertEquals("application/v.tuscany.scdl", contentTypeBuilder.getContentType(artifactURL, null));
+ }
+
+ public void testUnknownResolveContentType() throws Exception {
+ URL artifactURL = getClass().getResource("test.ext");
+ assertNull(contentTypeBuilder.getContentType(artifactURL, null));
+ }
+
+ public void testDefaultContentType() throws Exception {
+ URL artifactURL = getClass().getResource("test.ext");
+ assertEquals("application/v.tuscany.ext", contentTypeBuilder.getContentType(artifactURL,
+ "application/v.tuscany.ext"));
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ contentTypeBuilder = new ContentTypeDescriberImpl();
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionRepositoryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionRepositoryTestCase.java new file mode 100644 index 0000000000..9da0e0f015 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionRepositoryTestCase.java @@ -0,0 +1,67 @@ +/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.services.deployment;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+public class ContributionRepositoryTestCase extends TestCase {
+ protected ContributionRepositoryImpl repository;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ // create repository (this should re-create the root directory)
+ this.repository = new ContributionRepositoryImpl("target/repository");
+
+ }
+
+ public void testStore() throws Exception {
+ String resourceLocation = "/repository/sample-calculator.jar";
+ URI contribution = getClass().getResource(resourceLocation).toURI();
+ InputStream contributionStream = getClass().getResourceAsStream(resourceLocation);
+ repository.store(contribution, contributionStream);
+
+ URL contributionURL = repository.find(contribution);
+ assertNotNull(contributionURL);
+ }
+
+ public void testRemove() throws Exception {
+ String resourceLocation = "/repository/sample-calculator.jar";
+ URI contribution = getClass().getResource(resourceLocation).toURI();
+ InputStream contributionStream = getClass().getResourceAsStream(resourceLocation);
+ repository.store(contribution, contributionStream);
+
+ repository.remove(contribution);
+ URL contributionURL = repository.find(contribution);
+ assertNull(contributionURL);
+ }
+
+ public void testList() throws Exception {
+ String resourceLocation = "/repository/sample-calculator.jar";
+ URI contribution = getClass().getResource(resourceLocation).toURI();
+ InputStream contributionStream = getClass().getResourceAsStream(resourceLocation);
+ repository.store(contribution, contributionStream);
+
+ assertEquals(1, repository.list().size());
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionServiceImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionServiceImplTestCase.java new file mode 100644 index 0000000000..3f259fe0a3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionServiceImplTestCase.java @@ -0,0 +1,67 @@ +/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.services.deployment;
+
+import org.apache.tuscany.spi.deployer.ContentTypeDescriber;
+import org.apache.tuscany.spi.deployer.ContributionProcessorRegistry;
+import org.apache.tuscany.spi.deployer.ContributionRepository;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.host.deployment.ContributionService;
+
+/**
+ * This is more intended to be a integration test then a unit test. *
+ */
+public class ContributionServiceImplTestCase extends TestCase {
+ private static final String JAR_CONTRIBUTION = "/repository/sample-calculator.jar";
+ private ContributionRepository repository;
+ private ContentTypeDescriber contentTypeDescriber;
+ private ContributionProcessorRegistry registry;
+ private ContributionService contributionService;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+// this.repository = new ContributionRepositoryImpl("target/repository");
+//
+// this.contentTypeDescriber = new ContentTypeDescriberImpl();
+//
+// this.registry = new ContributionProcessorRegistryImpl(contentTypeDescriber);
+//
+// JarContributionProcessor jarProcessor = new JarContributionProcessor();
+// jarProcessor.setContributionProcessorRegistry(this.registry);
+// this.registry.register(JarContributionProcessor.CONTENT_TYPE, jarProcessor);
+//
+// JavaContributionProcessor javaProcessor = new JavaContributionProcessor(null);
+// javaProcessor.setContributionProcessorRegistry(this.registry);
+// this.registry.register(JavaContributionProcessor.CONTENT_TYPE, javaProcessor);
+//
+//
+// contributionService = new ContributionServiceImpl(repository, registry);
+ }
+
+ public void testContributeURL() throws Exception {
+// URL contribution = getClass().getResource(JAR_CONTRIBUTION);
+//
+// URI contributionURI = contributionService.contribute(contribution);
+// assertNotNull(contributionURI);
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/FolderContributionProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/FolderContributionProcessorTestCase.java new file mode 100644 index 0000000000..a6205e4b9b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/FolderContributionProcessorTestCase.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.core.services.deployment.contribution;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+public class FolderContributionProcessorTestCase extends TestCase {
+ private static final String DIRECTORY_CONTRIBUTION =
+ "//D:/DEV/Projects/Tuscany/source/java-sca-integration/samples/sca/calculator";
+
+ private File contributionRoot;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.contributionRoot = new File(DIRECTORY_CONTRIBUTION);
+ }
+
+ public final void testProcessJarArtifacts() throws Exception {
+ // FolderContributionProcessor folderContribution = new FolderContributionProcessor();
+ // ContributionProcessorRegistry mockRegistry = EasyMock.createMock(ContributionProcessorRegistry.class);
+ // mockRegistry.register(FolderContributionProcessor.CONTENT_TYPE, folderContribution);
+ // EasyMock.expectLastCall().anyTimes();
+ // EasyMock.replay(mockRegistry);
+ // folderContribution.setContributionProcessorRegistry(mockRegistry);
+ // folderContribution.start();
+ // EasyMock.verify(mockRegistry);
+ //
+ // Contribution contribution = new Contribution(URI.create("sca://contributions/001"));
+ // contribution.setLocation(this.contributionRoot.toURL());
+ // folderContribution.processContent(contribution, contribution.getUri(), null);
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/JarContributionProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/JarContributionProcessorTestCase.java new file mode 100644 index 0000000000..3762622425 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/JarContributionProcessorTestCase.java @@ -0,0 +1,46 @@ +/*
+ * 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.core.services.deployment.contribution;
+
+import junit.framework.TestCase;
+
+public class JarContributionProcessorTestCase extends TestCase {
+ private static final String JAR_CONTRIBUTION = "/repository/sample-calculator.jar";
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public final void testProcessJarArtifacts() throws Exception {
+ /*
+ JarContributionProcessor jarContribution = new JarContributionProcessor();
+ ContributionProcessorRegistry mockRegistry = EasyMock.createMock(ContributionProcessorRegistry.class);
+ mockRegistry.register(JarContributionProcessor.CONTENT_TYPE, jarContribution);
+ EasyMock.expectLastCall().once();
+ EasyMock.replay(mockRegistry);
+ jarContribution.setContributionProcessorRegistry(mockRegistry);
+ jarContribution.start();
+ EasyMock.verify(mockRegistry);
+ URL jarURL = getClass().getResource(JarContributionProcessorTestCase.JAR_CONTRIBUTION);
+ Contribution contribution = new Contribution(URI.create("sca://contributions/001"));
+ contribution.setLocation(jarURL);
+ jarContribution.processContent(contribution, contribution.getUri(), jarURL.openStream());
+ */
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/JavaContributionProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/JavaContributionProcessorTestCase.java new file mode 100644 index 0000000000..89f9a20b6b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/JavaContributionProcessorTestCase.java @@ -0,0 +1,86 @@ +/*
+ * 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.core.services.deployment.contribution;
+
+import java.net.URL;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.implementation.IntrospectionRegistryImpl;
+import org.apache.tuscany.core.implementation.processor.DestroyProcessor;
+import org.apache.tuscany.core.implementation.processor.ImplementationProcessorServiceImpl;
+import org.apache.tuscany.core.implementation.processor.InitProcessor;
+import org.apache.tuscany.core.implementation.processor.PropertyProcessor;
+import org.apache.tuscany.core.implementation.processor.ReferenceProcessor;
+import org.apache.tuscany.core.implementation.processor.ResourceProcessor;
+import org.apache.tuscany.core.implementation.processor.ScopeProcessor;
+import org.apache.tuscany.core.monitor.NullMonitorFactory;
+
+public class JavaContributionProcessorTestCase extends TestCase {
+ private static final String JAR_CONTRIBUTION = "/repository/sample-calculator.jar";
+ private static final String JAVA_ARTIFACT_URL =
+ "jar:file://repository/sample-calculator.jar!/calculator/AddService.class";
+ private IntrospectionRegistryImpl registry;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ registry = new IntrospectionRegistryImpl();
+ registry.setMonitor(new NullMonitorFactory().getMonitor(IntrospectionRegistryImpl.Monitor.class));
+ registry.registerProcessor(new DestroyProcessor());
+ registry.registerProcessor(new InitProcessor());
+ registry.registerProcessor(new ScopeProcessor());
+ JavaInterfaceProcessorRegistryImpl interfaceProcessorRegistry = new JavaInterfaceProcessorRegistryImpl();
+ ImplementationProcessorService service = new ImplementationProcessorServiceImpl(interfaceProcessorRegistry);
+ registry.registerProcessor(new PropertyProcessor(service));
+ registry.registerProcessor(new ReferenceProcessor(interfaceProcessorRegistry));
+ registry.registerProcessor(new ResourceProcessor());
+ }
+
+ protected URL getClassURL() throws Exception {
+ URL jarURL = getClass().getResource(JAR_CONTRIBUTION);
+ JarInputStream jar = new JarInputStream(getClass().getResourceAsStream(JAR_CONTRIBUTION));
+ URL rootURL = new URL("jar:" + jarURL.toString() + "!/");
+ URL classURL = null;
+
+ try {
+ while (true) {
+ JarEntry entry = jar.getNextJarEntry();
+ if (entry.getName().endsWith(".class")) {
+
+ classURL = new URL(rootURL, entry.getName());
+ break;
+ }
+ }
+ } finally {
+ jar.close();
+ }
+ return classURL;
+ }
+
+ public final void testProcessJarArtifacts() throws Exception {
+ //ContributionProcessor javaContributionProcessor = new JavaContributionProcessor(registry);
+
+ //URL jarURL = this.getClassURL();
+ //javaContributionProcessor.processContent(null, jarURL, jarURL.openStream());
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/host/DelegatingResourceHostRegistryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/host/DelegatingResourceHostRegistryTestCase.java new file mode 100644 index 0000000000..c3eb2fa1bf --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/host/DelegatingResourceHostRegistryTestCase.java @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.services.host; + +import org.apache.tuscany.spi.host.ResourceHost; +import org.apache.tuscany.spi.host.ResourceResolutionException; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class DelegatingResourceHostRegistryTestCase extends TestCase { + + public void testResolveByType() throws Exception { + Object ret = new Object(); + DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry(); + registry.registerResource(Object.class, ret); + assertEquals(ret, registry.resolveResource(Object.class)); + } + + public void testResolveByUri() throws Exception { + ResourceHost host = EasyMock.createMock(ResourceHost.class); + EasyMock.expect(host.resolveResource(String.class, "Foo://foo")).andReturn("result"); + EasyMock.replay(host); + DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry(); + registry.registerResourceHost("Foo://", host); + assertEquals("result", registry.resolveResource(String.class, "Foo://foo")); + EasyMock.verify(host); + } + + public void testResolveBySCAUri() throws Exception { + ResourceHost host = EasyMock.createMock(ResourceHost.class); + EasyMock.replay(host); + DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry(); + registry.registerResourceHost("Foo://", host); + Object ret = new Object(); + registry.registerResource(Object.class, "foo", ret); + assertEquals(ret, registry.resolveResource(Object.class, "SCA://foo")); + EasyMock.verify(host); + } + + public void testResolveByUriNotFound() throws Exception { + ResourceHost host = EasyMock.createMock(ResourceHost.class); + EasyMock.replay(host); + DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry(); + registry.registerResourceHost("Foo://", host); + try { + assertEquals("result", registry.resolveResource(String.class, "Bar://bar")); + fail(); + } catch (ResourceResolutionException e) { + //expected + } + EasyMock.verify(host); + } + + public void testUnregisterHost() throws Exception { + ResourceHost host = EasyMock.createMock(ResourceHost.class); + EasyMock.replay(host); + DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry(); + registry.registerResourceHost("Foo://", host); + registry.unregisterResourceHost("Foo://"); + try { + registry.resolveResource(String.class, "Foo://foo"); + fail(); + } catch (ResourceResolutionException e) { + //expected + } + EasyMock.verify(host); + } + + public void testUnregisterResource() throws Exception { + DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry(); + registry.registerResource(Object.class, new Object()); + registry.unregisterResource(Object.class); + assertNull(registry.resolveResource(Object.class)); + } + + public void testUnregisterMappedResource() throws Exception { + DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry(); + registry.registerResource(Object.class, "foo", new Object()); + registry.registerResource(Object.class, new Object()); + registry.unregisterResource(Object.class); + assertNull(registry.resolveResource(Object.class)); + assertNotNull(registry.resolveResource(Object.class, "foo")); + registry.unregisterResource(Object.class, "foo"); + assertNull(registry.resolveResource(Object.class)); + } + + public void testReolvedByTypeToMappedResource() throws Exception { + DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry(); + registry.registerResource(Object.class, "foo", new Object()); + assertNull(registry.resolveResource(Object.class)); + } + + public void testDelegatingResolveResource() throws Exception { + Object ret = new Object(); + ResourceHost host = EasyMock.createMock(ResourceHost.class); + EasyMock.expect(host.resolveResource(Object.class)).andReturn(ret); + EasyMock.replay(host); + DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry(); + registry.registerResourceHost("Foo://", host); + assertEquals(ret, registry.resolveResource(Object.class)); + EasyMock.verify(host); + } + + public void testDelegatingResolveResourceByTypeandName() throws Exception { + Object ret = new Object(); + ResourceHost host = EasyMock.createMock(ResourceHost.class); + EasyMock.expect(host.resolveResource(EasyMock.eq(Object.class), EasyMock.eq("Foo://bar"))).andReturn(ret); + EasyMock.replay(host); + DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry(); + registry.registerResourceHost("Foo://", host); + assertEquals(ret, registry.resolveResource(Object.class, "Foo://bar")); + EasyMock.verify(host); + } + + public void testResolveLocalResourceFirst() throws Exception { + Object local = new Object(); + ResourceHost host = EasyMock.createMock(ResourceHost.class); + EasyMock.replay(host); + DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry(); + registry.registerResourceHost("Foo://", host); + registry.registerResource(Object.class, local); + assertEquals(local, registry.resolveResource(Object.class)); + EasyMock.verify(host); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/store/memory/MemoryStoreTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/store/memory/MemoryStoreTestCase.java new file mode 100644 index 0000000000..06ea7cf903 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/store/memory/MemoryStoreTestCase.java @@ -0,0 +1,166 @@ +/* + * 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.core.services.store.memory; + +import java.net.URI; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.services.store.DuplicateRecordException; +import org.apache.tuscany.spi.services.store.Store; +import org.apache.tuscany.spi.services.store.StoreExpirationEvent; +import org.apache.tuscany.spi.services.store.StoreMonitor; + +import junit.framework.TestCase; +import org.easymock.EasyMock; +import org.easymock.IAnswer; + +/** + * @version $Rev$ $Date$ + */ +public class MemoryStoreTestCase extends TestCase { + private StoreMonitor monitor; + + public void testEviction() throws Exception { + MemoryStore store = new MemoryStore(monitor); + store.setReaperInterval(10); + store.init(); + AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class); + EasyMock.replay(component); + String id = UUID.randomUUID().toString(); + Object value = new Object(); + store.insertRecord(component, id, value, 1); + Thread.sleep(100); + assertNull(store.readRecord(component, id)); + store.destroy(); + } + + public void testNotifyOnEviction() throws Exception { + final CountDownLatch latch = new CountDownLatch(1); + RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class); + listener.onEvent(EasyMock.isA(StoreExpirationEvent.class)); + org.easymock.classextension.EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() { + public Object answer() throws Throwable { + latch.countDown(); + return null; + } + }); + EasyMock.replay(listener); + MemoryStore store = new MemoryStore(monitor); + store.addListener(listener); + store.setReaperInterval(10); + store.init(); + AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class); + EasyMock.replay(component); + String id = UUID.randomUUID().toString(); + Object value = new Object(); + store.insertRecord(component, id, value, 1); + if (!latch.await(1000, TimeUnit.MILLISECONDS)) { + // failed to notify listener + fail(); + } + EasyMock.verify(listener); + } + + public void testNoEviction() throws Exception { + MemoryStore store = new MemoryStore(monitor); + store.setReaperInterval(10); + store.init(); + AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class); + EasyMock.replay(component); + String id = UUID.randomUUID().toString(); + Object value = new Object(); + store.insertRecord(component, id, value, Store.NEVER); + Thread.sleep(100); + assertNotNull(store.readRecord(component, id)); + store.destroy(); + } + + public void testInsertRecord() throws Exception { + MemoryStore store = new MemoryStore(monitor); + store.setReaperInterval(10); + store.init(); + AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class); + EasyMock.replay(component); + String id = UUID.randomUUID().toString(); + Object value = new Object(); + store.insertRecord(component, id, value, Store.NEVER); + store.destroy(); + } + + public void testInsertAlreadyExists() throws Exception { + MemoryStore store = new MemoryStore(monitor); + store.setReaperInterval(10); + store.init(); + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(component.getUri()).andReturn(URI.create("component")); + EasyMock.replay(component); + String id = UUID.randomUUID().toString(); + Object value = new Object(); + store.insertRecord(component, id, value, Store.NEVER); + try { + store.insertRecord(component, id, value, Store.NEVER); + fail(); + } catch (DuplicateRecordException e) { + //expected + } + store.destroy(); + } + + public void testUpdateRecord() throws Exception { + MemoryStore store = new MemoryStore(monitor); + store.setReaperInterval(10); + store.init(); + AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class); + EasyMock.replay(component); + String id = UUID.randomUUID().toString(); + Object value = new Object(); + Object newValue = new Object(); + + store.insertRecord(component, id, value, Store.NEVER); + store.updateRecord(component, id, newValue, 1L); + assertEquals(newValue, store.readRecord(component, id)); + store.destroy(); + } + + public void testDeleteRecord() throws Exception { + MemoryStore store = new MemoryStore(monitor); + store.setReaperInterval(10); + store.init(); + AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class); + EasyMock.replay(component); + String id = UUID.randomUUID().toString(); + Object value = new Object(); + + store.insertRecord(component, id, value, Store.NEVER); + store.removeRecord(component, id); + assertNull(store.readRecord(component, id)); + store.destroy(); + } + + protected void setUp() throws Exception { + super.setUp(); + monitor = EasyMock.createNiceMock(StoreMonitor.class); + EasyMock.replay(monitor); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkSchedulerTest.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkSchedulerTest.java new file mode 100644 index 0000000000..1a5cb4ebe1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkSchedulerTest.java @@ -0,0 +1,81 @@ +/* + * 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.core.services.work.jsr237; + +import org.apache.tuscany.spi.services.work.NotificationListener; +import org.apache.tuscany.spi.services.work.WorkScheduler; + +import commonj.work.WorkManager; +import junit.framework.TestCase; +import org.apache.tuscany.core.services.work.jsr237.workmanager.ThreadPoolWorkManager; + +public class Jsr237WorkSchedulerTest extends TestCase { + + /* + * Test method for 'org.apache.tuscany.core.services.work.jsr237.Jsr237WorkScheduler.scheduleWork(T) <T>' + */ + public void testScheduleWorkT() { + + + WorkManager workManager = new ThreadPoolWorkManager(1); + WorkScheduler workScheduler = new Jsr237WorkScheduler(workManager); + + workScheduler.scheduleWork(new MyRunnable(), new MyNotificationListener()); + + } + + /* + * Test method for 'org.apache.tuscany.core.services.work.jsr237.Jsr237WorkScheduler.scheduleWork(T, + * NotificationListener<T>) <T>' + */ + public void testScheduleWorkTNotificationListenerOfT() { + + } + + private class MyRunnable implements Runnable { + public void run() { + System.err.println("Test executed"); + } + } + + private class MyNotificationListener implements NotificationListener<MyRunnable> { + + public void workAccepted(MyRunnable work) { + System.err.println("Work accepted"); + } + + public void workCompleted(MyRunnable work) { + System.err.println("Work completed"); + } + + public void workStarted(MyRunnable work) { + System.err.println("Work started"); + } + + public void workRejected(MyRunnable work) { + System.err.println("Work rejected"); + } + + public void workFailed(MyRunnable work, Throwable error) { + System.err.println("Work failed"); + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkSchedulerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkSchedulerTestCase.java new file mode 100644 index 0000000000..3966f65683 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkSchedulerTestCase.java @@ -0,0 +1,100 @@ +/* + * 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.core.services.work.jsr237; + +import org.apache.tuscany.spi.services.work.NotificationListener; +import org.apache.tuscany.spi.services.work.WorkSchedulerException; + +import commonj.work.Work; +import commonj.work.WorkItem; +import commonj.work.WorkListener; +import commonj.work.WorkManager; +import commonj.work.WorkRejectedException; +import junit.framework.TestCase; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.isA; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; + +/** + * @version $Rev$ $Date$ + */ +public class Jsr237WorkSchedulerTestCase extends TestCase { + + public void testSchedule() throws Exception { + WorkItem item = createMock(WorkItem.class); + WorkManager mgr = createMock(WorkManager.class); + mgr.schedule(isA(Work.class)); + expectLastCall().andReturn(item); + replay(mgr); + Jsr237WorkScheduler scheduler = new Jsr237WorkScheduler(mgr); + Work work = createMock(Work.class); + scheduler.scheduleWork(work); + verify(mgr); + } + + @SuppressWarnings("unchecked") + public void testListener() throws Exception { + WorkItem item = createMock(WorkItem.class); + WorkManager mgr = createMock(WorkManager.class); + mgr.schedule(isA(Work.class), isA(WorkListener.class)); + expectLastCall().andReturn(item); + replay(mgr); + Jsr237WorkScheduler scheduler = new Jsr237WorkScheduler(mgr); + Work work = createMock(Work.class); + NotificationListener<Runnable> listener = createMock(NotificationListener.class); + scheduler.scheduleWork(work, listener); + verify(mgr); + } + + @SuppressWarnings("unchecked") + public void testWorkRejectedListener() throws Exception { + WorkManager mgr = createMock(WorkManager.class); + mgr.schedule(isA(Work.class), isA(WorkListener.class)); + expectLastCall().andThrow(new WorkRejectedException()); + replay(mgr); + Jsr237WorkScheduler scheduler = new Jsr237WorkScheduler(mgr); + Work work = createMock(Work.class); + NotificationListener<Runnable> listener = createMock(NotificationListener.class); + listener.workRejected(isA(Runnable.class)); + expectLastCall(); + replay(listener); + scheduler.scheduleWork(work, listener); + verify(mgr); + } + + @SuppressWarnings("unchecked") + public void testWorkRejectedNoListener() throws Exception { + WorkManager mgr = createMock(WorkManager.class); + mgr.schedule(isA(Work.class)); + expectLastCall().andThrow(new WorkRejectedException()); + replay(mgr); + Jsr237WorkScheduler scheduler = new Jsr237WorkScheduler(mgr); + Work work = createMock(Work.class); + try { + scheduler.scheduleWork(work); + fail(); + } catch (WorkSchedulerException e) { + // expected + } + verify(mgr); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/workmanager/ThreadPoolWorkManagerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/workmanager/ThreadPoolWorkManagerTestCase.java new file mode 100644 index 0000000000..33ecd66fdc --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/workmanager/ThreadPoolWorkManagerTestCase.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.core.services.work.jsr237.workmanager; + +import java.util.concurrent.CountDownLatch; + +import commonj.work.Work; +import commonj.work.WorkEvent; +import commonj.work.WorkListener; +import junit.framework.TestCase; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.isA; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import org.easymock.IAnswer; + +/** + * @version $Rev$ $Date$ + */ +public class ThreadPoolWorkManagerTestCase extends TestCase { + + public void testSchedule() throws Exception { + final CountDownLatch latch = new CountDownLatch(1); + Work work = createMock(Work.class); + work.run(); + expectLastCall().andStubAnswer(new IAnswer<Object>() { + public Object answer() throws Throwable { + latch.countDown(); + return null; + } + }); + replay(work); + ThreadPoolWorkManager mgr = new ThreadPoolWorkManager(1); + mgr.schedule(work); + latch.await(); + verify(work); + } + + public void testListener() throws Exception { + final CountDownLatch latch = new CountDownLatch(1); + WorkListener listener = createStrictMock(WorkListener.class); + listener.workAccepted(isA(WorkEvent.class)); + listener.workStarted(isA(WorkEvent.class)); + listener.workCompleted(isA(WorkEvent.class)); + expectLastCall(); + replay(listener); + Work work = createMock(Work.class); + work.run(); + expectLastCall().andStubAnswer(new IAnswer<Object>() { + public Object answer() throws Throwable { + latch.countDown(); + return null; + } + }); + replay(work); + ThreadPoolWorkManager mgr = new ThreadPoolWorkManager(1); + mgr.schedule(work, listener); + latch.await(); + verify(work); + } + + public void testDelayListener() throws Exception { + final CountDownLatch latch = new CountDownLatch(1); + final CountDownLatch latch2 = new CountDownLatch(1); + WorkListener listener = createStrictMock(WorkListener.class); + listener.workAccepted(isA(WorkEvent.class)); + listener.workStarted(isA(WorkEvent.class)); + listener.workCompleted(isA(WorkEvent.class)); + expectLastCall().andStubAnswer(new IAnswer<Object>() { + public Object answer() throws Throwable { + latch2.countDown(); + return null; + } + }); + replay(listener); + Work work = createMock(Work.class); + work.run(); + expectLastCall().andStubAnswer(new IAnswer<Object>() { + public Object answer() throws Throwable { + latch.await(); + return null; + } + }); + replay(work); + ThreadPoolWorkManager mgr = new ThreadPoolWorkManager(1); + mgr.schedule(work, listener); + latch.countDown(); + verify(work); + } + + public void testErrorListener() throws Exception { + final CountDownLatch latch = new CountDownLatch(1); + WorkListener listener = createStrictMock(WorkListener.class); + listener.workAccepted(isA(WorkEvent.class)); + listener.workStarted(isA(WorkEvent.class)); + listener.workCompleted(isA(WorkEvent.class)); + replay(listener); + Work work = createMock(Work.class); + work.run(); + expectLastCall().andStubAnswer(new IAnswer<Object>() { + public Object answer() throws Throwable { + latch.countDown(); + throw new RuntimeException(); + } + }); + replay(work); + ThreadPoolWorkManager mgr = new ThreadPoolWorkManager(1); + mgr.schedule(work, listener); + latch.await(); + verify(work); + } + +} + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/util/Bean1.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/util/Bean1.java new file mode 100644 index 0000000000..79fad549aa --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/util/Bean1.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.core.util; + + +public class Bean1 extends SuperBean { + + public static final int ALL_BEAN1_FIELDS = 6 + ALL_SUPER_FIELDS; + public static final int ALL_BEAN1_PUBLIC_PROTECTED_FIELDS = 5 + ALL_SUPER_PUBLIC_PROTECTED_FIELDS; + public static final int ALL_BEAN1_METHODS = 4 + ALL_SUPER_METHODS - 1; + public String field3; + protected String field2; + private String field1; + + public void setMethod1(String param) { + } + + public void setMethod1(int param) { + } + + public void override(String param) throws Exception { + } + + + public void noOverride(String param) throws Exception { + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/util/Bean2.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/util/Bean2.java new file mode 100644 index 0000000000..7f7f03da9e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/util/Bean2.java @@ -0,0 +1,47 @@ +/* + * 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.core.util; + +import java.util.List; + +import junit.framework.AssertionFailedError; + +public class Bean2 { + + private List methodList; + private List fieldList; + + public List getMethodList() { + return methodList; + } + + public void setMethodList(List list) { + methodList = list; + } + + public List getfieldList() { + return fieldList; + } + + public void setfieldList(List list) { + throw new AssertionFailedError("setter inadvertantly called"); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/util/JavaIntrospectionHelperTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/util/JavaIntrospectionHelperTestCase.java new file mode 100644 index 0000000000..797b147b54 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/util/JavaIntrospectionHelperTestCase.java @@ -0,0 +1,180 @@ +/* + * 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.core.util; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import junit.framework.TestCase; +import org.apache.tuscany.core.mock.component.Target; + +public class JavaIntrospectionHelperTestCase extends TestCase { + + private List testNoGenericsList; + private List<String> testList; + private Map<String, Bean1> testMap; + private Target[] testArray; + private String[] testStringArray; + + public JavaIntrospectionHelperTestCase() { + super(); + } + + public JavaIntrospectionHelperTestCase(String arg0) { + super(arg0); + } + + public void testBean1AllPublicProtectedFields() throws Exception { + Set<Field> beanFields = JavaIntrospectionHelper.getAllPublicAndProtectedFields(Bean1.class); + assertEquals(4, beanFields.size()); //Bean1.ALL_BEAN1_PUBLIC_PROTECTED_FIELDS + } + + public void testGetSuperAllMethods() throws Exception { + Set<Method> superBeanMethods = JavaIntrospectionHelper.getAllUniquePublicProtectedMethods(SuperBean.class); + assertEquals(SuperBean.ALL_SUPER_METHODS, superBeanMethods.size()); + } + + public void testGetBean1AllMethods() throws Exception { + Set<Method> beanMethods = JavaIntrospectionHelper.getAllUniquePublicProtectedMethods(Bean1.class); + assertEquals(Bean1.ALL_BEAN1_METHODS, beanMethods.size()); + } + + public void testOverrideMethod() throws Exception { + Set<Method> beanFields = JavaIntrospectionHelper.getAllUniquePublicProtectedMethods(Bean1.class); + boolean invoked = false; + for (Method method : beanFields) { + if (method.getName().equals("override")) { + method.invoke(new Bean1(), "foo"); + invoked = true; + } + } + if (!invoked) { + throw new Exception("Override never invoked"); + } + } + + public void testNoOverrideMethod() throws Exception { + Set<Method> beanFields = JavaIntrospectionHelper.getAllUniquePublicProtectedMethods(Bean1.class); + boolean found = false; + for (Method method : beanFields) { + if (method.getName().equals("noOverride") && method.getParameterTypes().length == 0) { + found = true; + } + } + if (!found) { + throw new Exception("No override not found"); + } + } + + public void testDefaultConstructor() throws Exception { + Constructor ctr = JavaIntrospectionHelper.getDefaultConstructor(Bean2.class); + assertEquals(ctr, Bean2.class.getConstructor()); + assertTrue(Bean2.class == ctr.newInstance((Object[]) null).getClass()); + } + + + public void testGetAllInterfaces() { + Set<Class> interfaces = JavaIntrospectionHelper.getAllInterfaces(Z.class); + assertEquals(2, interfaces.size()); + assertTrue(interfaces.contains(W.class)); + assertTrue(interfaces.contains(W2.class)); + } + + + public void testGetAllInterfacesObject() { + Set<Class> interfaces = JavaIntrospectionHelper.getAllInterfaces(Object.class); + assertEquals(0, interfaces.size()); + } + + public void testGetAllInterfacesNoInterfaces() { + Set<Class> interfaces = JavaIntrospectionHelper.getAllInterfaces(NoInterface.class); + assertEquals(0, interfaces.size()); + } + + /** + * Tests generics introspection capabilities + */ + public void testGenerics() throws Exception { + + List classes = JavaIntrospectionHelper.getGenerics(getClass().getDeclaredField("testList").getGenericType()); + assertEquals(1, classes.size()); + assertEquals(String.class, classes.get(0)); + + classes = + JavaIntrospectionHelper.getGenerics(getClass().getDeclaredField("testNoGenericsList").getGenericType()); + assertEquals(0, classes.size()); + + classes = JavaIntrospectionHelper.getGenerics(getClass().getDeclaredField("testMap").getGenericType()); + assertEquals(2, classes.size()); + assertEquals(String.class, classes.get(0)); + assertEquals(Bean1.class, classes.get(1)); + + classes = JavaIntrospectionHelper + .getGenerics(getClass().getDeclaredMethod("fooMethod", Map.class).getGenericParameterTypes()[0]); + assertEquals(2, classes.size()); + assertEquals(String.class, classes.get(0)); + assertEquals(Bean1.class, classes.get(1)); + + classes = JavaIntrospectionHelper + .getGenerics(getClass().getDeclaredMethod("fooMethod", List.class).getGenericParameterTypes()[0]); + assertEquals(1, classes.size()); + assertEquals(String.class, classes.get(0)); + + } + + private void fooMethod(List<String> foo) { + + } + + private void fooMethod(Map<String, Bean1> foo) { + + } + + public void setTestArray(Target[] array) { + } + + private interface W { + + } + + private interface W2 { + + } + + private class X implements W { + + } + + private class Y extends X implements W, W2 { + + } + + private class Z extends Y { + + } + + private class NoInterface { + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/util/SuperBean.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/util/SuperBean.java new file mode 100644 index 0000000000..83aef7fb5e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/util/SuperBean.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.core.util; + +/** + * @version $Rev$ $Date$ + */ +public class SuperBean { + + public static final int ALL_SUPER_FIELDS = 6; + public static final int ALL_SUPER_PUBLIC_PROTECTED_FIELDS = 5; + public static final int ALL_SUPER_METHODS = 4; + public String superField2; + + protected String superField3; + + private String superField1; + + public void setSuperMethod1(String param) { + } + + public void setSuperMethod1(int param) { + } + + public void override(String param) throws Exception { + throw new Exception("Override not handled"); + } + + public void noOverride() throws Exception { + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/BasicReferenceInvocationHandlerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/BasicReferenceInvocationHandlerTestCase.java new file mode 100644 index 0000000000..9e6f54eea0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/BasicReferenceInvocationHandlerTestCase.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.core.wire; + +import java.lang.reflect.Method; +import java.net.URI; + +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.mock.component.SimpleTarget; +import org.apache.tuscany.core.mock.component.SimpleTargetImpl; +import org.apache.tuscany.core.mock.wire.MockStaticInvoker; +import org.apache.tuscany.core.mock.wire.MockSyncInterceptor; +import org.apache.tuscany.core.wire.jdk.JDKInvocationHandler; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class BasicReferenceInvocationHandlerTestCase extends TestCase { + + private Method echo; + + public void testInterceptorInvoke() throws Throwable { + JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl(); + ServiceContract<?> contract = registry.introspect(SimpleTarget.class); + Operation<?> operation = contract.getOperations().get("echo"); + MockStaticInvoker invoker = new MockStaticInvoker(echo, new SimpleTargetImpl()); + InvocationChain chain = new InvocationChainImpl(operation); + MockSyncInterceptor interceptor = new MockSyncInterceptor(); + chain.addInterceptor(interceptor); + chain.addInterceptor(new InvokerInterceptor()); + chain.setTargetInvoker(invoker); + //chains.put(echo, chain); + Wire wire = new WireImpl(); + wire.addInvocationChain(operation, chain); + wire.setSourceContract(contract); + wire.setSourceUri(URI.create("#wire")); + JDKInvocationHandler handler = new JDKInvocationHandler(SimpleTarget.class, wire, null); + assertEquals("foo", handler.invoke(null, echo, new String[]{"foo"})); + assertEquals(1, interceptor.getCount()); + } + + public void setUp() throws Exception { + super.setUp(); + echo = SimpleTarget.class.getMethod("echo", String.class); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/CallbackInterfaceInterceptorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/CallbackInterfaceInterceptorTestCase.java new file mode 100644 index 0000000000..6c50cb406f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/CallbackInterfaceInterceptorTestCase.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.wire; + +import org.osoa.sca.NoRegisteredCallbackException; + +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class CallbackInterfaceInterceptorTestCase extends TestCase { + + public void testOptimize() throws Exception { + CallbackInterfaceInterceptor interceptor = new CallbackInterfaceInterceptor(true); + assertFalse(interceptor.isOptimizable()); + } + + public void testImplements() { + CallbackInterfaceInterceptor interceptor = new CallbackInterfaceInterceptor(true); + Interceptor next = EasyMock.createMock(Interceptor.class); + EasyMock.expect(next.invoke(EasyMock.isA(Message.class))).andReturn(null); + EasyMock.replay(next); + interceptor.setNext(next); + interceptor.invoke(new MessageImpl()); + EasyMock.verify(next); + } + + public void testDoesNotImplement() { + CallbackInterfaceInterceptor interceptor = new CallbackInterfaceInterceptor(false); + try { + interceptor.invoke(new MessageImpl()); + fail(); + } catch (NoRegisteredCallbackException e) { + // expected + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/ContractCompatibilityTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/ContractCompatibilityTestCase.java new file mode 100644 index 0000000000..866ffe341d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/ContractCompatibilityTestCase.java @@ -0,0 +1,372 @@ +/* + * 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.core.wire; + +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.spi.QualifiedName; +import org.apache.tuscany.spi.component.ReferenceBinding; +import org.apache.tuscany.spi.model.DataType; +import org.apache.tuscany.spi.model.Operation; +import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.ChainHolder; +import org.apache.tuscany.spi.wire.IncompatibleServiceContractException; +import org.apache.tuscany.spi.wire.ProxyCreationException; +import org.apache.tuscany.spi.wire.Wire; +import org.apache.tuscany.spi.wire.ProxyService; + +import junit.framework.TestCase; +import org.osoa.sca.CallableReference; + +/** + * TODO some tests commented out due to DataType.equals() needing to be strict + * + * @version $Rev$ $Date$ + */ +public class ContractCompatibilityTestCase extends TestCase { + + private ProxyService proxyService = new MockProxyService(); + + public void testNoOperation() throws Exception { + ServiceContract source = new MockContract<Type>("FooContract"); + ServiceContract target = new MockContract<Type>("FooContract"); + proxyService.checkCompatibility(source, target, false, false); + } + + public void testBasic() throws Exception { + ServiceContract<Type> source = new MockContract<Type>("FooContract"); + Operation<Type> opSource1 = new Operation<Type>("op1", null, null, null, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>(); + sourceOperations.put("op1", opSource1); + source.setOperations(sourceOperations); + ServiceContract<Type> target = new MockContract<Type>("FooContract"); + Operation<Type> opSource2 = new Operation<Type>("op1", null, null, null, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>(); + targetOperations.put("op1", opSource2); + target.setOperations(targetOperations); + proxyService.checkCompatibility(source, target, false, false); + } + + public void testBasicIncompatibleOperationNames() throws Exception { + ServiceContract<Type> source = new MockContract<Type>("FooContract"); + Operation<Type> opSource1 = new Operation<Type>("op1", null, null, null, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>(); + sourceOperations.put("op1", opSource1); + source.setOperations(sourceOperations); + ServiceContract<Type> target = new MockContract<Type>("FooContract"); + Operation<Type> opSource2 = new Operation<Type>("op2", null, null, null, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>(); + targetOperations.put("op2", opSource2); + target.setOperations(targetOperations); + try { + proxyService.checkCompatibility(source, target, false, false); + fail(); + } catch (IncompatibleServiceContractException e) { + //expected + } + } + + public void testInputTypes() throws Exception { + ServiceContract<Type> source = new MockContract<Type>("FooContract"); + List<DataType<Type>> sourceInputTypes = new ArrayList<DataType<Type>>(); + sourceInputTypes.add(new DataType<Type>(Object.class, Object.class)); + DataType<List<DataType<Type>>> inputType = new DataType<List<DataType<Type>>>(String.class, sourceInputTypes); + Operation<Type> opSource1 = new Operation<Type>("op1", inputType, null, null, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>(); + sourceOperations.put("op1", opSource1); + source.setOperations(sourceOperations); + + ServiceContract<Type> target = new MockContract<Type>("FooContract"); + List<DataType<Type>> targetInputTypes = new ArrayList<DataType<Type>>(); + targetInputTypes.add(new DataType<Type>(Object.class, Object.class)); + DataType<List<DataType<Type>>> targetInputType = + new DataType<List<DataType<Type>>>(String.class, targetInputTypes); + + Operation<Type> opTarget = + new Operation<Type>("op1", targetInputType, null, null, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>(); + targetOperations.put("op1", opTarget); + target.setOperations(targetOperations); + proxyService.checkCompatibility(source, target, false, false); + } + + + public void testIncompatibleInputTypes() throws Exception { + ServiceContract<Type> source = new MockContract<Type>("FooContract"); + List<DataType<Type>> sourceInputTypes = new ArrayList<DataType<Type>>(); + sourceInputTypes.add(new DataType<Type>(Integer.class, Integer.class)); + DataType<List<DataType<Type>>> inputType = new DataType<List<DataType<Type>>>(String.class, sourceInputTypes); + Operation<Type> opSource1 = new Operation<Type>("op1", inputType, null, null, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>(); + sourceOperations.put("op1", opSource1); + source.setOperations(sourceOperations); + + ServiceContract<Type> target = new MockContract<Type>("FooContract"); + List<DataType<Type>> targetInputTypes = new ArrayList<DataType<Type>>(); + targetInputTypes.add(new DataType<Type>(String.class, String.class)); + DataType<List<DataType<Type>>> targetInputType = + new DataType<List<DataType<Type>>>(String.class, targetInputTypes); + + Operation<Type> opTarget = + new Operation<Type>("op1", targetInputType, null, null, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>(); + targetOperations.put("op1", opTarget); + target.setOperations(targetOperations); + try { + proxyService.checkCompatibility(source, target, false, false); + fail(); + } catch (IncompatibleServiceContractException e) { + //expected + } + } + + /** + * Verfies source input types can be super types of the target + */ + public void testSourceSuperTypeInputCompatibility() throws Exception { +// ServiceContract<Type> source = new MockContract<Type>("FooContract"); +// List<DataType<Type>> sourceInputTypes = new ArrayList<DataType<Type>>(); +// sourceInputTypes.add(new DataType<Type>(Object.class, Object.class)); +// DataType<List<DataType<Type>>> inputType = new DataType<List<DataType<Type>>>(String.class, sourceInputTypes); +// Operation<Type> opSource1 = new Operation<Type>("op1", inputType, null, null, false, null); +// Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>(); +// sourceOperations.put("op1", opSource1); +// source.setOperations(sourceOperations); +// +// ServiceContract<Type> target = new MockContract<Type>("FooContract"); +// List<DataType<Type>> targetInputTypes = new ArrayList<DataType<Type>>(); +// targetInputTypes.add(new DataType<Type>(String.class, String.class)); +// DataType<List<DataType<Type>>> targetInputType = +// new DataType<List<DataType<Type>>>(String.class, targetInputTypes); +// +// Operation<Type> opTarget = new Operation<Type>("op1", targetInputType, null, null, false, null); +// Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>(); +// targetOperations.put("op1", opTarget); +// target.setOperations(targetOperations); +// wireService.checkCompatibility(source, target, false); + } + + public void testOutputTypes() throws Exception { + ServiceContract<Type> source = new MockContract<Type>("FooContract"); + DataType<Type> sourceOutputType = new DataType<Type>(String.class, String.class); + Operation<Type> opSource1 = + new Operation<Type>("op1", null, sourceOutputType, null, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>(); + sourceOperations.put("op1", opSource1); + source.setOperations(sourceOperations); + + ServiceContract<Type> target = new MockContract<Type>("FooContract"); + DataType<Type> targetOutputType = new DataType<Type>(String.class, String.class); + Operation<Type> opTarget = + new Operation<Type>("op1", null, targetOutputType, null, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>(); + targetOperations.put("op1", opTarget); + target.setOperations(targetOperations); + proxyService.checkCompatibility(source, target, false, false); + } + + /** + * Verfies a return type that is a supertype of of the target is compatible + */ + public void testSupertypeOutputTypes() throws Exception { +// ServiceContract<Type> source = new MockContract<Type>("FooContract"); +// DataType<Type> sourceOutputType = new DataType<Type>(Object.class, Object.class); +// Operation<Type> opSource1 = new Operation<Type>("op1", null, sourceOutputType, null, false, null); +// Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>(); +// sourceOperations.put("op1", opSource1); +// source.setOperations(sourceOperations); +// +// ServiceContract<Type> target = new MockContract<Type>("FooContract"); +// DataType<Type> targetOutputType = new DataType<Type>(String.class, String.class); +// Operation<Type> opTarget = new Operation<Type>("op1", null, targetOutputType, null, false, null); +// Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>(); +// targetOperations.put("op1", opTarget); +// target.setOperations(targetOperations); +// wireService.checkCompatibility(source, target, false); + } + + public void testIncompatibleOutputTypes() throws Exception { + ServiceContract<Type> source = new MockContract<Type>("FooContract"); + DataType<Type> sourceOutputType = new DataType<Type>(String.class, String.class); + Operation<Type> opSource1 = + new Operation<Type>("op1", null, sourceOutputType, null, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>(); + sourceOperations.put("op1", opSource1); + source.setOperations(sourceOperations); + + ServiceContract<Type> target = new MockContract<Type>("FooContract"); + DataType<Type> targetOutputType = new DataType<Type>(Integer.class, Integer.class); + Operation<Type> opTarget = + new Operation<Type>("op1", null, targetOutputType, null, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>(); + targetOperations.put("op1", opTarget); + target.setOperations(targetOperations); + try { + proxyService.checkCompatibility(source, target, false, false); + fail(); + } catch (IncompatibleServiceContractException e) { + //expected + } + } + + public void testFaultTypes() throws Exception { + ServiceContract<Type> source = new MockContract<Type>("FooContract"); + DataType<Type> sourceFaultType = new DataType<Type>(String.class, String.class); + List<DataType<Type>> sourceFaultTypes = new ArrayList<DataType<Type>>(); + sourceFaultTypes.add(0, sourceFaultType); + Operation<Type> opSource1 = + new Operation<Type>("op1", null, null, sourceFaultTypes, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>(); + sourceOperations.put("op1", opSource1); + source.setOperations(sourceOperations); + + ServiceContract<Type> target = new MockContract<Type>("FooContract"); + DataType<Type> targetFaultType = new DataType<Type>(String.class, String.class); + List<DataType<Type>> targetFaultTypes = new ArrayList<DataType<Type>>(); + targetFaultTypes.add(0, targetFaultType); + + Operation<Type> opTarget = + new Operation<Type>("op1", null, null, targetFaultTypes, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>(); + targetOperations.put("op1", opTarget); + target.setOperations(targetOperations); + proxyService.checkCompatibility(source, target, false, false); + } + + public void testSourceFaultTargetNoFaultCompatibility() throws Exception { + ServiceContract<Type> source = new MockContract<Type>("FooContract"); + DataType<Type> sourceFaultType = new DataType<Type>(String.class, String.class); + List<DataType<Type>> sourceFaultTypes = new ArrayList<DataType<Type>>(); + sourceFaultTypes.add(0, sourceFaultType); + Operation<Type> opSource1 = + new Operation<Type>("op1", null, null, sourceFaultTypes, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>(); + sourceOperations.put("op1", opSource1); + source.setOperations(sourceOperations); + + ServiceContract<Type> target = new MockContract<Type>("FooContract"); + Operation<Type> opTarget = new Operation<Type>("op1", null, null, null, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>(); + targetOperations.put("op1", opTarget); + target.setOperations(targetOperations); + proxyService.checkCompatibility(source, target, false, false); + } + + /** + * Verifies a source's fault which is a supertype of the target's fault are compatibile + * + * @throws Exception + */ + public void testFaultSuperTypes() throws Exception { +// ServiceContract<Type> source = new MockContract<Type>("FooContract"); +// DataType<Type> sourceFaultType = new DataType<Type>(Exception.class, Exception.class); +// List<DataType<Type>> sourceFaultTypes = new ArrayList<DataType<Type>>(); +// sourceFaultTypes.add(0, sourceFaultType); +// Operation<Type> opSource1 = new Operation<Type>("op1", null, null, sourceFaultTypes, false, null); +// Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>(); +// sourceOperations.put("op1", opSource1); +// source.setOperations(sourceOperations); +// +// ServiceContract<Type> target = new MockContract<Type>("FooContract"); +// DataType<Type> targetFaultType = new DataType<Type>(TuscanyException.class, TuscanyException.class); +// List<DataType<Type>> targetFaultTypes = new ArrayList<DataType<Type>>(); +// targetFaultTypes.add(0, targetFaultType); +// +// Operation<Type> opTarget = new Operation<Type>("op1", null, null, targetFaultTypes, false, null); +// Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>(); +// targetOperations.put("op1", opTarget); +// target.setOperations(targetOperations); +// wireService.checkCompatibility(source, target, false); + } + + /** + * Verifies a source's faults which are supertypes and a superset of the target's faults are compatibile + */ + public void testFaultSuperTypesAndSuperset() throws Exception { +// ServiceContract<Type> source = new MockContract<Type>("FooContract"); +// DataType<Type> sourceFaultType = new DataType<Type>(Exception.class, Exception.class); +// DataType<Type> sourceFaultType2 = new DataType<Type>(RuntimeException.class, RuntimeException.class); +// List<DataType<Type>> sourceFaultTypes = new ArrayList<DataType<Type>>(); +// sourceFaultTypes.add(0, sourceFaultType); +// sourceFaultTypes.add(1, sourceFaultType2); +// Operation<Type> opSource1 = new Operation<Type>("op1", null, null, sourceFaultTypes, false, null); +// Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>(); +// sourceOperations.put("op1", opSource1); +// source.setOperations(sourceOperations); +// +// ServiceContract<Type> target = new MockContract<Type>("FooContract"); +// DataType<Type> targetFaultType = new DataType<Type>(TuscanyException.class, TuscanyException.class); +// List<DataType<Type>> targetFaultTypes = new ArrayList<DataType<Type>>(); +// targetFaultTypes.add(0, targetFaultType); +// +// Operation<Type> opTarget = new Operation<Type>("op1", null, null, targetFaultTypes, false, null); +// Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>(); +// targetOperations.put("op1", opTarget); +// target.setOperations(targetOperations); +// wireService.checkCompatibility(source, target, false); + } + + private class MockContract<T> extends ServiceContract<T> { + public MockContract() { + } + + public MockContract(Class interfaceClass) { + super(interfaceClass); + } + + public MockContract(String interfaceName) { + super(interfaceName); + } + } + + private class MockProxyService extends ProxyServiceExtension { + public MockProxyService() { + super(null); + } + + public <T> T createProxy(Class<T> interfaze, Wire wire) throws ProxyCreationException { + throw new UnsupportedOperationException(); + } + + public <T> T createProxy(Class<T> interfaze, Wire wire, Map<Method, ChainHolder> mapping) + throws ProxyCreationException { + throw new UnsupportedOperationException(); + } + + public Object createCallbackProxy(Class<?> interfaze, List<Wire> wires) throws ProxyCreationException { + return null; + } + + public void createWires(ReferenceBinding referenceBinding, ServiceContract<?> contract, + QualifiedName targetName) { + throw new UnsupportedOperationException(); + } + + public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException { + throw new UnsupportedOperationException(); + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/IncompatibleServiceContractExceptionFormatterTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/IncompatibleServiceContractExceptionFormatterTestCase.java new file mode 100644 index 0000000000..a9f455bc62 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/IncompatibleServiceContractExceptionFormatterTestCase.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.core.wire; + +import java.io.PrintWriter; +import java.io.StringWriter; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.IncompatibleServiceContractException; + +import junit.framework.TestCase; +import org.apache.tuscany.host.monitor.FormatterRegistry; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class IncompatibleServiceContractExceptionFormatterTestCase extends TestCase { + FormatterRegistry registry = EasyMock.createNiceMock(FormatterRegistry.class); + IncompatibleServiceContractExceptionFormatter formatter = + new IncompatibleServiceContractExceptionFormatter(registry); + + public void testFormat() throws Exception { + ServiceContract<Object> source = new ServiceContract<Object>() { + }; + source.setInterfaceName("sourceInterface"); + ServiceContract<Object> target = new ServiceContract<Object>() { + }; + target.setInterfaceName("targetInterface"); + Operation<Object> sourceOp = new Operation<Object>("sourceOp", null, null, null); + Operation<Object> targetOp = new Operation<Object>("targetOp", null, null, null); + + IncompatibleServiceContractException e = + new IncompatibleServiceContractException("message", source, target, sourceOp, targetOp); + StringWriter writer = new StringWriter(); + PrintWriter pw = new PrintWriter(writer); + formatter.write(pw, e); + String buffer = writer.toString(); + assertTrue(buffer.indexOf("message") >= 0); + assertTrue(buffer.indexOf("sourceInterface") >= 0); + assertTrue(buffer.indexOf("targetInterface") >= 0); + assertTrue(buffer.indexOf("sourceOp") >= 0); + assertTrue(buffer.indexOf("targetOp") >= 0); + } + + + public void testFormatNulls() throws Exception { + ServiceContract<Object> source = new ServiceContract<Object>() { + }; + source.setInterfaceName("sourceInterface"); + ServiceContract<Object> target = new ServiceContract<Object>() { + }; + target.setInterfaceName("targetInterface"); + + IncompatibleServiceContractException e = + new IncompatibleServiceContractException("message", source, target); + StringWriter writer = new StringWriter(); + PrintWriter pw = new PrintWriter(writer); + formatter.write(pw, e); + String buffer = writer.toString(); + assertTrue(buffer.indexOf("message") >= 0); + assertTrue(buffer.indexOf("sourceInterface") >= 0); + assertTrue(buffer.indexOf("targetInterface") >= 0); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/InvocationChainImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/InvocationChainImplTestCase.java new file mode 100644 index 0000000000..9875058abb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/InvocationChainImplTestCase.java @@ -0,0 +1,84 @@ +/* + * 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.core.wire; + +import java.lang.reflect.Type; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.InvocationChain; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class InvocationChainImplTestCase extends TestCase { + + public void testInsertAtPos() throws Exception { + InvocationChain chain = new InvocationChainImpl(new Operation<Type>("foo", null, null, null)); + Interceptor inter3 = new MockInterceptor(); + Interceptor inter2 = new MockInterceptor(); + Interceptor inter1 = new MockInterceptor(); + chain.addInterceptor(inter3); + chain.addInterceptor(0, inter1); + chain.addInterceptor(1, inter2); + Interceptor head = chain.getHeadInterceptor(); + assertEquals(inter1, head); + assertEquals(inter2, head.getNext()); + assertEquals(inter3, head.getNext().getNext()); + } + + public void testInsertAtEnd() throws Exception { + InvocationChain chain = new InvocationChainImpl(new Operation<Type>("foo", null, null, null)); + Interceptor inter2 = new MockInterceptor(); + Interceptor inter1 = new MockInterceptor(); + chain.addInterceptor(0, inter1); + chain.addInterceptor(1, inter2); + Interceptor head = chain.getHeadInterceptor(); + assertEquals(inter1, head); + assertEquals(inter2, head.getNext()); + assertEquals(inter2, chain.getTailInterceptor()); + + } + + private class MockInterceptor implements Interceptor { + + private Interceptor next; + + public Message invoke(Message msg) { + return null; + } + + public void setNext(Interceptor next) { + this.next = next; + } + + public Interceptor getNext() { + return next; + } + + public boolean isOptimizable() { + return false; + } + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationErrorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationErrorTestCase.java new file mode 100644 index 0000000000..b8e0b0b8ea --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationErrorTestCase.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.core.wire; + +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.mock.component.SimpleTarget; +import org.apache.tuscany.core.mock.component.SimpleTargetImpl; +import org.apache.tuscany.core.mock.wire.MockStaticInvoker; +import org.apache.tuscany.core.mock.wire.MockSyncInterceptor; + +/** + * Tests error propagation through an innvocation + * + * @version $Rev$ $Date$ + */ +public class InvocationConfigurationErrorTestCase extends TestCase { + + private ServiceContract<?> contract; + private Method hello; + + public InvocationConfigurationErrorTestCase() { + super(); + } + + public InvocationConfigurationErrorTestCase(String arg0) { + super(arg0); + } + + public void setUp() throws Exception { + super.setUp(); + JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl(); + contract = registry.introspect(SimpleTarget.class); + hello = SimpleTarget.class.getMethod("hello", String.class); + } + + /** + * Tests basic wiring of a source to a target, including handlers and interceptors + */ + public void testInvokeWithInterceptors() throws Exception { + Operation operation = contract.getOperations().get("hello"); + InvocationChain source = new InvocationChainImpl(operation); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addInterceptor(sourceInterceptor); + + InvocationChain target = new InvocationChainImpl(operation); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + // connect the source to the target + source.addInterceptor(target.getHeadInterceptor()); + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Message msg = new MessageImpl(); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + assertTrue(response.isFault()); + assertTrue(response.getBody() instanceof IllegalArgumentException); + assertEquals(1, sourceInterceptor.getCount()); + assertEquals(1, targetInterceptor.getCount()); + + } + +} + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationTestCase.java new file mode 100644 index 0000000000..000101771a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationTestCase.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.core.wire; + +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.mock.component.SimpleTarget; +import org.apache.tuscany.core.mock.component.SimpleTargetImpl; +import org.apache.tuscany.core.mock.wire.MockStaticInvoker; +import org.apache.tuscany.core.mock.wire.MockSyncInterceptor; + +public class InvocationConfigurationTestCase extends TestCase { + + private Method hello; + private Operation operation; + + + public InvocationConfigurationTestCase() { + super(); + } + + public InvocationConfigurationTestCase(String arg0) { + super(arg0); + } + + public void setUp() throws Exception { + super.setUp(); + JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl(); + ServiceContract<?> contract; + try { + contract = registry.introspect(SimpleTarget.class); + } catch (InvalidServiceContractException e) { + throw new AssertionError(); + } + + operation = contract.getOperations().get("echo"); + hello = SimpleTarget.class.getMethod("hello", String.class); + } + + /** + * Tests basic wiring of a source to a target, including handlers and interceptors + */ + public void testInvokeWithInterceptors() throws Exception { + InvocationChain source = new InvocationChainImpl(operation); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addInterceptor(sourceInterceptor); + + InvocationChain target = new InvocationChainImpl(operation); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + // connect the source to the target + source.addInterceptor(target.getHeadInterceptor()); + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Message msg = new MessageImpl(); + msg.setBody("foo"); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + assertEquals("foo", response.getBody()); + assertEquals(1, sourceInterceptor.getCount()); + assertEquals(1, targetInterceptor.getCount()); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/InvocationHandlerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/InvocationHandlerTestCase.java new file mode 100644 index 0000000000..f37ce6cd7c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/InvocationHandlerTestCase.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.core.wire; + +import java.lang.reflect.Method; +import java.net.URI; + +import org.apache.tuscany.spi.idl.java.JavaIDLUtils; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.mock.component.SimpleTarget; +import org.apache.tuscany.core.mock.component.SimpleTargetImpl; +import org.apache.tuscany.core.mock.wire.MockStaticInvoker; +import org.apache.tuscany.core.mock.wire.MockSyncInterceptor; +import org.apache.tuscany.core.wire.jdk.JDKInvocationHandler; + +public class InvocationHandlerTestCase extends TestCase { + + private Method hello; + private ServiceContract<?> contract; + + public InvocationHandlerTestCase() { + super(); + } + + public InvocationHandlerTestCase(String arg0) { + super(arg0); + } + + public void testBasicInvoke() throws Throwable { + Wire wire = new WireImpl(); + wire.setSourceUri(URI.create("#wire")); + Operation operation = contract.getOperations().get("hello"); + wire.addInvocationChain(operation, createChain(operation)); + wire.setSourceContract(contract); + JDKInvocationHandler handler = new JDKInvocationHandler(SimpleTarget.class, wire, null); + assertEquals("foo", handler.invoke(hello, new Object[]{"foo"})); + } + + public void testErrorInvoke() throws Throwable { + Wire wire = new WireImpl(); + wire.setSourceUri(URI.create("#wire")); + Operation operation = contract.getOperations().get("hello"); + wire.addInvocationChain(operation, createChain(operation)); + wire.setSourceContract(contract); + JDKInvocationHandler handler = new JDKInvocationHandler(SimpleTarget.class, wire, null); + try { + handler.invoke(hello, new Object[]{}); + fail("Expected " + IllegalArgumentException.class.getName()); + } catch (IllegalArgumentException e) { + // should throw + } + } + + public void testDirectErrorInvoke() throws Throwable { + Operation operation = contract.getOperations().get("hello"); + InvocationChain source = new InvocationChainImpl(operation); + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Wire wire = new WireImpl(); + wire.setSourceUri(URI.create("#wire")); + wire.setSourceContract(contract); + wire.addInvocationChain(operation, source); + JDKInvocationHandler handler = new JDKInvocationHandler(SimpleTarget.class, wire, null); + try { + assertEquals("foo", handler.invoke(hello, new Object[]{})); + fail("Expected " + IllegalArgumentException.class.getName()); + } catch (IllegalArgumentException e) { + // should throw + } + } + + public void testDirectInvoke() throws Throwable { + Operation operation = contract.getOperations().get("hello"); + InvocationChain source = new InvocationChainImpl(operation); + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Wire wire = new WireImpl(); + wire.setSourceUri(URI.create("#wire")); + wire.setSourceContract(contract); + wire.addInvocationChain(operation, source); + JDKInvocationHandler handler = new JDKInvocationHandler(SimpleTarget.class, wire, null); + assertEquals("foo", handler.invoke(hello, new Object[]{"foo"})); + } + + private InvocationChain createChain(Operation operation) { + InvocationChain chain = new InvocationChainImpl(operation); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + chain.addInterceptor(targetInterceptor); + chain.addInterceptor(new InvokerInterceptor()); + + Method method = JavaIDLUtils.findMethod(operation, SimpleTarget.class.getMethods()); + MockStaticInvoker invoker = new MockStaticInvoker(method, new SimpleTargetImpl()); + chain.setTargetInvoker(invoker); + return chain; + } + + public void setUp() throws Exception { + super.setUp(); + JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl(); + contract = registry.introspect(SimpleTarget.class); + hello = SimpleTarget.class.getMethod("hello", String.class); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/NonBlockingInterceptorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/NonBlockingInterceptorTestCase.java new file mode 100644 index 0000000000..c08d1453db --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/NonBlockingInterceptorTestCase.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.core.wire; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.services.work.WorkScheduler; +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; + +import junit.framework.TestCase; +import org.easymock.EasyMock; +import static org.easymock.EasyMock.createMock; +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; + +/** + * @version $Rev$ $Date$ + */ +public class NonBlockingInterceptorTestCase extends TestCase { + + public void testInvoke() throws Exception { + WorkScheduler scheduler = createMock(WorkScheduler.class); + scheduler.scheduleWork(isA(Runnable.class)); + expectLastCall().andStubAnswer(new IAnswer<Object>() { + public Object answer() throws Throwable { + Runnable runnable = (Runnable) getCurrentArguments()[0]; + runnable.run(); + return null; + } + }); + replay(scheduler); + WorkContext context = createMock(WorkContext.class); + String convID = "convID"; + EasyMock.expect(context.getIdentifier(Scope.CONVERSATION)).andReturn(convID); + context.setCorrelationId(null); + context.setIdentifier(Scope.CONVERSATION, convID); + EasyMock.replay(context); + Message msg = new MessageImpl(); + Interceptor next = EasyMock.createMock(Interceptor.class); + EasyMock.expect(next.invoke(EasyMock.eq(msg))).andReturn(msg); + EasyMock.replay(next); + Interceptor interceptor = new NonBlockingInterceptor(scheduler, context, next); + interceptor.invoke(msg); + verify(context); + verify(next); + } + + public void testOptimizable() { + NonBlockingInterceptor interceptor = new NonBlockingInterceptor(null, null); + assertFalse(interceptor.isOptimizable()); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/OptimizedWireObjectFactoryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/OptimizedWireObjectFactoryTestCase.java new file mode 100644 index 0000000000..5293678d12 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/OptimizedWireObjectFactoryTestCase.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.core.wire; + +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class OptimizedWireObjectFactoryTestCase extends TestCase { + + public void testGetInstance() throws Exception { + Foo foo = new Foo(); + Wire wire = EasyMock.createMock(Wire.class); + EasyMock.expect(wire.getTargetInstance()).andReturn(foo); + EasyMock.replay(wire); + OptimizedWireObjectFactory<Foo> factory = new OptimizedWireObjectFactory<Foo>(Foo.class, wire); + assertEquals(foo, factory.getInstance()); + EasyMock.verify(wire); + } + + private class Foo { + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/WireImplTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/WireImplTestCase.java new file mode 100644 index 0000000000..e337133523 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/WireImplTestCase.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.core.wire; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class WireImplTestCase extends TestCase { + + /** + * Tests that the target wire returns null if there is no connected wire. This behavior is needed for optional + * autowires. + */ + public void testGetNonExistentTarget() throws Exception { + Wire wire = new WireImpl(); + assertNull(wire.getTargetInstance()); + } + + public void testTargetInstance() throws Exception { + Wire wire = new WireImpl(); + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(component.getTargetInstance()).andReturn(new Object()); + EasyMock.replay(component); + wire.setTarget(component); + assertNotNull(wire.getTargetInstance()); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/WireObjectFactoryTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/WireObjectFactoryTestCase.java new file mode 100644 index 0000000000..9f21b9efdb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/WireObjectFactoryTestCase.java @@ -0,0 +1,138 @@ +/* + * 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.core.wire; + +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.ProxyService; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class WireObjectFactoryTestCase extends TestCase { + + @SuppressWarnings({"unchecked"}) + public void testCreateInstance() throws Exception { + Operation<Type> op = new Operation<Type>("hello", null, null, null); + InvocationChain chain = new InvocationChainImpl(op); + Wire wire = EasyMock.createMock(Wire.class); + Map<Operation<?>, InvocationChain> chains = new HashMap<Operation<?>, InvocationChain>(); + chains.put(op, chain); + EasyMock.expect(wire.getInvocationChains()).andReturn(chains); + EasyMock.expect(wire.isOptimizable()).andReturn(false); + EasyMock.replay(wire); + ProxyService service = EasyMock.createMock(ProxyService.class); + service.createProxy(EasyMock.eq(Foo.class), EasyMock.eq(wire), EasyMock.isA(Map.class)); + EasyMock.expectLastCall().andReturn(new Foo() { + public void hello() { + + } + }); + EasyMock.replay(service); + + WireObjectFactory<Foo> factory = new WireObjectFactory<Foo>(Foo.class, wire, service); + factory.getInstance(); + EasyMock.verify(service); + EasyMock.verify(wire); + } + + @SuppressWarnings("unchecked") + public void testOptimizedCreateInstance() throws Exception { + ServiceContract<?> contract = new JavaServiceContract(Foo.class); + Wire wire = EasyMock.createMock(Wire.class); + EasyMock.expect(wire.isOptimizable()).andReturn(true); + EasyMock.expect(wire.getSourceContract()).andReturn(contract).atLeastOnce(); + EasyMock.expect(wire.getInvocationChains()).andReturn((Map) Collections.emptyMap()); + EasyMock.expect(wire.getTargetInstance()).andReturn(new Foo() { + public void hello() { + } + }); + EasyMock.replay(wire); + WireObjectFactory<Foo> factory = new WireObjectFactory<Foo>(Foo.class, wire, null); + factory.getInstance(); + EasyMock.verify(wire); + + } + + /** + * Verifies that a proxy is created when the required client contract is different than the wire contract + */ + @SuppressWarnings("unchecked") + public void testCannotOptimizeDifferentContractsCreateInstance() throws Exception { + ServiceContract<?> contract = new JavaServiceContract(Object.class); + Wire wire = EasyMock.createMock(Wire.class); + EasyMock.expect(wire.isOptimizable()).andReturn(true); + EasyMock.expect(wire.getSourceContract()).andReturn(contract).atLeastOnce(); + EasyMock.expect(wire.getInvocationChains()).andReturn((Map) Collections.emptyMap()); + EasyMock.replay(wire); + ProxyService service = EasyMock.createMock(ProxyService.class); + service.createProxy(EasyMock.eq(Foo.class), EasyMock.eq(wire), EasyMock.isA(Map.class)); + EasyMock.expectLastCall().andReturn(new Foo() { + public void hello() { + + } + }); + EasyMock.replay(service); + + WireObjectFactory<Foo> factory = new WireObjectFactory<Foo>(Foo.class, wire, service); + factory.getInstance(); + EasyMock.verify(service); + EasyMock.verify(wire); + } + + @SuppressWarnings("unchecked") + public void testNoJavaInterfaceCreateInstance() throws Exception { + ServiceContract<?> contract = new JavaServiceContract(); + Wire wire = EasyMock.createMock(Wire.class); + EasyMock.expect(wire.isOptimizable()).andReturn(true); + EasyMock.expect(wire.getSourceContract()).andReturn(contract).atLeastOnce(); + EasyMock.expect(wire.getInvocationChains()).andReturn((Map) Collections.emptyMap()); + EasyMock.replay(wire); + ProxyService service = EasyMock.createMock(ProxyService.class); + service.createProxy(EasyMock.eq(Foo.class), EasyMock.eq(wire), EasyMock.isA(Map.class)); + EasyMock.expectLastCall().andReturn(new Foo() { + public void hello() { + + } + }); + EasyMock.replay(service); + + WireObjectFactory<Foo> factory = new WireObjectFactory<Foo>(Foo.class, wire, service); + factory.getInstance(); + EasyMock.verify(service); + EasyMock.verify(wire); + } + + private interface Foo { + void hello(); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/WireOptimizationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/WireOptimizationTestCase.java new file mode 100644 index 0000000000..1db3892471 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/WireOptimizationTestCase.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.core.wire; + +import java.lang.reflect.Type; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.model.Operation; +import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION; +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * Verifies wire optimization analysis + * + * @version $$Rev$$ $$Date$$ + */ +public class WireOptimizationTestCase extends TestCase { + private Operation operation; + + public void foo() { + } + + public void testWireInterceptorOptimization() throws Exception { + AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class); + EasyMock.replay(component); + Wire wire = new WireImpl(); + InvocationChain chain = new InvocationChainImpl(operation); + chain.addInterceptor(new OptimizableInterceptor()); + wire.addInvocationChain(operation, chain); + assertTrue(WireUtils.isOptimizable(wire)); + } + + public void testWireNonInterceptorOptimization() throws Exception { + AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class); + EasyMock.replay(component); + Wire wire = new WireImpl(); + InvocationChain chain = new InvocationChainImpl(operation); + chain.addInterceptor(new NonOptimizableInterceptor()); + wire.addInvocationChain(operation, chain); + assertFalse(WireUtils.isOptimizable(wire)); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + protected void setUp() throws Exception { + super.setUp(); + operation = new Operation<Type>("foo", null, null, null, false, null, NO_CONVERSATION); + + } + + private class OptimizableInterceptor implements Interceptor { + + public Message invoke(Message msg) { + return null; + } + + public void setNext(Interceptor next) { + + } + + public Interceptor getNext() { + return null; + } + + public boolean isOptimizable() { + return true; + } + } + + private class NonOptimizableInterceptor implements Interceptor { + + public Message invoke(Message msg) { + return null; + } + + public void setNext(Interceptor next) { + + } + + public Interceptor getNext() { + return null; + } + + public boolean isOptimizable() { + return false; + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/WireUtilsTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/WireUtilsTestCase.java new file mode 100644 index 0000000000..9845a55c47 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/WireUtilsTestCase.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.core.wire; + +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.Map; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.ChainHolder; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class WireUtilsTestCase extends TestCase { + private Method m; + + public void testCreateInterfaceToWireMapping() throws Exception { + Wire wire = new WireImpl(); + Operation<Type> op = new Operation<Type>("hello", null, null, null); + InvocationChain chain = new InvocationChainImpl(op); + wire.addInvocationChain(op, chain); + Map<Method, ChainHolder> chains = WireUtils.createInterfaceToWireMapping(Foo.class, wire); + assertEquals(1, chains.size()); + assertNotNull(chains.get(m)); + } + + public void testCreateInterfaceToWireMappingNoOperation() throws Exception { + Wire wire = new WireImpl(); + Operation<Type> op = new Operation<Type>("goodbye", null, null, null); + InvocationChain chain = new InvocationChainImpl(op); + wire.addInvocationChain(op, chain); + try { + WireUtils.createInterfaceToWireMapping(Foo.class, wire); + fail(); + } catch (NoMethodForOperationException e) { + // expected + } + } + + public void testCreateMapping() throws Exception { + Wire wire = new WireImpl(); + Operation<Type> op = new Operation<Type>("hello", null, null, null); + InvocationChain chain = new InvocationChainImpl(op); + wire.addInvocationChain(op, chain); + Map<Method, InvocationChain> chains = WireUtils.createInboundMapping(wire, new Method[]{m}); + assertEquals(1, chains.size()); + assertNotNull(chains.get(m)); + } + + public void testCreateMappingNoOperation() throws Exception { + Wire wire = new WireImpl(); + Operation<Type> op = new Operation<Type>("goodbye", null, null, null); + InvocationChain chain = new InvocationChainImpl(op); + wire.addInvocationChain(op, chain); + try { + WireUtils.createInboundMapping(wire, new Method[]{m}); + fail(); + } catch (NoMethodForOperationException e) { + // expected + } + } + + protected void setUp() throws Exception { + super.setUp(); + m = Foo.class.getMethod("hello"); + } + + private interface Foo { + void hello(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandlerSerializationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandlerSerializationTestCase.java new file mode 100644 index 0000000000..ff4f882b42 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandlerSerializationTestCase.java @@ -0,0 +1,81 @@ +/* + * 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.core.wire.jdk; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.SCAExternalizable; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.wire.WireImpl; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class JDKCallbackInvocationHandlerSerializationTestCase extends TestCase { + private WorkContext workContext; + private List<Wire> wires; + private AtomicComponent component; + + public void testSerializeDeserialize() throws Exception { + JDKCallbackInvocationHandler handler = new JDKCallbackInvocationHandler(wires, workContext); + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + ObjectOutputStream ostream = new ObjectOutputStream(stream); + ostream.writeObject(handler); + + ObjectInputStream istream = new ObjectInputStream(new ByteArrayInputStream(stream.toByteArray())); + SCAExternalizable externalizable = (SCAExternalizable) istream.readObject(); + + externalizable.setWorkContext(workContext); + externalizable.reactivate(); + EasyMock.verify(component); + } + + protected void setUp() throws Exception { + super.setUp(); + URI uri = URI.create("#foo"); + Wire wire = new WireImpl(); + wire.setSourceUri(uri); + wires = new ArrayList<Wire>(); + wires.add(wire); + List<Wire> wireList = new ArrayList<Wire>(); + wireList.add(wire); + component = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(component.getWires("foo")).andReturn(wireList); + EasyMock.replay(component); + workContext = new WorkContextImpl(); + workContext.setCurrentAtomicComponent(component); + } + + protected void tearDown() throws Exception { + super.tearDown(); + workContext.setCurrentAtomicComponent(null); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandlerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandlerTestCase.java new file mode 100644 index 0000000000..90e5c4f818 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandlerTestCase.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.core.wire.jdk; + +import java.lang.reflect.Proxy; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.wire.WireImpl; + +/** + * @version $Rev$ $Date$ + */ +public class JDKCallbackInvocationHandlerTestCase extends TestCase { + + public void testToString() { + Wire wire = new WireImpl(); + URI uri = URI.create("#wire"); + wire.setSourceUri(uri); + List<Wire> wires = new ArrayList<Wire>(); + wires.add(wire); + wire.setSourceContract(new JavaServiceContract(Foo.class)); + JDKCallbackInvocationHandler handler = new JDKCallbackInvocationHandler(wires, new WorkContextImpl()); + Foo foo = (Foo) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Foo.class}, handler); + assertNotNull(foo.toString()); + } + + public void testHashCode() { + Wire wire = new WireImpl(); + wire.setSourceContract(new JavaServiceContract(Foo.class)); + URI uri = URI.create("#wire"); + wire.setSourceUri(uri); + List<Wire> wires = new ArrayList<Wire>(); + wires.add(wire); + JDKCallbackInvocationHandler handler = new JDKCallbackInvocationHandler(wires, new WorkContextImpl()); + Foo foo = (Foo) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Foo.class}, handler); + assertNotNull(foo.hashCode()); + } + + private interface Foo { + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandlerProxyTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandlerProxyTestCase.java new file mode 100644 index 0000000000..28c3b58f3a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandlerProxyTestCase.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.core.wire.jdk; + +import java.lang.reflect.Method; +import java.net.URI; + +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.MessageImpl; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl; +import org.apache.tuscany.core.wire.InvocationChainImpl; +import org.apache.tuscany.core.wire.WireImpl; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class JDKInvocationHandlerProxyTestCase extends TestCase { + private JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl(); + private Method clientHello; + + /** + * Verifies a handler configured to use a different interface than the wire target can dispatch + */ + public void testDifferentInterface() throws Throwable { + Wire wire = new WireImpl(); + JavaServiceContract contract = registry.introspect(Target.class); + for (Operation<?> operation : contract.getOperations().values()) { + InvocationChain chain = new InvocationChainImpl(operation); + wire.addInvocationChain(operation, chain); + } + wire.setSourceContract(contract); + wire.setSourceUri(URI.create("foo#bar")); + TargetInvoker targetInvoker = EasyMock.createMock(TargetInvoker.class); + EasyMock.expect(targetInvoker.invokeTarget(EasyMock.isNull(), EasyMock.eq(TargetInvoker.NONE))) + .andReturn(new MessageImpl()); + EasyMock.expect(targetInvoker.isCacheable()).andReturn(false); + EasyMock.replay(targetInvoker); + wire.getInvocationChains().values().iterator().next().setTargetInvoker(targetInvoker); + + JDKInvocationHandler handler = new JDKInvocationHandler(Client.class, wire, null); + handler.invoke(null, clientHello, null); + EasyMock.verify(targetInvoker); + } + + protected void setUp() throws Exception { + super.setUp(); + clientHello = Client.class.getMethod("hello"); + } + + private interface Target { + String hello(); + } + + private interface Client { + String hello(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandlerSerializationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandlerSerializationTestCase.java new file mode 100644 index 0000000000..4c613011a3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandlerSerializationTestCase.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.core.wire.jdk; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.SCAObject; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.Operation; +import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.wire.InvocationChainImpl; +import org.apache.tuscany.core.wire.InvokerInterceptor; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class JDKInvocationHandlerSerializationTestCase extends TestCase { + private Wire wire; + private WorkContext workContext; + private TargetInvoker invoker; + + public void testSerializeDeserialize() throws Throwable { + JDKInvocationHandler handler = + new JDKInvocationHandler(Foo.class, wire, workContext); + handler.invoke(Foo.class.getMethod("invoke"), null); + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + ObjectOutputStream ostream = new ObjectOutputStream(stream); + ostream.writeObject(handler); + + ObjectInputStream istream = new ObjectInputStream(new ByteArrayInputStream(stream.toByteArray())); + JDKInvocationHandler externalizable = (JDKInvocationHandler) istream.readObject(); + + externalizable.setWorkContext(workContext); + externalizable.reactivate(); + externalizable.invoke(Foo.class.getMethod("invoke"), null); + EasyMock.verify(invoker); + EasyMock.verify(wire); + } + + protected void setUp() throws Exception { + super.setUp(); + SCAObject container = EasyMock.createMock(SCAObject.class); + ServiceContract<Foo> contract = new ServiceContract<Foo>() { + }; + contract.setInterfaceClass(Foo.class); + contract.setConversational(false); + EasyMock.expect(container.getUri()).andReturn(URI.create("bar")).atLeastOnce(); + + wire = EasyMock.createMock(Wire.class); + Map<Operation<?>, InvocationChain> map = new HashMap<Operation<?>, InvocationChain>(); + Operation<Object> operation = new Operation<Object>("invoke", null, null, null, false, null, NO_CONVERSATION); + ServiceContract<Object> opContract = new ServiceContract<Object>() { + }; + contract.setInterfaceClass(Foo.class); + contract.setConversational(false); + operation.setServiceContract(opContract); + map.put(operation, createChain(operation)); + EasyMock.expect(wire.getSourceContract()).andReturn(contract).atLeastOnce(); + URI uri = URI.create("#foo"); + EasyMock.expect(wire.getSourceUri()).andReturn(uri).atLeastOnce(); + EasyMock.expect(wire.getInvocationChains()).andReturn(map).times(2); + EasyMock.replay(wire); + List<Wire> list = new ArrayList<Wire>(); + list.add(wire); + AtomicComponent component = EasyMock.createMock(AtomicComponent.class); + EasyMock.expect(component.getWires("foo")).andReturn(list); + EasyMock.replay(component); + workContext = new WorkContextImpl(); + workContext.setCurrentAtomicComponent(component); + } + + protected void tearDown() throws Exception { + super.tearDown(); + workContext.setCurrentAtomicComponent(null); + } + + private InvocationChain createChain(Operation operation) { + invoker = EasyMock.createMock(TargetInvoker.class); + EasyMock.expect(invoker.invoke(EasyMock.isA(Message.class))).andReturn(new MessageImpl()).times(2); + EasyMock.expect(invoker.isCacheable()).andReturn(false).atLeastOnce(); + EasyMock.replay(invoker); + InvocationChain chain = new InvocationChainImpl(operation); + chain.setTargetInvoker(invoker); + chain.addInterceptor(new InvokerInterceptor()); + return chain; + } + + public class Foo { + + public void invoke() { + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandlerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandlerTestCase.java new file mode 100644 index 0000000000..7d88c0c7a1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandlerTestCase.java @@ -0,0 +1,156 @@ +/* + * 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.core.wire.jdk; + +import java.lang.reflect.Array; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Proxy; +import java.lang.reflect.Type; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.model.DataType; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.component.WorkContextImpl; +import org.apache.tuscany.core.wire.InvocationChainImpl; +import org.apache.tuscany.core.wire.WireImpl; + +/** + * @version $Rev$ $Date$ + */ +public class JDKInvocationHandlerTestCase extends TestCase { + + public void testToString() { + Wire wire = new WireImpl(); + ServiceContract contract = new JavaServiceContract(Foo.class); + contract.setConversational(false); + wire.setSourceContract(contract); + wire.setSourceUri(URI.create("foo#bar")); + JDKInvocationHandler handler = new JDKInvocationHandler(Foo.class, wire, null); + Foo foo = (Foo) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Foo.class}, handler); + assertNotNull(foo.toString()); + } + + public void testHashCode() { + Wire wire = new WireImpl(); + ServiceContract contract = new JavaServiceContract(Foo.class); + contract.setConversational(false); + wire.setSourceContract(contract); + wire.setSourceUri(URI.create("foo#bar")); + JDKInvocationHandler handler = new JDKInvocationHandler(Foo.class, wire, null); + Foo foo = (Foo) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Foo.class}, handler); + assertNotNull(foo.hashCode()); + } + + public void testConversational() throws Throwable { + Wire wire = new WireImpl(); + DataType<Type> type1 = new DataType<Type>(String.class, String.class); + List<DataType<Type>> types = new ArrayList<DataType<Type>>(); + types.add(type1); + DataType<List<DataType<Type>>> inputType1 = new DataType<List<DataType<Type>>>(Object[].class, types); + DataType<Type> outputType1 = new DataType<Type>(String.class, String.class); + Operation<Type> op1 = new Operation<Type>("test", inputType1, outputType1, null); + ServiceContract<Type> contract = new JavaServiceContract(Foo.class); + contract.setConversational(true); + op1.setServiceContract(contract); + + WorkContext wc = new WorkContextImpl(); + MockInvoker invoker = new MockInvoker(wc); + + InvocationChain chain = new InvocationChainImpl(op1); + chain.setTargetInvoker(invoker); + wire.addInvocationChain(op1, chain); + URI uri = URI.create("fooRef"); + wire.setSourceUri(uri); + wire.setSourceContract(contract); + + String convID = UUID.randomUUID().toString(); + wc.setIdentifier(Scope.CONVERSATION, convID); + invoker.setCurrentConversationID(convID); + + JDKInvocationHandler handler = new JDKInvocationHandler(Foo.class, wire, wc); + handler.invoke(Foo.class.getMethod("test", String.class), new Object[]{"bar"}); + String currentConvID = (String) wc.getIdentifier(Scope.CONVERSATION); + assertSame(convID, currentConvID); + + JDKInvocationHandler handler2 = new JDKInvocationHandler(Foo.class, wire, wc); + handler2.invoke(Foo.class.getMethod("test", String.class), new Object[]{"bar"}); + currentConvID = (String) wc.getIdentifier(Scope.CONVERSATION); + assertSame(convID, currentConvID); + } + + private interface Foo { + String test(String s); + } + + private class MockInvoker implements TargetInvoker { + + private WorkContext wc; + private String currentConversationID; + + public MockInvoker(WorkContext wc) { + this.wc = wc; + } + + public void setCurrentConversationID(String id) { + currentConversationID = id; + } + + public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException { + assertEquals("bar", Array.get(payload, 0)); + String convID = (String) wc.getIdentifier(Scope.CONVERSATION); + assertSame(convID, currentConversationID); + return "response"; + } + + public Message invoke(Message msg) throws InvocationRuntimeException { + fail(); + return null; + } + + public boolean isCacheable() { + return false; + } + + public void setCacheable(boolean cacheable) { + + } + + public boolean isOptimizable() { + return false; + } + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKProxyTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKProxyTestCase.java new file mode 100644 index 0000000000..d140c699c6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKProxyTestCase.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.core.wire.jdk; + +import java.lang.reflect.Proxy; +import java.net.URI; + +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.apache.tuscany.core.wire.WireImpl; + +/** + * @version $Rev$ $Date$ + */ +public class JDKProxyTestCase extends TestCase { + private JDKProxyService proxyService; + + public void testCreateProxy() { + URI uri = URI.create("#service"); + Wire wire = new WireImpl(); + wire.setSourceUri(uri); + ServiceContract contract = new ServiceContract() { + }; + wire.setSourceContract(contract); + TestInterface proxy = proxyService.createProxy(TestInterface.class, wire); + assertTrue(Proxy.isProxyClass(proxy.getClass())); + } + + protected void setUp() throws Exception { + super.setUp(); + proxyService = new JDKProxyService(); + } + + public static interface TestInterface { + int primitives(int i); + + String objects(String object); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/deployables/sample-calculator.jar b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/deployables/sample-calculator.jar Binary files differnew file mode 100644 index 0000000000..0ca3a1b781 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/deployables/sample-calculator.jar diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/marshall/javaChangeSet.xml b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/marshall/javaChangeSet.xml new file mode 100644 index 0000000000..18db713c5d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/marshall/javaChangeSet.xml @@ -0,0 +1,58 @@ +<?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. +--> +<core:changeSet xmlns:core="http://tuscany.apache.org/xmlns/marshaller/1.0-SNAPSHOT"> + + <!-- Component 1 --> + <java:component xmlns:java="http://tuscany.apache.org/xmlns/marshaller/java/1.0-SNAPSHOT" componentId="cmp1"> + <java:reference name="rf1"> + <core:operation name="op2"/> + </java:reference> + <java:service name="sv1"> + <core:operation name="op1"/> + </java:service> + <java:instanceFactory>1234ASF</java:instanceFactory> + <java:scope>STATELESS</java:scope> + <java:classLoaderId>#123</java:classLoaderId> + </java:component> + + <!-- Component 2 --> + <java:component xmlns:java="http://tuscany.apache.org/xmlns/marshaller/java/1.0-SNAPSHOT" componentId="cmp2"> + <java:reference name="rf2"> + <core:operation name="op1"/> + </java:reference> + <java:service name="sv2"> + <core:operation name="op2"/> + </java:service> + <java:instanceFactory>1234ASF</java:instanceFactory> + <java:scope>STATELESS</java:scope> + <java:classLoaderId>#123</java:classLoaderId> + </java:component> + + <!-- Wire 1 --> + <core:wire sourceUri="cmp1#rf1" targetUri="cmp2#sv2"> + <core:operation name="op2"/> + </core:wire> + + <!-- Wire 2 --> + <core:wire sourceUri="cmp2#rf2" targetUri="cmp1#sv1"> + <core:operation name="op1"/> + </core:wire> + +</core:changeSet>
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/databinding/impl/ipo.xsd b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/databinding/impl/ipo.xsd new file mode 100644 index 0000000000..92a576fb98 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/databinding/impl/ipo.xsd @@ -0,0 +1,136 @@ +<!-- + * 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. +--> +<schema targetNamespace="http://www.example.com/IPO" + xmlns="http://www.w3.org/2001/XMLSchema" + xmlns:ipo="http://www.example.com/IPO"> + + <annotation> + <documentation xml:lang="en"> + International Purchase order schema for Example.com + Copyright 2000 Example.com. All rights reserved. + </documentation> + </annotation> + + + <element name="purchaseOrder" type="ipo:PurchaseOrderType" /> + + <element name="comment" type="string" /> + + <complexType name="PurchaseOrderType"> + <sequence> + <element name="shipTo" type="ipo:Address" /> + <element name="billTo" type="ipo:Address" /> + <element ref="ipo:comment" minOccurs="0" /> + <element name="items" type="ipo:Items" /> + </sequence> + <attribute name="orderDate" type="date" /> + </complexType> + + <complexType name="Items"> + <sequence> + <element name="item" minOccurs="0" maxOccurs="unbounded"> + <complexType> + <sequence> + <element name="productName" type="string" /> + <element name="quantity"> + <simpleType> + <restriction base="positiveInteger"> + <maxExclusive value="100" /> + </restriction> + </simpleType> + </element> + <element name="USPrice" type="decimal" /> + <element ref="ipo:comment" minOccurs="0" /> + <element name="shipDate" type="date" + minOccurs="0" /> + </sequence> + <attribute name="partNum" type="ipo:SKU" + use="required" /> + </complexType> + </element> + </sequence> + </complexType> + + <simpleType name="SKU"> + <restriction base="string"> + <pattern value="\d{3}-[A-Z]{2}" /> + </restriction> + </simpleType> + + <complexType name="Address"> + <sequence> + <element name="name" type="string" /> + <element name="street" type="string" /> + <element name="city" type="string" /> + </sequence> + </complexType> + + <complexType name="USAddress"> + <complexContent> + <extension base="ipo:Address"> + <sequence> + <element name="state" type="ipo:USState" /> + <element name="zip" type="positiveInteger" /> + </sequence> + </extension> + </complexContent> + </complexType> + + <complexType name="UKAddress"> + <complexContent> + <extension base="ipo:Address"> + <sequence> + <element name="postcode" type="ipo:UKPostcode" /> + </sequence> + <attribute name="exportCode" type="positiveInteger" + fixed="1" /> + </extension> + </complexContent> + </complexType> + + <!-- other Address derivations for more countries --> + + <simpleType name="USState"> + <restriction base="string"> + <enumeration value="AK" /> + <enumeration value="AL" /> + <enumeration value="AR" /> + <enumeration value="CA" /> + <enumeration value="PA" /> + <!-- and so on ... --> + </restriction> + </simpleType> + + <simpleType name="Postcode"> + <restriction base="string"> + <length value="7" fixed="true" /> + </restriction> + </simpleType> + + + <simpleType name="UKPostcode"> + <restriction base="ipo:Postcode"> + <pattern value="[A-Z]{2}\d\s\d[A-Z]{2}" /> + </restriction> + </simpleType> + + + +</schema> + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/databinding/impl/order.wsdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/databinding/impl/order.wsdl new file mode 100644 index 0000000000..100890e10b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/databinding/impl/order.wsdl @@ -0,0 +1,76 @@ +<?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="StockQuote" targetNamespace="http://example.com/order.wsdl" xmlns:tns="http://example.com/order.wsdl"
+ xmlns:xsd1="http://example.com/order.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns="http://schemas.xmlsoap.org/wsdl/">
+
+ <types>
+ <schema targetNamespace="http://example.com/order.xsd" xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:ipo="http://www.example.com/IPO">
+ <import namespace="http://www.example.com/IPO" schemaLocation="ipo.xsd"/>
+ <element name="checkOrderStatus">
+ <complexType>
+ <sequence>
+ <element name="customerId" type="string" />
+ <element name="order" type="ipo:PurchaseOrderType" />
+ <element name="flag" type="int" />
+ </sequence>
+ </complexType>
+ </element>
+ <element name="checkOrderStatusResponse">
+ <complexType>
+ <sequence>
+ <element name="status" type="string" />
+ </sequence>
+ </complexType>
+ </element>
+ <element name="note" type="string" />
+ </schema>
+ </types>
+
+ <message name="CheckOrderStatusInput1">
+ <part name="body" element="xsd1:checkOrderStatus" />
+ </message>
+
+ <message name="CheckOrderStatusOutput1">
+ <part name="body" element="xsd1:checkOrderStatusResponse" />
+ </message>
+
+ <message name="CheckOrderStatusInput2">
+ <part name="p1" element="xsd1:checkOrderStatus" />
+ <part name="p2" element="xsd1:note" />
+ </message>
+
+ <message name="CheckOrderStatusOutput2">
+ <part name="p1" element="xsd1:checkOrderStatusResponse" />
+ </message>
+
+ <portType name="OrderPortType">
+ <operation name="checkOrderStatus">
+ <input message="tns:CheckOrderStatusInput1" />
+ <output message="tns:CheckOrderStatusOutput1" />
+ </operation>
+ <operation name="checkOrderStatus2">
+ <input message="tns:CheckOrderStatusInput2" />
+ <output message="tns:CheckOrderStatusOutput2" />
+ </operation>
+ </portType>
+
+</definitions>
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/databinding/xml/foo.xml b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/databinding/xml/foo.xml new file mode 100644 index 0000000000..0ba8ade1e0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/databinding/xml/foo.xml @@ -0,0 +1,22 @@ +<?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. +--> +<f:foo xmlns:f="http://foo" name="foo"> + <b:bar xmlns:b="http://bar">bar</b:bar> +</f:foo>
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/deployer/boot1-include.scdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/deployer/boot1-include.scdl new file mode 100644 index 0000000000..838dbf6a9c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/deployer/boot1-include.scdl @@ -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. +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://tuscany.apache.org/xmlns/sca/system/2.0-alpha" + name="boot1-include"> + + <component name="component2"> + <system:implementation.system class="org.apache.tuscany.core.mock.component.BasicInterfaceImpl"/> + </component> + + <service name="service2" promote = "component2"> + <interface.java interface="org.apache.tuscany.core.mock.component.BasicInterface"/> + </service> + +</composite> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/deployer/boot1.scdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/deployer/boot1.scdl new file mode 100644 index 0000000000..8a71aa5698 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/deployer/boot1.scdl @@ -0,0 +1,34 @@ +<?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:system="http://tuscany.apache.org/xmlns/sca/system/2.0-alpha" + targetNamespace="http://example.com" name="boot1"> + <service name="service" promote = "component"> + <interface.java interface="org.apache.tuscany.core.mock.component.BasicInterface"/> + </service> + + <component name="component"> + <system:implementation.system class="org.apache.tuscany.core.mock.component.BasicInterfaceImpl"/> + <property name="publicProperty">propval</property> + <reference name="publicReference" target="component2"/> + </component> + + <include name="boot1-include" scdlLocation="boot1-include.scdl"/> +</composite> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/deployer/boot2.scdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/deployer/boot2.scdl new file mode 100644 index 0000000000..6292f75a96 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/deployer/boot2.scdl @@ -0,0 +1,155 @@ +<?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. +--> +<!-- + A more complex example closer to a typical bootstrap configuration + $Rev$ $Date$ +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://tuscany.apache.org/xmlns/sca/system/2.0-alpha" + name="boot2" + autowire="true"> + + + <!-- expose Deployer API as a service --> + <service name="deployer" promote="deployerImpl"> + <interface.java interface="org.apache.tuscany.spi.deployer.Deployer"/> + </service> + + <!-- Component that provides the Deployer service --> + <component name="deployerImpl"> + <system:implementation.system class="org.apache.tuscany.core.deployer.DeployerImpl"/> + </component> + + <!-- Component that provides the Autowire resolver service --> + <component name="autowireResolver"> + <system:implementation.system class="org.apache.tuscany.core.resolver.DefaultAutowireResolver"/> + </component> + + <!-- Work management --> + <component name="workContext"> + <system:implementation.system class="org.apache.tuscany.core.component.WorkContextImpl"/> + </component> + + <component name="workScheduler"> + <system:implementation.system class="org.apache.tuscany.core.services.work.jsr237.Jsr237WorkScheduler"/> + </component> + + <component name="workManager"> + <system:implementation.system + class="org.apache.tuscany.core.services.work.jsr237.workmanager.ThreadPoolWorkManager"/> + </component> + + <!-- Scope infrastructure --> + <component name="scopeRegistry"> + <system:implementation.system class="org.apache.tuscany.core.component.scope.ScopeRegistryImpl"/> + </component> + + <!-- Builder and BuilderRegistry --> + <component name="builder"> + <system:implementation.system class="org.apache.tuscany.core.builder.BuilderRegistryImpl"/> + </component> + + <!-- Loader and LoaderRegistry --> + <component name="loader"> + <system:implementation.system class="org.apache.tuscany.core.loader.LoaderRegistryImpl"/> + </component> + + <!-- Introspector and IntrospectionRegistry --> + <component name="interfaceProcessorRegistry"> + <system:implementation.system class="org.apache.tuscany.core.implementation.IntrospectionRegistryImpl"/> + </component> + + <!-- Connector infrastructure --> + <component name="connector"> + <system:implementation.system class="org.apache.tuscany.core.builder.ConnectorImpl"/> + </component> + + <component name="wirePostProcess"> + <system:implementation.system class="org.apache.tuscany.core.builder.WirePostProcessorRegistryImpl"/> + </component> + + <!-- Resource host registry --> + <component name="resourceHostRegistry"> + <system:implementation.system class="org.apache.tuscany.core.services.host.DelegatingResourceHostRegistry"/> + </component> + + <!-- Foundation element loader implementations --> + <component name="elementLoader.component"> + <system:implementation.system class="org.apache.tuscany.core.loader.ComponentLoader"/> + </component> + <component name="elementLoader.componentType"> + <system:implementation.system class="org.apache.tuscany.core.loader.ComponentTypeElementLoader"/> + </component> + <component name="elementLoader.interface.java"> + <system:implementation.system class="org.apache.tuscany.core.idl.java.InterfaceJavaLoader"/> + </component> + <component name="elementLoader.property"> + <system:implementation.system class="org.apache.tuscany.core.loader.PropertyLoader"/> + </component> + <component name="elementLoader.reference"> + <system:implementation.system class="org.apache.tuscany.core.loader.ReferenceLoader"/> + </component> + <component name="elementLoader.service"> + <system:implementation.system class="org.apache.tuscany.core.loader.ServiceLoader"/> + </component> + + <component name="proxyService"> + <system:implementation.system class="org.apache.tuscany.core.wire.jdk.JDKProxyService"/> + </component> + + <!-- Composite implementation type --> + <component name="composite.loader"> + <system:implementation.system class="org.apache.tuscany.core.implementation.composite.CompositeLoader"/> + </component> + + <component name="interfaceJava.interfaceProcessorRegistry"> + <system:implementation.system class="org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl"/> + </component> + + <component name="artifactRepository"> + <system:implementation.system class="org.apache.tuscany.core.services.artifact.LocalMavenRepository"/> + <property name="repository">.m2/repository</property> + </component> + + <!-- DataBinding registry --> + <component name="databinding.registry"> + <system:implementation.system class="org.apache.tuscany.core.databinding.impl.DataBindingRegistryImpl"/> + </component> + + <!-- DataBinding registry --> + <component name="databinding.mediator"> + <system:implementation.system class="org.apache.tuscany.core.databinding.impl.MediatorImpl"/> + </component> + + <!-- Transformer registry --> + <component name="databinding.transformerRegistry" initLevel="90"> + <system:implementation.system class="org.apache.tuscany.core.databinding.impl.TransformerRegistryImpl"/> + </component> + + <component name="propertyFactory"> + <system:implementation.system class="org.apache.tuscany.core.property.PropertyObjectFactoryImpl"/> + </component> + + <component name="policyBuilderRegistry"> + <system:implementation.system class="org.apache.tuscany.core.policy.PolicyBuilderRegistryImpl"/> + </component> + + +</composite> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/loader/TestPolicy.scdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/loader/TestPolicy.scdl new file mode 100644 index 0000000000..ee75ea23f0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/loader/TestPolicy.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. +--> +<!-- + Default system configuration for the launcher environment. + + $Rev$ $Date$ +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://tuscany.apache.org/xmlns/sca/system/2.0-alpha" + xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" + name="org.apache.tuscany.core.policy.testCase"> + <policySet name="BasicAuthMsgProtSecurity" + provides="sec.confidentiality" appliesTo="binding.ws binding.jms" + xmlns="http://www.osoa.org/xmlns/sca/1.0"> + <wsp:PolicyAttachment/> + <intentMap provides="sec.confidentiality" default="transport"> + <qualifier name="transport"> + <wsp:PolicyAttachment/> + <wsp:PolicyAttachment/> + </qualifier> + <qualifier name="message"> + <intentMap provides="sec.confidentiality/message" + default="all"> + <qualifier name="all"> + <wsp:PolicyAttachment/> + </qualifier> + <qualifier name="body"> + <wsp:PolicyAttachment/> + </qualifier> + </intentMap> + </qualifier> + </intentMap> + </policySet> +</composite>
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/loader/test-include.scdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/loader/test-include.scdl new file mode 100644 index 0000000000..584846504b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/loader/test-include.scdl @@ -0,0 +1,22 @@ +<?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> + This file just needs to exist +</composite>
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/policy/PolicySet.scdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/policy/PolicySet.scdl new file mode 100644 index 0000000000..0860855d9d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/policy/PolicySet.scdl @@ -0,0 +1,66 @@ +<?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. +--> +<!-- + Default system configuration for the launcher environment. + + $Rev$ $Date$ +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://tuscany.apache.org/xmlns/sca/system/2.0-alpha" + xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" + name="org.apache.tuscany.core.policy.testCase"> + <policySet name="BasicMsgProtSecurity" + provides="sec.confidentiality" appliesTo="binding.ws binding.jms" + xmlns="http://www.osoa.org/xmlns/sca/1.0"> + <wsp:PolicyAttachment/> + <intentMap provides="sec.confidentiality" default="transport"> + <qualifier name="transport"> + <wsp:PolicyAttachment/> + <wsp:PolicyAttachment/> + </qualifier> + <qualifier name="message"> + <intentMap provides="sec.confidentiality/message" + default="all"> + <qualifier name="all"> + <wsp:PolicyAttachment/> + </qualifier> + <qualifier name="body"> + <wsp:PolicyAttachment/> + </qualifier> + </intentMap> + </qualifier> + </intentMap> + </policySet> + + <policySet name="Authentication" + provides="sec.authentication" appliesTo="binding.ws binding.jms"> + <wsp:PolicyAttachment/> + <intentMap provides="authentication" default="cert"> + <qualifier name="cert"> + <wsp:PolicyAttachment/> + <wsp:PolicyAttachment/> + </qualifier> + <qualifier name="basic"> + <wsp:PolicyAttachment/> + </qualifier> + </intentMap> + </policySet> + +</composite>
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/property/ipo.xml b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/property/ipo.xml new file mode 100644 index 0000000000..5bef464cf7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/property/ipo.xml @@ -0,0 +1,51 @@ +<?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. +--> +<ipo:purchaseOrder + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ipo="http://www.example.com/IPO" + xsi:schemaLocation="http://www.example.com/IPO ipo.xsd" + orderDate="1999-12-01"> + + <shipTo exportCode="1" xsi:type="ipo:UKAddress"> + <name>Helen Zoe</name> + <street>47 Eden Street</street> + <city>Cambridge</city> + <postcode>CB1 1JR</postcode> + </shipTo> + + <billTo xsi:type="ipo:USAddress"> + <name>Robert Smith</name> + <street>8 Oak Avenue</street> + <city>Old Town</city> + <state>PA</state> + <zip>95819</zip> + </billTo> + + <items> + <item partNum="833-AA"> + <productName>Lapis necklace</productName> + <quantity>1</quantity> + <USPrice>99.95</USPrice> + <ipo:comment>Want this for the holidays</ipo:comment> + <shipDate>1999-12-05</shipDate> + </item> + </items> +</ipo:purchaseOrder> + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/services/deployment/test.ext b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/services/deployment/test.ext new file mode 100644 index 0000000000..042f3ce1f3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/services/deployment/test.ext @@ -0,0 +1,18 @@ +/* + * 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. + */ diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/services/deployment/test.scdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/services/deployment/test.scdl new file mode 100644 index 0000000000..1e09549194 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/org/apache/tuscany/core/services/deployment/test.scdl @@ -0,0 +1,22 @@ +<?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>
+ This file just needs to exist
+</composite>
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/repository/sample-calculator.jar b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/repository/sample-calculator.jar Binary files differnew file mode 100644 index 0000000000..0ca3a1b781 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/core/src/test/resources/repository/sample-calculator.jar diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/.checkstyle b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/.checkstyle new file mode 100644 index 0000000000..3e57539570 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/.checkstyle @@ -0,0 +1,24 @@ +<?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. +--> +<fileset-config file-format-version="1.2.0" simple-config="true"> + <fileset name="all" enabled="true" check-config-name="Tuscany Checks" local="false"> + <file-match-pattern match-pattern="." include-pattern="true"/> + </fileset> +</fileset-config> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/.pmd b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/.pmd new file mode 100644 index 0000000000..ffc4fe2bbb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/.pmd @@ -0,0 +1,20 @@ +<?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. +--> +<pmd><useProjectRuleSet>true</useProjectRuleSet><rules/></pmd> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/.ruleset b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/.ruleset new file mode 100644 index 0000000000..3886f07f2d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/.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/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/LICENSE.txt b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/LICENSE.txt new file mode 100644 index 0000000000..0084319535 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/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/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/NOTICE.txt b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/NOTICE.txt new file mode 100644 index 0000000000..d83ebbe236 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/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/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/pom.xml b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/pom.xml new file mode 100644 index 0000000000..36c215e812 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/pom.xml @@ -0,0 +1,49 @@ +<?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</groupId> + <artifactId>kernel</artifactId> + <version>2.0-alpha-incubating</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <groupId>org.apache.tuscany.sca.kernel</groupId> + <artifactId>tuscany-host-api</artifactId> + <name>Apache Tuscany Host API</name> + <description>Tuscany Host Programming Interfaces.</description> + + <dependencies> + <dependency> + <groupId>org.apache.tuscany.sca.kernel</groupId> + <artifactId>tuscany-api</artifactId> + <version>${project.version}</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + </dependencies> +</project> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/AbstractRuntimeInfo.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/AbstractRuntimeInfo.java new file mode 100644 index 0000000000..513d02232a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/AbstractRuntimeInfo.java @@ -0,0 +1,125 @@ +/* + * 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.host; + +import java.io.File; +import java.net.URL; +import java.net.URI; + +/** + * Abstract runtime info implementation. + * + * @version $Revision$ $Date$ + */ +public abstract class AbstractRuntimeInfo implements RuntimeInfo { + + /** + * This SCA Domain this runtime belongs to. + */ + private final URI domain; + + /** + * Application root directory. + */ + private final File applicationRootDirectory; + + /** + * Base URL. + */ + private final URL baseUrl; + + /** + * Online indicator. + */ + private final boolean online; + + /** + * Runtime Id. + */ + private String runtimeId; + + /** + * Initializes the runtime info instance. + * + * @param domain the SCA Domain that this runtime belongs to + * @param applicationRootDirectory Application root directory. + * @param baseUrl Base Url. + * @param online Onlne indicator. + * @param runtimeId Runtime Id. + */ + public AbstractRuntimeInfo(final URI domain, + final File applicationRootDirectory, + final URL baseUrl, + final boolean online, + final String runtimeId) { + this.domain = domain; + this.applicationRootDirectory = applicationRootDirectory; + this.baseUrl = baseUrl; + this.online = online; + this.runtimeId = runtimeId; + } + + /** + * Returns the SCA domain associated with this runtime. + * A null domain indicates that this is a standalone runtime with a self-contained assembly. + * + * @return the SCA domain associated with this runtime; may be null + */ + public URI getDomain() { + return domain; + } + + /** + * Returns the unique runtime is in the SCA domain. + * + * @return the SCA domain associated with this runtime; may be null + */ + public String getRuntimeId() { + return runtimeId; + } + + /** + * Return the root directory used to resolve application file paths. + * + * @return the directory used to resolve application file paths. + */ + public final File getApplicationRootDirectory() { + return applicationRootDirectory; + } + + /** + * Gets the base URL for the runtime. + * + * @return The base URL for the runtime. + */ + public final URL getBaseURL() { + return baseUrl; + } + + /** + * Returns whether the runtime considers itself "online" or connected to the internet. + * This can be used by services to enable access to remote resources. + * + * @return true if the runtime is online. + */ + public final boolean isOnline() { + return online; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/MonitorFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/MonitorFactory.java new file mode 100644 index 0000000000..6dc0f53a04 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/MonitorFactory.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.host; + +import java.util.Map; + +import org.apache.tuscany.host.monitor.FormatterRegistry; + +/** + * A MonitorFactory creates implementations of components' monitor interfaces that interface with a its monitoring + * scheme. For example, a implementation may create versions that emit appropriate logging events or which send + * notifications to a management API. + * <p/> + * MonitorFactory implementations must provide a no-arg constructor and implement the {@link #initialize} method to + * perform configuration of instances created using that constructor. Additional constructors may be defined; typically + * their implementations delegate to {@link #initialize}. + * + * @version $Rev$ $Date$ + */ +public interface MonitorFactory extends FormatterRegistry { + /** + * Initializes MonitorFactory instances with implementation-specific configuration properties. + * + * @param configProperties a map of named configuration properties. May be null. + * @throws IllegalArgumentException if the instance can't be configured using the supplied properties + */ + void initialize(Map<String, Object> configProperties); + + /** + * Return a monitor for a component's monitor interface. + * + * @param monitorInterface the component's monitoring interface + * @return an implementation of the monitoring interface; will not be null + */ + <T> T getMonitor(Class<T> monitorInterface); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/RuntimeInfo.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/RuntimeInfo.java new file mode 100644 index 0000000000..e275abbe95 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/RuntimeInfo.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.host; + +import java.io.File; +import java.net.URI; +import java.net.URL; + +/** + * Interface that provides information on the runtime environment. + * + * @version $Rev$ $Date$ + */ +public interface RuntimeInfo { + + /** + * Returns the SCA domain associated with this runtime. + * A null domain indicates that this is a standalone runtime with a self-contained assembly. + * + * @return the SCA domain associated with this runtime; may be null + */ + URI getDomain(); + + /** + * Returns the unique runtime is in the SCA domain. + * + * @return the SCA domain associated with this runtime; may be null + */ + String getRuntimeId(); + + /** + * Return the root directory used to resolve application file paths. + * + * @return the directory used to resolve application file paths. + */ + File getApplicationRootDirectory(); + + /** + * Gets the base URL for the runtime. + * + * @return The base URL for the runtime. + */ + URL getBaseURL(); + + /** + * Returns whether the runtime considers itself "online" or connected to the internet. + * This can be used by services to enable access to remote resources. + * + * @return true if the runtime is online. + */ + boolean isOnline(); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/deployment/AssemblyService.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/deployment/AssemblyService.java new file mode 100644 index 0000000000..50eb24fded --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/deployment/AssemblyService.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.host.deployment; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +/** + * Service interface for managing the logical assembly for a Tuscany runtime. + * + * @version $Rev$ $Date$ + */ +public interface AssemblyService { + /** + * Apply a set of changes to the SCA Domain's logical assembly. + * + * @param changeSet the location of a resource containing a set of changes + * @throws DeploymentException if there was a problem making the changes + * @throws IOException if there was a problem accessing the resource + */ + void applyChanges(URL changeSet) throws DeploymentException, IOException; + + /** + * Apply a set of changes to the SCA Domain's logical assembly. + * + * @param changeSet a stream for reading a resource containing a set of changes; the stream will not be closed + * but no guarantee is made on the position the stream is left in + * @param contentType the type of changeSet on the stream; must be a valid Content-Type value + * as specified by <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC2045</a> + * and must not be null + * @throws DeploymentException if there was a problem making the changes + * @throws IOException if there was a problem reading the stream + */ + void applyChanges(InputStream changeSet, String contentType) throws DeploymentException, IOException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/deployment/ContentTypes.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/deployment/ContentTypes.java new file mode 100644 index 0000000000..a1f0b26b40 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/deployment/ContentTypes.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.host.deployment; + +/** + * Definitions of common Content-Type values. + * + * @version $Rev$ $Date$ + */ +public final class ContentTypes { + /** + * An Assembly changeSet represented as XML. + */ + public static final String CHANGESET_XML = "application/x-apache.tuscany.changeSet+xml"; + + private ContentTypes() { + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/deployment/ContributionService.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/deployment/ContributionService.java new file mode 100644 index 0000000000..ee8ff958c2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/deployment/ContributionService.java @@ -0,0 +1,96 @@ +/* + * 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.host.deployment; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URL; + + +/** + * Service interface that manages artifacts contributed to a Tuscany runtime. + * + * @version $Rev$ $Date$ + */ +public interface ContributionService { + /** + * Contribute an artifact to the SCA Domain. The type of the contribution is determined by the Content-Type of the + * resource or, if that is undefined, by some implementation-specific means (such as mapping an extension in the + * URL's path). + * + * @param contribution the location of the resource containing the artifact + * @param storeInRepository flag that identifies if you want to copy the contribution to the repository + * @return a URI that uniquely identifies this contribution within the SCA Domain + * @throws DeploymentException if there was a problem with the contribution + * @throws IOException if there was a problem reading the resource + */ + URI contribute(URL contribution, boolean storeInRepository) throws DeploymentException, IOException; + + /** + * Contribute an artifact to the SCA Domain. + * + * @param source an identifier for the source of this contribution + * @param contribution a stream containing the resource being contributed; the stream will not be closed but the + * read position after the call is undefined + * @param storeInRepository flag that identifies if you want to copy the contribution to the repository + * @return a URI that uniquely identifies this contribution within the SCA Domain + * @throws DeploymentException if there was a problem with the contribution + * @throws IOException if there was a problem reading the stream + */ + URI contribute(URI source, InputStream contribution, boolean storeInRepository) + throws DeploymentException, IOException; + + /** + * Remove a contribution from the SCA domain + * @param contribution The URI of the contribution + * @throws DeploymentException if there was a problem with the contribution + */ + void remove(URI contribution) throws DeploymentException; + + /** + * Resolve an artifact by QName within the contribution + * + * @param <T> The java type of the artifact such as javax.wsdl.Definition + * @param contribution The URI of the contribution + * @param definitionType The java type of the artifact + * @param namespace The namespace of the artifact + * @param name The name of the artifact + * @return The resolved artifact + */ + <T> T resolve(URI contribution, Class<T> definitionType, String namespace, String name); + + /** + * Resolve the reference to an artifact by the location URI within the given contribution. + * Some typical use cases are: + * <ul> + * <li>Reference a XML schema using + * {http://www.w3.org/2001/XMLSchema-instance}schemaLocation or + * <li>Reference a list of WSDLs using + * {http://www.w3.org/2004/08/wsdl-instance}wsdlLocation + * </ul> + * @param contribution The URI of the contribution + * @param namespace The namespace of the artifact. This is for validation purpose. If the namespace is null, + * then no check will be performed. + * @param uri The location URI + * @param baseURI The URI of the base artifact where the reference is declared + * @return The URL of the resolved artifact + */ + URL resolve(URI contribution, String namespace, URI uri, URI baseURI); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/deployment/DeploymentException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/deployment/DeploymentException.java new file mode 100644 index 0000000000..95ebb50b5c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/deployment/DeploymentException.java @@ -0,0 +1,51 @@ +/* + * 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.host.deployment; + +import org.apache.tuscany.api.TuscanyException; + +/** + * Base class for exceptions raised during deployment. + * + * @version $Rev$ $Date$ + */ +public abstract class DeploymentException extends TuscanyException { + protected DeploymentException() { + } + + protected DeploymentException(String message) { + super(message); + } + + protected DeploymentException(String message, String identifier) { + super(message, identifier); + } + + protected DeploymentException(String message, Throwable cause) { + super(message, cause); + } + + protected DeploymentException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + protected DeploymentException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/deployment/UnsupportedContentTypeException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/deployment/UnsupportedContentTypeException.java new file mode 100644 index 0000000000..579465e3d1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/deployment/UnsupportedContentTypeException.java @@ -0,0 +1,49 @@ +/* + * 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.host.deployment; + +/** + * Exception thrown to indicate that a Content-Type is not supported by this SCA Domain. + * The Content-Type value supplied will be returned as the message text for this exception. + * + * @version $Rev$ $Date$ + */ +public class UnsupportedContentTypeException extends DeploymentException { + private static final long serialVersionUID = -1831797280021355672L; + + /** + * Constructor specifying the Content-Type value that is not supported. + * + * @param contentType the type that is not supported + */ + public UnsupportedContentTypeException(String contentType) { + super(contentType); + } + + /** + * Constructor specifying the Content-Type value that is not supported + * and an identifier to use with this exception (typically the resource being processed). + * + * @param contentType the type that is not supported + * @param identifier an identifier for this exception + */ + public UnsupportedContentTypeException(String contentType, String identifier) { + super(contentType, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/management/ManagementService.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/management/ManagementService.java new file mode 100644 index 0000000000..1b62d3bbed --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/management/ManagementService.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.host.management; + +/** + * + * @version $Revision$ $Date$ + */ +public interface ManagementService<T> { + + /** + * Registers the object for management. + * + * @param name Name under which the object is registered. + * @param managedObject Managed object to be registered. + */ + void registerComponent(String name, T managedObject); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/monitor/ExceptionFormatter.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/monitor/ExceptionFormatter.java new file mode 100644 index 0000000000..4c1e04ecb9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/monitor/ExceptionFormatter.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.host.monitor; + +import java.io.PrintWriter; + +/** + * Formats exception data during a monitor event + * + * @version $Rev$ $Date$ + */ +public interface ExceptionFormatter { + + boolean canFormat(Class<?> type); + + PrintWriter write(PrintWriter writer, Throwable exception); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/monitor/FormatterRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/monitor/FormatterRegistry.java new file mode 100644 index 0000000000..277abb63a7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/monitor/FormatterRegistry.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.host.monitor; + +/** + * A registry for exception formatters + * + * @version $Rev$ $Date$ + */ +public interface FormatterRegistry { + + /** + * Registers the given formatter + * + * @param formatter the formatter to register + */ + void register(ExceptionFormatter formatter); + + /** + * De-registers the given formatter + * + * @param formatter the formatter to de-register + */ + void unregister(ExceptionFormatter formatter); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/package-info.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/package-info.java new file mode 100644 index 0000000000..e5f0575b60 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/package-info.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Overview of Apache Tuscany API for hosts that are embedding the kernel. + */ +package org.apache.tuscany.host;
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/rmi/RMIHost.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/rmi/RMIHost.java new file mode 100644 index 0000000000..3dc68f430d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/rmi/RMIHost.java @@ -0,0 +1,49 @@ +/* + * 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.host.rmi; + +import java.rmi.Remote; + +/* RMI Service hosting interface to be implemented by host environments that allows SCA Components + * to register RMI Services to handle inbound service requests over RMI to SCA Components + */ + +public interface RMIHost { + int RMI_DEFAULT_PORT = 1299; + + // registers an RMI service with the given name and port + void registerService(String serviceName, int port, Remote serviceObject) throws RMIHostException, + RMIHostRuntimeException; + + // registers an RMI service with the given name and default port (1099) + void registerService(String serviceName, Remote serviceObject) throws RMIHostException, + RMIHostRuntimeException; + + // unregister a service registered under the given service name and port number + void unregisterService(String serviceName, int port) throws RMIHostException, + RMIHostRuntimeException; + + // unregister a service registered under the given service name and defalut port number (1099) + void unregisterService(String serviceName) throws RMIHostException, + RMIHostRuntimeException; + + //find a remote service hosted on the given host, port and service name + Remote findService(String host, String port, String svcName) throws RMIHostException, + RMIHostRuntimeException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/rmi/RMIHostAdmin.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/rmi/RMIHostAdmin.java new file mode 100644 index 0000000000..dedfff1cdd --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/rmi/RMIHostAdmin.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.host.rmi; + +import java.rmi.registry.Registry; +import java.util.List; + +/* RMI Service hosting Admin Interface to be implemented by host environments that allows SCA Components + * to register RMI Services to handle inbound service requests over RMI to SCA Components. This interface + * can be used by admin functions to obtain information on RMI registries started and running in the host + * environment + */ + +public interface RMIHostAdmin { + //gets all RMI registries running on the host. Each element of the list is an object of type + //java.rmi.registry + List getAllRegistries() throws RMIHostRuntimeException; + + //gets a registry that is running at a particular port + Registry getRegistry(int port) throws RMIHostRuntimeException; + + //more methods to be added +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/rmi/RMIHostException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/rmi/RMIHostException.java new file mode 100644 index 0000000000..5d7733927d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/rmi/RMIHostException.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.host.rmi; + +import org.apache.tuscany.api.TuscanyException; + +/** + * This exception will relate to situations where the end applicaition's input is the cause of the exception + * + * @version $Rev$ $Date$ + */ +public class RMIHostException extends TuscanyException { + private static final long serialVersionUID = 8031031440259175970L; + + public RMIHostException() { + } + + public RMIHostException(String message) { + super(message); + } + + public RMIHostException(Throwable e) { + super(e); + } + + public RMIHostException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/rmi/RMIHostRuntimeException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/rmi/RMIHostRuntimeException.java new file mode 100644 index 0000000000..35b207b5d2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/rmi/RMIHostRuntimeException.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.host.rmi; + +import org.apache.tuscany.api.TuscanyRuntimeException; + +/** + * This exception relates to cases where there is a problem with the + * Host runtime + * + */ +public class RMIHostRuntimeException extends TuscanyRuntimeException { + private static final long serialVersionUID = -1L; + + public RMIHostRuntimeException() { + } + + public RMIHostRuntimeException(String message) { + super(message); + } + + public RMIHostRuntimeException(Throwable e) { + super(e); + } + + public RMIHostRuntimeException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/runtime/InitializationException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/runtime/InitializationException.java new file mode 100644 index 0000000000..20b518609e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/runtime/InitializationException.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.host.runtime; + +import org.apache.tuscany.api.TuscanyException; + +/** + * Denotes an error starting the runtime + * + * @version $Rev$ $Date$ + */ +public class InitializationException extends TuscanyException { + + public InitializationException(String message) { + super(message); + } + + public InitializationException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/runtime/ShutdownException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/runtime/ShutdownException.java new file mode 100644 index 0000000000..769c928471 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/runtime/ShutdownException.java @@ -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. + */ +package org.apache.tuscany.host.runtime; + +import org.apache.tuscany.api.TuscanyException; + +/** + * Denotes an error during runtime shutdown + * + * @version $Rev$ $Date$ + */ +public class ShutdownException extends TuscanyException { + + public ShutdownException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/runtime/TuscanyRuntime.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/runtime/TuscanyRuntime.java new file mode 100644 index 0000000000..315c02ccf7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/runtime/TuscanyRuntime.java @@ -0,0 +1,125 @@ +/* + * 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.host.runtime; + +import java.net.URL; +import java.net.URI; + +import org.osoa.sca.ComponentContext; + +import org.apache.tuscany.host.MonitorFactory; +import org.apache.tuscany.host.RuntimeInfo; +import org.apache.tuscany.host.management.ManagementService; + +/** + * @version $Rev$ $Date$ + */ +public interface TuscanyRuntime<I extends RuntimeInfo> { + /** + * Returns the location of the SCDL used to boot this runtime. + * + * @return the location of the SCDL used to boot this runtime + */ + URL getSystemScdl(); + + /** + * Sets the location of the SCDL used to boot this runtime. + * + * @param systemScdl the location of the SCDL used to boot this runtime + */ + void setSystemScdl(URL systemScdl); + + /** + * Returns the host ClassLoader that is parent to all Tuscany classloaders. + * + * @return the host's ClassLoader + */ + ClassLoader getHostClassLoader(); + + /** + * Sets the host ClassLoader; this will be a parent for all Tuscany classloaders. + * + * @param classLoader the host's ClassLoader + */ + void setHostClassLoader(ClassLoader classLoader); + + /** + * Returns the info this runtime will make available to service components. + * + * @return the info this runtime will make available to service components + */ + I getRuntimeInfo(); + + /** + * Sets the info this runtime should make available to service components. + * + * @param runtimeInfo the information this runtime should make available to service components + */ + void setRuntimeInfo(I runtimeInfo); + + /** + * Returns the MonitorFactory that this runtime is using. + * + * @return the MonitorFactory that this runtime is using + */ + MonitorFactory getMonitorFactory(); + + /** + * Sets the MonitorFactory that this runtime should use. + * + * @param monitorFactory the MonitorFactory that this runtime should use + */ + void setMonitorFactory(MonitorFactory monitorFactory); + + /** + * Sets the ManagementService that this runtime should use. + * + * @param managementService the ManagementService that this runtime should use + */ + void setManagementService(ManagementService<?> managementService); + + /** + * Returns the ManagementService that this runtime is using. + * + * @return the ManagementService that this runtime is using + */ + ManagementService<?> getManagementService(); + + /** + * Initialize a runtime. + * + * @throws InitializationException if there is an error initializing the runtime + */ + void initialize() throws InitializationException; + + /** + * Destroy the runtime. Any further invocations should result in an error. + * + * @throws ShutdownException if there is an error destroying the runtime + */ + void destroy() throws ShutdownException; + + /** + * Returns the ComponentContext for the designated component. + * + * @param componentId the id of the component whose context should be returned + * @return the ComponentContext for the designated component + */ + ComponentContext getComponentContext(URI componentId); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/servlet/ServletRequestInjector.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/servlet/ServletRequestInjector.java new file mode 100644 index 0000000000..e4b11aee90 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/main/java/org/apache/tuscany/host/servlet/ServletRequestInjector.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.host.servlet; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +/** + * Interface to a system component that dispatches servlet requests to the Tuscany runtime + */ +public interface ServletRequestInjector { + + /** + * Dispatch servlet requests to the Tuscany runtime + * + * @param req the ServletRequest object that contains the request the client made of the servlet + * @param res the ServletResponse object that contains the response the servlet returns to the client + * @throws ServletException if the request cannot be handled + * @throws IOException if an input or output error occurs while handling the request + */ + void service(ServletRequest req, ServletResponse res) throws ServletException, IOException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/test/java/org/apache/tuscany/host/rmi/RMIHostExceptionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/test/java/org/apache/tuscany/host/rmi/RMIHostExceptionTestCase.java new file mode 100644 index 0000000000..0e62dbb3e1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/test/java/org/apache/tuscany/host/rmi/RMIHostExceptionTestCase.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.host.rmi; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class RMIHostExceptionTestCase extends TestCase { + private static final Throwable CAUSE = new Throwable("Cause"); + private static final String MESSAGE = "Message"; + + public void testNoArgConstructor() { + Exception ex = new RMIHostException(); + assertNull(ex.getMessage()); + assertNull(ex.getCause()); + } + + public void testMessageConstructor() { + Exception ex = new RMIHostException(MESSAGE); + assertEquals(MESSAGE, ex.getMessage()); + assertNull(ex.getCause()); + } + + public void testThrowableConstructor() { + Exception ex = new RMIHostException(CAUSE); + assertEquals(CAUSE.getClass().getName() + ": " + CAUSE.getMessage(), ex.getMessage()); + assertEquals(CAUSE, ex.getCause()); + } + + public void testMessageThrowableConstructor() { + Exception ex = new RMIHostException(MESSAGE, CAUSE); + assertEquals(MESSAGE, ex.getMessage()); + assertEquals(CAUSE, ex.getCause()); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/test/java/org/apache/tuscany/host/rmi/RMIHostRuntimeExceptionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/test/java/org/apache/tuscany/host/rmi/RMIHostRuntimeExceptionTestCase.java new file mode 100644 index 0000000000..5071a68132 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/host-api/src/test/java/org/apache/tuscany/host/rmi/RMIHostRuntimeExceptionTestCase.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.host.rmi; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class RMIHostRuntimeExceptionTestCase extends TestCase { + private static final Throwable CAUSE = new Throwable("Cause"); + private static final String MESSAGE = "Message"; + + public void testNoArgConstructor() { + Exception ex = new RMIHostRuntimeException(); + assertNull(ex.getMessage()); + assertNull(ex.getCause()); + } + + public void testMessageConstructor() { + Exception ex = new RMIHostRuntimeException(MESSAGE); + assertSame(MESSAGE, ex.getMessage()); + assertNull(ex.getCause()); + } + + public void testThrowableConstructor() { + Exception ex = new RMIHostRuntimeException(CAUSE); + assertEquals(CAUSE.getClass().getName() + ": " + CAUSE.getMessage(), ex.getMessage()); + assertSame(CAUSE, ex.getCause()); + } + + public void testMessageThrowableConstructor() { + Exception ex = new RMIHostRuntimeException(MESSAGE, CAUSE); + assertSame(MESSAGE, ex.getMessage()); + assertSame(CAUSE, ex.getCause()); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/overview.html b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/overview.html new file mode 100644 index 0000000000..39e9f84069 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/overview.html @@ -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. +--> +<html> +<body> +<p>This document is the API documentation for the Apache Tuscany SCA Kernel.</p> +<p>The API is broken into three main sections each aimed at different user communities:</p> +<ul> + <li>api documentation for users writing components to run in Apache Tuscany</li> + <li>host documentation for users looking to embed Apache Tuscany in a runtime environment</li> + <li>spi documentation for users who wish to add extension functionality</li> +</ul> +</body> +</html> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/pom.xml b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/pom.xml new file mode 100644 index 0000000000..b04eb26430 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/pom.xml @@ -0,0 +1,209 @@ +<?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</groupId> + <artifactId>sca</artifactId> + <version>1.0-incubating</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>kernel</artifactId> + <version>2.0-alpha-incubating</version> + <packaging>pom</packaging> + <name>Apache Tuscany SCA Kernel Sub-Project</name> + <description>Apache Tuscany Kernel project providing an embeddable SCA runtime.</description> + + <properties> + <!-- version the SCA API that we implement --> + <scaSpecVersion>1.0</scaSpecVersion> + </properties> + + <!-- definition of repositories where the parent pom can be found --> + <repositories> + <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> + + <!-- dependencies used by the kernel --> + <dependencyManagement> + <dependencies> + <!-- org.osoa.sca API --> + <dependency> + <groupId>org.osoa</groupId> + <artifactId>sca-api-r${scaSpecVersion}</artifactId> + <version>1.0-incubating</version> + <scope>compile</scope> + </dependency> + + <!-- javax.servlet API --> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <version>2.4</version> + <scope>provided</scope> + </dependency> + + <!-- java.xml.stream API --> + <dependency> + <groupId>stax</groupId> + <artifactId>stax-api</artifactId> + <version>1.0.1</version> + <scope>compile</scope> + </dependency> + + <!-- StAX implementation --> + <dependency> + <groupId>org.codehaus.woodstox</groupId> + <artifactId>wstx-asl</artifactId> + <version>3.2.0</version> + <scope>runtime</scope> + </dependency> + + <!-- junit version --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>3.8.1</version> + <scope>test</scope> + </dependency> + + <!-- EasyMock version --> + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymock</artifactId> + <version>2.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymockclassextension</artifactId> + <version>2.2</version> + <scope>test</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>2.2</version> + <configuration> + <links> + <link>http://java.sun.com/j2se/1.5.0/docs/api</link> + </links> + </configuration> + </plugin> + </plugins> + </pluginManagement> + </build> + + <profiles> + <profile> + <!-- default profile that just builds the jar files --> + <id>default</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <modules> + <module>api</module> + <module>host-api</module> + <module>spi</module> + <module>core</module> + </modules> + <build> + <defaultGoal>install</defaultGoal> + </build> + </profile> + + <profile> + <!-- release profile that prepares artifacts for release --> + <id>release</id> + <modules> + <module>api</module> + <module>host-api</module> + <module>spi</module> + <module>core</module> + </modules> + <build> + <defaultGoal>verify</defaultGoal> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-gpg-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>sign</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + + <profile> + <!-- javadoc profile for generating online javadoc --> + <id>javadoc</id> + <modules> + <module>api</module> + <module>host-api</module> + <module>spi</module> + </modules> + <build> + <defaultGoal>org.apache.maven.plugins:maven-javadoc-plugin:javadoc</defaultGoal> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <overview>${basedir}/overview.html</overview> + <aggregate>true</aggregate> + </configuration> + </plugin> + </plugins> + </build> + </profile> + </profiles> +</project> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/.checkstyle b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/.checkstyle new file mode 100644 index 0000000000..3e57539570 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/.checkstyle @@ -0,0 +1,24 @@ +<?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. +--> +<fileset-config file-format-version="1.2.0" simple-config="true"> + <fileset name="all" enabled="true" check-config-name="Tuscany Checks" local="false"> + <file-match-pattern match-pattern="." include-pattern="true"/> + </fileset> +</fileset-config> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/.pmd b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/.pmd new file mode 100644 index 0000000000..ffc4fe2bbb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/.pmd @@ -0,0 +1,20 @@ +<?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. +--> +<pmd><useProjectRuleSet>true</useProjectRuleSet><rules/></pmd> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/.ruleset b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/.ruleset new file mode 100644 index 0000000000..3886f07f2d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/.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/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/LICENSE.txt b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/LICENSE.txt new file mode 100644 index 0000000000..0084319535 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/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/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/NOTICE.txt b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/NOTICE.txt new file mode 100644 index 0000000000..d83ebbe236 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/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/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/pom.xml b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/pom.xml new file mode 100644 index 0000000000..e3f76533a8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/pom.xml @@ -0,0 +1,66 @@ +<?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</groupId> + <artifactId>kernel</artifactId> + <version>2.0-alpha-incubating</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <groupId>org.apache.tuscany.sca.kernel</groupId> + <artifactId>tuscany-spi</artifactId> + <name>Apache Tuscany SCA SPI</name> + <description>Tuscany Service Provider Interfaces.</description> + + <dependencies> + <dependency> + <groupId>org.apache.tuscany.sca.kernel</groupId> + <artifactId>tuscany-host-api</artifactId> + <version>${project.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>stax</groupId> + <artifactId>stax-api</artifactId> + </dependency> + + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + </dependency> + + <dependency> + <groupId>org.codehaus.woodstox</groupId> + <artifactId>wstx-asl</artifactId> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymock</artifactId> + </dependency> + + </dependencies> +</project> diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/doc/Context Model.emx b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/doc/Context Model.emx new file mode 100644 index 0000000000..0445ea5a6b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/doc/Context Model.emx @@ -0,0 +1,673 @@ +<?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.
+-->
+<!--xtools2_universal_type_manager-->
+<uml:Model xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.ibm.com/xtools/1.5.0/Notation" xmlns:uml="http://www.eclipse.org/uml2/1.0.0/UML" xmlns:umlnotation="http://www.ibm.com/xtools/1.5.0/Umlnotation" xmi:id="_al1S8NovEdqRBPR5WyT36A" name="Context Model" appliedProfile="_al1S9NovEdqRBPR5WyT36A _al1S99ovEdqRBPR5WyT36A _al1S-tovEdqRBPR5WyT36A _al1S_dovEdqRBPR5WyT36A _al1TANovEdqRBPR5WyT36A">
+ <eAnnotations xmi:id="_al1S8dovEdqRBPR5WyT36A" source="uml2.diagrams" references="_al1S8tovEdqRBPR5WyT36A">
+ <contents xmi:type="notation:Diagram" xmi:id="_al1S8tovEdqRBPR5WyT36A" type="Class" name="Main">
+ <children xmi:id="_ePDcYdovEdqRBPR5WyT36A" sourceEdges="_Fd3lQdowEdqRBPR5WyT36A _R5Rjwdo1EdqRBPR5WyT36A _pdfmkNo2EdqRBPR5WyT36A" targetEdges="_hmIF4dovEdqRBPR5WyT36A _mu9A4dovEdqRBPR5WyT36A _pe3jwNovEdqRBPR5WyT36A" element="_ePDcYNovEdqRBPR5WyT36A">
+ <children xmi:id="_ePJjANovEdqRBPR5WyT36A" type="ImageCompartment" element="_ePDcYNovEdqRBPR5WyT36A">
+ <layoutConstraint xmi:type="notation:Size" xmi:id="_ePJjAdovEdqRBPR5WyT36A" width="530" height="530"/>
+ </children>
+ <children xmi:id="_ePJjAtovEdqRBPR5WyT36A" type="Stereotype" element="_ePDcYNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_ePJjA9ovEdqRBPR5WyT36A" type="Kind" element="_ePDcYNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_ePJjBNovEdqRBPR5WyT36A" type="Name" element="_ePDcYNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_ePJjBdovEdqRBPR5WyT36A" type="AttributeCompartment" element="_ePDcYNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_ePJjBtovEdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_ePJjB9ovEdqRBPR5WyT36A" type="OperationCompartment" element="_ePDcYNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_ePJjCNovEdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_ePJjCdovEdqRBPR5WyT36A" visible="false" type="SignalCompartment" element="_ePDcYNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_ePJjCtovEdqRBPR5WyT36A"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_ePDcYtovEdqRBPR5WyT36A" showStereotype="Label" useClassifierShape="true"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_ePDcY9ovEdqRBPR5WyT36A" x="6693" y="3545"/>
+ </children>
+ <children xmi:id="_fs1pANovEdqRBPR5WyT36A" sourceEdges="_hmIF4dovEdqRBPR5WyT36A _pe3jwNovEdqRBPR5WyT36A" targetEdges="_xInjYdovEdqRBPR5WyT36A" element="_fsviYNovEdqRBPR5WyT36A">
+ <children xmi:id="_fs1pA9ovEdqRBPR5WyT36A" type="ImageCompartment" element="_fsviYNovEdqRBPR5WyT36A">
+ <layoutConstraint xmi:type="notation:Size" xmi:id="_fs1pBNovEdqRBPR5WyT36A" width="530" height="530"/>
+ </children>
+ <children xmi:id="_fs1pBdovEdqRBPR5WyT36A" type="Stereotype" element="_fsviYNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_fs1pBtovEdqRBPR5WyT36A" type="Kind" element="_fsviYNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_fs1pB9ovEdqRBPR5WyT36A" type="Name" element="_fsviYNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_fs1pCNovEdqRBPR5WyT36A" type="AttributeCompartment" element="_fsviYNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_fs1pCdovEdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_fs1pCtovEdqRBPR5WyT36A" type="OperationCompartment" element="_fsviYNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_fs1pC9ovEdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_fs1pDNovEdqRBPR5WyT36A" visible="false" type="SignalCompartment" element="_fsviYNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_fs1pDdovEdqRBPR5WyT36A"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_fs1pAdovEdqRBPR5WyT36A" showStereotype="Label" useClassifierShape="true"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_fs1pAtovEdqRBPR5WyT36A" x="2226" y="8268"/>
+ </children>
+ <children xmi:id="_ikr_4NovEdqRBPR5WyT36A" sourceEdges="_mu9A4dovEdqRBPR5WyT36A" element="_ikl5QNovEdqRBPR5WyT36A">
+ <children xmi:id="_ikr_49ovEdqRBPR5WyT36A" type="ImageCompartment" element="_ikl5QNovEdqRBPR5WyT36A">
+ <layoutConstraint xmi:type="notation:Size" xmi:id="_ikr_5NovEdqRBPR5WyT36A" width="530" height="530"/>
+ </children>
+ <children xmi:id="_ikr_5dovEdqRBPR5WyT36A" type="Stereotype" element="_ikl5QNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_ikr_5tovEdqRBPR5WyT36A" type="Kind" element="_ikl5QNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_ikr_59ovEdqRBPR5WyT36A" type="Name" element="_ikl5QNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_ikr_6NovEdqRBPR5WyT36A" type="AttributeCompartment" element="_ikl5QNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_ikr_6dovEdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_ikr_6tovEdqRBPR5WyT36A" type="OperationCompartment" element="_ikl5QNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_ikr_69ovEdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_ikr_7NovEdqRBPR5WyT36A" visible="false" type="SignalCompartment" element="_ikl5QNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_ikr_7dovEdqRBPR5WyT36A"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_ikr_4dovEdqRBPR5WyT36A" showStereotype="Label" useClassifierShape="true"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_ikr_4tovEdqRBPR5WyT36A" x="9222" y="8268"/>
+ </children>
+ <children xmi:id="_tZF9odovEdqRBPR5WyT36A" sourceEdges="_xInjYdovEdqRBPR5WyT36A _BkUg0dowEdqRBPR5WyT36A" element="_tZF9oNovEdqRBPR5WyT36A">
+ <children xmi:id="_tZF9pNovEdqRBPR5WyT36A" type="ImageCompartment" element="_tZF9oNovEdqRBPR5WyT36A">
+ <layoutConstraint xmi:type="notation:Size" xmi:id="_tZF9pdovEdqRBPR5WyT36A" width="530" height="530"/>
+ </children>
+ <children xmi:id="_tZF9ptovEdqRBPR5WyT36A" type="Stereotype" element="_tZF9oNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_tZF9p9ovEdqRBPR5WyT36A" type="Kind" element="_tZF9oNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_tZF9qNovEdqRBPR5WyT36A" type="Name" element="_tZF9oNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_tZF9qdovEdqRBPR5WyT36A" type="AttributeCompartment" element="_tZF9oNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_tZF9qtovEdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_tZF9q9ovEdqRBPR5WyT36A" type="OperationCompartment" element="_tZF9oNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_tZF9rNovEdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_tZF9rdovEdqRBPR5WyT36A" visible="false" type="SignalCompartment" element="_tZF9oNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_tZF9rtovEdqRBPR5WyT36A"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_tZF9otovEdqRBPR5WyT36A" showStereotype="Label" useClassifierShape="true"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_tZF9o9ovEdqRBPR5WyT36A" x="2226" y="12084"/>
+ </children>
+ <children xmi:id="_z_m-oNovEdqRBPR5WyT36A" sourceEdges="_cN4xsdo2EdqRBPR5WyT36A" targetEdges="_3Ic-4NovEdqRBPR5WyT36A _9XeF4tovEdqRBPR5WyT36A _Fd3lQdowEdqRBPR5WyT36A" element="_z_g4ANovEdqRBPR5WyT36A">
+ <children xmi:id="_z_m-o9ovEdqRBPR5WyT36A" type="ImageCompartment" element="_z_g4ANovEdqRBPR5WyT36A">
+ <layoutConstraint xmi:type="notation:Size" xmi:id="_z_m-pNovEdqRBPR5WyT36A" width="530" height="530"/>
+ </children>
+ <children xmi:id="_z_m-pdovEdqRBPR5WyT36A" type="Stereotype" element="_z_g4ANovEdqRBPR5WyT36A"/>
+ <children xmi:id="_z_m-ptovEdqRBPR5WyT36A" type="Kind" element="_z_g4ANovEdqRBPR5WyT36A"/>
+ <children xmi:id="_z_m-p9ovEdqRBPR5WyT36A" type="Name" element="_z_g4ANovEdqRBPR5WyT36A"/>
+ <children xmi:id="_z_m-qNovEdqRBPR5WyT36A" type="AttributeCompartment" element="_z_g4ANovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_z_m-qdovEdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_z_m-qtovEdqRBPR5WyT36A" type="OperationCompartment" element="_z_g4ANovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_z_m-q9ovEdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_z_m-rNovEdqRBPR5WyT36A" visible="false" type="SignalCompartment" element="_z_g4ANovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_z_m-rdovEdqRBPR5WyT36A"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_z_m-odovEdqRBPR5WyT36A" showStereotype="Label" useClassifierShape="true"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_z_m-otovEdqRBPR5WyT36A" x="17172" y="6996"/>
+ </children>
+ <children xmi:id="_1y-ZsNovEdqRBPR5WyT36A" sourceEdges="_3Ic-4NovEdqRBPR5WyT36A _9-BEUNo2EdqRBPR5WyT36A" targetEdges="_BkUg0dowEdqRBPR5WyT36A" element="_1yyMcNovEdqRBPR5WyT36A">
+ <children xmi:id="_1y-Zs9ovEdqRBPR5WyT36A" type="ImageCompartment" element="_1yyMcNovEdqRBPR5WyT36A">
+ <layoutConstraint xmi:type="notation:Size" xmi:id="_1y-ZtNovEdqRBPR5WyT36A" width="1320" height="1320"/>
+ </children>
+ <children xmi:id="_1y-ZtdovEdqRBPR5WyT36A" type="Stereotype" element="_1yyMcNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_1y-ZttovEdqRBPR5WyT36A" type="Name" element="_1yyMcNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_1y-Zt9ovEdqRBPR5WyT36A" type="AttributeCompartment" element="_1yyMcNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_1y-ZuNovEdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_1y-ZudovEdqRBPR5WyT36A" type="OperationCompartment" element="_1yyMcNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_1y-ZutovEdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_1y-Zu9ovEdqRBPR5WyT36A" visible="false" type="SignalCompartment" element="_1yyMcNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_1y-ZvNovEdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_1y-ZvdovEdqRBPR5WyT36A" visible="false" type="StructureCompartment" element="_1yyMcNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLShapeCompartmentStyle" xmi:id="_1y-ZvtovEdqRBPR5WyT36A"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_1y-ZsdovEdqRBPR5WyT36A" showStereotype="Label"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_1y-ZstovEdqRBPR5WyT36A" x="13992" y="12084"/>
+ </children>
+ <children xmi:id="_4WSrANovEdqRBPR5WyT36A" sourceEdges="_9XeF4tovEdqRBPR5WyT36A _9PaR4No2EdqRBPR5WyT36A" element="_4WMkYNovEdqRBPR5WyT36A">
+ <children xmi:id="_4WSrA9ovEdqRBPR5WyT36A" type="ImageCompartment" element="_4WMkYNovEdqRBPR5WyT36A">
+ <layoutConstraint xmi:type="notation:Size" xmi:id="_4WSrBNovEdqRBPR5WyT36A" width="1320" height="1320"/>
+ </children>
+ <children xmi:id="_4WSrBdovEdqRBPR5WyT36A" type="Stereotype" element="_4WMkYNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_4WSrBtovEdqRBPR5WyT36A" type="Name" element="_4WMkYNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_4WSrB9ovEdqRBPR5WyT36A" type="AttributeCompartment" element="_4WMkYNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_4WSrCNovEdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_4WSrCdovEdqRBPR5WyT36A" type="OperationCompartment" element="_4WMkYNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_4WSrCtovEdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_4WSrC9ovEdqRBPR5WyT36A" visible="false" type="SignalCompartment" element="_4WMkYNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_4WSrDNovEdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_4WSrDdovEdqRBPR5WyT36A" visible="false" type="StructureCompartment" element="_4WMkYNovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLShapeCompartmentStyle" xmi:id="_4WSrDtovEdqRBPR5WyT36A"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_4WSrAdovEdqRBPR5WyT36A" showStereotype="Label"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_4WSrAtovEdqRBPR5WyT36A" x="19716" y="12084"/>
+ </children>
+ <children xmi:id="_o2m3oNo0EdqRBPR5WyT36A" targetEdges="_9PaR4No2EdqRBPR5WyT36A _9-BEUNo2EdqRBPR5WyT36A" element="_o2gxANo0EdqRBPR5WyT36A">
+ <children xmi:id="_o2m3o9o0EdqRBPR5WyT36A" type="ImageCompartment" element="_o2gxANo0EdqRBPR5WyT36A">
+ <layoutConstraint xmi:type="notation:Size" xmi:id="_o2m3pNo0EdqRBPR5WyT36A" width="530" height="530"/>
+ </children>
+ <children xmi:id="_o2m3pdo0EdqRBPR5WyT36A" type="Stereotype" element="_o2gxANo0EdqRBPR5WyT36A"/>
+ <children xmi:id="_o2m3pto0EdqRBPR5WyT36A" type="Kind" element="_o2gxANo0EdqRBPR5WyT36A"/>
+ <children xmi:id="_o2m3p9o0EdqRBPR5WyT36A" type="Name" element="_o2gxANo0EdqRBPR5WyT36A"/>
+ <children xmi:id="_o2m3qNo0EdqRBPR5WyT36A" type="AttributeCompartment" element="_o2gxANo0EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_o2m3qdo0EdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_o2m3qto0EdqRBPR5WyT36A" type="OperationCompartment" element="_o2gxANo0EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_o2m3q9o0EdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_o2m3rNo0EdqRBPR5WyT36A" visible="false" type="SignalCompartment" element="_o2gxANo0EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_o2m3rdo0EdqRBPR5WyT36A"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_o2m3odo0EdqRBPR5WyT36A" showStereotype="Label" useClassifierShape="true"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_o2m3oto0EdqRBPR5WyT36A" x="23532" y="6996"/>
+ </children>
+ <children xmi:id="_M0FLkNo1EdqRBPR5WyT36A" targetEdges="_R5Rjwdo1EdqRBPR5WyT36A _V7zlEdo1EdqRBPR5WyT36A" element="_Mz_E8No1EdqRBPR5WyT36A">
+ <children xmi:id="_M0FLk9o1EdqRBPR5WyT36A" type="ImageCompartment" element="_Mz_E8No1EdqRBPR5WyT36A">
+ <layoutConstraint xmi:type="notation:Size" xmi:id="_M0FLlNo1EdqRBPR5WyT36A" width="530" height="530"/>
+ </children>
+ <children xmi:id="_M0FLldo1EdqRBPR5WyT36A" type="Stereotype" element="_Mz_E8No1EdqRBPR5WyT36A"/>
+ <children xmi:id="_M0FLlto1EdqRBPR5WyT36A" type="Kind" element="_Mz_E8No1EdqRBPR5WyT36A"/>
+ <children xmi:id="_M0FLl9o1EdqRBPR5WyT36A" type="Name" element="_Mz_E8No1EdqRBPR5WyT36A"/>
+ <children xmi:id="_M0FLmNo1EdqRBPR5WyT36A" type="AttributeCompartment" element="_Mz_E8No1EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_M0FLmdo1EdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_M0FLmto1EdqRBPR5WyT36A" type="OperationCompartment" element="_Mz_E8No1EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_M0FLm9o1EdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_M0FLnNo1EdqRBPR5WyT36A" visible="false" type="SignalCompartment" element="_Mz_E8No1EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_M0FLndo1EdqRBPR5WyT36A"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_M0FLkdo1EdqRBPR5WyT36A" showStereotype="Label" useClassifierShape="true"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M0FLkto1EdqRBPR5WyT36A" x="6678" y="318"/>
+ </children>
+ <children xmi:id="_TJHbANo1EdqRBPR5WyT36A" sourceEdges="_V7zlEdo1EdqRBPR5WyT36A" targetEdges="_cN4xsdo2EdqRBPR5WyT36A" element="_TI7NwNo1EdqRBPR5WyT36A">
+ <children xmi:id="_TJHbA9o1EdqRBPR5WyT36A" type="ImageCompartment" element="_TI7NwNo1EdqRBPR5WyT36A">
+ <layoutConstraint xmi:type="notation:Size" xmi:id="_TJHbBNo1EdqRBPR5WyT36A" width="530" height="530"/>
+ </children>
+ <children xmi:id="_TJHbBdo1EdqRBPR5WyT36A" type="Stereotype" element="_TI7NwNo1EdqRBPR5WyT36A"/>
+ <children xmi:id="_TJHbBto1EdqRBPR5WyT36A" type="Kind" element="_TI7NwNo1EdqRBPR5WyT36A"/>
+ <children xmi:id="_TJHbB9o1EdqRBPR5WyT36A" type="Name" element="_TI7NwNo1EdqRBPR5WyT36A"/>
+ <children xmi:id="_TJHbCNo1EdqRBPR5WyT36A" type="AttributeCompartment" element="_TI7NwNo1EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_TJHbCdo1EdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_TJHbCto1EdqRBPR5WyT36A" type="OperationCompartment" element="_TI7NwNo1EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_TJHbC9o1EdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_TJHbDNo1EdqRBPR5WyT36A" visible="false" type="SignalCompartment" element="_TI7NwNo1EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_TJHbDdo1EdqRBPR5WyT36A"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_TJHbAdo1EdqRBPR5WyT36A" showStereotype="Label" useClassifierShape="true"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_TJHbAto1EdqRBPR5WyT36A" x="16854" y="318"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLDiagramStyle" xmi:id="_al1S89ovEdqRBPR5WyT36A"/>
+ <edges xmi:id="_hmIF4dovEdqRBPR5WyT36A" element="_hmIF4NovEdqRBPR5WyT36A" source="_fs1pANovEdqRBPR5WyT36A" target="_ePDcYdovEdqRBPR5WyT36A">
+ <children xmi:id="_hmIF5NovEdqRBPR5WyT36A" type="NameLabel" element="_hmIF4NovEdqRBPR5WyT36A">
+ <children xmi:id="_hmIF5tovEdqRBPR5WyT36A" type="Stereotype" element="_hmIF4NovEdqRBPR5WyT36A"/>
+ <children xmi:id="_hmIF59ovEdqRBPR5WyT36A" type="Name" element="_hmIF4NovEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_hmIF5dovEdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_hmIF4tovEdqRBPR5WyT36A" routing="Tree" showStereotype="Text"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_hmIF49ovEdqRBPR5WyT36A" points="[26, -31, -110, 148]$[140, -148, 4, 31]"/>
+ </edges>
+ <edges xmi:id="_mu9A4dovEdqRBPR5WyT36A" element="_mu9A4NovEdqRBPR5WyT36A" source="_ikr_4NovEdqRBPR5WyT36A" target="_ePDcYdovEdqRBPR5WyT36A">
+ <children xmi:id="_mu9A5NovEdqRBPR5WyT36A" type="NameLabel" element="_mu9A4NovEdqRBPR5WyT36A">
+ <children xmi:id="_mu9A5tovEdqRBPR5WyT36A" type="Stereotype" element="_mu9A4NovEdqRBPR5WyT36A"/>
+ <children xmi:id="_mu9A59ovEdqRBPR5WyT36A" type="Name" element="_mu9A4NovEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_mu9A5dovEdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_mu9A4tovEdqRBPR5WyT36A" routing="Tree" showStereotype="Text"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_mu9A49ovEdqRBPR5WyT36A" points="[-185, -820, 2937, 3916]$[-185, -3042, 2937, 1694]$[-3255, -3042, -133, 1694]$[-3255, -3916, -133, 820]"/>
+ </edges>
+ <edges xmi:id="_pe3jwNovEdqRBPR5WyT36A" element="_peM1YNovEdqRBPR5WyT36A" source="_fs1pANovEdqRBPR5WyT36A" target="_ePDcYdovEdqRBPR5WyT36A">
+ <children xmi:id="_pe3jw9ovEdqRBPR5WyT36A" type="NameLabel" element="_peM1YNovEdqRBPR5WyT36A">
+ <children xmi:id="_pe3jxdovEdqRBPR5WyT36A" type="Stereotype" element="_peM1YNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_pe3jxtovEdqRBPR5WyT36A" type="Name" element="_peM1YNovEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_pe3jxNovEdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <children xmi:id="_pe3jx9ovEdqRBPR5WyT36A" type="ToMultiplicityLabel" element="_peM1YtovEdqRBPR5WyT36A">
+ <children xmi:id="_pe3jydovEdqRBPR5WyT36A" type="ToMultiplicity" element="_peM1YtovEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_pe3jyNovEdqRBPR5WyT36A" y="397"/>
+ </children>
+ <children xmi:id="_pe3jytovEdqRBPR5WyT36A" type="ToRoleLabel" element="_peM1YtovEdqRBPR5WyT36A">
+ <children xmi:id="_pe3jzNovEdqRBPR5WyT36A" type="ToRole" element="_peM1YtovEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_pe3jy9ovEdqRBPR5WyT36A" y="-397"/>
+ </children>
+ <children xmi:id="_pe3jzdovEdqRBPR5WyT36A" type="FromMultiplicityLabel" element="_peM1YdovEdqRBPR5WyT36A">
+ <children xmi:id="_pe3jz9ovEdqRBPR5WyT36A" type="FromMultiplicity" element="_peM1YdovEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_pe3jztovEdqRBPR5WyT36A" y="397"/>
+ </children>
+ <children xmi:id="_pe3j0NovEdqRBPR5WyT36A" type="FromRoleLabel" element="_peM1YdovEdqRBPR5WyT36A">
+ <children xmi:id="_pe3j0tovEdqRBPR5WyT36A" type="FromRole" element="_peM1YdovEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_pe3j0dovEdqRBPR5WyT36A" y="-397"/>
+ </children>
+ <children xmi:id="_pe3j09ovEdqRBPR5WyT36A" type="ToQualifierLabel" element="_peM1YtovEdqRBPR5WyT36A">
+ <children xmi:id="_pe3j1dovEdqRBPR5WyT36A" type="QualifierCompartment" element="_peM1YtovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_pe3j1tovEdqRBPR5WyT36A"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_pe3j1NovEdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <children xmi:id="_pe3j19ovEdqRBPR5WyT36A" type="FromQualifierLabel" element="_peM1YdovEdqRBPR5WyT36A">
+ <children xmi:id="_pe3j2dovEdqRBPR5WyT36A" type="QualifierCompartment" element="_peM1YdovEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_pe3j2tovEdqRBPR5WyT36A"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_pe3j2NovEdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_pe3jwdovEdqRBPR5WyT36A" showStereotype="Text"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_pe3jwtovEdqRBPR5WyT36A" points="[-317, -820, -3916, 3916]$[-1931, -4762, -5530, -26]$[2382, -4762, -1217, -26]"/>
+ </edges>
+ <edges xmi:id="_xInjYdovEdqRBPR5WyT36A" element="_xInjYNovEdqRBPR5WyT36A" source="_tZF9odovEdqRBPR5WyT36A" target="_fs1pANovEdqRBPR5WyT36A">
+ <children xmi:id="_xInjZNovEdqRBPR5WyT36A" type="NameLabel" element="_xInjYNovEdqRBPR5WyT36A">
+ <children xmi:id="_xInjZtovEdqRBPR5WyT36A" type="Stereotype" element="_xInjYNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_xInjZ9ovEdqRBPR5WyT36A" type="Name" element="_xInjYNovEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_xInjZdovEdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_xInjYtovEdqRBPR5WyT36A" showStereotype="Text"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_xInjY9ovEdqRBPR5WyT36A" points="[-4, -31, 1, 113]$[-4, -115, 1, 29]"/>
+ </edges>
+ <edges xmi:id="_3Ic-4NovEdqRBPR5WyT36A" element="_3IW4QNovEdqRBPR5WyT36A" source="_1y-ZsNovEdqRBPR5WyT36A" target="_z_m-oNovEdqRBPR5WyT36A">
+ <children xmi:id="_3Ic-49ovEdqRBPR5WyT36A" type="NameLabel" element="_3IW4QNovEdqRBPR5WyT36A">
+ <children xmi:id="_3Ic-5dovEdqRBPR5WyT36A" type="Stereotype" element="_3IW4QNovEdqRBPR5WyT36A"/>
+ <children xmi:id="_3Ic-5tovEdqRBPR5WyT36A" type="Name" element="_3IW4QNovEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_3Ic-5NovEdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_3Ic-4dovEdqRBPR5WyT36A" showStereotype="Text"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_3Ic-4tovEdqRBPR5WyT36A" points="[6, -24, -37, 154]$[-22, -170, -65, 8]"/>
+ </edges>
+ <edges xmi:id="_9XeF4tovEdqRBPR5WyT36A" element="_9XeF4NovEdqRBPR5WyT36A" source="_4WSrANovEdqRBPR5WyT36A" target="_z_m-oNovEdqRBPR5WyT36A">
+ <children xmi:id="_9XeF5dovEdqRBPR5WyT36A" type="NameLabel" element="_9XeF4NovEdqRBPR5WyT36A">
+ <children xmi:id="_9XeF59ovEdqRBPR5WyT36A" type="Stereotype" element="_9XeF4NovEdqRBPR5WyT36A"/>
+ <children xmi:id="_9XeF6NovEdqRBPR5WyT36A" type="Name" element="_9XeF4NovEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_9XeF5tovEdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_9XeF49ovEdqRBPR5WyT36A" showStereotype="Text"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_9XeF5NovEdqRBPR5WyT36A" points="[-23, -23, 162, 151]$[-121, -170, 64, 4]"/>
+ </edges>
+ <edges xmi:id="_BkUg0dowEdqRBPR5WyT36A" element="_Bj8GUNowEdqRBPR5WyT36A" source="_tZF9odovEdqRBPR5WyT36A" target="_1y-ZsNovEdqRBPR5WyT36A">
+ <children xmi:id="_BkancNowEdqRBPR5WyT36A" type="NameLabel" element="_Bj8GUNowEdqRBPR5WyT36A">
+ <children xmi:id="_BkanctowEdqRBPR5WyT36A" type="Stereotype" element="_Bj8GUNowEdqRBPR5WyT36A"/>
+ <children xmi:id="_Bkanc9owEdqRBPR5WyT36A" type="Name" element="_Bj8GUNowEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_BkancdowEdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <children xmi:id="_BkandNowEdqRBPR5WyT36A" type="ToMultiplicityLabel" element="_Bj8GUtowEdqRBPR5WyT36A">
+ <children xmi:id="_BkandtowEdqRBPR5WyT36A" type="ToMultiplicity" element="_Bj8GUtowEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_BkanddowEdqRBPR5WyT36A" y="397"/>
+ </children>
+ <children xmi:id="_Bkand9owEdqRBPR5WyT36A" type="ToRoleLabel" element="_Bj8GUtowEdqRBPR5WyT36A">
+ <children xmi:id="_BkanedowEdqRBPR5WyT36A" type="ToRole" element="_Bj8GUtowEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_BkaneNowEdqRBPR5WyT36A" y="-397"/>
+ </children>
+ <children xmi:id="_BkanetowEdqRBPR5WyT36A" type="FromMultiplicityLabel" element="_Bj8GUdowEdqRBPR5WyT36A">
+ <children xmi:id="_BkanfNowEdqRBPR5WyT36A" type="FromMultiplicity" element="_Bj8GUdowEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_Bkane9owEdqRBPR5WyT36A" y="397"/>
+ </children>
+ <children xmi:id="_BkanfdowEdqRBPR5WyT36A" type="FromRoleLabel" element="_Bj8GUdowEdqRBPR5WyT36A">
+ <children xmi:id="_Bkanf9owEdqRBPR5WyT36A" type="FromRole" element="_Bj8GUdowEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_BkanftowEdqRBPR5WyT36A" y="-397"/>
+ </children>
+ <children xmi:id="_BkangNowEdqRBPR5WyT36A" type="ToQualifierLabel" element="_Bj8GUtowEdqRBPR5WyT36A">
+ <children xmi:id="_BkangtowEdqRBPR5WyT36A" type="QualifierCompartment" element="_Bj8GUtowEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_Bkang9owEdqRBPR5WyT36A"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_BkangdowEdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <children xmi:id="_BkanhNowEdqRBPR5WyT36A" type="FromQualifierLabel" element="_Bj8GUdowEdqRBPR5WyT36A">
+ <children xmi:id="_BkanhtowEdqRBPR5WyT36A" type="QualifierCompartment" element="_Bj8GUdowEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_Bkanh9owEdqRBPR5WyT36A"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_BkanhdowEdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_BkUg0towEdqRBPR5WyT36A" showStereotype="Text"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_BkUg09owEdqRBPR5WyT36A" points="[83, -24, -490, 123]$[486, -151, -87, -4]"/>
+ </edges>
+ <edges xmi:id="_Fd3lQdowEdqRBPR5WyT36A" element="_FdlRYNowEdqRBPR5WyT36A" source="_ePDcYdovEdqRBPR5WyT36A" target="_z_m-oNovEdqRBPR5WyT36A">
+ <children xmi:id="_Fd3lRNowEdqRBPR5WyT36A" type="NameLabel" element="_FdlRYNowEdqRBPR5WyT36A">
+ <children xmi:id="_Fd3lRtowEdqRBPR5WyT36A" type="Stereotype" element="_FdlRYNowEdqRBPR5WyT36A"/>
+ <children xmi:id="_Fd3lR9owEdqRBPR5WyT36A" type="Name" element="_FdlRYNowEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_Fd3lRdowEdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <children xmi:id="_Fd3lSNowEdqRBPR5WyT36A" type="ToMultiplicityLabel" element="_FdlRYtowEdqRBPR5WyT36A">
+ <children xmi:id="_Fd3lStowEdqRBPR5WyT36A" type="ToMultiplicity" element="_FdlRYtowEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_Fd3lSdowEdqRBPR5WyT36A" y="397"/>
+ </children>
+ <children xmi:id="_Fd3lS9owEdqRBPR5WyT36A" type="ToRoleLabel" element="_FdlRYtowEdqRBPR5WyT36A">
+ <children xmi:id="_Fd3lTdowEdqRBPR5WyT36A" type="ToRole" element="_FdlRYtowEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_Fd3lTNowEdqRBPR5WyT36A" y="-397"/>
+ </children>
+ <children xmi:id="_Fd3lTtowEdqRBPR5WyT36A" type="FromMultiplicityLabel" element="_FdlRYdowEdqRBPR5WyT36A">
+ <children xmi:id="_Fd3lUNowEdqRBPR5WyT36A" type="FromMultiplicity" element="_FdlRYdowEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_Fd3lT9owEdqRBPR5WyT36A" y="397"/>
+ </children>
+ <children xmi:id="_Fd3lUdowEdqRBPR5WyT36A" type="FromRoleLabel" element="_FdlRYdowEdqRBPR5WyT36A">
+ <children xmi:id="_Fd3lU9owEdqRBPR5WyT36A" type="FromRole" element="_FdlRYdowEdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_Fd3lUtowEdqRBPR5WyT36A" y="-397"/>
+ </children>
+ <children xmi:id="_Fd3lVNowEdqRBPR5WyT36A" type="ToQualifierLabel" element="_FdlRYtowEdqRBPR5WyT36A">
+ <children xmi:id="_Fd3lVtowEdqRBPR5WyT36A" type="QualifierCompartment" element="_FdlRYtowEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_Fd3lV9owEdqRBPR5WyT36A"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_Fd3lVdowEdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <children xmi:id="_Fd3lWNowEdqRBPR5WyT36A" type="FromQualifierLabel" element="_FdlRYdowEdqRBPR5WyT36A">
+ <children xmi:id="_Fd3lWtowEdqRBPR5WyT36A" type="QualifierCompartment" element="_FdlRYdowEdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_Fd3lW9owEdqRBPR5WyT36A"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_Fd3lWdowEdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_Fd3lQtowEdqRBPR5WyT36A" showStereotype="Text"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_Fd3lQ9owEdqRBPR5WyT36A" points="[46, -11, -369, -9]$[351, -11, -64, -9]"/>
+ </edges>
+ <edges xmi:id="_R5Rjwdo1EdqRBPR5WyT36A" element="_R5RjwNo1EdqRBPR5WyT36A" source="_ePDcYdovEdqRBPR5WyT36A" target="_M0FLkNo1EdqRBPR5WyT36A">
+ <children xmi:id="_R5RjxNo1EdqRBPR5WyT36A" type="NameLabel" element="_R5RjwNo1EdqRBPR5WyT36A">
+ <children xmi:id="_R5Rjxto1EdqRBPR5WyT36A" type="Stereotype" element="_R5RjwNo1EdqRBPR5WyT36A"/>
+ <children xmi:id="_R5Rjx9o1EdqRBPR5WyT36A" type="Name" element="_R5RjwNo1EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_R5Rjxdo1EdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_R5Rjwto1EdqRBPR5WyT36A" showStereotype="Text"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_R5Rjw9o1EdqRBPR5WyT36A" points="[-2, -31, -2, 91]$[-2, -91, -2, 31]"/>
+ </edges>
+ <edges xmi:id="_V7zlEdo1EdqRBPR5WyT36A" element="_V7zlENo1EdqRBPR5WyT36A" source="_TJHbANo1EdqRBPR5WyT36A" target="_M0FLkNo1EdqRBPR5WyT36A">
+ <children xmi:id="_V7zlFNo1EdqRBPR5WyT36A" type="NameLabel" element="_V7zlENo1EdqRBPR5WyT36A">
+ <children xmi:id="_V7zlFto1EdqRBPR5WyT36A" type="Stereotype" element="_V7zlENo1EdqRBPR5WyT36A"/>
+ <children xmi:id="_V7zlF9o1EdqRBPR5WyT36A" type="Name" element="_V7zlENo1EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_V7zlFdo1EdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_V7zlEto1EdqRBPR5WyT36A" showStereotype="Text"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_V7zlE9o1EdqRBPR5WyT36A" points="[-73, 0, 339, 0]$[-457, 0, -45, 0]"/>
+ </edges>
+ <edges xmi:id="_cN4xsdo2EdqRBPR5WyT36A" targetEdges="_pdfmkNo2EdqRBPR5WyT36A" element="_cNskcNo2EdqRBPR5WyT36A" source="_z_m-oNovEdqRBPR5WyT36A" target="_TJHbANo1EdqRBPR5WyT36A">
+ <children xmi:id="_cN4xtNo2EdqRBPR5WyT36A" type="NameLabel" element="_cNskcNo2EdqRBPR5WyT36A">
+ <children xmi:id="_cN4xtto2EdqRBPR5WyT36A" type="Stereotype" element="_cNskcNo2EdqRBPR5WyT36A"/>
+ <children xmi:id="_cN4xt9o2EdqRBPR5WyT36A" type="Name" element="_cNskcNo2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_cN4xtdo2EdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <children xmi:id="_cN4xuNo2EdqRBPR5WyT36A" type="ToMultiplicityLabel" element="_cNskcto2EdqRBPR5WyT36A">
+ <children xmi:id="_cN4xuto2EdqRBPR5WyT36A" type="ToMultiplicity" element="_cNskcto2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_cN4xudo2EdqRBPR5WyT36A" y="397"/>
+ </children>
+ <children xmi:id="_cN4xu9o2EdqRBPR5WyT36A" type="ToRoleLabel" element="_cNskcto2EdqRBPR5WyT36A">
+ <children xmi:id="_cN4xvdo2EdqRBPR5WyT36A" type="ToRole" element="_cNskcto2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_cN4xvNo2EdqRBPR5WyT36A" y="-397"/>
+ </children>
+ <children xmi:id="_cN_fYNo2EdqRBPR5WyT36A" type="FromMultiplicityLabel" element="_cNskcdo2EdqRBPR5WyT36A">
+ <children xmi:id="_cN_fYto2EdqRBPR5WyT36A" type="FromMultiplicity" element="_cNskcdo2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_cN_fYdo2EdqRBPR5WyT36A" y="397"/>
+ </children>
+ <children xmi:id="_cN_fY9o2EdqRBPR5WyT36A" type="FromRoleLabel" element="_cNskcdo2EdqRBPR5WyT36A">
+ <children xmi:id="_cN_fZdo2EdqRBPR5WyT36A" type="FromRole" element="_cNskcdo2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_cN_fZNo2EdqRBPR5WyT36A" y="-397"/>
+ </children>
+ <children xmi:id="_cN_fZto2EdqRBPR5WyT36A" type="ToQualifierLabel" element="_cNskcto2EdqRBPR5WyT36A">
+ <children xmi:id="_cN_faNo2EdqRBPR5WyT36A" type="QualifierCompartment" element="_cNskcto2EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_cN_fado2EdqRBPR5WyT36A"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_cN_fZ9o2EdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <children xmi:id="_cN_fato2EdqRBPR5WyT36A" type="FromQualifierLabel" element="_cNskcdo2EdqRBPR5WyT36A">
+ <children xmi:id="_cN_fbNo2EdqRBPR5WyT36A" type="QualifierCompartment" element="_cNskcdo2EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_cN_fbdo2EdqRBPR5WyT36A"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_cN_fa9o2EdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_cN4xsto2EdqRBPR5WyT36A" showStereotype="Text"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_cN4xs9o2EdqRBPR5WyT36A" points="[-2, -29, 1, 91]$[26, -89, 29, 31]"/>
+ </edges>
+ <edges xmi:id="_pdfmkNo2EdqRBPR5WyT36A" element="_pdHMENo2EdqRBPR5WyT36A" source="_ePDcYdovEdqRBPR5WyT36A" target="_cN4xsdo2EdqRBPR5WyT36A">
+ <children xmi:id="_pdfml9o2EdqRBPR5WyT36A" type="ToMultiplicityLabel" element="_pdTZUdo2EdqRBPR5WyT36A">
+ <children xmi:id="_pdfmmdo2EdqRBPR5WyT36A" type="ToMultiplicity" element="_pdTZUdo2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_pdfmmNo2EdqRBPR5WyT36A" y="397"/>
+ </children>
+ <children xmi:id="_pdfmmto2EdqRBPR5WyT36A" type="ToRoleLabel" element="_pdTZUdo2EdqRBPR5WyT36A">
+ <children xmi:id="_pdfmnNo2EdqRBPR5WyT36A" type="ToRole" element="_pdTZUdo2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_pdfmm9o2EdqRBPR5WyT36A" y="-397"/>
+ </children>
+ <children xmi:id="_pdfmndo2EdqRBPR5WyT36A" type="FromMultiplicityLabel" element="_pdTZUNo2EdqRBPR5WyT36A">
+ <children xmi:id="_pdfmn9o2EdqRBPR5WyT36A" type="FromMultiplicity" element="_pdTZUNo2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_pdfmnto2EdqRBPR5WyT36A" y="397"/>
+ </children>
+ <children xmi:id="_pdfmoNo2EdqRBPR5WyT36A" type="FromRoleLabel" element="_pdTZUNo2EdqRBPR5WyT36A">
+ <children xmi:id="_pdfmoto2EdqRBPR5WyT36A" type="FromRole" element="_pdTZUNo2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_pdfmodo2EdqRBPR5WyT36A" y="-397"/>
+ </children>
+ <children xmi:id="_pdfmo9o2EdqRBPR5WyT36A" type="ToQualifierLabel" element="_pdTZUdo2EdqRBPR5WyT36A">
+ <children xmi:id="_pdfmpdo2EdqRBPR5WyT36A" type="QualifierCompartment" element="_pdTZUdo2EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_pdfmpto2EdqRBPR5WyT36A"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_pdfmpNo2EdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <children xmi:id="_pdfmp9o2EdqRBPR5WyT36A" type="FromQualifierLabel" element="_pdTZUNo2EdqRBPR5WyT36A">
+ <children xmi:id="_pdfmqdo2EdqRBPR5WyT36A" type="QualifierCompartment" element="_pdTZUNo2EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_pdfmqto2EdqRBPR5WyT36A"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_pdfmqNo2EdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <children xmi:id="_pdfmq9o2EdqRBPR5WyT36A" element="_pdHMENo2EdqRBPR5WyT36A">
+ <children xmi:id="_pdfmrto2EdqRBPR5WyT36A" type="ImageCompartment" element="_pdHMENo2EdqRBPR5WyT36A">
+ <layoutConstraint xmi:type="notation:Size" xmi:id="_pdfmr9o2EdqRBPR5WyT36A" width="1320" height="1320"/>
+ </children>
+ <children xmi:id="_pdfmsNo2EdqRBPR5WyT36A" type="Stereotype" element="_pdHMENo2EdqRBPR5WyT36A"/>
+ <children xmi:id="_pdfmsdo2EdqRBPR5WyT36A" type="Name" element="_pdHMENo2EdqRBPR5WyT36A"/>
+ <children xmi:id="_pdfmsto2EdqRBPR5WyT36A" type="AttributeCompartment" element="_pdHMENo2EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_pdfms9o2EdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_pdfmtNo2EdqRBPR5WyT36A" type="OperationCompartment" element="_pdHMENo2EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_pdfmtdo2EdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_pdfmtto2EdqRBPR5WyT36A" visible="false" type="SignalCompartment" element="_pdHMENo2EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_pdfmt9o2EdqRBPR5WyT36A"/>
+ </children>
+ <children xmi:id="_pdfmuNo2EdqRBPR5WyT36A" visible="false" type="StructureCompartment" element="_pdHMENo2EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLShapeCompartmentStyle" xmi:id="_pdfmudo2EdqRBPR5WyT36A"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_pdfmrNo2EdqRBPR5WyT36A" showStereotype="Label"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_pdfmrdo2EdqRBPR5WyT36A" y="1323"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_pdfmkdo2EdqRBPR5WyT36A" showStereotype="Text"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_pdfmkto2EdqRBPR5WyT36A" points="[46, 3, -366, 94]$[412, -91, 0, 0]"/>
+ <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_pdrz0No2EdqRBPR5WyT36A" id="100"/>
+ </edges>
+ <edges xmi:id="_9PaR4No2EdqRBPR5WyT36A" element="_9PH-ANo2EdqRBPR5WyT36A" source="_4WSrANovEdqRBPR5WyT36A" target="_o2m3oNo0EdqRBPR5WyT36A">
+ <children xmi:id="_9PaR49o2EdqRBPR5WyT36A" type="NameLabel" element="_9PH-ANo2EdqRBPR5WyT36A">
+ <children xmi:id="_9PaR5do2EdqRBPR5WyT36A" type="Stereotype" element="_9PH-ANo2EdqRBPR5WyT36A"/>
+ <children xmi:id="_9PaR5to2EdqRBPR5WyT36A" type="Name" element="_9PH-ANo2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_9PaR5No2EdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <children xmi:id="_9PaR59o2EdqRBPR5WyT36A" type="ToMultiplicityLabel" element="_9PH-Ato2EdqRBPR5WyT36A">
+ <children xmi:id="_9PaR6do2EdqRBPR5WyT36A" type="ToMultiplicity" element="_9PH-Ato2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_9PaR6No2EdqRBPR5WyT36A" y="397"/>
+ </children>
+ <children xmi:id="_9PaR6to2EdqRBPR5WyT36A" type="ToRoleLabel" element="_9PH-Ato2EdqRBPR5WyT36A">
+ <children xmi:id="_9PaR7No2EdqRBPR5WyT36A" type="ToRole" element="_9PH-Ato2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_9PaR69o2EdqRBPR5WyT36A" y="-397"/>
+ </children>
+ <children xmi:id="_9PaR7do2EdqRBPR5WyT36A" type="FromMultiplicityLabel" element="_9PH-Ado2EdqRBPR5WyT36A">
+ <children xmi:id="_9PaR79o2EdqRBPR5WyT36A" type="FromMultiplicity" element="_9PH-Ado2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_9PaR7to2EdqRBPR5WyT36A" y="397"/>
+ </children>
+ <children xmi:id="_9PaR8No2EdqRBPR5WyT36A" type="FromRoleLabel" element="_9PH-Ado2EdqRBPR5WyT36A">
+ <children xmi:id="_9PaR8to2EdqRBPR5WyT36A" type="FromRole" element="_9PH-Ado2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_9PaR8do2EdqRBPR5WyT36A" y="-397"/>
+ </children>
+ <children xmi:id="_9PgYgNo2EdqRBPR5WyT36A" type="ToQualifierLabel" element="_9PH-Ato2EdqRBPR5WyT36A">
+ <children xmi:id="_9PgYgto2EdqRBPR5WyT36A" type="QualifierCompartment" element="_9PH-Ato2EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_9PgYg9o2EdqRBPR5WyT36A"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_9PgYgdo2EdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <children xmi:id="_9PgYhNo2EdqRBPR5WyT36A" type="FromQualifierLabel" element="_9PH-Ado2EdqRBPR5WyT36A">
+ <children xmi:id="_9PgYhto2EdqRBPR5WyT36A" type="QualifierCompartment" element="_9PH-Ado2EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_9PgYh9o2EdqRBPR5WyT36A"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_9PgYhdo2EdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_9PaR4do2EdqRBPR5WyT36A" showStereotype="Text"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_9PaR4to2EdqRBPR5WyT36A" points="[12, -24, -94, 162]$[80, -155, -26, 31]"/>
+ </edges>
+ <edges xmi:id="_9-BEUNo2EdqRBPR5WyT36A" element="_99uwcNo2EdqRBPR5WyT36A" source="_1y-ZsNovEdqRBPR5WyT36A" target="_o2m3oNo0EdqRBPR5WyT36A">
+ <children xmi:id="_9-BEU9o2EdqRBPR5WyT36A" type="NameLabel" element="_99uwcNo2EdqRBPR5WyT36A">
+ <children xmi:id="_9-HK8No2EdqRBPR5WyT36A" type="Stereotype" element="_99uwcNo2EdqRBPR5WyT36A"/>
+ <children xmi:id="_9-HK8do2EdqRBPR5WyT36A" type="Name" element="_99uwcNo2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_9-BEVNo2EdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <children xmi:id="_9-HK8to2EdqRBPR5WyT36A" type="ToMultiplicityLabel" element="_99uwcto2EdqRBPR5WyT36A">
+ <children xmi:id="_9-HK9No2EdqRBPR5WyT36A" type="ToMultiplicity" element="_99uwcto2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_9-HK89o2EdqRBPR5WyT36A" y="397"/>
+ </children>
+ <children xmi:id="_9-HK9do2EdqRBPR5WyT36A" type="ToRoleLabel" element="_99uwcto2EdqRBPR5WyT36A">
+ <children xmi:id="_9-HK99o2EdqRBPR5WyT36A" type="ToRole" element="_99uwcto2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_9-HK9to2EdqRBPR5WyT36A" y="-397"/>
+ </children>
+ <children xmi:id="_9-HK-No2EdqRBPR5WyT36A" type="FromMultiplicityLabel" element="_99uwcdo2EdqRBPR5WyT36A">
+ <children xmi:id="_9-HK-to2EdqRBPR5WyT36A" type="FromMultiplicity" element="_99uwcdo2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_9-HK-do2EdqRBPR5WyT36A" y="397"/>
+ </children>
+ <children xmi:id="_9-HK-9o2EdqRBPR5WyT36A" type="FromRoleLabel" element="_99uwcdo2EdqRBPR5WyT36A">
+ <children xmi:id="_9-HK_do2EdqRBPR5WyT36A" type="FromRole" element="_99uwcdo2EdqRBPR5WyT36A"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_9-HK_No2EdqRBPR5WyT36A" y="-397"/>
+ </children>
+ <children xmi:id="_9-HK_to2EdqRBPR5WyT36A" type="ToQualifierLabel" element="_99uwcto2EdqRBPR5WyT36A">
+ <children xmi:id="_9-HLANo2EdqRBPR5WyT36A" type="QualifierCompartment" element="_99uwcto2EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_9-HLAdo2EdqRBPR5WyT36A"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_9-HK_9o2EdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <children xmi:id="_9-HLAto2EdqRBPR5WyT36A" type="FromQualifierLabel" element="_99uwcdo2EdqRBPR5WyT36A">
+ <children xmi:id="_9-HLBNo2EdqRBPR5WyT36A" type="QualifierCompartment" element="_99uwcdo2EdqRBPR5WyT36A">
+ <styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_9-HLBdo2EdqRBPR5WyT36A"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_9-HLA9o2EdqRBPR5WyT36A" y="-185"/>
+ </children>
+ <styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_9-BEUdo2EdqRBPR5WyT36A" showStereotype="Text"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_9-BEUto2EdqRBPR5WyT36A" points="[49, -24, -290, 162]$[404, -163, 65, 23]"/>
+ </edges>
+ </contents>
+ </eAnnotations>
+ <packageImport xmi:type="uml:ProfileApplication" xmi:id="_al1S9NovEdqRBPR5WyT36A">
+ <eAnnotations xmi:id="_al1S9dovEdqRBPR5WyT36A" source="attributes">
+ <details xmi:id="_al1S9tovEdqRBPR5WyT36A" key="version" value="0"/>
+ </eAnnotations>
+ <importedPackage xmi:type="uml:Profile" href="pathmap://UML2_PROFILES/Basic.profile.uml2#_6mFRgK86Edih9-GG5afQ0g"/>
+ <importedProfile href="pathmap://UML2_PROFILES/Basic.profile.uml2#_6mFRgK86Edih9-GG5afQ0g"/>
+ </packageImport>
+ <packageImport xmi:type="uml:ProfileApplication" xmi:id="_al1S99ovEdqRBPR5WyT36A">
+ <eAnnotations xmi:id="_al1S-NovEdqRBPR5WyT36A" source="attributes">
+ <details xmi:id="_al1S-dovEdqRBPR5WyT36A" key="version" value="0"/>
+ </eAnnotations>
+ <importedPackage xmi:type="uml:Profile" href="pathmap://UML2_PROFILES/Intermediate.profile.uml2#_Cz7csK87Edih9-GG5afQ0g"/>
+ <importedProfile href="pathmap://UML2_PROFILES/Intermediate.profile.uml2#_Cz7csK87Edih9-GG5afQ0g"/>
+ </packageImport>
+ <packageImport xmi:type="uml:ProfileApplication" xmi:id="_al1S-tovEdqRBPR5WyT36A">
+ <eAnnotations xmi:id="_al1S-9ovEdqRBPR5WyT36A" source="attributes">
+ <details xmi:id="_al1S_NovEdqRBPR5WyT36A" key="version" value="0"/>
+ </eAnnotations>
+ <importedPackage xmi:type="uml:Profile" href="pathmap://UML2_PROFILES/Complete.profile.uml2#_M7pTkK87Edih9-GG5afQ0g"/>
+ <importedProfile href="pathmap://UML2_PROFILES/Complete.profile.uml2#_M7pTkK87Edih9-GG5afQ0g"/>
+ </packageImport>
+ <packageImport xmi:type="uml:ProfileApplication" xmi:id="_al1S_dovEdqRBPR5WyT36A">
+ <eAnnotations xmi:id="_al1S_tovEdqRBPR5WyT36A" source="attributes">
+ <details xmi:id="_al1S_9ovEdqRBPR5WyT36A" key="version" value="0"/>
+ </eAnnotations>
+ <importedPackage xmi:type="uml:Profile" href="pathmap://UML2_MSL_PROFILES/Default.epx#_a_S3wNWLEdiy4IqP8whjFA?Default"/>
+ <importedProfile href="pathmap://UML2_MSL_PROFILES/Default.epx#_a_S3wNWLEdiy4IqP8whjFA?Default"/>
+ </packageImport>
+ <packageImport xmi:type="uml:ProfileApplication" xmi:id="_al1TANovEdqRBPR5WyT36A">
+ <eAnnotations xmi:id="_al1TAdovEdqRBPR5WyT36A" source="attributes">
+ <details xmi:id="_al1TAtovEdqRBPR5WyT36A" key="version" value="0"/>
+ </eAnnotations>
+ <importedPackage xmi:type="uml:Profile" href="pathmap://UML2_MSL_PROFILES/Deployment.epx#_vjbuwOvHEdiDX5bji0iVSA?Deployment"/>
+ <importedProfile href="pathmap://UML2_MSL_PROFILES/Deployment.epx#_vjbuwOvHEdiDX5bji0iVSA?Deployment"/>
+ </packageImport>
+ <packageImport xmi:id="_al1TA9ovEdqRBPR5WyT36A">
+ <importedPackage xmi:type="uml:Model" href="pathmap://UML2_LIBRARIES/UML2PrimitiveTypes.library.uml2#_EfRZoK86EdieaYgxtVWN8Q"/>
+ </packageImport>
+ <ownedMember xmi:type="uml:Interface" xmi:id="_ePDcYNovEdqRBPR5WyT36A" name="Context">
+ <generalization xmi:id="_R5RjwNo1EdqRBPR5WyT36A" general="_Mz_E8No1EdqRBPR5WyT36A"/>
+ <ownedAttribute xmi:id="_FdlRYdowEdqRBPR5WyT36A" name="scopecontext" visibility="private" type="_z_g4ANovEdqRBPR5WyT36A" association="_FdlRYNowEdqRBPR5WyT36A">
+ <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="_FdlRZNowEdqRBPR5WyT36A" value="1"/>
+ <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_FdlRY9owEdqRBPR5WyT36A"/>
+ </ownedAttribute>
+ </ownedMember>
+ <ownedMember xmi:type="uml:Interface" xmi:id="_fsviYNovEdqRBPR5WyT36A" name="CompositeContext">
+ <generalization xmi:id="_hmIF4NovEdqRBPR5WyT36A" general="_ePDcYNovEdqRBPR5WyT36A"/>
+ <ownedAttribute xmi:id="_peM1YdovEdqRBPR5WyT36A" name="context" visibility="private" type="_ePDcYNovEdqRBPR5WyT36A" association="_peM1YNovEdqRBPR5WyT36A" aggregation="composite">
+ <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="_peM1ZNovEdqRBPR5WyT36A" value="-1"/>
+ <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_peM1Y9ovEdqRBPR5WyT36A"/>
+ </ownedAttribute>
+ </ownedMember>
+ <ownedMember xmi:type="uml:Interface" xmi:id="_ikl5QNovEdqRBPR5WyT36A" name="AtomicContext">
+ <generalization xmi:id="_mu9A4NovEdqRBPR5WyT36A" general="_ePDcYNovEdqRBPR5WyT36A"/>
+ </ownedMember>
+ <ownedMember xmi:type="uml:Association" xmi:id="_peM1YNovEdqRBPR5WyT36A" memberEnd="_peM1YdovEdqRBPR5WyT36A _peM1YtovEdqRBPR5WyT36A">
+ <ownedEnd xmi:id="_peM1YtovEdqRBPR5WyT36A" visibility="private" type="_fsviYNovEdqRBPR5WyT36A" association="_peM1YNovEdqRBPR5WyT36A"/>
+ </ownedMember>
+ <ownedMember xmi:type="uml:Interface" xmi:id="_tZF9oNovEdqRBPR5WyT36A" name="DeploymentContext">
+ <generalization xmi:id="_xInjYNovEdqRBPR5WyT36A" general="_fsviYNovEdqRBPR5WyT36A"/>
+ <ownedAttribute xmi:id="_Bj8GUdowEdqRBPR5WyT36A" name="modulescopecontext" visibility="private" type="_1yyMcNovEdqRBPR5WyT36A" association="_Bj8GUNowEdqRBPR5WyT36A">
+ <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="_Bj8GVNowEdqRBPR5WyT36A" value="1"/>
+ <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_Bj8GU9owEdqRBPR5WyT36A"/>
+ </ownedAttribute>
+ </ownedMember>
+ <ownedMember xmi:type="uml:Interface" xmi:id="_z_g4ANovEdqRBPR5WyT36A" name="ScopeContext">
+ <ownedAttribute xmi:id="_cNskcdo2EdqRBPR5WyT36A" name="instancewrapper" visibility="private" type="_TI7NwNo1EdqRBPR5WyT36A" association="_cNskcNo2EdqRBPR5WyT36A">
+ <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="_cNskdNo2EdqRBPR5WyT36A" value="1"/>
+ <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_cNskc9o2EdqRBPR5WyT36A"/>
+ </ownedAttribute>
+ </ownedMember>
+ <ownedMember xmi:type="uml:Class" xmi:id="_1yyMcNovEdqRBPR5WyT36A" name="ModuleScopeContext" clientDependency="_3IW4QNovEdqRBPR5WyT36A">
+ <implementation xmi:id="_3IW4QNovEdqRBPR5WyT36A" client="_1yyMcNovEdqRBPR5WyT36A" supplier="_z_g4ANovEdqRBPR5WyT36A" realizingClassifier="_z_g4ANovEdqRBPR5WyT36A" contract="_z_g4ANovEdqRBPR5WyT36A">
+ <mapping xmi:id="_3IW4QdovEdqRBPR5WyT36A"/>
+ </implementation>
+ <ownedAttribute xmi:id="_99uwcdo2EdqRBPR5WyT36A" name="scoperegistry" visibility="private" type="_o2gxANo0EdqRBPR5WyT36A" association="_99uwcNo2EdqRBPR5WyT36A">
+ <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="_99uwdNo2EdqRBPR5WyT36A" value="1"/>
+ <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_99uwc9o2EdqRBPR5WyT36A"/>
+ </ownedAttribute>
+ </ownedMember>
+ <ownedMember xmi:type="uml:Class" xmi:id="_4WMkYNovEdqRBPR5WyT36A" name="HTTPSessionScopeContext" clientDependency="_9XeF4NovEdqRBPR5WyT36A">
+ <implementation xmi:id="_9XeF4NovEdqRBPR5WyT36A" client="_4WMkYNovEdqRBPR5WyT36A" supplier="_z_g4ANovEdqRBPR5WyT36A" realizingClassifier="_z_g4ANovEdqRBPR5WyT36A" contract="_z_g4ANovEdqRBPR5WyT36A">
+ <mapping xmi:id="_9XeF4dovEdqRBPR5WyT36A"/>
+ </implementation>
+ <ownedAttribute xmi:id="_9PH-Ado2EdqRBPR5WyT36A" name="scoperegistry" visibility="private" type="_o2gxANo0EdqRBPR5WyT36A" association="_9PH-ANo2EdqRBPR5WyT36A">
+ <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="_9PH-BNo2EdqRBPR5WyT36A" value="1"/>
+ <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_9PH-A9o2EdqRBPR5WyT36A"/>
+ </ownedAttribute>
+ </ownedMember>
+ <ownedMember xmi:type="uml:Association" xmi:id="_Bj8GUNowEdqRBPR5WyT36A" memberEnd="_Bj8GUdowEdqRBPR5WyT36A _Bj8GUtowEdqRBPR5WyT36A">
+ <ownedEnd xmi:id="_Bj8GUtowEdqRBPR5WyT36A" visibility="private" type="_tZF9oNovEdqRBPR5WyT36A" association="_Bj8GUNowEdqRBPR5WyT36A"/>
+ </ownedMember>
+ <ownedMember xmi:type="uml:Association" xmi:id="_FdlRYNowEdqRBPR5WyT36A" memberEnd="_FdlRYdowEdqRBPR5WyT36A _FdlRYtowEdqRBPR5WyT36A">
+ <ownedEnd xmi:id="_FdlRYtowEdqRBPR5WyT36A" visibility="private" type="_ePDcYNovEdqRBPR5WyT36A" association="_FdlRYNowEdqRBPR5WyT36A"/>
+ </ownedMember>
+ <ownedMember xmi:type="uml:Interface" xmi:id="_o2gxANo0EdqRBPR5WyT36A" name="ScopeRegistry"/>
+ <ownedMember xmi:type="uml:Interface" xmi:id="_Mz_E8No1EdqRBPR5WyT36A" name="Lifecycle"/>
+ <ownedMember xmi:type="uml:Interface" xmi:id="_TI7NwNo1EdqRBPR5WyT36A" name="InstanceWrapper">
+ <generalization xmi:id="_V7zlENo1EdqRBPR5WyT36A" general="_Mz_E8No1EdqRBPR5WyT36A"/>
+ </ownedMember>
+ <ownedMember xmi:type="uml:Association" xmi:id="_cNskcNo2EdqRBPR5WyT36A" memberEnd="_cNskcdo2EdqRBPR5WyT36A _cNskcto2EdqRBPR5WyT36A">
+ <ownedEnd xmi:id="_cNskcto2EdqRBPR5WyT36A" visibility="private" type="_z_g4ANovEdqRBPR5WyT36A" association="_cNskcNo2EdqRBPR5WyT36A"/>
+ </ownedMember>
+ <ownedMember xmi:type="uml:AssociationClass" xmi:id="_pdHMENo2EdqRBPR5WyT36A" name="AssociationClass1" memberEnd="_pdTZUNo2EdqRBPR5WyT36A _pdTZUdo2EdqRBPR5WyT36A">
+ <ownedEnd xmi:id="_pdTZUNo2EdqRBPR5WyT36A" visibility="private" type="_cNskcNo2EdqRBPR5WyT36A" association="_pdHMENo2EdqRBPR5WyT36A"/>
+ <ownedEnd xmi:id="_pdTZUdo2EdqRBPR5WyT36A" visibility="private" type="_ePDcYNovEdqRBPR5WyT36A" association="_pdHMENo2EdqRBPR5WyT36A"/>
+ </ownedMember>
+ <ownedMember xmi:type="uml:Association" xmi:id="_9PH-ANo2EdqRBPR5WyT36A" memberEnd="_9PH-Ado2EdqRBPR5WyT36A _9PH-Ato2EdqRBPR5WyT36A">
+ <ownedEnd xmi:id="_9PH-Ato2EdqRBPR5WyT36A" visibility="private" type="_4WMkYNovEdqRBPR5WyT36A" association="_9PH-ANo2EdqRBPR5WyT36A"/>
+ </ownedMember>
+ <ownedMember xmi:type="uml:Association" xmi:id="_99uwcNo2EdqRBPR5WyT36A" memberEnd="_99uwcdo2EdqRBPR5WyT36A _99uwcto2EdqRBPR5WyT36A">
+ <ownedEnd xmi:id="_99uwcto2EdqRBPR5WyT36A" visibility="private" type="_1yyMcNovEdqRBPR5WyT36A" association="_99uwcNo2EdqRBPR5WyT36A"/>
+ </ownedMember>
+</uml:Model>
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/AbstractLifecycle.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/AbstractLifecycle.java new file mode 100644 index 0000000000..e8597a55fc --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/AbstractLifecycle.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.spi; + +/** + * Base class providing a simple implementation of Lifecycle. + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractLifecycle implements Lifecycle { + protected volatile int lifecycleState = UNINITIALIZED; + + public int getLifecycleState() { + return lifecycleState; + } + + /** + * Set the current state of the Lifecycle. + * + * @param lifecycleState the new state + */ + protected void setLifecycleState(int lifecycleState) { + this.lifecycleState = lifecycleState; + } + + public void start() { + setLifecycleState(RUNNING); + } + + public void stop() { + setLifecycleState(STOPPED); + } + + /** + * Returns the current lifecycle as a String (for example, "RUNNING"). + * + * @return the current lifecycle as a String + */ + public String toString() { + switch (lifecycleState) { + case Lifecycle.CONFIG_ERROR: + return "CONFIG_ERROR"; + case Lifecycle.ERROR: + return "ERROR"; + case Lifecycle.INITIALIZING: + return "INITIALIZING"; + case Lifecycle.INITIALIZED: + return "INITIALIZED"; + case Lifecycle.RUNNING: + return "RUNNING"; + case Lifecycle.STOPPING: + return "STOPPING"; + case Lifecycle.STOPPED: + return "STOPPED"; + case Lifecycle.UNINITIALIZED: + return "UNINITIALIZED"; + default: + return "UNKNOWN"; + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/CoreRuntimeException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/CoreRuntimeException.java new file mode 100644 index 0000000000..641a4e5d21 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/CoreRuntimeException.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.spi; + +import org.apache.tuscany.api.TuscanyRuntimeException; + +/** + * The root exception for the runtime package. Exceptions occurring in the runtime are generally non-recoverable + * + * @version $Rev$ $Date$ + */ +public abstract class CoreRuntimeException extends TuscanyRuntimeException { + + public CoreRuntimeException() { + super(); + } + + public CoreRuntimeException(String message) { + super(message); + } + + + protected CoreRuntimeException(String message, String identifier) { + super(message, identifier); + } + + public CoreRuntimeException(String message, Throwable cause) { + super(message, cause); + } + + + protected CoreRuntimeException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + public CoreRuntimeException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/InvalidNameException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/InvalidNameException.java new file mode 100644 index 0000000000..28bc8652b2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/InvalidNameException.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.spi; + +/** + * Denotes an invalid name + * + * @version $Rev$ $Date$ + */ +public class InvalidNameException extends CoreRuntimeException { + + public InvalidNameException() { + super(); + } + + public InvalidNameException(String message) { + super(message); + } + + public InvalidNameException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidNameException(Throwable cause) { + super(cause); + } + +} + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/Lifecycle.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/Lifecycle.java new file mode 100644 index 0000000000..e8a0448e44 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/Lifecycle.java @@ -0,0 +1,69 @@ +/* + * 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.spi; + +/** + * Implementations adhere to runtime lifecycle semantics + * + * @version $Rev$ $Date$ + */ +public interface Lifecycle { + /* A configuration error state */ + int CONFIG_ERROR = -1; + /* Has not been initialized */ + int UNINITIALIZED = 0; + /* In the process of being configured and initialized */ + int INITIALIZING = 1; + /* Instantiated and configured */ + int INITIALIZED = 2; + /* Configured and initialized */ + int RUNNING = 4; + /* In the process of being shutdown */ + int STOPPING = 5; + /* Has been shutdown and removed from the composite */ + int STOPPED = 6; + /* In an error state */ + int ERROR = 7; + + /** + * Returns the lifecycle state + * + * @see #UNINITIALIZED + * @see #INITIALIZING + * @see #INITIALIZED + * @see #RUNNING + * @see #STOPPING + * @see #STOPPED + */ + int getLifecycleState(); + + /** + * Starts the Lifecycle. + * + * @throws CoreRuntimeException + */ + void start() throws CoreRuntimeException; + + /** + * Stops the Lifecycle. + * + * @throws CoreRuntimeException + */ + void stop() throws CoreRuntimeException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/ObjectCreationException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/ObjectCreationException.java new file mode 100644 index 0000000000..580e928000 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/ObjectCreationException.java @@ -0,0 +1,56 @@ +/* + * 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.spi; + +import org.apache.tuscany.api.TuscanyRuntimeException; + +/** + * Denotes an error creating a new object instance + * + * @version $Rev$ $Date$ + */ +public class ObjectCreationException extends TuscanyRuntimeException { + private static final long serialVersionUID = -6423113430265944499L; + + public ObjectCreationException() { + super(); + } + + public ObjectCreationException(String message) { + super(message); + } + + public ObjectCreationException(String message, String identifier) { + super(message, identifier); + } + + public ObjectCreationException(String message, Throwable cause) { + super(message, cause); + } + + public ObjectCreationException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + public ObjectCreationException(Throwable cause) { + super(cause); + } + +} + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/ObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/ObjectFactory.java new file mode 100644 index 0000000000..d505e14f61 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/ObjectFactory.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi; + +/** + * Implementations create new instances of a particular type + * + * @version $Rev$ $Date$ + */ +public interface ObjectFactory<T> { + + /** + * Return a instance of the type that this factory creates. + * + * @return a instance from this factory + */ + T getInstance() throws ObjectCreationException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/QualifiedName.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/QualifiedName.java new file mode 100644 index 0000000000..25e2dbbc65 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/QualifiedName.java @@ -0,0 +1,105 @@ +/* + * 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.spi; + +/** + * An evaluated name consisting of a part/port pair. In the runtime, a part generally 'contains' or 'provides' ports + * such as a component/service point or a component/reference pair. + * + * @version $Rev$ $Date$ + */ +public class QualifiedName { + public static final String NAME_SEPARATOR = "/"; + + private final String qName; + private final String fragment; + private final String partName; + private final String portName; + + /** + * Constructs a new qualified name in the form of part/port where part is the parent context and port represents a + * child, which is either a service in the case of an atomic context or a contained context in the case of a + * composite. + * + * @throws InvalidNameException if the name is in an invalid format + */ + public QualifiedName(String qualifiedName) throws InvalidNameException { + String[] parts = qualifiedName.split(NAME_SEPARATOR); + if (parts.length == 1) { + partName = parts[0]; + portName = null; + qName = partName; + fragment = partName; + } else if (parts.length == 2) { + partName = parts[0]; + portName = parts[1]; + qName = partName + '/' + portName; + fragment = partName + '#' + portName; + } else { + throw new InvalidNameException(qualifiedName); + } + } + + /** + * Constructs a qualified name using the given part/port combination + * + * @param partName the part name + * @param portName the port name + */ + public QualifiedName(String partName, String portName) { + this.partName = partName; + this.portName = portName; + if (portName == null) { + qName = partName; + fragment = partName; + } else { + qName = partName + '/' + portName; + fragment = partName + '#' + portName; + } + } + + /** + * Returns the parsed part name + */ + public String getPartName() { + return partName; + } + + /** + * Returns the parsed port name if the original is of the compound for part/port + */ + public String getPortName() { + return portName; + } + + /** + * Returns the full part/port name pair + */ + public String getQualifiedName() { + return qName; + } + + public String getFragment() { + return fragment; + } + + public String toString() { + return qName; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/bootstrap/ComponentNames.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/bootstrap/ComponentNames.java new file mode 100644 index 0000000000..347c4f4d0b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/bootstrap/ComponentNames.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.spi.bootstrap; + +import java.net.URI; + +/** + * Class that defines the names of well known component + * + * @version $Rev$ $Date$ + */ +public final class ComponentNames { + /** + * The name of the component that forms the root of the runtime tree. + */ + public static final URI TUSCANY_RUNTIME = URI.create("tuscany.runtime"); + + /** + * The name of the component that is the root of the application composite tree. + */ + public static final URI TUSCANY_APPLICATION_ROOT = URI.create("sca://root.application/"); + + /** + * The name of the component that is the root of the system composite tree. + */ + public static final URI TUSCANY_SYSTEM_ROOT = URI.create("sca://root.system/"); + + /** + * The name of the top-level component in the system composite tree. + */ + public static final URI TUSCANY_SYSTEM = TUSCANY_SYSTEM_ROOT.resolve("main/"); + + /** + * The name of the component that contains the deployer. + */ + public static final URI TUSCANY_DEPLOYER = TUSCANY_SYSTEM.resolve("deployer"); + + /** + * The name of the component that contains the deployer. + */ + public static final URI TUSCANY_WIRE_SERVICE = TUSCANY_SYSTEM.resolve("proxyService"); + + private ComponentNames() { + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/BindingBuilder.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/BindingBuilder.java new file mode 100644 index 0000000000..4b63f6d7e9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/BindingBuilder.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.builder; + +import org.apache.tuscany.spi.component.ReferenceBinding; +import org.apache.tuscany.spi.component.ServiceBinding; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.BindingDefinition; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceDefinition; + +/** + * Responsible for processing a service or reference in an assembly configured with a particular binding. The builder + * will create and return corresponding {@link org.apache.tuscany.spi.component.ServiceBinding} or {@link + * org.apache.tuscany.spi.component.ReferenceBinding} + * + * @version $Rev$ $Date$ + */ +public interface BindingBuilder<B extends BindingDefinition> { + + /** + * Creates a service binding + * + * @param serviceDefinition the service the binding is configured for + * @param bindingDefinition the binding definition + * @param context the current deployment context + * @return a service binding + * @throws BuilderException + */ + ServiceBinding build(ServiceDefinition serviceDefinition, B bindingDefinition, DeploymentContext context) + throws BuilderException; + + /** + * Creates a reference binding + * + * @param referenceDefinition the reference the binding is configured for + * @param bindingDefinition the binding definition + * @param context the current deployment context + * @return a reference binding + * @throws BuilderException + */ + ReferenceBinding build(ReferenceDefinition referenceDefinition, B bindingDefinition, DeploymentContext context) + throws BuilderException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/Builder.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/Builder.java new file mode 100644 index 0000000000..4433a4689c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/Builder.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.builder; + +import org.apache.tuscany.spi.component.Component; +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.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceDefinition; + +/** + * Implementations build <code>SCAObject</code> types from model objects. + * + * @version $Rev$ $Date$ + */ +public interface Builder { + /** + * Builds a <code>Component</code> from a <code>ComponentDefinition</code> + * + * @param definition the component definition as parsed from an SCA assembly + * @param context the current deployment context + * @return the newly created component + * @throws BuilderException + */ + <I extends Implementation<?>> Component build(ComponentDefinition<I> definition, DeploymentContext context) + throws BuilderException; + + /** + * Builds a <code>Service</code> and its bindings from a <code>BoundServiceDefinition</code> + * + * @param definition the service definition as parsed from an SCA assembly + * @param context the current deployment context + * @return the newly created service + * @throws BuilderException + */ + Service build(ServiceDefinition definition, DeploymentContext context) throws BuilderException; + + /** + * Builds a <code>Reference</code> and its bindings from a <code>BoundReferenceDefinition</code> + * + * @param definition the reference definition as parsed from an SCA assembly + * @param context the current deployment context + * @return the newly created reference + * @throws BuilderException + */ + Reference build(ReferenceDefinition definition, DeploymentContext context) throws BuilderException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderConfigException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderConfigException.java new file mode 100644 index 0000000000..6e9f2ef95d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderConfigException.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.spi.builder; + +/** + * Represents an error processing an assembly model + * + * @version $Rev$ $Date$ + */ +public class BuilderConfigException extends BuilderException { + + public BuilderConfigException() { + super(); + } + + public BuilderConfigException(String message) { + super(message); + } + + public BuilderConfigException(String message, String identifier) { + super(message, identifier); + } + + public BuilderConfigException(String message, Throwable cause) { + super(message, cause); + } + + public BuilderConfigException(Throwable cause) { + super(cause); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderException.java new file mode 100644 index 0000000000..846d52492c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderException.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.spi.builder; + +import org.apache.tuscany.api.TuscanyException; + +/** + * The root exception for the builder package. Builder exceptions denote a non-recoverable failure. + * + * @version $Rev$ $Date$ + */ +public abstract class BuilderException extends TuscanyException { + + public BuilderException() { + super(); + } + + public BuilderException(String message) { + super(message); + } + + + protected BuilderException(String message, String identifier) { + super(message, identifier); + } + + public BuilderException(String message, Throwable cause) { + super(message, cause); + } + + protected BuilderException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + public BuilderException(Throwable cause) { + super(cause); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderInstantiationException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderInstantiationException.java new file mode 100644 index 0000000000..30957635db --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderInstantiationException.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.builder; + +/** + * Denotes an error instantiating an <code>SCAObject</code> + * + * @version $Rev$ $Date$ + */ +public class BuilderInstantiationException extends BuilderException { + + public BuilderInstantiationException(String message, String identifier) { + super(message, identifier); + } + + public BuilderInstantiationException(String message, Throwable cause) { + super(message, cause); + } + + public BuilderInstantiationException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderRegistry.java new file mode 100644 index 0000000000..c4ecdfa35b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/BuilderRegistry.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.spi.builder; + +import org.apache.tuscany.spi.model.BindingDefinition; +import org.apache.tuscany.spi.model.Implementation; + +/** + * Maintains a registry of builders in the runtime, dispatching to the appropriate one as an assembly model is processed + * into runtime artifacts + * + * @version $Rev$ $Date$ + */ +public interface BuilderRegistry extends Builder { + + /** + * Register a builder for an implementation type. + * + * @param implClass the type of implementation that this builder can handle + * @param builder the builder to be registered + */ + <I extends Implementation<?>> void register(Class<I> implClass, ComponentBuilder<I> builder); + + /** + * Unregister a builder for an implementation type. + * + * @param implClass the implementation whose builder should be unregistered + */ + <I extends Implementation<?>> void unregister(Class<I> implClass); + + /** + * Register a binding builder for a binding type + * + * @param implClass the binding type + * @param builder the buinder to be registered + */ + <B extends BindingDefinition> void register(Class<B> implClass, BindingBuilder<B> builder); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/ComponentBuilder.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/ComponentBuilder.java new file mode 100644 index 0000000000..b381adddc4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/ComponentBuilder.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.spi.builder; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Implementation; + +/** + * Responsible for building a {@link Component} from an component definition + * + * @version $Rev$ $Date$ + */ +public interface ComponentBuilder<I extends Implementation<?>> { + + /** + * Builds the component + * + * @param componentDefinition the component definition + * @param context the deployment context + * @return the built component + * @throws BuilderException + */ + Component build(ComponentDefinition<I> componentDefinition, DeploymentContext context) throws BuilderException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/Connector.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/Connector.java new file mode 100644 index 0000000000..ecc56c5630 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/Connector.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.spi.builder; + +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.physical.PhysicalWireDefinition; + +/** + * Implementations are responsible for creating a wires between source and target artifacts + * + * @version $$Rev$$ $$Date$$ + */ +public interface Connector { + + /** + * Recursively connects component references and its children. This method will eventially be replaced by one that + * just takes a WireDefinition + * + * @param definition the component definition to connect + * @throws WiringException + * @deprecated + */ + void connect(ComponentDefinition<? extends Implementation<?>> definition) throws WiringException; + + /** + * Placeholder for the connect operation using federated deployment + * + * @param definition metadata describing the wire to create + * @throws WiringException + */ + void connect(PhysicalWireDefinition definition) throws WiringException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/InvalidServiceInterfaceException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/InvalidServiceInterfaceException.java new file mode 100644 index 0000000000..78bb5a5cc8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/InvalidServiceInterfaceException.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.builder; + +/** + * @version $Rev$ $Date$ + */ +public class InvalidServiceInterfaceException extends BuilderConfigException { + private final Class<?> interfaceClass; + + public InvalidServiceInterfaceException(String message, Class<?> interfaceClass) { + super(message); + this.interfaceClass = interfaceClass; + } + + public Class<?> getInterfaceClass() { + return interfaceClass; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/MissingWireTargetException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/MissingWireTargetException.java new file mode 100644 index 0000000000..dcb0068b9d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/MissingWireTargetException.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.spi.builder; + +import java.net.URI; + +/** + * Denotes a missing wire target in an assembly + * + * @version $Rev$ $Date$ + */ +public class MissingWireTargetException extends WiringException { + + public MissingWireTargetException(String message) { + super(message); + } + + public MissingWireTargetException(String message, URI sourceUri, URI targetUri) { + super(message, sourceUri, targetUri); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/ScopeNotFoundException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/ScopeNotFoundException.java new file mode 100644 index 0000000000..acf8dadda6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/ScopeNotFoundException.java @@ -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. + */ +package org.apache.tuscany.spi.builder; + +/** + * @version $Rev$ $Date$ + */ +public class ScopeNotFoundException extends BuilderConfigException { + + public ScopeNotFoundException(String scope) { + super("Scope not found", scope); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/WiringException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/WiringException.java new file mode 100644 index 0000000000..f692eb1084 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/WiringException.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.spi.builder; + +import java.net.URI; + + +/** + * Denotes a general error raised during wiring + * + * @version $Rev$ $Date$ + */ +public abstract class WiringException extends BuilderException { + private final URI sourceUri; + private final URI targetUri; + + protected WiringException(String message) { + super(message); + sourceUri = null; + targetUri = null; + } + + protected WiringException(String message, URI sourceUri, URI targetUri) { + super(message); + this.sourceUri = sourceUri; + this.targetUri = targetUri; + } + + protected WiringException(String message, URI sourceUri, URI targetUri, Throwable cause) { + super(message, cause); + this.sourceUri = sourceUri; + this.targetUri = targetUri; + } + + protected WiringException(String message, String identifier, URI sourceUri, URI targetUri) { + super(message, identifier); + this.sourceUri = sourceUri; + this.targetUri = targetUri; + } + + /** + * Returns the source name for the wire + * + * @return the source name the source name for the wire + */ + public URI getSourceUri() { + return sourceUri; + } + + /** + * Returns the target name for the wire + * + * @return the target name the source name for the wire + */ + public URI getTargetUri() { + return targetUri; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/physical/PhysicalComponentBuilder.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/physical/PhysicalComponentBuilder.java new file mode 100644 index 0000000000..065b7e793c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/physical/PhysicalComponentBuilder.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.spi.builder.physical; + +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.model.physical.PhysicalComponentDefinition; + +/** + * Interface for building components from physical component definitions. + * + * @version $Rev$ $Date$ + */ +public interface PhysicalComponentBuilder<PCD extends PhysicalComponentDefinition, C extends Component> { + + /** + * Builds a component from its physical component definition. + * + * @param componentDefinition Physical component definition of the component + * to be built. + * @return A component instance that is ready to go live. + * @throws BuilderException If unable to build the component. + */ + C build(PCD componentDefinition) throws BuilderException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/physical/PhysicalComponentBuilderRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/physical/PhysicalComponentBuilderRegistry.java new file mode 100644 index 0000000000..0bf5594fcc --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/builder/physical/PhysicalComponentBuilderRegistry.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.spi.builder.physical; + +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.model.physical.PhysicalComponentDefinition; + +/** + * A registry of physical component builders. + * + * @version $Rev$ $Date$ + */ +public interface PhysicalComponentBuilderRegistry { + + /** + * Registers a physical component builder. + * + * @param <PCD> Type of the physical component definition. + * @param definitionClass Class of the physical component definition. + * @param builder Builder for the physical component definition. + */ + <PCD extends PhysicalComponentDefinition, C extends Component> void register(Class<PCD> definitionClass, + PhysicalComponentBuilder<PCD, + C> builder); + + /** + * Builds a physical component from component definition. + * @param componentDefinition Component definition. + * @return Component to be built. + */ + Component build(PhysicalComponentDefinition componentDefinition) throws BuilderException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/AbstractSCAObject.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/AbstractSCAObject.java new file mode 100644 index 0000000000..d13626ad03 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/AbstractSCAObject.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.spi.component; + +import java.net.URI; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.apache.tuscany.spi.AbstractLifecycle; +import org.apache.tuscany.spi.event.Event; +import org.apache.tuscany.spi.event.EventFilter; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.event.TrueFilter; + +/** + * Functionality common to all <code>SCAObject<code> implementations + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractSCAObject extends AbstractLifecycle implements SCAObject { + protected static final EventFilter TRUE_FILTER = new TrueFilter(); + protected Map<EventFilter, List<RuntimeEventListener>> listeners; + protected final URI uri; + + public AbstractSCAObject(URI uri) { + assert uri != null; + this.uri = uri; + } + + public URI getUri() { + return uri; + } + + public void addListener(RuntimeEventListener listener) { + addListener(TRUE_FILTER, listener); + } + + public void removeListener(RuntimeEventListener listener) { + assert listener != null : "Listener cannot be null"; + synchronized (getListeners()) { + for (List<RuntimeEventListener> currentList : getListeners().values()) { + for (RuntimeEventListener current : currentList) { + if (current == listener) { + currentList.remove(current); + return; + } + } + } + } + } + + public void addListener(EventFilter filter, RuntimeEventListener listener) { + assert listener != null : "Listener cannot be null"; + synchronized (getListeners()) { + List<RuntimeEventListener> list = getListeners().get(filter); + if (list == null) { + list = new CopyOnWriteArrayList<RuntimeEventListener>(); + listeners.put(filter, list); + } + list.add(listener); + } + } + + public void publish(Event event) { + assert event != null : "Event object was null"; + for (Map.Entry<EventFilter, List<RuntimeEventListener>> entry : getListeners().entrySet()) { + if (entry.getKey().match(event)) { + for (RuntimeEventListener listener : entry.getValue()) { + listener.onEvent(event); + } + } + } + } + + protected Map<EventFilter, List<RuntimeEventListener>> getListeners() { + if (listeners == null) { + listeners = new ConcurrentHashMap<EventFilter, List<RuntimeEventListener>>(); + } + return listeners; + } + + public String toString() { + return "[" + uri.toString() + "] in state [" + super.toString() + ']'; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/AtomicComponent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/AtomicComponent.java new file mode 100644 index 0000000000..4c3fab8666 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/AtomicComponent.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.spi.component; + +import org.apache.tuscany.spi.ObjectCreationException; + +/** + * The runtime instantiation of an SCA atomic, or leaf-type, component + * + * @version $Rev$ $Date$ + */ +public interface AtomicComponent extends Component { + + /** + * Returns true if component instances should be eagerly initialized. + * + * @return true if component instances should be eagerly initialized + */ + boolean isEagerInit(); + + /** + * Returns true if component instances receive destroy events. + * + * @return true if component instances receive destroy events + */ + boolean isDestroyable(); + + /** + * Returns the initialization level for this component. + * + * @return the initialization level for this component + */ + int getInitLevel(); + + /** + * Returns the idle time allowed between operations in milliseconds if the implementation is conversational. + * + * @return the idle time allowed between operations in milliseconds if the implementation is conversational + */ + long getMaxIdleTime(); + + /** + * Returns the maximum age a conversation may remain active in milliseconds if the implementation is + * conversational. + * + * @return the maximum age a conversation may remain active in milliseconds if the implementation is conversational + */ + long getMaxAge(); + + /** + * Notifies the given instance of an initialization event. + * + * @throws TargetInitializationException + */ + void init(Object instance) throws TargetInitializationException; + + /** + * Notifies the given instance of a destroy event. + * + * @throws TargetDestructionException + */ + void destroy(Object instance) throws TargetDestructionException; + + /** + * Creates a new implementation instance, generally used as a callback by a {@link + * org.apache.tuscany.spi.component.ScopeContainer}. + * + * @return the instance + * @throws ObjectCreationException + */ + Object createInstance() throws ObjectCreationException; + + /** + * Removes an implementation instance associated with the current invocation context. + * + * @throws ComponentException + */ + void removeInstance() throws ComponentException; + + /** + * Returns the target instance associated with the component. A target instance is the actual object a request is + * dispatched to sans wire chain. + * + * @throws TargetResolutionException + */ + Object getTargetInstance() throws TargetResolutionException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/Component.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/Component.java new file mode 100644 index 0000000000..f61f80e228 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/Component.java @@ -0,0 +1,139 @@ +/* + * 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.spi.component; + +import java.util.List; +import java.util.Map; + +import org.osoa.sca.ComponentContext; + +import org.apache.tuscany.spi.model.PropertyValue; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.wire.Wire; + +/** + * The runtime instantiation of an SCA component + * + * @version $$Rev$$ $$Date$$ + */ +public interface Component extends Invocable { + + /** + * Returns the component scope + * + * @return the component scope + */ + Scope getScope(); + + /** + * Returns the SCA ComponentContext for this component. + * + * @return the SCA ComponentContext for this component + */ + ComponentContext getComponentContext(); + + /** + * Sets the scope container associated with the component + * + * @param scopeContainer the scope container associated with the component + */ + void setScopeContainer(ScopeContainer scopeContainer); + + /** + * Returns a collection of wires for the component associated with a reference name + * + * @return a collection of wires for the component associated with a reference name + */ + List<Wire> getWires(String name); + + /** + * Returns the default property values associated with the component. + * + * @return default property values associated with the component. + */ + Map<String, PropertyValue<?>> getDefaultPropertyValues(); + + /** + * Sets the default property values associated with the component. + * + * @param defaultPropertyValues Default property values associated with the component. + */ + void setDefaultPropertyValues(Map<String, PropertyValue<?>> defaultPropertyValues); + + /** + * Returns true if invocation dispatching can be optimized, i.e. invocation chains are not required + * + * @return true if invocation dispatching can be optimized, i.e. invocation chains are not required + */ + boolean isOptimizable(); + + /** + * Registers a service of this composite. + * + * @param service the service to add as a child + * @throws RegistrationException + */ + void register(Service service) throws RegistrationException; + + /** + * Registers a reference of this composite. + * + * @param reference the reference to add as a child + * @throws RegistrationException + */ + void register(Reference reference) throws RegistrationException; + + /** + * Returns the service with the given name or null if not found + * + * @param name the service name which is relative to the composite + * @return the service with the given name or null if not found + */ + Service getService(String name); + + /** + * Returns the reference with the given name or null if not found + * + * @param name the reference name which is relative to the composite + * @return the reference with the given name or null if not found + */ + Reference getReference(String name); + + /** + * Attaches a callback wire to the comoponent + * + * @param wire the wire to attach + */ + void attachCallbackWire(Wire wire); + + /** + * Attaches a wire to a component reference + * + * @param wire the wire to attach + */ + void attachWire(Wire wire); + + /** + * Attaches a set of wires to a comoponent reference. Used for multiplicity. + * + * @param wires the wire to attach + */ + void attachWires(List<Wire> wires); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ComponentException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ComponentException.java new file mode 100644 index 0000000000..2007cbb6bc --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ComponentException.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.spi.component; + +import org.apache.tuscany.api.TuscanyException; + +/** + * An checked exception encountered by an {@link org.apache.tuscany.spi.component.Component} + * + * @version $Rev$ $Date$ + */ +public abstract class ComponentException extends TuscanyException { + + protected ComponentException() { + } + + protected ComponentException(String message) { + super(message); + } + + protected ComponentException(String message, String identifier) { + super(message, identifier); + } + + protected ComponentException(String message, Throwable cause) { + super(message, cause); + } + + protected ComponentException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + protected ComponentException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ComponentRuntimeException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ComponentRuntimeException.java new file mode 100644 index 0000000000..8479681c75 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ComponentRuntimeException.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.spi.component; + +import org.apache.tuscany.spi.CoreRuntimeException; + +/** + * An unchecked exception encountered by an {@link org.apache.tuscany.spi.component.Component} + * + * @version $Rev$ $Date$ + */ +public abstract class ComponentRuntimeException extends CoreRuntimeException { + + public ComponentRuntimeException() { + super(); + } + + public ComponentRuntimeException(String message) { + super(message); + } + + public ComponentRuntimeException(String message, String identifier) { + super(message, identifier); + } + + public ComponentRuntimeException(String message, Throwable cause) { + super(message, cause); + } + + public ComponentRuntimeException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + public ComponentRuntimeException(Throwable cause) { + super(cause); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/DuplicateNameException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/DuplicateNameException.java new file mode 100644 index 0000000000..b9ee834b55 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/DuplicateNameException.java @@ -0,0 +1,36 @@ +/* + * 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.spi.component; + +/** + * Denotes an attempt to add an child to a composite component with a name equal to an existing child + * + * @version $Rev$ $Date$ + */ +public class DuplicateNameException extends RegistrationException { + + public DuplicateNameException(String message) { + super(message); + } + + public DuplicateNameException(String message, String identifier) { + super(message, identifier); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/IllegalTargetException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/IllegalTargetException.java new file mode 100644 index 0000000000..7eb37c3639 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/IllegalTargetException.java @@ -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. + */ +package org.apache.tuscany.spi.component; + +/** + * Thrown when a target for an operation is not of the required type + * + * @version $$Rev$$ $$Date$$ + */ +public class IllegalTargetException extends TargetResolutionException { + + public IllegalTargetException(String message, String identifier) { + super(message, identifier); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/InvalidAutowireInterface.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/InvalidAutowireInterface.java new file mode 100644 index 0000000000..20e5732dd4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/InvalidAutowireInterface.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.spi.component; + +/** + * Thrown when an invalid interface is specified during autowire registration + * + * @version $Rev$ $Date$ + */ +public class InvalidAutowireInterface extends RegistrationException { + + public InvalidAutowireInterface(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/InvalidConversationSequenceException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/InvalidConversationSequenceException.java new file mode 100644 index 0000000000..21a1712e1a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/InvalidConversationSequenceException.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.spi.component; + +/** + * Denotes an unknown operation sequence in a conversation + * + * @version $Rev$ $Date$ + */ +public class InvalidConversationSequenceException extends TargetInvocationException { + + public InvalidConversationSequenceException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/Invocable.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/Invocable.java new file mode 100644 index 0000000000..6a38bbddec --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/Invocable.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.component; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.TargetInvoker; + +/** + * @version $Rev$ $Date$ + */ +public interface Invocable extends SCAObject { + + /** + * Callback to create a {@link org.apache.tuscany.spi.wire.TargetInvoker} which dispatches to a service offered this + * artifact + * + * @param targetName the service name + * @param operation the operation to invoke + * @return the target invoker + * @throws TargetInvokerCreationException + */ + TargetInvoker createTargetInvoker(String targetName, Operation operation) throws TargetInvokerCreationException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/MalformedNameException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/MalformedNameException.java new file mode 100644 index 0000000000..de5225d12b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/MalformedNameException.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.component; + +/** + * Denotes an attempt to add a child to a composite component with an illegal name + * + * @version $Rev$ $Date$ + */ +public class MalformedNameException extends RegistrationException { + + public MalformedNameException(Throwable e) { + super("Malformed name", e); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/PersistenceException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/PersistenceException.java new file mode 100644 index 0000000000..06940aaff7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/PersistenceException.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.spi.component; + +/** + * Raised when an error persisting a component implementation instance is encountered + * + * @version $Rev$ $Date$ + */ +public class PersistenceException extends ComponentException { + public PersistenceException() { + } + + public PersistenceException(String message) { + super(message); + } + + public PersistenceException(String message, Throwable cause) { + super(message, cause); + } + + public PersistenceException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ReactivationException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ReactivationException.java new file mode 100644 index 0000000000..4ef0929422 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ReactivationException.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.spi.component; + +/** + * Raised when an error is encountered reactivating a serialized instance + * + * @version $Rev$ $Date$ + */ +public class ReactivationException extends ComponentRuntimeException { + private String owner; + + public ReactivationException(String message) { + super(message); + } + + public ReactivationException(String message, String identifier, String ower) { + super(message, identifier); + this.owner = ower; + } + + public ReactivationException(Throwable cause) { + super(cause); + } + + public String getOwner() { + return owner; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/Reference.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/Reference.java new file mode 100644 index 0000000000..67bb6eabaf --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/Reference.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.spi.component; + +import java.util.List; + +import org.apache.tuscany.spi.model.ServiceContract; + +/** + * The runtime instantiation of an SCA reference + * + * @version $Rev$ $Date$ + */ +public interface Reference extends SCAObject { + + /** + * Returns the contract for the reference. + * + * @return the contract for the reference. + */ + ServiceContract<?> getServiceContract(); + + /** + * Returns the collection of bindings configured for the reference. + * + * @return the collection of bindings configured for the reference. + */ + List<ReferenceBinding> getReferenceBindings(); + + /** + * Adds a binding the reference is configured with. + * + * @param binding the binding the reference is configured with. + */ + void addReferenceBinding(ReferenceBinding binding); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ReferenceBinding.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ReferenceBinding.java new file mode 100644 index 0000000000..eeec11f013 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ReferenceBinding.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.spi.component; + +import java.net.URI; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.Wire; + +/** + * Manages an SCA reference configured with a binding + * + * @version $Rev$ $Date$ + */ +public interface ReferenceBinding extends Invocable { + + /** + * Returns the binding qualified name + * + * @return the binding qualified name + */ + QName getBindingType(); + + /** + * Returns the wire for flowing a request through the reference + */ + Wire getWire(); + + /** + * Sets the wire wire for flowing a request through the reference + */ + void setWire(Wire wire); + + /** + * Returns the service contract for the binding + * + * @return the service contract for the binding + */ + ServiceContract<?> getBindingServiceContract(); + + /** + * Returns the target URI for the binding + * + * @return the target URI for the binding + */ + URI getTargetUri(); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/RegistrationException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/RegistrationException.java new file mode 100644 index 0000000000..b776c49c00 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/RegistrationException.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.spi.component; + +/** + * Thrown when an error is encountered registering a service or reference on a composite + * + * @version $$Rev$$ $$Date$$ + */ +public abstract class RegistrationException extends ComponentException { + public RegistrationException() { + } + + public RegistrationException(String message) { + super(message); + } + + public RegistrationException(String message, String identifier) { + super(message, identifier); + } + + public RegistrationException(String message, Throwable cause) { + super(message, cause); + } + + public RegistrationException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/SCAExternalizable.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/SCAExternalizable.java new file mode 100644 index 0000000000..6454e66369 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/SCAExternalizable.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.spi.component; + +/** + * A serialization contract for runtime SCA artifacts. When an instance is deserialized, runtime services defined in + * this contract must be set before reactivating the instance + * + * @version $Rev$ $Date$ + */ +public interface SCAExternalizable { + + /** + * Sets the current work context + * + * @param context the current work context + */ + void setWorkContext(WorkContext context); + + /** + * Callback after all values have been set prior to making the instance available in the runtime + * + * @throws org.apache.tuscany.spi.component.ReactivationException + * + */ + void reactivate() throws ReactivationException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/SCAObject.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/SCAObject.java new file mode 100644 index 0000000000..d92385cd6f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/SCAObject.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.component; + +import java.net.URI; + +import org.apache.tuscany.spi.Lifecycle; +import org.apache.tuscany.spi.event.EventPublisher; + +/** + * Represents the base SCA artifact type in an assembly + * + * @version $Rev$ $Date$ + */ +public interface SCAObject extends EventPublisher, Lifecycle { + + /** + * Returns the artifact URI + * + * @return the artifact URI + */ + URI getUri(); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/SCAObjectInputStream.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/SCAObjectInputStream.java new file mode 100644 index 0000000000..052a1d053b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/SCAObjectInputStream.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.spi.component; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectStreamClass; + +/** + * Deserializes an object based on the thread context classloader and provides special handling for {@link + * SCAExternalizable} + * + * @version $Rev$ $Date$ + */ +public class SCAObjectInputStream extends ObjectInputStream { + private final ClassLoader classLoader; + private WorkContext context; + + public SCAObjectInputStream(InputStream in, WorkContext context) throws IOException, SecurityException { + super(in); + this.context = context; + this.classLoader = Thread.currentThread().getContextClassLoader(); + enableResolveObject(true); + } + + protected Class resolveClass(ObjectStreamClass streamClass) throws IOException, ClassNotFoundException { + return classLoader.loadClass(streamClass.getName()); + } + + protected Object resolveObject(Object obj) throws IOException { + if (obj instanceof SCAExternalizable) { + SCAExternalizable ext = (SCAExternalizable) obj; + ext.setWorkContext(context); + ext.reactivate(); + } + return obj; + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/SCAObjectStartException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/SCAObjectStartException.java new file mode 100644 index 0000000000..a712b1b0eb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/SCAObjectStartException.java @@ -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. + */ +package org.apache.tuscany.spi.component; + +import org.apache.tuscany.spi.CoreRuntimeException; + +/** + * Denotes an error starting an SCAObject + * + * @version $Rev$ $Date$ + */ +public class SCAObjectStartException extends CoreRuntimeException { + + public SCAObjectStartException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/SCAObjectStopException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/SCAObjectStopException.java new file mode 100644 index 0000000000..9f430bc414 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/SCAObjectStopException.java @@ -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. + */ +package org.apache.tuscany.spi.component; + +import org.apache.tuscany.spi.CoreRuntimeException; + +/** + * Denotes an error stopping an SCAObject + * + * @version $Rev$ $Date$ + */ +public class SCAObjectStopException extends CoreRuntimeException { + + public SCAObjectStopException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ScopeContainer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ScopeContainer.java new file mode 100644 index 0000000000..8b67dfa696 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ScopeContainer.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.spi.component; + +import org.apache.tuscany.spi.Lifecycle; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.model.Scope; + + +/** + * Manages the lifecycle and visibility of instances associated with a an {@link AtomicComponent}. + * + * @version $Rev$ $Date$ + */ +public interface ScopeContainer extends Lifecycle, RuntimeEventListener { + + /** + * Returns the scope value representing the scope context + */ + Scope getScope(); + + /** + * Registers a component with the scope component + */ + void register(AtomicComponent component); + + /** + * Returns an implementation instance associated with the current request context, creating one if necessary + * + * @throws TargetResolutionException + */ + Object getInstance(AtomicComponent component) throws TargetResolutionException; + + /** + * Returns an implementation instance associated with the current context. If no instance is found, a {@link + * TargetNotFoundException} is thrown + * + * @throws TargetResolutionException + */ + Object getAssociatedInstance(AtomicComponent component) throws TargetResolutionException; + + /** + * Persists a new component implementation instance, equivalent to an insert or append operation + * + * @param component the owning component + * @param id the id associated with the instance + * @param instance the instance to persist + * @param expiration the expiration in milliseconds + * @throws PersistenceException + */ + void persistNew(AtomicComponent component, String id, Object instance, long expiration) throws PersistenceException; + + /** + * Persists a component implementation instance, equivalent to an update operation + * + * @param component the owning component + * @param id the id associated with the instance + * @param instance the instance to persist + * @param expiration the expiration in milliseconds + * @throws PersistenceException + */ + void persist(AtomicComponent component, String id, Object instance, long expiration) throws PersistenceException; + + /** + * Removes a component implementation instance associated with the current context from persistent storage + * + * @param component the owning component + * @throws PersistenceException + */ + void remove(AtomicComponent component) throws PersistenceException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ScopeContainerMonitor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ScopeContainerMonitor.java new file mode 100644 index 0000000000..3e7649d59e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ScopeContainerMonitor.java @@ -0,0 +1,36 @@ +/* + * 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.spi.component; + +import org.apache.tuscany.api.annotation.LogLevel; + +/** + * Defines monitor events for scope containers + * + * @version $Rev$ $Date$ + */ +public interface ScopeContainerMonitor { + + @LogLevel("SEVERE") + void eagerInitializationError(Exception e); + + @LogLevel("SEVERE") + void destructionError(TargetDestructionException e); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ScopeRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ScopeRegistry.java new file mode 100644 index 0000000000..181b094403 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ScopeRegistry.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.spi.component; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.model.Scope; + +/** + * Manages {@link ScopeContainer}s in the runtime + * + * @version $$Rev$$ $$Date$$ + */ +public interface ScopeRegistry { + + /** + * Returns the scope container for the given scope or null if one not found + * + * @param scope the scope + * @return the scope container for the given scope or null if one not found + */ + ScopeContainer getScopeContainer(Scope scope); + + <T extends ScopeContainer> void registerFactory(Scope scope, ObjectFactory<T> factory); + + void deregisterFactory(Scope scope); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/Service.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/Service.java new file mode 100644 index 0000000000..714a0a4313 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/Service.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.spi.component; + +import java.util.List; + +import org.apache.tuscany.spi.model.ServiceContract; + +/** + * The runtime instantiation of an SCA service + * + * @version $Rev$ $Date$ + */ +public interface Service extends SCAObject { + + /** + * Returns the contract for the service. + * + * @return the contract for the service. + */ + ServiceContract<?> getServiceContract(); + + /** + * Returns the collection of bindings configured for the service. + * + * @return the collection of bindings configured for the service. + */ + List<ServiceBinding> getServiceBindings(); + + /** + * Adds a binding the service is exposed over. + * + * @param binding the binding the service is exposed over. + */ + void addServiceBinding(ServiceBinding binding); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ServiceBinding.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ServiceBinding.java new file mode 100644 index 0000000000..10d2dd5196 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/ServiceBinding.java @@ -0,0 +1,51 @@ +/* + * 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.spi.component; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.Wire; + +/** + * The runtime instantiation of an SCA service binding. + * + * @version $Rev$ $Date$ + */ +public interface ServiceBinding extends Invocable { + + /** + * Returns the binding qualified name + * + * @return the binding qualified name + */ + QName getBindingType(); + + /** + * Get the ServiceContract for the binding + * + * @return the ServiceContract for the binding + */ + ServiceContract<?> getBindingServiceContract(); + + Wire getWire(); + + void setWire(Wire wire); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetDestructionException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetDestructionException.java new file mode 100644 index 0000000000..5f521f9b0a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetDestructionException.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.component; + +/** + * Denotes an error destroying a target + * + * @version $Rev$ $Date$ + */ +public class TargetDestructionException extends TargetResolutionException { + + public TargetDestructionException(String message, String identifier) { + super(message, identifier); + } + + public TargetDestructionException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + + public TargetDestructionException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetException.java new file mode 100644 index 0000000000..6b8278cf8b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetException.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.spi.component; + +/** + * Denotes an error while performing an operation on a target component implementation instance + * + * @version $Rev$ $Date$ + */ +public abstract class TargetException extends ComponentException { + + public TargetException(String message) { + super(message); + } + + + public TargetException(String message, String identifier) { + super(message, identifier); + } + + public TargetException(String message, Throwable cause) { + super(message, cause); + } + + + public TargetException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + public TargetException(Throwable cause) { + super(cause); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetInitializationException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetInitializationException.java new file mode 100644 index 0000000000..eaea4c3bc9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetInitializationException.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.component; + +/** + * Denotes an error initializing a target + * + * @version $Rev$ $Date$ + */ +public class TargetInitializationException extends TargetResolutionException { + + public TargetInitializationException(String message, String identifier) { + super(message, identifier); + } + + public TargetInitializationException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + public TargetInitializationException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetInvocationException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetInvocationException.java new file mode 100644 index 0000000000..1fc2b24f5b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetInvocationException.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.spi.component; + +/** + * Raised when an error is encountered during a target invocation + * + * @version $Rev$ $Date$ + */ +public class TargetInvocationException extends TargetException { + + public TargetInvocationException(String message) { + super(message); + } + + public TargetInvocationException(String message, String identifier) { + super(message, identifier); + } + + public TargetInvocationException(String message, Throwable cause) { + super(message, cause); + } + + public TargetInvocationException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetInvokerCreationException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetInvokerCreationException.java new file mode 100644 index 0000000000..ac914401cf --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetInvokerCreationException.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.spi.component; + +/** + * Denotes an error creating a {@link org.apache.tuscany.spi.wire.TargetInvoker} + * + * @version $Rev$ $Date$ + */ +public abstract class TargetInvokerCreationException extends ComponentException { + + public TargetInvokerCreationException() { + } + + public TargetInvokerCreationException(String message) { + super(message); + } + + public TargetInvokerCreationException(String message, String identifier) { + super(message, identifier); + } + + public TargetInvokerCreationException(String message, Throwable cause) { + super(message, cause); + } + + public TargetInvokerCreationException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + public TargetInvokerCreationException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetNotFoundException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetNotFoundException.java new file mode 100644 index 0000000000..cd6996789c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetNotFoundException.java @@ -0,0 +1,36 @@ +/* + * 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.spi.component; + +/** + * Thrown when a target of an operation cannot be found + * + * @version $$Rev$$ $$Date$$ + */ +public class TargetNotFoundException extends TargetResolutionException { + + public TargetNotFoundException(String message) { + super(message); + } + + public TargetNotFoundException(String message, String identifier) { + super(message, identifier); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetResolutionException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetResolutionException.java new file mode 100644 index 0000000000..858fa9415d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/TargetResolutionException.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.spi.component; + +/** + * Denotes an error retrieving a target instance + * + * @version $Rev$ $Date$ + */ +public class TargetResolutionException extends TargetException { + + public TargetResolutionException(String message) { + super(message); + } + + public TargetResolutionException(String message, String identifier) { + super(message, identifier); + } + + public TargetResolutionException(String message, Throwable cause) { + super(message, cause); + } + + public TargetResolutionException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/WorkContext.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/WorkContext.java new file mode 100644 index 0000000000..4034681c20 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/component/WorkContext.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.spi.component; + +import java.net.URI; +import java.util.LinkedList; + +/** + * Implementations track information associated with a request as it is processed by the runtime + * + * @version $Rev$ $Date$ + */ +public interface WorkContext { + + /** + * Returns the unique key for the given identifier associated with the current request + */ + Object getIdentifier(Object type); + + /** + * Sets the unique key for the given identifier associated with the current request + */ + void setIdentifier(Object type, Object identifier); + + /** + * Clears the unique key for the given identifier associated with the current request + */ + void clearIdentifier(Object type); + + /** + * Clears all identifiers associated with the current request + */ + void clearIdentifiers(); + + /** + * Returns an ordered list of callback URIs for the current context. Ordering is based on the sequence of service + * invocations for collocated components + * + * @return the current list of callback URIs + */ + LinkedList<URI> getCallbackUris(); + + /** + * Sets an ordered list of callback URIs for the current context. Ordering is based on the sequence of service + * invocations for collocated components + */ + void setCallbackUris(LinkedList<URI> uris); + + /** + * Returns the correlation id for the current invocation or null if not available. Transports may use correlation + * ids for message routing. + * + * @return the correlation id for the current invocation or null + */ + Object getCorrelationId(); + + /** + * Sets the correlation id for the current invocation. Transports may use correlation ids for message routing. + * + * @param id the correlation id + */ + void setCorrelationId(Object id); + + /** + * Returns the composite where a remote request came in + */ + Component getRemoteComponent(); + + /** + * Sets the composite where a remote request came in + */ + void setRemoteComponent(Component component); + + /** + * Returns the current atomic component as a request is processed or null if it is not being tracked. Note that the + * current atomic component is typically only tracked during persistence operations involving implementation + * instances + * + * @return the current atomic component as a request is processed or null + */ + AtomicComponent getCurrentAtomicComponent(); + + /** + * Sets the current atomic component that is handling processing of a request. Note that in most cases it will not + * be necessary to track this in the rumtime + * + * @param component the current atomic component + */ + void setCurrentAtomicComponent(AtomicComponent component); + + /** + * Removes and returns the name of the last remotable service to handle the current request + * + * @return the name of the last remotable service to handle the current request or null + */ + String popServiceName(); + + /** + * Returns the name of the last remotable service to handle the current request + * + * @return the name of the last remotable service to handle the current request or null + */ + String getCurrentServiceName(); + + /** + * Adds the name of the last remotable service to handle the current request + * + * @param name the name of the last remotable service to handle the current request or null + */ + void pushServiceName(String name); + + /** + * Clears the stack of current service names + */ + void clearServiceNames(); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/DataBinding.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/DataBinding.java new file mode 100644 index 0000000000..a33b40a785 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/DataBinding.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.spi.databinding; + +import org.apache.tuscany.spi.model.DataType; + +/** + * DataBinding represents a data representation, for example, SDO, JAXB and AXIOM + */ +public interface DataBinding { + /** + * The name of a databinding should be case-insensitive and unique + * + * @return The name of the databinding + */ + String getName(); + + /** + * Introspect a java class or interface to create a DataType model + * + * @param javaType The java class or interface to be introspected + * @return The DataType or null if the java type is not supported by this databinding + */ + DataType introspect(Class<?> javaType); + + /** + * Introspect the data to figure out the corresponding data type + * + * @param value The object to be checked + * @return The DataType or null if the java type is not supported by this databinding + */ + DataType introspect(Object value); + + /** + * Provide a WrapperHandler for this databinding + * + * @return A wrapper handler which can handle wrapping/wrapping for this databinding + */ + WrapperHandler getWrapperHandler(); + + /** + * Make a copy of the object for "pass-by-value" semantics + * + * @param object object to copy + * @return copy of the object passed in as argument + */ + Object copy(Object object); + + /** + * Get the type mapper for simple types + * + * @return The databinding-specific simple type mapper + */ + SimpleTypeMapper getSimpleTypeMapper(); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/DataBindingRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/DataBindingRegistry.java new file mode 100644 index 0000000000..ba47401cc2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/DataBindingRegistry.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.databinding; + +import org.apache.tuscany.spi.model.DataType; + +/** + * The registry for data bindings + */ +public interface DataBindingRegistry { + /** + * Register a data binding + * + * @param dataBinding + */ + void register(DataBinding dataBinding); + + /** + * Look up a data binding by id + * + * @param id The name of the databinding + * @return The databinding + */ + DataBinding getDataBinding(String id); + + /** + * Unregister a data binding + * + * @param id + * @return The unregistered databinding + */ + DataBinding unregister(String id); + + /** + * Introspect the java class to figure out what DataType supports it + * + * @param javaType The java class or interface + * @return A DataType representing the java type or null if no databinding + * recognizes the java type + */ + DataType introspectType(Class<?> javaType); + + /** + * Introspect the value to figure out the corresponding DataType + * + * @param value The object value + * @return A DataType representing the value or null if no databinding + * recognizes the value + */ + DataType introspectType(Object value); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/DataPipe.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/DataPipe.java new file mode 100755 index 0000000000..dcb83426d1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/DataPipe.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.databinding; + +/** + * Data pipe allows a data source pushes data into its sink and pipe the data into its result + * + * @param <S> The data binding type of the sink + * @param <R> The data binding type of the result + */ +public interface DataPipe<S, R> extends Transformer { + + /** + * Returns a sink (for example, java.io.OutputStream, java.io.Writer or org.xml.sax.ContentHandler) to receive data + * pushed by the source + * + * @return The sink to consume data + */ + S getSink(); + + /** + * Returns the data populated by the sink + * + * @return R the result + */ + R getResult(); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/Mediator.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/Mediator.java new file mode 100755 index 0000000000..0983ed46fd --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/Mediator.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.spi.databinding; + +import java.util.Map; + +import org.apache.tuscany.spi.model.DataType; + +/** + * This interface will be used as a Tuscany system service to perform data mediations + * <p/> + * Mediate the data from one type to the other one + */ +public interface Mediator { + + /** + * Mediate the data from the source type to the target type + * + * @param source The data to be mediated + * @param sourceDataType Data type for the source data + * @param targetDataType Data type for the target data + * @param context the context for the mediation + * @return the result of the mediation + */ + Object mediate(Object source, DataType sourceDataType, DataType targetDataType, Map<Class<?>, Object> context); + + /** + * Mediate the source data into the target which is a sink to receive the data + * + * @param source The data to be mediated + * @param target The sink to receive data + * @param sourceDataType Data type for the source data + * @param targetDataType Data type for the target data + * @param context the context for the mediation + */ + void mediate(Object source, + Object target, + DataType sourceDataType, + DataType targetDataType, + Map<Class<?>, Object> context); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/PullTransformer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/PullTransformer.java new file mode 100644 index 0000000000..21e8cc2750 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/PullTransformer.java @@ -0,0 +1,36 @@ +/* + * 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.spi.databinding; + +/** + * PullTransformer transforms data from one binding format to the other one which can be directly consumed + * + * @param <S> The source data type + * @param <R> the target data type + */ +public interface PullTransformer<S, R> extends Transformer { + /** + * Transform source data into the result type. + * + * @param source The source data + * @param context The context for the transformation + * @return The transformed result + */ + R transform(S source, TransformationContext context); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/PushTransformer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/PushTransformer.java new file mode 100644 index 0000000000..d68b6aa772 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/PushTransformer.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.spi.databinding; + +/** + * A transformer that pushes data from its source into the sink + * + * @param <S> + * @param <R> + */ +public interface PushTransformer<S, R> extends Transformer { + /** + * @param source The source data + * @param sink The sink to receive the data + * @param context + */ + void transform(S source, R sink, TransformationContext context); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/SimpleTypeMapper.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/SimpleTypeMapper.java new file mode 100644 index 0000000000..0da681c71e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/SimpleTypeMapper.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.spi.databinding; + +import org.apache.tuscany.spi.model.TypeInfo; + +/** + * Type Mapper between XML schema simple data types and java objects + */ +public interface SimpleTypeMapper { + /** + * Parse the XML lexical representation into a java object + * @param simpleType The XSD simple type + * @param value the XML lexical representation + * @param context The context of the transformation + * @return A java object for the XML value + */ + Object toJavaObject(TypeInfo simpleType, String value, TransformationContext context); + /** + * Create the XML lexical representation for a java object + * @param simpleType The XSD simple type + * @param obj The java object + * @param context The context of the transformation + * @return The XML lexical representation + */ + String toXMLLiteral(TypeInfo simpleType, Object obj, TransformationContext context); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformationContext.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformationContext.java new file mode 100755 index 0000000000..efddfb8fc0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformationContext.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.spi.databinding; + +import java.util.Map; + +import org.apache.tuscany.spi.model.DataType; + +/** + * Context for data transformation + */ +public interface TransformationContext { + /** + * Get the source data type + * + * @return the source data type + */ + DataType getSourceDataType(); + + /** + * Get the target data type + * + * @return the target datatype + */ + DataType getTargetDataType(); + + /** + * Set the source data type + * + * @param sourceDataType the source data type + */ + void setSourceDataType(DataType sourceDataType); + + /** + * Set the target data type + * + * @param targetDataType the target data type + */ + void setTargetDataType(DataType targetDataType); + + /** + * Get the classloader + * + * @return the classloader + */ + ClassLoader getClassLoader(); + + /** + * Get a map of metadata + * + * @return the map of metadata + */ + Map<Class<?>, Object> getMetadata(); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformationException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformationException.java new file mode 100755 index 0000000000..9b57e1cf70 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformationException.java @@ -0,0 +1,46 @@ +/* + * 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.spi.databinding; + +import org.apache.tuscany.api.TuscanyRuntimeException; + +/** + * Reports problems during data transformation + */ +public class TransformationException extends TuscanyRuntimeException { + + private static final long serialVersionUID = 7662385613693006428L; + + public TransformationException() { + super(); + } + + public TransformationException(String message, Throwable cause) { + super(message, cause); + } + + public TransformationException(String message) { + super(message); + } + + public TransformationException(Throwable cause) { + super(cause); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/Transformer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/Transformer.java new file mode 100755 index 0000000000..2f969e979d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/Transformer.java @@ -0,0 +1,49 @@ +/* + * 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.spi.databinding; + +/** + * A transformer provides the data transformation from source type to target type. The cost of the transformation is + * modeled as weight. + */ +public interface Transformer { + /** + * Get the source type that this transformer transforms data from. The type is used as the key when the transformer + * is registered with TransformerRegistry. + * + * @return A key indentifying the source type + */ + String getSourceDataBinding(); + + /** + * Get the target type that this transformer transforms data into. The type is used as the key when the transformer + * is registered with TransformerRegistry. + * + * @return A key indentifying the target type + */ + String getTargetDataBinding(); + + /** + * Get the cost of the transformation. The weight can be used to choose the most efficient path if there are more + * than one available from the source to the target. + * + * @return An integer representing the cost of the transformation + */ + int getWeight(); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformerRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformerRegistry.java new file mode 100755 index 0000000000..18a01b7853 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/TransformerRegistry.java @@ -0,0 +1,73 @@ +/* + * 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.spi.databinding; + +import java.util.List; + +/** + * Registry for data transformers + */ +public interface TransformerRegistry { + /** + * Register a transformer + * + * @param sourceDataBinding + * @param targetDataBinding + * @param weight + * @param transformer + */ + void registerTransformer(String sourceDataBinding, + String targetDataBinding, + int weight, + Transformer transformer); + + /** + * Register a transformer + * + * @param transformer + */ + void registerTransformer(Transformer transformer); + + /** + * Unregister a transformer + * + * @param sourceDataBinding + * @param targetDataBinding + * @return true if sucessfully unregistered + */ + boolean unregisterTransformer(String sourceDataBinding, String targetDataBinding); + + /** + * Get the direct Transformer which can transform data from source type to result type + * + * @param sourceDataBinding + * @param targetDataBinding + * @return the transformer + */ + Transformer getTransformer(String sourceDataBinding, String targetDataBinding); + + /** + * Get the a chain of Transformers which can transform data from source type to result type + * + * @param sourceDataBinding + * @param targetDataBinding + * @return the list of transformers + */ + List<Transformer> getTransformerChain(String sourceDataBinding, String targetDataBinding); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/WrapperHandler.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/WrapperHandler.java new file mode 100644 index 0000000000..1cb8d00bf5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/WrapperHandler.java @@ -0,0 +1,56 @@ +/* + * 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.spi.databinding; + +import org.apache.tuscany.spi.model.ElementInfo; + +/** + * A contract for transformers to deal with wrapping/unwrapping for WSDL wrapper style operations + */ +public interface WrapperHandler<T> { + /** + * Create a wrapper element + * + * @param element The XSD element + * @param context The transformation context + * @return An object representing the wrapper element + */ + T create(ElementInfo element, TransformationContext context); + + /** + * Set child element for the wrapper + * + * @param wrapper The wrapper + * @param i The index + * @param childElement The XSD element + * @param value The value of the child + */ + void setChild(T wrapper, int i, ElementInfo childElement, Object value); + + /** + * Get child element from the wrapper + * + * @param wrapper The wrapper + * @param i The index + * @param element The XSD element + * @return The value of the child + */ + Object getChild(T wrapper, int i, ElementInfo element); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/DOMHelper.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/DOMHelper.java new file mode 100644 index 0000000000..2b927b8e55 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/DOMHelper.java @@ -0,0 +1,69 @@ +/* + * 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.spi.databinding.extension; + +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Helper for DOM + */ +public final class DOMHelper { + private static final DocumentBuilderFactory FACTORY = DocumentBuilderFactory.newInstance(); + static { + FACTORY.setNamespaceAware(true); + } + + private DOMHelper() { + } + + public static Document newDocument() throws ParserConfigurationException { + return newDocumentBuilder().newDocument(); + } + + public static DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { + return FACTORY.newDocumentBuilder(); + } + + public static QName getQName(Node node) { + String ns = node.getNamespaceURI(); + if (ns == null) { + ns = ""; + } + // node.getLocalName() will return null if it is created using DOM Level + // 1 method + // such as createElement() + return new QName(ns, node.getNodeName()); + } + + public static Element createElement(Document document, QName name) { + String prefix = name.getPrefix(); + String qname = + (prefix != null && prefix.length() > 0) ? prefix + ":" + name.getLocalPart() : name + .getLocalPart(); + return document.createElementNS(name.getNamespaceURI(), qname); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/DataBindingExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/DataBindingExtension.java new file mode 100644 index 0000000000..bc9483f01f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/DataBindingExtension.java @@ -0,0 +1,179 @@ +/* + * 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.spi.databinding.extension; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamClass; +import java.io.OutputStream; +import java.io.Serializable; + +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +import org.apache.tuscany.spi.databinding.DataBinding; +import org.apache.tuscany.spi.databinding.DataBindingRegistry; +import org.apache.tuscany.spi.databinding.SimpleTypeMapper; +import org.apache.tuscany.spi.databinding.WrapperHandler; +import org.apache.tuscany.spi.model.DataType; + +/** + * Base Implementation of DataBinding + * + * @version $Rev$ $Date$ + */ +@Service(DataBinding.class) +@Scope("COMPOSITE") +@EagerInit +public abstract class DataBindingExtension implements DataBinding { + + protected DataBindingRegistry registry; + + protected Class<?> baseType; + + protected String name; + + /** + * Create a databinding with the base java type whose name will be used as the name of the databinding + * + * @param baseType The base java class or interface representing the databinding, for example, org.w3c.dom.Node + */ + protected DataBindingExtension(Class<?> baseType) { + this(baseType.getName(), baseType); + } + + /** + * Create a databinding with the name and base java type + * + * @param name The name of the databinding + * @param baseType The base java class or interface representing the databinding, for example, org.w3c.dom.Node + */ + protected DataBindingExtension(String name, Class<?> baseType) { + this.name = name; + this.baseType = baseType; + } + + @Reference + public void setDataBindingRegistry(DataBindingRegistry registry) { + this.registry = registry; + } + + @Init + public void init() { + registry.register(this); + } + + public DataType introspect(Class<?> javaType) { + if (baseType == null || javaType == null) { + return null; + } + if (baseType.isAssignableFrom(javaType)) { + return new DataType<Class>(name, javaType, baseType); + } else { + return null; + } + } + + public DataType introspect(Object value) { + if (value == null) { + return null; + } else { + return introspect(value.getClass()); + } + } + + public final String getName() { + return name; + } + + /** + * @see org.apache.tuscany.spi.databinding.DataBinding#getWrapperHandler() + */ + public WrapperHandler getWrapperHandler() { + return null; + } + + public Object copy(Object arg) { + if (arg == null) { + return null; + } + final Class clazz = arg.getClass(); + if (String.class == clazz || clazz.isPrimitive() || Number.class.isAssignableFrom(clazz) + || Boolean.class.isAssignableFrom(clazz) || Character.class.isAssignableFrom(clazz) + || Byte.class.isAssignableFrom(clazz)) { + // Immutable classes + return arg; + } + try { + if (arg instanceof Serializable) { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = getObjectOutputStream(bos); + oos.writeObject(arg); + oos.close(); + bos.close(); + + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + ObjectInputStream ois = getObjectInputStream(bis, clazz.getClassLoader()); + Object objectCopy = ois.readObject(); + ois.close(); + bis.close(); + return objectCopy; + } else { + //return arg; + throw new IllegalArgumentException( + "Pass-by-value is not supported for the given object"); + } + } catch (Exception e) { + throw new IllegalArgumentException( + "Pass-by-value is not supported for the given object", e); + } + } + + protected ObjectOutputStream getObjectOutputStream(OutputStream os) throws IOException { + return new ObjectOutputStream(os); + } + + protected ObjectInputStream getObjectInputStream(InputStream is, final ClassLoader cl) + throws IOException { + ObjectInputStream ois = new ObjectInputStream(is) { + @Override + protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { + try { + return Class.forName(desc.getName(), false, cl); + } catch (ClassNotFoundException e) { + return super.resolveClass(desc); + } + } + + }; + return ois; + } + + public SimpleTypeMapper getSimpleTypeMapper() { + return new SimpleTypeMapperExtension(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/Java2SimpleTypeTransformer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/Java2SimpleTypeTransformer.java new file mode 100644 index 0000000000..3150dfad3d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/Java2SimpleTypeTransformer.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.spi.databinding.extension; + +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.SimpleTypeMapper; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.model.ElementInfo; +import org.apache.tuscany.spi.model.TypeInfo; + +/** + * Transformer to convert data from a simple java object to a databinding's representation + */ +public abstract class Java2SimpleTypeTransformer<T> extends TransformerExtension<Object, T> implements + PullTransformer<Object, T> { + + protected SimpleTypeMapper mapper; + + public Java2SimpleTypeTransformer() { + this.mapper = new SimpleTypeMapperExtension(); + } + + public Java2SimpleTypeTransformer(SimpleTypeMapper mapper) { + this.mapper = (mapper != null) ? mapper : new SimpleTypeMapperExtension(); + } + + public T transform(Object source, TransformationContext context) { + ElementInfo element = + (ElementInfo) context.getTargetDataType().getMetadata(ElementInfo.class.getName()); + TypeInfo simpleType = (TypeInfo) element.getType(); + String text = mapper.toXMLLiteral(simpleType, source, context); + return createElement(element, text, context); + } + + public Class getSourceType() { + return Object.class; + } + + public int getWeight() { + return 10000; + } + + protected abstract T createElement(ElementInfo element, String literal, TransformationContext context); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/SimpleType2JavaTransformer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/SimpleType2JavaTransformer.java new file mode 100644 index 0000000000..2304990e88 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/SimpleType2JavaTransformer.java @@ -0,0 +1,72 @@ +/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.spi.databinding.extension;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.SimpleTypeMapper;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.model.ElementInfo;
+import org.apache.tuscany.spi.model.TypeInfo;
+
+/**
+ * Transformer to convert data from a databinding's representation of simple types to Java Objects
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class SimpleType2JavaTransformer<T> extends TransformerExtension<T, Object> implements
+ PullTransformer<T, Object> {
+
+ protected SimpleTypeMapper mapper;
+
+ public SimpleType2JavaTransformer() {
+ this.mapper = new SimpleTypeMapperExtension();
+ }
+
+ public SimpleType2JavaTransformer(SimpleTypeMapper mapper) {
+ this.mapper = (mapper != null) ? mapper : new SimpleTypeMapperExtension();
+ }
+
+ public Object transform(T source, TransformationContext context) {
+ TypeInfo simpleType = (TypeInfo) context.getSourceDataType().getMetadata(TypeInfo.class.getName());
+ if (simpleType == null) {
+ ElementInfo element =
+ (ElementInfo) context.getSourceDataType().getMetadata(ElementInfo.class.getName());
+ simpleType = element.getType();
+ }
+
+ return mapper.toJavaObject(simpleType, getText(source), context);
+ }
+
+ public Class getTargetType() {
+ return Object.class;
+ }
+
+ public int getWeight() {
+ // Cannot be used for imtermediate
+ return 10000;
+ }
+
+ /**
+ * Get the string value from the source
+ *
+ * @param source the source to return the string from
+ * @return A string
+ */
+ protected abstract String getText(T source);
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/SimpleTypeMapperExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/SimpleTypeMapperExtension.java new file mode 100644 index 0000000000..5ce3eb978e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/SimpleTypeMapperExtension.java @@ -0,0 +1,415 @@ +/* + * 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.spi.databinding.extension; + +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.databinding.SimpleTypeMapper; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.model.TypeInfo; + +public class SimpleTypeMapperExtension extends XSDDataTypeConverter implements SimpleTypeMapper { + + public static final int BASE64_ENCODING = 1; + public static final int HEXBIN_ENCODING = 2; + + public static final String SET = "set"; + + public static final Map<Class, String> JAVA2XML = new HashMap<Class, String>(); + + public static final String URI_2001_SCHEMA_XSD = "http://www.w3.org/2001/XMLSchema"; + + public static final Map<String, Class> XML2JAVA = new HashMap<String, Class>(); + + public static final QName XSD_ANY = new QName(URI_2001_SCHEMA_XSD, "any"); + + public static final QName XSD_ANYSIMPLETYPE = new QName(URI_2001_SCHEMA_XSD, "anySimpleType"); + + public static final QName XSD_ANYTYPE = new QName(URI_2001_SCHEMA_XSD, "anyType"); + + public static final QName XSD_ANYURI = new QName(URI_2001_SCHEMA_XSD, "anyURI"); + + public static final QName XSD_BASE64 = new QName(URI_2001_SCHEMA_XSD, "base64Binary"); + + public static final QName XSD_BOOLEAN = new QName(URI_2001_SCHEMA_XSD, "boolean"); + + public static final QName XSD_BYTE = new QName(URI_2001_SCHEMA_XSD, "byte"); + + public static final QName XSD_DATE = new QName(URI_2001_SCHEMA_XSD, "date"); + + public static final QName XSD_DATETIME = new QName(URI_2001_SCHEMA_XSD, "dateTime"); + + public static final QName XSD_DAY = new QName(URI_2001_SCHEMA_XSD, "gDay"); + + public static final QName XSD_DECIMAL = new QName(URI_2001_SCHEMA_XSD, "decimal"); + + public static final QName XSD_DOUBLE = new QName(URI_2001_SCHEMA_XSD, "double"); + + public static final QName XSD_DURATION = new QName(URI_2001_SCHEMA_XSD, "duration"); + + public static final QName XSD_ENTITIES = new QName(URI_2001_SCHEMA_XSD, "ENTITIES"); + + public static final QName XSD_ENTITY = new QName(URI_2001_SCHEMA_XSD, "ENTITY"); + + public static final QName XSD_FLOAT = new QName(URI_2001_SCHEMA_XSD, "float"); + + public static final QName XSD_HEXBIN = new QName(URI_2001_SCHEMA_XSD, "hexBinary"); + + public static final QName XSD_IDREF = new QName(URI_2001_SCHEMA_XSD, "IDREF"); + + public static final QName XSD_IDREFS = new QName(URI_2001_SCHEMA_XSD, "IDREFS"); + + public static final QName XSD_INT = new QName(URI_2001_SCHEMA_XSD, "int"); + + public static final QName XSD_INTEGER = new QName(URI_2001_SCHEMA_XSD, "integer"); + + public static final QName XSD_LONG = new QName(URI_2001_SCHEMA_XSD, "long"); + + public static final QName XSD_MONTH = new QName(URI_2001_SCHEMA_XSD, "gMonth"); + + public static final QName XSD_MONTHDAY = new QName(URI_2001_SCHEMA_XSD, "gMonthDay"); + + public static final QName XSD_NAME = new QName(URI_2001_SCHEMA_XSD, "Name"); + + public static final QName XSD_NCNAME = new QName(URI_2001_SCHEMA_XSD, "NCName"); + + public static final QName XSD_NEGATIVEINTEGER = new QName(URI_2001_SCHEMA_XSD, "negativeInteger"); + + public static final QName XSD_NMTOKEN = new QName(URI_2001_SCHEMA_XSD, "NMTOKEN"); + + public static final QName XSD_NMTOKENS = new QName(URI_2001_SCHEMA_XSD, "NMTOKENS"); + + public static final QName XSD_NONNEGATIVEINTEGER = new QName(URI_2001_SCHEMA_XSD, "nonNegativeInteger"); + + public static final QName XSD_NONPOSITIVEINTEGER = new QName(URI_2001_SCHEMA_XSD, "nonPositiveInteger"); + + public static final QName XSD_NORMALIZEDSTRING = new QName(URI_2001_SCHEMA_XSD, "normalizedString"); + + public static final QName XSD_NOTATION = new QName(URI_2001_SCHEMA_XSD, "NOTATION"); + + public static final QName XSD_POSITIVEINTEGER = new QName(URI_2001_SCHEMA_XSD, "positiveInteger"); + + public static final QName XSD_QNAME = new QName(URI_2001_SCHEMA_XSD, "QName"); + + public static final QName XSD_SHORT = new QName(URI_2001_SCHEMA_XSD, "short"); + + public static final Map<String, TypeInfo> XSD_SIMPLE_TYPES = new HashMap<String, TypeInfo>(); + + public static final QName XSD_STRING = new QName(URI_2001_SCHEMA_XSD, "string"); + + public static final QName XSD_TIME = new QName(URI_2001_SCHEMA_XSD, "time"); + + public static final QName XSD_TOKEN = new QName(URI_2001_SCHEMA_XSD, "token"); + + public static final QName XSD_UNSIGNEDBYTE = new QName(URI_2001_SCHEMA_XSD, "unsignedByte"); + + public static final QName XSD_UNSIGNEDINT = new QName(URI_2001_SCHEMA_XSD, "unsignedInt"); + + public static final QName XSD_UNSIGNEDLONG = new QName(URI_2001_SCHEMA_XSD, "unsignedLong"); + + public static final QName XSD_UNSIGNEDSHORT = new QName(URI_2001_SCHEMA_XSD, "unsignedShort"); + + public static final QName XSD_YEAR = new QName(URI_2001_SCHEMA_XSD, "gYear"); + + public static final QName XSD_YEARMONTH = new QName(URI_2001_SCHEMA_XSD, "gYearMonth"); + + private static final String[] XSD_TYPE_NAMES = + {"string", "boolean", "double", "float", "int", "integer", "long", "short", "byte", "decimal", "base64Binary", + "hexBinary", "anySimpleType", "anyType", "any", "QName", "dateTime", "date", "time", "normalizedString", + "token", "unsignedLong", "unsignedInt", "unsignedShort", "unsignedByte", "positiveInteger", "negativeInteger", + "nonNegativeInteger", "nonPositiveInteger", "gYearMonth", "gMonthDay", "gYear", "gMonth", "gDay", "duration", + "Name", "NCName", "NMTOKEN", "NMTOKENS", "NOTATION", "ENTITY", "ENTITIES", "IDREF", "IDREFS", "anyURI", + "language", "ID"}; + + static { + for (String type : XSD_TYPE_NAMES) { + TypeInfo simpleType = new TypeInfo(new QName(URI_2001_SCHEMA_XSD, type), true, null); + XSD_SIMPLE_TYPES.put(type, simpleType); + } + } + + static { + JAVA2XML.put(boolean.class, "boolean"); + JAVA2XML.put(byte.class, "byte"); + JAVA2XML.put(short.class, "short"); + JAVA2XML.put(int.class, "int"); + JAVA2XML.put(long.class, "long"); + JAVA2XML.put(float.class, "float"); + JAVA2XML.put(double.class, "double"); + JAVA2XML.put(Boolean.class, "boolean"); + JAVA2XML.put(Byte.class, "byte"); + JAVA2XML.put(Short.class, "short"); + JAVA2XML.put(Integer.class, "int"); + JAVA2XML.put(Long.class, "long"); + JAVA2XML.put(Float.class, "float"); + JAVA2XML.put(Double.class, "double"); + JAVA2XML.put(java.lang.String.class, "string"); + JAVA2XML.put(java.math.BigInteger.class, "integer"); + JAVA2XML.put(java.math.BigDecimal.class, "decimal"); + JAVA2XML.put(java.util.Calendar.class, "dateTime"); + JAVA2XML.put(java.util.Date.class, "dateTime"); + JAVA2XML.put(javax.xml.namespace.QName.class, "QName"); + JAVA2XML.put(java.net.URI.class, "string"); + JAVA2XML.put(javax.xml.datatype.XMLGregorianCalendar.class, "anySimpleType"); + JAVA2XML.put(javax.xml.datatype.Duration.class, "duration"); + JAVA2XML.put(java.lang.Object.class, "anyType"); + JAVA2XML.put(java.awt.Image.class, "base64Binary"); + JAVA2XML.put(byte[].class, "base64Binary"); + // java2XSD.put(javax.activation.DataHandler.class, "base64Binary"); + JAVA2XML.put(javax.xml.transform.Source.class, "base64Binary"); + JAVA2XML.put(java.util.UUID.class, "string"); + } + + static { + XML2JAVA.put("string", java.lang.String.class); + XML2JAVA.put("integer", java.math.BigInteger.class); + XML2JAVA.put("int", int.class); + XML2JAVA.put("long", long.class); + XML2JAVA.put("short", short.class); + XML2JAVA.put("decimal", java.math.BigDecimal.class); + XML2JAVA.put("float", float.class); + XML2JAVA.put("double", double.class); + XML2JAVA.put("boolean", boolean.class); + XML2JAVA.put("byte", byte.class); + XML2JAVA.put("QName", javax.xml.namespace.QName.class); + XML2JAVA.put("dateTime", javax.xml.datatype.XMLGregorianCalendar.class); + XML2JAVA.put("base64Binary", byte[].class); + XML2JAVA.put("hexBinary", byte[].class); + XML2JAVA.put("unsignedInt", long.class); + XML2JAVA.put("unsignedShort", int.class); + XML2JAVA.put("unsignedByte", short.class); + XML2JAVA.put("time", javax.xml.datatype.XMLGregorianCalendar.class); + XML2JAVA.put("date", javax.xml.datatype.XMLGregorianCalendar.class); + XML2JAVA.put("gDay", javax.xml.datatype.XMLGregorianCalendar.class); + XML2JAVA.put("gMonth", javax.xml.datatype.XMLGregorianCalendar.class); + XML2JAVA.put("gYear", javax.xml.datatype.XMLGregorianCalendar.class); + XML2JAVA.put("gYearMonth", javax.xml.datatype.XMLGregorianCalendar.class); + XML2JAVA.put("gMonthDay", javax.xml.datatype.XMLGregorianCalendar.class); + XML2JAVA.put("anySimpleType", java.lang.Object.class); // For elements + // XML2JAVA.put("anySimpleType", java.lang.String.class); // For + // attributes + XML2JAVA.put("duration", javax.xml.datatype.Duration.class); + XML2JAVA.put("NOTATION", javax.xml.namespace.QName.class); + } + + private int byteEncoding = BASE64_ENCODING; + private DatatypeFactory factory; + + public SimpleTypeMapperExtension() { + super(); + try { + this.factory = DatatypeFactory.newInstance(); + } catch (DatatypeConfigurationException e) { + throw new IllegalArgumentException(e); + } + } + + public Class getJavaType(TypeInfo xmlType) { + TypeInfo baseType = xmlType; + while (baseType.getBaseType() != null) { + baseType = baseType.getBaseType(); + } + return XML2JAVA.get(baseType.getQName().getLocalPart()); + } + + public TypeInfo getXMLType(Class javaType) { + return XSD_SIMPLE_TYPES.get(JAVA2XML.get(javaType)); + } + + public Object toJavaObject(TypeInfo simpleType, String literal, TransformationContext context) { + /** + * <ul> + * <li>xsd:string --- java.lang.String + * <li>xsd:integer --- java.math.BigInteger + * <li>xsd:int --- int + * <li>xsd:long --- long + * <li>xsd:short --- short + * <li>xsd:decimal --- java.math.BigDecimal + * <li>xsd:float --- float + * <li>xsd:double --- double + * <li>xsd:boolean --- boolean + * <li>xsd:byte --- byte + * <li>xsd:QName --- javax.xml.namespace.QName + * <li>xsd:dateTime --- javax.xml.datatype.XMLGregorianCalendar + * <li>xsd:base64Binary --- byte[] + * <li>xsd:hexBinary --- byte[] + * <li>xsd:unsignedInt --- long + * <li>xsd:unsignedShort --- int + * <li>xsd:unsignedByte --- short + * <li>xsd:time --- javax.xml.datatype.XMLGregorianCalendar + * <li>xsd:date --- javax.xml.datatype.XMLGregorianCalendar + * <li>xsd:g* --- javax.xml.datatype.XMLGregorianCalendar + * <li>xsd:anySimpleType (for xsd:element of this type)a + * java.lang.Object + * <li>xsd:anySimpleType (for xsd:attribute of this type) + * java.lang.String + * <li>xsd:duration javax.xml.datatype.Duration + * <li>xsd:NOTATION javax.xml.namespace.QName + * </ul> + */ + + if (literal == null) { + return null; + } + String value = literal.trim(); + if (!simpleType.isSimpleType()) { + throw new IllegalArgumentException("Complex type is not supported for simple java databinding."); + } + TypeInfo baseType = simpleType; + while (baseType.getBaseType() != null) { + baseType = (TypeInfo)baseType.getBaseType(); + } + + QName type = baseType.getQName(); + if (type.equals(XSD_STRING)) { + return parseString(value); + } else if (type.equals(XSD_INT)) { + return parseInt(value); + } else if (type.equals(XSD_INTEGER)) { + return parseInteger(value); + } else if (type.equals(XSD_INT)) { + return parseInt(value); + } else if (type.equals(XSD_FLOAT)) { + return parseFloat(value); + } else if (type.equals(XSD_DOUBLE)) { + return parseDouble(value); + } else if (type.equals(XSD_SHORT)) { + return parseShort(value); + } else if (type.equals(XSD_DECIMAL)) { + return parseDecimal(value); + } else if (type.equals(XSD_BOOLEAN)) { + return parseBoolean(value); + } else if (type.equals(XSD_BYTE)) { + return parseByte(value); + } else if (type.equals(XSD_LONG)) { + return parseLong(value); + } else if (type.equals(XSD_UNSIGNEDBYTE)) { + return parseUnsignedShort(value); + } else if (type.equals(XSD_UNSIGNEDSHORT)) { + return parseUnsignedShort(value); + } else if (type.equals(XSD_UNSIGNEDINT)) { + return parseUnsignedInt(value); + } else if (type.equals(XSD_UNSIGNEDLONG)) { + return parseUnsignedInt(value); + } else if (type.equals(XSD_DATETIME)) { + return parseDateTime(value); + } else if (type.equals(XSD_DATE)) { + return parseDate(value); + } else if (type.equals(XSD_TIME)) { + return parseTime(value); + } else if (type.equals(XSD_DURATION)) { + return parseDuration(value); + } else if (type.equals(XSD_HEXBIN)) { + return parseHexBinary(value); + } else if (type.equals(XSD_BASE64)) { + return parseBase64Binary(value); + } else if (type.equals(XSD_QNAME)) { + NamespaceContext namespaceContext = + (NamespaceContext)((context != null) ? context.getMetadata().get(NamespaceContext.class) : null); + return parseQName(value, namespaceContext); + } else if (type.equals(XSD_NOTATION)) { + NamespaceContext namespaceContext = + (NamespaceContext)((context != null) ? context.getMetadata().get(NamespaceContext.class) : null); + return parseQName(value, namespaceContext); + } else if (type.equals(XSD_YEAR)) { + return factory.newXMLGregorianCalendar(value); + } else if (type.equals(XSD_MONTH)) { + return factory.newXMLGregorianCalendar(value); + } else if (type.equals(XSD_DAY)) { + return factory.newXMLGregorianCalendar(value); + } else if (type.equals(XSD_YEARMONTH)) { + return factory.newXMLGregorianCalendar(value); + } else if (type.equals(XSD_MONTHDAY)) { + return factory.newXMLGregorianCalendar(value); + } else { + return value; + } + } + + @SuppressWarnings("deprecation") + private XMLGregorianCalendar toXMLGregorianCalendar(Date date) { + GregorianCalendar c = + new GregorianCalendar(date.getYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), + date.getSeconds()); + return factory.newXMLGregorianCalendar(c); + } + + private XMLGregorianCalendar toXMLGregorianCalendar(GregorianCalendar calendar) { + return factory.newXMLGregorianCalendar(calendar); + } + + public String toXMLLiteral(TypeInfo simpleType, Object obj, TransformationContext context) { + if (obj instanceof Float || obj instanceof Double) { + if (obj instanceof Float) { + return printDouble(((Float)obj).floatValue()); + } else { + return printDouble(((Double)obj).doubleValue()); + } + } else if (obj instanceof GregorianCalendar) { + GregorianCalendar calendar = (GregorianCalendar)obj; + return toXMLGregorianCalendar(calendar).toXMLFormat(); + } else if (obj instanceof Date) { + return toXMLGregorianCalendar((Date)obj).toXMLFormat(); + } else if (obj instanceof XMLGregorianCalendar) { + return ((XMLGregorianCalendar)obj).toXMLFormat(); + } else if (obj instanceof byte[]) { + if (simpleType != null) { + if (simpleType.getQName().equals(XSD_BASE64)) { + byteEncoding = BASE64_ENCODING; + } else if (simpleType.getQName().equals(XSD_HEXBIN)) { + byteEncoding = BASE64_ENCODING; + } + } + if (byteEncoding == BASE64_ENCODING) { + return printBase64Binary((byte[])obj); + } else if (byteEncoding == HEXBIN_ENCODING) { + return printHexBinary((byte[])obj); + } + } else if (obj instanceof QName) { + NamespaceContext namespaceContext = + (NamespaceContext)((context != null) ? context.getMetadata().get(NamespaceContext.class) : null); + return printQName((QName)obj, namespaceContext); + } + return obj.toString(); + } + + public static boolean isSimpleXSDType(QName typeName) { + return typeName.getNamespaceURI().equals(URI_2001_SCHEMA_XSD) + && XSD_SIMPLE_TYPES.get(typeName.getLocalPart()) != null; + } + + public int getByteEncoding() { + return byteEncoding; + } + + public void setByteEncoding(int byteEncoding) { + this.byteEncoding = byteEncoding; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/TransformerExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/TransformerExtension.java new file mode 100644 index 0000000000..374ac58e0d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/TransformerExtension.java @@ -0,0 +1,73 @@ +/* + * 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.spi.databinding.extension; + +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.TransformerRegistry; + +/** + * Base Implementation of Transformer which provides the registration to the transformer registry + * + * @version $Rev$ $Date$ + */ +@Service(Transformer.class) +@Scope("COMPOSITE") +@EagerInit +public abstract class TransformerExtension<S, T> implements Transformer { + + protected TransformerRegistry registry; + + protected TransformerExtension() { + super(); + } + + @Reference + public void setTransformerRegistry(TransformerRegistry registry) { + this.registry = registry; + } + + @Init + public void init() { + registry.registerTransformer(this); + } + + protected abstract Class getSourceType(); + + protected abstract Class getTargetType(); + + public String getSourceDataBinding() { + return getSourceType().getName(); + } + + public String getTargetDataBinding() { + return getTargetType().getName(); + } + + public int getWeight() { + // default to 50 + return 50; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/XSDDataTypeConverter.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/XSDDataTypeConverter.java new file mode 100644 index 0000000000..a0c75570bd --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/databinding/extension/XSDDataTypeConverter.java @@ -0,0 +1,940 @@ +/* + * 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.spi.databinding.extension; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.text.FieldPosition; +import java.text.Format; +import java.text.ParsePosition; +import java.util.Calendar; +import java.util.TimeZone; +import javax.xml.XMLConstants; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.Duration; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; + +/** + * Utility class for XSD data type conversions + */ +public class XSDDataTypeConverter { + public static final class Base64Binary { + private static final char[] S_BASE64CHAR = + {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', + 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', + '5', '6', '7', '8', '9', '+', '/'}; + + private static final char S_BASE64PAD = '='; + + private static final byte[] S_DECODETABLE = new byte[128]; + + static { + for (int i = 0; i < S_DECODETABLE.length; i++) { + S_DECODETABLE[i] = Byte.MAX_VALUE; // 127 + } + for (int i = 0; i < S_BASE64CHAR.length; i++) { + // 0 to 63 + S_DECODETABLE[S_BASE64CHAR[i]] = (byte) i; + } + } + + private Base64Binary() { + } + + /** + * + */ + public static byte[] decode(char[] data, int off, int len) { + char[] ibuf = new char[4]; + int ibufcount = 0; + byte[] obuf = new byte[len / 4 * 3 + 3]; + int obufcount = 0; + for (int i = off; i < off + len; i++) { + char ch = data[i]; + if (ch == S_BASE64PAD || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) { + ibuf[ibufcount++] = ch; + if (ibufcount == ibuf.length) { + ibufcount = 0; + obufcount += decode0(ibuf, obuf, obufcount); + } + } + } + if (obufcount == obuf.length) { + return obuf; + } + byte[] ret = new byte[obufcount]; + System.arraycopy(obuf, 0, ret, 0, obufcount); + return ret; + } + + /** + * + */ + public static void decode(char[] data, int off, int len, OutputStream ostream) throws IOException { + char[] ibuf = new char[4]; + int ibufcount = 0; + byte[] obuf = new byte[3]; + for (int i = off; i < off + len; i++) { + char ch = data[i]; + if (ch == S_BASE64PAD || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) { + ibuf[ibufcount++] = ch; + if (ibufcount == ibuf.length) { + ibufcount = 0; + int obufcount = decode0(ibuf, obuf, 0); + ostream.write(obuf, 0, obufcount); + } + } + } + } + + /** + * + */ + public static byte[] decode(String data) { + char[] ibuf = new char[4]; + int ibufcount = 0; + byte[] obuf = new byte[data.length() / 4 * 3 + 3]; + int obufcount = 0; + for (int i = 0; i < data.length(); i++) { + char ch = data.charAt(i); + if (ch == S_BASE64PAD || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) { + ibuf[ibufcount++] = ch; + if (ibufcount == ibuf.length) { + ibufcount = 0; + obufcount += decode0(ibuf, obuf, obufcount); + } + } + } + if (obufcount == obuf.length) { + return obuf; + } + byte[] ret = new byte[obufcount]; + System.arraycopy(obuf, 0, ret, 0, obufcount); + return ret; + } + + /** + * + */ + public static void decode(String data, OutputStream ostream) throws IOException { + char[] ibuf = new char[4]; + int ibufcount = 0; + byte[] obuf = new byte[3]; + for (int i = 0; i < data.length(); i++) { + char ch = data.charAt(i); + if (ch == S_BASE64PAD || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) { + ibuf[ibufcount++] = ch; + if (ibufcount == ibuf.length) { + ibufcount = 0; + int obufcount = decode0(ibuf, obuf, 0); + ostream.write(obuf, 0, obufcount); + } + } + } + } + + private static int decode0(char[] ibuf, byte[] obuf, int index) { + int wp = index; + int outlen = 3; + if (ibuf[3] == S_BASE64PAD) { + outlen = 2; + } + if (ibuf[2] == S_BASE64PAD) { + outlen = 1; + } + int b0 = S_DECODETABLE[ibuf[0]]; + int b1 = S_DECODETABLE[ibuf[1]]; + int b2 = S_DECODETABLE[ibuf[2]]; + int b3 = S_DECODETABLE[ibuf[3]]; + switch (outlen) { + case 1: + obuf[wp] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3); + return 1; + case 2: + obuf[wp++] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3); + obuf[wp] = (byte) (b1 << 4 & 0xf0 | b2 >> 2 & 0xf); + return 2; + case 3: + obuf[wp++] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3); + obuf[wp++] = (byte) (b1 << 4 & 0xf0 | b2 >> 2 & 0xf); + obuf[wp] = (byte) (b2 << 6 & 0xc0 | b3 & 0x3f); + return 3; + default: + throw new IllegalArgumentException("The character sequence is not base64 encoded."); + } + } + + /** + * Returns base64 representation of specified byte array. + */ + public static String encode(byte[] data) { + return encode(data, 0, data.length); + } + + /** + * Returns base64 representation of specified byte array. + */ + public static String encode(byte[] data, int off, int len) { + if (len <= 0) { + return ""; + } + char[] out = new char[len / 3 * 4 + 4]; + int rindex = off; + int windex = 0; + int rest = len - off; + while (rest >= 3) { + int i = + ((data[rindex] & 0xff) << 16) + ((data[rindex + 1] & 0xff) << 8) + + (data[rindex + 2] & 0xff); + out[windex++] = S_BASE64CHAR[i >> 18]; + out[windex++] = S_BASE64CHAR[(i >> 12) & 0x3f]; + out[windex++] = S_BASE64CHAR[(i >> 6) & 0x3f]; + out[windex++] = S_BASE64CHAR[i & 0x3f]; + rindex += 3; + rest -= 3; + } + if (rest == 1) { + int i = data[rindex] & 0xff; + out[windex++] = S_BASE64CHAR[i >> 2]; + out[windex++] = S_BASE64CHAR[(i << 4) & 0x3f]; + out[windex++] = S_BASE64PAD; + out[windex++] = S_BASE64PAD; + } else if (rest == 2) { + int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff); + out[windex++] = S_BASE64CHAR[i >> 10]; + out[windex++] = S_BASE64CHAR[(i >> 4) & 0x3f]; + out[windex++] = S_BASE64CHAR[(i << 2) & 0x3f]; + out[windex++] = S_BASE64PAD; + } + return new String(out, 0, windex); + } + + /** + * Outputs base64 representation of the specified byte array to a byte stream. + */ + public static void encode(byte[] data, int off, int len, OutputStream ostream) throws IOException { + if (len <= 0) { + return; + } + byte[] out = new byte[4]; + int rindex = off; + int rest = len - off; + while (rest >= 3) { + int i = + ((data[rindex] & 0xff) << 16) + ((data[rindex + 1] & 0xff) << 8) + + (data[rindex + 2] & 0xff); + out[0] = (byte) S_BASE64CHAR[i >> 18]; + out[1] = (byte) S_BASE64CHAR[(i >> 12) & 0x3f]; + out[2] = (byte) S_BASE64CHAR[(i >> 6) & 0x3f]; + out[3] = (byte) S_BASE64CHAR[i & 0x3f]; + ostream.write(out, 0, 4); + rindex += 3; + rest -= 3; + } + if (rest == 1) { + int i = data[rindex] & 0xff; + out[0] = (byte) S_BASE64CHAR[i >> 2]; + out[1] = (byte) S_BASE64CHAR[(i << 4) & 0x3f]; + out[2] = (byte) S_BASE64PAD; + out[3] = (byte) S_BASE64PAD; + ostream.write(out, 0, 4); + } else if (rest == 2) { + int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff); + out[0] = (byte) S_BASE64CHAR[i >> 10]; + out[1] = (byte) S_BASE64CHAR[(i >> 4) & 0x3f]; + out[2] = (byte) S_BASE64CHAR[(i << 2) & 0x3f]; + out[3] = (byte) S_BASE64PAD; + ostream.write(out, 0, 4); + } + } + + /** + * Outputs base64 representation of the specified byte array to a character stream. + */ + public static void encode(byte[] data, int off, int len, Writer writer) throws IOException { + if (len <= 0) { + return; + } + char[] out = new char[4]; + int rindex = off; + int rest = len - off; + int output = 0; + while (rest >= 3) { + int i = + ((data[rindex] & 0xff) << 16) + ((data[rindex + 1] & 0xff) << 8) + + (data[rindex + 2] & 0xff); + out[0] = S_BASE64CHAR[i >> 18]; + out[1] = S_BASE64CHAR[(i >> 12) & 0x3f]; + out[2] = S_BASE64CHAR[(i >> 6) & 0x3f]; + out[3] = S_BASE64CHAR[i & 0x3f]; + writer.write(out, 0, 4); + rindex += 3; + rest -= 3; + output += 4; + if (output % 76 == 0) { + writer.write("\n"); + } + } + if (rest == 1) { + int i = data[rindex] & 0xff; + out[0] = S_BASE64CHAR[i >> 2]; + out[1] = S_BASE64CHAR[(i << 4) & 0x3f]; + out[2] = S_BASE64PAD; + out[3] = S_BASE64PAD; + writer.write(out, 0, 4); + } else if (rest == 2) { + int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff); + out[0] = S_BASE64CHAR[i >> 10]; + out[1] = S_BASE64CHAR[(i >> 4) & 0x3f]; + out[2] = S_BASE64CHAR[(i << 2) & 0x3f]; + out[3] = S_BASE64PAD; + writer.write(out, 0, 4); + } + } + } + + /** + * <p/> + * Utility class for xs:hexbinary. </p> + */ + public static final class HexBinary { + private HexBinary() { + } + + /** + * Converts the string <code>pValue</code> into an array of hex bytes. + */ + public static byte[] decode(String pValue) { + if ((pValue.length() % 2) != 0) { + throw new IllegalArgumentException("A HexBinary string must have even length."); + } + byte[] result = new byte[pValue.length() / 2]; + int j = 0; + int i = 0; + while (i < pValue.length()) { + byte b; + char c = pValue.charAt(i++); + char d = pValue.charAt(i++); + if (c >= '0' && c <= '9') { + b = (byte) ((c - '0') << 4); + } else if (c >= 'A' && c <= 'F') { + b = (byte) ((c - 'A' + 10) << 4); + } else if (c >= 'a' && c <= 'f') { + b = (byte) ((c - 'a' + 10) << 4); + } else { + throw new IllegalArgumentException("Invalid hex digit: " + c); + } + if (d >= '0' && d <= '9') { + b += (byte) (d - '0'); + } else if (d >= 'A' && d <= 'F') { + b += (byte) (d - 'A' + 10); + } else if (d >= 'a' && d <= 'f') { + b += (byte) (d - 'a' + 10); + } else { + throw new IllegalArgumentException("Invalid hex digit: " + d); + } + result[j++] = b; + } + return result; + } + + /** + * Converts the byte array <code>pHexBinary</code> into a string. + */ + public static String encode(byte[] pHexBinary) { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < pHexBinary.length; i++) { + byte b = pHexBinary[i]; + byte c = (byte) ((b & 0xf0) >> 4); + if (c <= 9) { + result.append((char) ('0' + c)); + } else { + result.append((char) ('A' + c - 10)); + } + c = (byte) (b & 0x0f); + if (c <= 9) { + result.append((char) ('0' + c)); + } else { + result.append((char) ('A' + c - 10)); + } + } + return result.toString(); + } + + /** + * Creates a clone of the given byte array. + */ + public static byte[] getClone(byte[] pHexBinary) { + byte[] result = new byte[pHexBinary.length]; + System.arraycopy(pHexBinary, 0, result, 0, pHexBinary.length); + return result; + } + } + + public class XSDDateFormat extends XSDDateTimeFormat { + private static final long serialVersionUID = -1629412916827246627L; + + /** + * Creates a new instance. + */ + public XSDDateFormat() { + super(true, false); + } + } + + /** + * <p/> + * An instance of {@link java.text.Format}, which may be used to parse and format <code>xs:dateTime</code> values. + * </p> + */ + public static class XSDDateTimeFormat extends Format { + private static final long serialVersionUID = -1148332471737068969L; + + final boolean parseDate; + + final boolean parseTime; + + /** + * Creates a new instance. + */ + public XSDDateTimeFormat() { + this(true, true); + } + + XSDDateTimeFormat(boolean pParseDate, boolean pParseTime) { + parseDate = pParseDate; + parseTime = pParseTime; + } + + private void append(StringBuffer pBuffer, int pNum, int pMinLen) { + String s = Integer.toString(pNum); + for (int i = s.length(); i < pMinLen; i++) { + pBuffer.append('0'); + } + pBuffer.append(s); + } + + public StringBuffer format(Object pCalendar, StringBuffer pBuffer, FieldPosition pPos) { + assert pCalendar != null : "The Calendar argument must not be null."; + assert pBuffer != null : "The StringBuffer argument must not be null."; + assert pPos != null : "The FieldPosition argument must not be null."; + + Calendar cal = (Calendar) pCalendar; + if (parseDate) { + int year = cal.get(Calendar.YEAR); + if (year < 0) { + pBuffer.append('-'); + year = -year; + } + append(pBuffer, year, 4); + pBuffer.append('-'); + append(pBuffer, cal.get(Calendar.MONTH) + 1, 2); + pBuffer.append('-'); + append(pBuffer, cal.get(Calendar.DAY_OF_MONTH), 2); + if (parseTime) { + pBuffer.append('T'); + } + } + if (parseTime) { + append(pBuffer, cal.get(Calendar.HOUR_OF_DAY), 2); + pBuffer.append(':'); + append(pBuffer, cal.get(Calendar.MINUTE), 2); + pBuffer.append(':'); + append(pBuffer, cal.get(Calendar.SECOND), 2); + int millis = cal.get(Calendar.MILLISECOND); + if (millis > 0) { + pBuffer.append('.'); + append(pBuffer, millis, 3); + } + } + TimeZone tz = cal.getTimeZone(); + // JDK 1.4: int offset = tz.getOffset(cal.getTimeInMillis()); + int offset = cal.get(Calendar.ZONE_OFFSET); + if (tz.inDaylightTime(cal.getTime())) { + offset += cal.get(Calendar.DST_OFFSET); + } + if (offset == 0) { + pBuffer.append('Z'); + } else { + if (offset < 0) { + pBuffer.append('-'); + offset = -offset; + } else { + pBuffer.append('+'); + } + int minutes = offset / (60 * 1000); + int hours = minutes / 60; + minutes -= hours * 60; + append(pBuffer, hours, 2); + pBuffer.append(':'); + append(pBuffer, minutes, 2); + } + return pBuffer; + } + + private int parseInt(String pString, int offset, StringBuffer pDigits) { + int length = pString.length(); + int pOffset = offset; + pDigits.setLength(0); + while (pOffset < length) { + char c = pString.charAt(pOffset); + if (Character.isDigit(c)) { + pDigits.append(c); + ++pOffset; + } else { + break; + } + } + return pOffset; + } + + public Object parseObject(String pString, ParsePosition pParsePosition) { + assert pString != null : "The String argument must not be null."; + assert pParsePosition != null : "The ParsePosition argument must not be null."; + int offset = pParsePosition.getIndex(); + int length = pString.length(); + + boolean isMinus = false; + StringBuffer digits = new StringBuffer(); + int year = 0; + int month = 0; + int mday = 0; + if (parseDate) { + // Sign + if (offset < length) { + char c = pString.charAt(offset); + if (c == '+') { + ++offset; + } else if (c == '-') { + ++offset; + isMinus = true; + } + } + + offset = parseInt(pString, offset, digits); + if (digits.length() < 4) { + pParsePosition.setErrorIndex(offset); + return null; + } + year = Integer.parseInt(digits.toString()); + + if (offset < length && pString.charAt(offset) == '-') { + ++offset; + } else { + pParsePosition.setErrorIndex(offset); + return null; + } + + offset = parseInt(pString, offset, digits); + if (digits.length() != 2) { + pParsePosition.setErrorIndex(offset); + return null; + } + month = Integer.parseInt(digits.toString()); + + if (offset < length && pString.charAt(offset) == '-') { + ++offset; + } else { + pParsePosition.setErrorIndex(offset); + return null; + } + + offset = parseInt(pString, offset, digits); + if (digits.length() != 2) { + pParsePosition.setErrorIndex(offset); + return null; + } + mday = Integer.parseInt(digits.toString()); + + if (parseTime) { + if (offset < length && pString.charAt(offset) == 'T') { + ++offset; + } else { + pParsePosition.setErrorIndex(offset); + return null; + } + } + } else { + year = month = mday = 0; + } + + int hour = 0; + int minute = 0; + int second = 0; + int millis = 0; + if (parseTime) { + offset = parseInt(pString, offset, digits); + if (digits.length() != 2) { + pParsePosition.setErrorIndex(offset); + return null; + } + hour = Integer.parseInt(digits.toString()); + + if (offset < length && pString.charAt(offset) == ':') { + ++offset; + } else { + pParsePosition.setErrorIndex(offset); + return null; + } + + offset = parseInt(pString, offset, digits); + if (digits.length() != 2) { + pParsePosition.setErrorIndex(offset); + return null; + } + minute = Integer.parseInt(digits.toString()); + + if (offset < length && pString.charAt(offset) == ':') { + ++offset; + } else { + pParsePosition.setErrorIndex(offset); + return null; + } + + offset = parseInt(pString, offset, digits); + if (digits.length() != 2) { + pParsePosition.setErrorIndex(offset); + return null; + } + second = Integer.parseInt(digits.toString()); + + if (offset < length && pString.charAt(offset) == '.') { + ++offset; + offset = parseInt(pString, offset, digits); + if (digits.length() > 0) { + millis = Integer.parseInt(digits.toString()); + } else { + millis = 0; + } + } else { + millis = 0; + } + } else { + hour = minute = second = millis = 0; + } + + digits.setLength(0); + digits.append("GMT"); + if (offset < length) { + char c = pString.charAt(offset); + if (c == 'Z') { + // Ignore UTC, it is the default + ++offset; + } else if (c == '+' || c == '-') { + digits.append(c); + ++offset; + for (int i = 0; i < 5; i++) { + if (offset >= length) { + pParsePosition.setErrorIndex(offset); + return null; + } + c = pString.charAt(offset); + if ((i != 2 && Character.isDigit(c)) || (i == 2 && c == ':')) { + digits.append(c); + } else { + pParsePosition.setErrorIndex(offset); + return null; + } + ++offset; + } + } + } + + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(digits.toString())); + cal.set(isMinus ? -year : year, parseDate ? month - 1 : month, mday, hour, minute, second); + cal.set(Calendar.MILLISECOND, millis); + pParsePosition.setIndex(offset); + return cal; + } + } + + public static class XSDTimeFormat extends XSDDateTimeFormat { + private static final long serialVersionUID = 1346506860724640517L; + + /** + * Creates a new instance. + */ + public XSDTimeFormat() { + super(false, true); + } + } + + private static final long MAX_UNSIGNED_INT = (((long) Integer.MAX_VALUE) * 2) + 1; + + private static final int MAX_UNSIGNED_SHORT = Short.MAX_VALUE * 2 + 1; + + public String parseAnySimpleType(String value) { + return value; + } + + public byte[] parseBase64Binary(String value) { + return Base64Binary.decode(value); + } + + public boolean parseBoolean(String value) { + return Boolean.valueOf(value).booleanValue(); + } + + public byte parseByte(String value) { + return Byte.parseByte(value); + } + + public Calendar parseDate(String value) { + XSDDateFormat format = new XSDDateFormat(); + ParsePosition pos = new ParsePosition(0); + Calendar cal = (Calendar) format.parseObject(value, pos); + if (cal == null) { + throw new IllegalArgumentException("Failed to parse date " + value + " at:" + + value.substring(pos.getErrorIndex())); + } + return cal; + } + + public Calendar parseDateTime(String value) { + XSDDateTimeFormat format = new XSDDateTimeFormat(); + ParsePosition pos = new ParsePosition(0); + Calendar cal = (Calendar) format.parseObject(value, pos); + if (cal == null) { + throw new IllegalArgumentException("Failed to parse dateTime " + value + " at:" + + value.substring(pos.getErrorIndex())); + } + return cal; + } + + public BigDecimal parseDecimal(String value) { + return new BigDecimal(value); + } + + public double parseDouble(String value) { + if ("INF".equals(value)) { + return Double.POSITIVE_INFINITY; + } else if ("-INF".equals(value)) { + return Double.NEGATIVE_INFINITY; + } else if ("NaN".equals(value)) { + return Double.NaN; + } else { + return Double.parseDouble(value); + } + } + + public Duration parseDuration(String pDuration) { + try { + return DatatypeFactory.newInstance().newDuration(pDuration); + } catch (DatatypeConfigurationException e) { + throw new IllegalArgumentException(e); + } + } + + public float parseFloat(String value) { + if ("INF".equals(value)) { + return Float.POSITIVE_INFINITY; + } else if ("-INF".equals(value)) { + return Float.NEGATIVE_INFINITY; + } else if ("NaN".equals(value)) { + return Float.NaN; + } else { + return Float.parseFloat(value); + } + } + + public byte[] parseHexBinary(String value) { + return HexBinary.decode(value); + } + + public int parseInt(String value) { + return Integer.parseInt(value); + } + + public BigInteger parseInteger(String value) { + return new BigInteger(value); + } + + public long parseLong(String value) { + return Long.parseLong(value); + } + + public QName parseQName(String value, NamespaceContext context) { + int offset = value.indexOf(':'); + String uri; + String localName; + switch (offset) { + case -1: + localName = value; + uri = context.getNamespaceURI(""); + if (uri == null) { + // Should not happen, indicates an error in the + // NamespaceContext + // implementation + throw new IllegalArgumentException("The default prefix is not bound."); + } + break; + case 0: + throw new IllegalArgumentException("Default prefix must be indicated by not using a colon: " + + value); + default: + String prefix = value.substring(0, offset); + localName = value.substring(offset + 1); + uri = context.getNamespaceURI(prefix); + if (uri == null) { + throw new IllegalArgumentException("The prefix " + prefix + " is not bound."); + } + } + return new QName(uri, localName); + } + + public short parseShort(String value) { + return Short.parseShort(value); + } + + public String parseString(String value) { + return value; + } + + public Calendar parseTime(String value) { + XSDTimeFormat format = new XSDTimeFormat(); + ParsePosition pos = new ParsePosition(0); + Calendar cal = (Calendar) format.parseObject(value, pos); + if (cal == null) { + throw new IllegalArgumentException("Failed to parse time " + value + " at:" + + value.substring(pos.getErrorIndex())); + } + return cal; + } + + public long parseUnsignedInt(String value) { + long l = Long.parseLong(value); + if (l < 0) { + throw new IllegalArgumentException("Failed to parse UnsignedInt " + value + + ": result is negative"); + } + if (l > MAX_UNSIGNED_INT) { + throw new IllegalArgumentException("Failed to parse UnsignedInt " + value + + ": result exceeds maximum value " + MAX_UNSIGNED_INT); + } + return l; + } + + public int parseUnsignedShort(String value) { + int i = Integer.parseInt(value); + if (i < 0) { + throw new IllegalArgumentException("Failed to parse UnsignedShort " + value + + ": result is negative"); + } + if (i > MAX_UNSIGNED_SHORT) { + throw new IllegalArgumentException("Failed to parse UnsignedShort " + value + + ": result exceeds maximum value " + MAX_UNSIGNED_SHORT); + } + return i; + } + + public String printAnySimpleType(String value) { + return value; + } + + public String printBase64Binary(byte[] value) { + return Base64Binary.encode(value); + } + + public String printBoolean(boolean value) { + return (value ? Boolean.TRUE : Boolean.FALSE).toString(); + } + + public String printByte(byte value) { + return Byte.toString(value); + } + + public String printDate(Calendar value) { + return new XSDDateFormat().format(value); + } + + public String printDateTime(Calendar value) { + return new XSDDateTimeFormat().format(value); + } + + public String printDecimal(BigDecimal value) { + return value.toString(); + } + + public String printDouble(double value) { + return Double.toString(value); + } + + public String printDuration(Duration pDuration) { + return pDuration.toString(); + } + + public String printFloat(float value) { + return Float.toString(value); + } + + public String printHexBinary(byte[] value) { + return HexBinary.encode(value); + } + + public String printInt(int value) { + return Integer.toString(value); + } + + public String printInteger(BigInteger value) { + return value.toString(); + } + + public String printLong(long value) { + return Long.toString(value); + } + + public String printQName(QName value, NamespaceContext context) { + String prefix = context.getPrefix(value.getNamespaceURI()); + if (prefix == null) { + throw new IllegalArgumentException("The namespace URI " + value.getNamespaceURI() + + " is not bound."); + } else if (XMLConstants.DEFAULT_NS_PREFIX.equals(prefix)) { + return value.getLocalPart(); + } else { + return prefix + ":" + value.getLocalPart(); + } + } + + public String printShort(short value) { + return Short.toString(value); + } + + public String printString(String value) { + return value; + } + + public String printTime(Calendar value) { + return new XSDTimeFormat().format(value); + } + + public String printUnsignedInt(long value) { + return Long.toString(value); + } + + public String printUnsignedShort(int value) { + return Integer.toString(value); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ArtifactResolver.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ArtifactResolver.java new file mode 100644 index 0000000000..78d2bd3770 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ArtifactResolver.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.spi.deployer; + +import java.net.URI; +import java.net.URL; +import java.util.Map; + + +/** + * SCA Assemblies reference many artifacts of a wide variety of types. These + * include: + * <ul> + * <li> Reference from one SCA composite to another SCA composite + * <li> Reference to PolicySet files + * <li> Reference to interface definition files, either WSDL or Java interfaces + * <li> Reference to XSD files + * <li> Reference to any of a wide variety of implementation artifact files, + * including Java classes, BPEL scripts, C++ DLLs and classes, PHP scripts + * </ul> + * In the SCA assemblies, these various artifacts are referenced using either + * QNames or URIs that do not point to a specific entity. Resolution of these + * references to concrete artifacts is necessary as part of the operation of the + * SCA domain. + * + * @version $Rev$ $Date$ + */ +public interface ArtifactResolver { + /** + * Resolve an artifact by the qualified name + * + * @param contribution the URI of the contribution + * @param modelClass The java type of the artifact + * @param namespace The namespace of the artifact + * @param name The name of the artifact + * @param attributes Additional attributes that can be used to constrain the + * resolution + * @param context The deployment context + * @return The resolved artifact + */ + <T> T resolve(URI contribution, + Class<T> modelClass, + String namespace, + String name, + Map attributes, + DeploymentContext context); + + /** + * Resolve an artifact by the URI. Some typical use cases are: + * <ul> + * <li>Reference a XML schema using + * {http://www.w3.org/2001/XMLSchema-instance}schemaLocation or + * <li>Reference a list of WSDLs using + * {http://www.w3.org/2004/08/wsdl-instance}wsdlLocation + * </ul> + * @param targetNamespace The target namespace of the referenced artifact, + * if the targetNamespace is null, then it's not specified + * @param location The URI of the referenced artifact, it can be absolute or + * relative + * @param baseURI The URI of the owning artifact + * + * @return The URI of the resolved artifact + */ + URL resolve(URI contribution, String targetNamespace, String location, String baseURI); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ArtifactResolverRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ArtifactResolverRegistry.java new file mode 100644 index 0000000000..f24fb7269a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ArtifactResolverRegistry.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.spi.deployer; + + +/** + * Registry for artifact resolvers + * + * @version $Rev$ $Date$ + */ +public interface ArtifactResolverRegistry extends ArtifactResolver { + /** + * Register a resolver by the type of artifacts. For example, you can + * register a resolver to resolve WSDL model objects and other resolver + * for java classes + * + * @param modelClass The java type of the model object + * @param resolver The resolver + */ + void registerResolver(Class<?> modelClass, ArtifactResolver resolver); + + /** + * Unregister all resolvers for the given model class + * + * @param modelClass + */ + void unregisterResolver(Class<?> modelClass); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ChangeSetHandler.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ChangeSetHandler.java new file mode 100644 index 0000000000..fead0453be --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ChangeSetHandler.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.spi.deployer; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.tuscany.host.deployment.DeploymentException; + +/** + * Interface implemented by services that process assembly change sets. + * + * @version $Rev$ $Date$ + */ +public interface ChangeSetHandler { + /** + * Returns the content type that this implementation can handle. + * + * @return the content type that this implementation can handle + */ + String getContentType(); + + /** + * Apply the changes in the supplied changeSet stream to an Assembly. + * The content on the stream must match the content type this implementation can handle. + * + * @param changeSet the set of changes to apply represented as the supported content type + * @throws DeploymentException if there was a problem applying the changes + * @throws IOException if there was a problem reading the stream + */ + void applyChanges(InputStream changeSet) throws DeploymentException, IOException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ChangeSetHandlerRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ChangeSetHandlerRegistry.java new file mode 100644 index 0000000000..df0bf4109b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ChangeSetHandlerRegistry.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.spi.deployer; + +/** + * Registry for ChangeSetHandler implementations. + * + * @version $Rev$ $Date$ + */ +public interface ChangeSetHandlerRegistry { + void register(ChangeSetHandler handler); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/CompositeClassLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/CompositeClassLoader.java new file mode 100644 index 0000000000..63db5b9e24 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/CompositeClassLoader.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.spi.deployer; + +import java.net.URLClassLoader; +import java.net.URL; +import java.net.URLStreamHandlerFactory; + +/** + * ClassLoader associated with a composite. + * + * @version $Rev$ $Date$ + */ +public class CompositeClassLoader extends URLClassLoader { + private static final URL[] NOURLS = {}; + + public CompositeClassLoader(ClassLoader classLoader) { + super(NOURLS, classLoader); + } + + public CompositeClassLoader(URL[] urls, ClassLoader classLoader) { + super(urls, classLoader); + } + + public CompositeClassLoader(URL[] urls) { + super(urls); + } + + public CompositeClassLoader(URL[] urls, ClassLoader classLoader, URLStreamHandlerFactory urlStreamHandlerFactory) { + super(urls, classLoader, urlStreamHandlerFactory); + } + + public void addURL(URL url) { + super.addURL(url); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ContentTypeDescriber.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ContentTypeDescriber.java new file mode 100644 index 0000000000..e723080781 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ContentTypeDescriber.java @@ -0,0 +1,36 @@ +/* + * 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.spi.deployer; + +import java.net.URL; + +/** + * Provide content type for a given resource + * + * @version $Rev$ $Date$ + */ +public interface ContentTypeDescriber { + /** + * @param resourceURL the resource url + * @param defaultContentType the default content type + * @return the content type + */ + String getContentType(URL resourceURL, String defaultContentType); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ContributionProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ContributionProcessor.java new file mode 100644 index 0000000000..a3d57870a7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ContributionProcessor.java @@ -0,0 +1,66 @@ +/* + * 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.spi.deployer; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; + +import org.apache.tuscany.host.deployment.DeploymentException; +import org.apache.tuscany.spi.model.Contribution; + +/** + * Interface for services that can process contributions. + * + * @version $Rev$ $Date$ + */ +public interface ContributionProcessor { + /** + * Process a contribution or an artifact in the contribution from the input + * stream. The processor might add artifacts or model objects to the + * contribution object. + * + * @param contribution The contribution model that will be used to hold the + * results from the processing + * @param source The URI for the contribution/artifact + * @param inputStream The input stream for the contribution. The stream will + * not be closed but the read position after the call is + * undefined + * @throws DeploymentException if there was a problem with the contribution + * @throws IOException if there was a problem reading the stream + */ + void processContent(Contribution contribution, URI source, InputStream inputStream) throws DeploymentException, + IOException; + + /** + * Process a contribution from another model object. It will be used for the + * case that one artifact has other inline artifacts, for example, the WSDL + * with inline schemas. The schema contribution processor should be able to + * load the schema model from the WSDL definition. + * + * @param contribution The contribution model that will be used to hold the + * results from the processing + * @param source The URI for the contribution/artifact. + * @param modelObject A model object for further processing by the processor + * @throws DeploymentException + * @throws IOException + */ + void processModel(Contribution contribution, URI source, Object modelObject) throws DeploymentException, + IOException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ContributionProcessorRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ContributionProcessorRegistry.java new file mode 100644 index 0000000000..c1b6e93cb3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ContributionProcessorRegistry.java @@ -0,0 +1,36 @@ +/* + * 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.spi.deployer; + +/** + * @version $Rev$ $Date$ + */ +public interface ContributionProcessorRegistry extends ContributionProcessor { + /** + * Register a ContributionProcessor using the content type as the key + * @param processor + */ + void register(String contentType, ContributionProcessor processor); + + /** + * Unregister a ContributionProcessor by content type + * @param contentType + */ + void unregister(String contentType); +}
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ContributionRepository.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ContributionRepository.java new file mode 100644 index 0000000000..28d7e1f6a1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/ContributionRepository.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.spi.deployer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.util.List;
+
+public interface ContributionRepository {
+
+ /**
+ * Copies a contribution to the repository.
+ *
+ * @param contribution A URl pointing to the contribution being copied to
+ * the repository
+ * @param contributionStream InputStream with the content of the
+ * distribution
+ */
+ URL store(URI contribution, InputStream contributionStream) throws IOException;
+
+ /**
+ * Look up the contribution by URI
+ *
+ * @param contribution The URI of the contribution
+ * @return A URL pointing to the content of the contribution in the
+ * repository, it will be null if the contribution cannot be found
+ * in the repository
+ */
+ URL find(URI contribution);
+
+ /**
+ * Remove a contribution from the repository
+ *
+ * @param contribution The URI of the contribution to be removed
+ */
+ void remove(URI contribution);
+
+ /**
+ * Get list of URIs for all the contributions in the repository
+ *
+ * @return A list of contribution URIs
+ */
+ List<URI> list();
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/Deployer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/Deployer.java new file mode 100644 index 0000000000..0b655fc5aa --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/Deployer.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.spi.deployer; + +import java.util.Collection; + +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.ComponentException; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.model.ComponentDefinition; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.resolver.ResolutionException; + +/** + * Interface that can be used to deploy SCA bundles to a runtime. + * + * @version $Rev$ $Date$ + */ +public interface Deployer { + /** + * Deploy a component as a child of the supplied parent. This operation creates a new component in the runtime to + * represent the supplied component definition. The type of component created will depend on the component + * definition implementation; for example, if the implementation of the component definition is a composite then + * typically a CompositeComponent would be returned. + * + * @param parent the parent context + * @param componentDefinition the component definition as parsed from an assembly + * @return the newly deployed component + */ + <I extends Implementation<?>> Collection<Component> deploy(Component parent, + ComponentDefinition<I> componentDefinition) + throws LoaderException, BuilderException, ComponentException, ResolutionException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/DeploymentContext.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/DeploymentContext.java new file mode 100644 index 0000000000..37354730d0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/DeploymentContext.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.spi.deployer; + +import java.net.URI; +import java.net.URL; +import java.util.Map; +import javax.xml.stream.XMLInputFactory; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.ScopeContainer; + +/** + * A holder that can be used during the load process to store information that is not part of the logical assembly + * model. This should be regarded as transient and references to this context should not be stored inside the model. + * + * @version $Rev$ $Date$ + */ +public interface DeploymentContext { + /** + * Returns the parent of this deployment context. Will be null for the context created at the root of a deployment. + * + * @return the parent of this deployment context; may be null + */ + DeploymentContext getParent(); + + /** + * Returns a class loader that can be used to load application resources. + * + * @return a class loader that can be used to load application resources + */ + ClassLoader getClassLoader(); + + /** + * Returns a factory that can be used to obtain an StAX XMLStreamReader. + * + * @return a factory that can be used to obtain an StAX XMLStreamReader + */ + XMLInputFactory getXmlFactory(); + + /** + * Returns the ScopeContainer for the COMPOSITE scope that will be associated with this deployment unit. + * + * @return the ScopeContainer for the COMPOSITE scope that will be associated with this deployment unit + */ + ScopeContainer getCompositeScope(); + + /** + * Returns the location of the SCDL definition being deployed. + * + * @return the location of the SCDL definition being deployed + */ + URL getScdlLocation(); + + /** + * Returns the URI of the composite component currently being deployed. + * + * @return the URI of the composite component currently being deployed + */ + URI getComponentId(); + + /** + * Returns true if the autowire is enabled for the current deployment. + * + * @return true if the autowire is enabled for the current deployment + */ + boolean isAutowire(); + + /** + * Sets if the autowire is enabled for the current deployment. + * + * @param autowire true if autowire is enabled + */ + void setAutowire(boolean autowire); + + @Deprecated + Map<URI, Component> getComponents(); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/DeploymentMonitor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/DeploymentMonitor.java new file mode 100644 index 0000000000..12ce6e73e6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/deployer/DeploymentMonitor.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.spi.deployer; + +import org.apache.tuscany.api.TuscanyException; +import org.apache.tuscany.api.annotation.LogLevel; + +/** + * @version $Rev$ $Date$ + */ +public interface DeploymentMonitor { + + @LogLevel("FINER") + void startDeployment(); + + @LogLevel("FINER") + void endDeployment(); + + @LogLevel("SEVERE") + void deploymentError(TuscanyException e); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/AbstractEventPublisher.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/AbstractEventPublisher.java new file mode 100644 index 0000000000..cc20866cbb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/AbstractEventPublisher.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.spi.event; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Base implementation of an <code>EventPublisher</code> + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractEventPublisher implements EventPublisher { + protected static final EventFilter TRUE_FILTER = new TrueFilter(); + protected Map<EventFilter, List<RuntimeEventListener>> listeners; + + public void addListener(RuntimeEventListener listener) { + addListener(TRUE_FILTER, listener); + } + + public void removeListener(RuntimeEventListener listener) { + assert listener != null : "Listener cannot be null"; + synchronized (getListeners()) { + for (List<RuntimeEventListener> currentList : getListeners().values()) { + for (RuntimeEventListener current : currentList) { + if (current == listener) { + currentList.remove(current); + return; + } + } + } + } + } + + public void addListener(EventFilter filter, RuntimeEventListener listener) { + assert listener != null : "Listener cannot be null"; + synchronized (getListeners()) { + List<RuntimeEventListener> list = getListeners().get(filter); + if (list == null) { + list = new CopyOnWriteArrayList<RuntimeEventListener>(); + listeners.put(filter, list); + } + list.add(listener); + } + } + + public void publish(Event event) { + assert event != null : "Event object was null"; + for (Map.Entry<EventFilter, List<RuntimeEventListener>> entry : getListeners().entrySet()) { + if (entry.getKey().match(event)) { + for (RuntimeEventListener listener : entry.getValue()) { + listener.onEvent(event); + } + } + } + } + + protected Map<EventFilter, List<RuntimeEventListener>> getListeners() { + if (listeners == null) { + listeners = new ConcurrentHashMap<EventFilter, List<RuntimeEventListener>>(); + } + return listeners; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/Event.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/Event.java new file mode 100644 index 0000000000..b874ca43c9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/Event.java @@ -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. + */ +package org.apache.tuscany.spi.event; + +/** + * Represents an event that is propagated in the runtime + * + * @version $$Rev$$ $$Date$$ + */ +public interface Event { + + /** + * Returns the source of the event + */ + Object getSource(); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/EventFilter.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/EventFilter.java new file mode 100644 index 0000000000..d61d04cdc8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/EventFilter.java @@ -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. + */ +package org.apache.tuscany.spi.event; + +/** + * Evaluates whether a {@link RuntimeEventListener} is applicable to a given runtime event + * + * @version $$Rev$$ $$Date$$ + */ +public interface EventFilter { + + /** + * Performs the actual evaluation on an event + */ + boolean match(Event event); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/EventPublisher.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/EventPublisher.java new file mode 100644 index 0000000000..35df22fb9c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/EventPublisher.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.spi.event; + +/** + * Publishes events in the runtime + * + * @version $$Rev$$ $$Date$$ + */ +public interface EventPublisher { + + /** + * Publish an event + */ + void publish(Event object); + + /** + * Registers a listener to receive notifications for the context + */ + void addListener(RuntimeEventListener listener); + + /** + * Registers a listener to receive notifications for the context + */ + void addListener(EventFilter filter, RuntimeEventListener listener); + + + /** + * Removes a previously registered listener + */ + void removeListener(RuntimeEventListener listener); + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/RuntimeEventListener.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/RuntimeEventListener.java new file mode 100644 index 0000000000..5146559098 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/RuntimeEventListener.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.spi.event; + +import java.util.EventListener; + +/** + * Listeners observe events fired in the SCA runtime. + * + * @version $Rev$ $Date$ + */ +public interface RuntimeEventListener extends EventListener { + + void onEvent(Event event); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/TrueFilter.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/TrueFilter.java new file mode 100644 index 0000000000..81382b86ac --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/event/TrueFilter.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.spi.event; + +/** + * An event filter that always returns a true condition + * + * @version $$Rev$$ $$Date$$ + */ +public class TrueFilter implements EventFilter { + + public boolean match(Event event) { + return true; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/AbstractComponentExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/AbstractComponentExtension.java new file mode 100644 index 0000000000..eb2f3a4bdb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/AbstractComponentExtension.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.spi.extension; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.osoa.sca.ComponentContext; + +import org.apache.tuscany.spi.component.AbstractSCAObject; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.DuplicateNameException; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.RegistrationException; +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.model.PropertyValue; + +/** + * @version Provides support for property accessors. + */ +public abstract class AbstractComponentExtension extends AbstractSCAObject implements Component { + protected final List<Service> services = new ArrayList<Service>(); + protected final List<Reference> references = new ArrayList<Reference>(); + protected final Map<String, SCAObject> children = new ConcurrentHashMap<String, SCAObject>(); + protected ScopeContainer scopeContainer; + private Map<String, PropertyValue<?>> defaultPropertyValues; + + /** + * Initializes component name and parent. + * + * @param name Name of the component. + */ + public AbstractComponentExtension(URI name) { + super(name); + } + + public void setScopeContainer(ScopeContainer scopeContainer) { + this.scopeContainer = scopeContainer; + } + + public Map<String, PropertyValue<?>> getDefaultPropertyValues() { + return defaultPropertyValues; + } + + public void setDefaultPropertyValues(Map<String, PropertyValue<?>> defaultPropertyValues) { + this.defaultPropertyValues = defaultPropertyValues; + } + + public boolean isOptimizable() { + return false; + } + + public Service getService(String name) { + if (name == null) { + if (services.size() == 1) { + return services.get(0); + } else { + return null; + } + } + SCAObject o = children.get(name); + if (o instanceof Service) { + return (Service) o; + } + return null; + } + + public Reference getReference(String name) { + if (name == null) { + if (references.size() == 1) { + return references.get(0); + } else { + return null; + } + } + SCAObject o = children.get(name); + if (o instanceof Reference) { + return (Reference) o; + } + return null; + } + + public void register(Service service) throws RegistrationException { + String name = service.getUri().getFragment(); + assert name != null; + if (children.get(name) != null) { + String uri = service.getUri().toString(); + throw new DuplicateNameException("A service or reference is already registered with the name", uri); + } + children.put(name, service); + synchronized (services) { + services.add(service); + } + } + + public void register(Reference reference) throws RegistrationException { + String name = reference.getUri().getFragment(); + assert name != null; + if (children.get(name) != null) { + String uri = reference.getUri().toString(); + throw new DuplicateNameException("A service or reference is already registered with the name", uri); + } + children.put(name, reference); + synchronized (services) { + references.add(reference); + } + } + + public ComponentContext getComponentContext() { + // by default, a component will not give out a component context + return null; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/AtomicComponentExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/AtomicComponentExtension.java new file mode 100644 index 0000000000..873760ab39 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/AtomicComponentExtension.java @@ -0,0 +1,112 @@ +/* + * 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.spi.extension; + +import java.net.URI; + +import org.apache.tuscany.spi.CoreRuntimeException; +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.ComponentException; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.TargetDestructionException; +import org.apache.tuscany.spi.component.TargetInitializationException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.wire.ProxyService; + +/** + * An extension point for atomic component type, which new implementation types may extend + * + * @version $$Rev$$ $$Date$$ + */ +public abstract class AtomicComponentExtension extends AbstractComponentExtension implements AtomicComponent { + protected ScopeContainer scopeContainer; + protected Scope scope; + protected ProxyService proxyService; + protected WorkContext workContext; + private final int initLevel; + private final long maxIdleTime; + private final long maxAge; + + protected AtomicComponentExtension(URI name, ProxyService proxyService, WorkContext workContext, int initLevel) { + this(name, proxyService, workContext, initLevel, -1, -1); + } + + protected AtomicComponentExtension(URI name, + ProxyService proxyService, + WorkContext workContext, + int initLevel, + long maxIdleTime, + long maxAge) { + super(name); + assert !(maxIdleTime > 0 && maxAge > 0); + this.proxyService = proxyService; + this.workContext = workContext; + this.initLevel = initLevel; + this.maxIdleTime = maxIdleTime; + this.maxAge = maxAge; + } + + public Scope getScope() { + return scope; + } + + public int getInitLevel() { + return initLevel; + } + + public boolean isEagerInit() { + return initLevel > 0; + } + + public boolean isDestroyable() { + return false; + } + + public long getMaxIdleTime() { + return maxIdleTime; + } + + public long getMaxAge() { + return maxAge; + } + + public void setScopeContainer(ScopeContainer scopeContainer) { + this.scopeContainer = scopeContainer; + scope = scopeContainer.getScope(); + } + + public void start() throws CoreRuntimeException { + super.start(); + scopeContainer.register(this); + } + + public void init(Object instance) throws TargetInitializationException { + + } + + public void destroy(Object instance) throws TargetDestructionException { + + } + + public void removeInstance() throws ComponentException { + scopeContainer.remove(this); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/BindingBuilderExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/BindingBuilderExtension.java new file mode 100644 index 0000000000..8490eb187d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/BindingBuilderExtension.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.extension; + +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.builder.BindingBuilder; +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.builder.BuilderRegistry; +import org.apache.tuscany.spi.component.ReferenceBinding; +import org.apache.tuscany.spi.component.ServiceBinding; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.BindingDefinition; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceDefinition; + +/** + * An extension point for binding builders. When adding support for new serviceBindings, implementations may extend this + * class as a convenience. + * + * @version $$Rev$$ $$Date$$ + */ +@EagerInit +public abstract class BindingBuilderExtension<B extends BindingDefinition> implements BindingBuilder<B> { + protected BuilderRegistry builderRegistry; + + @Reference + public void setBuilderRegistry(BuilderRegistry registry) { + this.builderRegistry = registry; + } + + @Init + public void init() { + builderRegistry.register(getBindingType(), this); + } + + public ServiceBinding build(ServiceDefinition serviceDefinition, B bindingDefinition, DeploymentContext context) + throws BuilderException { + return null; + } + + public ReferenceBinding build(ReferenceDefinition boundReferenceDefinition, + B bindingDefinition, + DeploymentContext context) throws BuilderException { + return null; + } + + protected abstract Class<B> getBindingType(); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ComponentBuilderExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ComponentBuilderExtension.java new file mode 100644 index 0000000000..203a703133 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ComponentBuilderExtension.java @@ -0,0 +1,78 @@ +/* + * 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.spi.extension; + +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.builder.BuilderRegistry; +import org.apache.tuscany.spi.builder.ComponentBuilder; +import org.apache.tuscany.spi.component.ScopeRegistry; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.policy.PolicyBuilderRegistry; +import org.apache.tuscany.spi.wire.ProxyService; + +/** + * An extension point for component builders. When adding support for new component types, implementations may extend + * this class as a convenience. + * + * @version $$Rev$$ $$Date$$ + */ +@EagerInit +public abstract class ComponentBuilderExtension<I extends Implementation<?>> implements ComponentBuilder<I> { + protected BuilderRegistry builderRegistry; + protected ScopeRegistry scopeRegistry; + protected ProxyService proxyService; + protected WorkContext workContext; + protected PolicyBuilderRegistry policyBuilderRegistry; + + @Reference + public void setBuilderRegistry(BuilderRegistry registry) { + this.builderRegistry = registry; + } + + @Reference + public void setScopeRegistry(ScopeRegistry scopeRegistry) { + this.scopeRegistry = scopeRegistry; + } + + @Reference + public void setProxyService(ProxyService proxyService) { + this.proxyService = proxyService; + } + + @Reference + public void setWorkContext(WorkContext workContext) { + this.workContext = workContext; + } + + @Reference + public void setPolicyBuilderRegistry(PolicyBuilderRegistry registry) { + policyBuilderRegistry = registry; + } + + @Init + public void init() { + builderRegistry.register(getImplementationType(), this); + } + + protected abstract Class<I> getImplementationType(); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ComponentTypeLoaderExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ComponentTypeLoaderExtension.java new file mode 100644 index 0000000000..097b94318a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ComponentTypeLoaderExtension.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.spi.extension; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; + +import org.apache.tuscany.spi.loader.ComponentTypeLoader; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.model.Implementation; + +/** + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +@EagerInit +public abstract class ComponentTypeLoaderExtension<I extends Implementation> implements ComponentTypeLoader<I> { + protected LoaderRegistry loaderRegistry; + + protected ComponentTypeLoaderExtension() { + } + + protected ComponentTypeLoaderExtension(LoaderRegistry loaderRegistry) { + this.loaderRegistry = loaderRegistry; + } + + @Reference + public void setLoaderRegistry(LoaderRegistry loaderRegistry) { + this.loaderRegistry = loaderRegistry; + } + + @Init + public void start() { + loaderRegistry.registerLoader(getImplementationClass(), this); + } + + @Destroy + public void stop() { + loaderRegistry.unregisterLoader(getImplementationClass()); + } + + protected abstract Class<I> getImplementationClass(); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/CompositeComponentExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/CompositeComponentExtension.java new file mode 100644 index 0000000000..61446a922e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/CompositeComponentExtension.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.spi.extension; + +import java.net.URI; + +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.ReferenceBinding; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.component.ServiceBinding; +import org.apache.tuscany.spi.component.TargetInvokerCreationException; +import org.apache.tuscany.spi.event.Event; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.wire.TargetInvoker; + +/** + * An extension point for composite components, which new types may extend + * + * @version $$Rev$$ $$Date$$ + */ +public abstract class CompositeComponentExtension extends AbstractComponentExtension implements RuntimeEventListener { + + protected CompositeComponentExtension(URI name) { + super(name); + } + + public Scope getScope() { + return Scope.SYSTEM; + } + + public void onEvent(Event event) { + publish(event); + } + + public TargetInvoker createTargetInvoker(String name, Operation operation) + throws TargetInvokerCreationException { + Service service = getService(name); + if (service != null) { + if (service.getServiceBindings().isEmpty()) { + // for now, throw an assertion exception. + // We will need to choose bindings during allocation + throw new AssertionError(); + } + ServiceBinding binding = service.getServiceBindings().get(0); + return binding.createTargetInvoker(name, operation); + } + Reference reference = getReference(name); + if (reference != null) { + if (reference.getReferenceBindings().isEmpty()) { + // for now, throw an assertion exception. + // We will need to choose bindings during allocation + throw new AssertionError(); + } + ReferenceBinding binding = reference.getReferenceBindings().get(0); + binding.createTargetInvoker(name, operation); + } + return null; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ContributionProcessorExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ContributionProcessorExtension.java new file mode 100644 index 0000000000..8b9b1e8dc7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ContributionProcessorExtension.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.spi.extension;
+
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.EagerInit;
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Reference;
+import org.osoa.sca.annotations.Service;
+
+import org.apache.tuscany.spi.deployer.ContributionProcessor;
+import org.apache.tuscany.spi.deployer.ContributionProcessorRegistry;
+
+/**
+ * The base class for ContributionProcessor implementations
+ *
+ * @version $Rev$ $Date$
+ */
+@EagerInit
+@Service(ContributionProcessor.class)
+public abstract class ContributionProcessorExtension implements ContributionProcessor {
+ /**
+ * The ContributionProcessorRegistry that this processor should register with; usually set by injection. This
+ * registry may also be used to process other sub-artifacts.
+ */
+ protected ContributionProcessorRegistry registry;
+
+ /**
+ * @param registry the registry to set
+ */
+ @Reference
+ public void setContributionProcessorRegistry(ContributionProcessorRegistry registry) {
+ this.registry = registry;
+ }
+
+ /**
+ * Initialize the processor. It registers itself to the registry by content type it supports.
+ */
+ @Init
+ public void start() {
+ registry.register(this.getContentType(), this);
+ }
+
+ /**
+ * Destroy the processor. It unregisters itself from the registry.
+ */
+ @Destroy
+ public void stop() {
+ registry.unregister(this.getContentType());
+ }
+
+ /**
+ * Returns the content type that this implementation can handle.
+ *
+ * @return the content type that this implementation can handle
+ */
+ public abstract String getContentType();
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ExecutionMonitor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ExecutionMonitor.java new file mode 100644 index 0000000000..fc6e5b7a14 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ExecutionMonitor.java @@ -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. + */ +package org.apache.tuscany.spi.extension; + +/** + * A monitor used to log events during an invocation + * + * @version $$Rev$$ $$Date$$ + */ +public interface ExecutionMonitor { + + /** + * Logs an exception thrown during an invocation + */ + void executionError(Throwable e); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/LoaderExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/LoaderExtension.java new file mode 100644 index 0000000000..db041cd51d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/LoaderExtension.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.spi.extension; + +import javax.xml.namespace.QName; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.StAXElementLoader; +import org.apache.tuscany.spi.model.ModelObject; + +/** + * Support class for extending the Loader mechanism. + * + * @version $Rev$ $Date$ + */ +@EagerInit +public abstract class LoaderExtension<T extends ModelObject> implements StAXElementLoader<T> { + /** + * The LoaderRegistry that this loader should register with; usually set by injection. This registry may also be + * used to load sub-elements. + */ + protected LoaderRegistry registry; + + /** + * Constructor specifies the registry to register with. + * + * @param registry the LoaderRegistry this loader should register with + */ + protected LoaderExtension(@Reference LoaderRegistry registry) { + this.registry = registry; + } + + /** + * Initialize the loader. The base implementation registers this loader with the registry as a handler for the XML + * type returned by {@link #getXMLType()}. Implementations may override this to register the loader as a handler for + * multiple XML types. + */ + @Init + public void start() { + registry.registerLoader(getXMLType(), this); + } + + /** + * Destroy the loader. The base implementation unregisters the loader from the regsitry based on the type returned + * by {@link #getXMLType()}. + */ + @Destroy + public void stop() { + registry.unregisterLoader(getXMLType(), this); + } + + /** + * Returns the QName of the element that this implementation handles. + * + * @return the QName of the element that this implementation handles + */ + public abstract QName getXMLType(); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ReferenceBindingExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ReferenceBindingExtension.java new file mode 100644 index 0000000000..a4231c3bbb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ReferenceBindingExtension.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.spi.extension; + +import java.net.URI; + +import org.apache.tuscany.spi.component.AbstractSCAObject; +import org.apache.tuscany.spi.component.ReferenceBinding; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.Wire; + +/** + * The default implementation of an SCA reference + * + * @version $Rev$ $Date$ + */ +public abstract class ReferenceBindingExtension extends AbstractSCAObject implements ReferenceBinding { + protected Wire wire; + protected ServiceContract<?> bindingServiceContract; + protected URI targetUri; + + protected ReferenceBindingExtension(URI name, URI targetUri) { + super(name); + this.targetUri = targetUri; + } + + public ServiceContract<?> getBindingServiceContract() { + return bindingServiceContract; + } + + public Wire getWire() { + return wire; + } + + public void setWire(Wire wire) { + this.wire = wire; + } + + + public URI getTargetUri() { + return targetUri; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ServiceBindingExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ServiceBindingExtension.java new file mode 100644 index 0000000000..5d207e1f3f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/ServiceBindingExtension.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.spi.extension; + +import java.net.URI; + +import org.apache.tuscany.spi.CoreRuntimeException; +import org.apache.tuscany.spi.component.AbstractSCAObject; +import org.apache.tuscany.spi.component.ServiceBinding; +import org.apache.tuscany.spi.component.TargetInvokerCreationException; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; + +/** + * The default implementation of an SCA service + * + * @version $Rev$ $Date$ + */ +public abstract class ServiceBindingExtension extends AbstractSCAObject implements ServiceBinding { + protected ServiceContract<?> bindingServiceContract; + protected Wire wire; + + public ServiceBindingExtension(URI name) throws CoreRuntimeException { + super(name); + } + + public TargetInvoker createTargetInvoker(ServiceContract contract, Operation operation) + throws TargetInvokerCreationException { + throw new UnsupportedOperationException(); + } + + public ServiceContract<?> getBindingServiceContract() { + return bindingServiceContract; + } + + public Wire getWire() { + return wire; + } + + public void setWire(Wire wire) { + this.wire = wire; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/TargetInvokerExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/TargetInvokerExtension.java new file mode 100644 index 0000000000..ee69736c05 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/extension/TargetInvokerExtension.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.spi.extension; + +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.LinkedList; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.TargetInvoker; + +/** + * The default implementation of a TargetInvoker + * + * @version $Rev$ $Date$ + */ +public abstract class TargetInvokerExtension implements TargetInvoker { + protected WorkContext workContext; + protected boolean cacheable; + + /** + * Creates a new invoker + * + * @param workContext the work context to use for setting correlation information + */ + public TargetInvokerExtension(WorkContext workContext) { + this.workContext = workContext; + } + + public Message invoke(Message msg) throws InvocationRuntimeException { + try { + Object messageId = msg.getMessageId(); + if (messageId != null) { + workContext.setCorrelationId(messageId); + } + LinkedList<URI> callbackRoutingChain = msg.getCallbackUris(); + if (callbackRoutingChain != null) { + workContext.setCallbackUris(callbackRoutingChain); + } + Object resp = invokeTarget(msg.getBody(), msg.getConversationSequence()); + msg.setBody(resp); + } catch (InvocationTargetException e) { + msg.setBodyWithFault(e.getCause()); + } + return msg; + } + + public boolean isCacheable() { + return cacheable; + } + + public void setCacheable(boolean cacheable) { + this.cacheable = cacheable; + } + + public boolean isOptimizable() { + return isCacheable(); + } + + public Object clone() throws CloneNotSupportedException { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + // TargetInvoker extends Cloneable so this should not have been thrown + throw new AssertionError(e); + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/host/ResourceHost.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/host/ResourceHost.java new file mode 100644 index 0000000000..b273ec6729 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/host/ResourceHost.java @@ -0,0 +1,46 @@ +/* + * 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.spi.host; + +/** + * Interface implemented by host environments that allow for resolution of component implementation resources, e.g. + * items bound in a JNDI tree. + * + * @version $Rev$ $Date$ + */ +public interface ResourceHost { + + /** + * Resolve a resource matching the given type + * + * @param type the type of the resources + * @throws ResourceResolutionException if an error is encountered during resolution + */ + <T> T resolveResource(Class<T> type) throws ResourceResolutionException; + + /** + * Resolve a resource matching the given type and name + * + * @param type the type of the resources + * @param mappedName the mapped name of the resource + * @throws ResourceResolutionException if an error is encountered during resolution + */ + <T> T resolveResource(Class<T> type, String mappedName) throws ResourceResolutionException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/host/ResourceHostRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/host/ResourceHostRegistry.java new file mode 100644 index 0000000000..b4964cce3b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/host/ResourceHostRegistry.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.host; + +/** + * Implementations manage a registry of resources and resource hosts in the runtime + * + * @version $Rev$ $Date$ + */ +public interface ResourceHostRegistry { + /** + * Registers a resource host for the given uri prefix + * + * @param uri the uri prefix the host resolves resources for + * @param host the resource host + */ + void registerResourceHost(String uri, ResourceHost host); + + /** + * Removes a resource host registered for the given uri prefix + */ + void unregisterResourceHost(String uri); + + /** + * Register a resource by type + * + * @param type the type of the resource + * @param resource the resource + */ + void registerResource(Class<?> type, Object resource); + + /** + * Register a resource by type and name + * + * @param type the type of the resource + * @param name the mapped resource name + * @param resource the resource + */ + void registerResource(Class<?> type, String name, Object resource); + + /** + * Unregister a resource + * + * @param type the type the resource was registered with + * @param name the mapped name the resource was registered with + */ + void unregisterResource(Class<?> type, String name); + + /** + * Unregister a resource + * + * @param type the type the resource was registered with + */ + void unregisterResource(Class<?> type); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/host/ResourceResolutionException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/host/ResourceResolutionException.java new file mode 100644 index 0000000000..23c18f5115 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/host/ResourceResolutionException.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.host; + +import org.apache.tuscany.api.TuscanyException; + +/** + * @version $Rev$ $Date$ + */ +public class ResourceResolutionException extends TuscanyException { + + public ResourceResolutionException(String message, String identifier) { + super(message, identifier); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/host/ServletHost.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/host/ServletHost.java new file mode 100644 index 0000000000..37937808d4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/host/ServletHost.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.spi.host; + +import javax.servlet.Servlet; + +/** + * Interface implemented by host environments that allow Servlets to be registered. + * <p/> + * This interface allows an SCA system service to register a servlet to handle inbound requests. + * + * @version $Rev$ $Date$ + */ +public interface ServletHost { + /** + * Register a mapping for an instance of a Servlet. This requests that the servlet container direct all requests to + * the designated mapping to the supplied Servlet instance. + * + * @param mapping the uri-mapping for the Servlet + * @param servlet the Servlet that should be invoked + */ + void registerMapping(String mapping, Servlet servlet); + + /** + * Unregister a servlet mapping. This directs the servlet contain not to direct any more requests to a previously + * registered Servlet. + * + * @param mapping the uri-mapping for the Servlet + * @return the servlet that was registered to the mapping, null if nothing was registered to the mapping + */ + Servlet unregisterMapping(String mapping); + + /** + * Check to see if a mapping exists. + * + * @param mapping the uri-mapping for the Servlet + * @return true if mapping is registered, false otherwise + */ + boolean isMappingRegistered(String mapping); + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/InvalidConversationalOperationException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/InvalidConversationalOperationException.java new file mode 100644 index 0000000000..e2b4acec24 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/InvalidConversationalOperationException.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.idl; + +import java.lang.reflect.Method; + +/** + * Denotes an invalid conversational interface definition + * + * @version $Rev$ $Date$ + */ +public class InvalidConversationalOperationException extends InvalidServiceContractException { + private final Method operation; + + public InvalidConversationalOperationException(String message, String identifier, Method operation) { + super(message, identifier); + this.operation = operation; + } + + public Method getOperation() { + return operation; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/InvalidServiceContractException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/InvalidServiceContractException.java new file mode 100644 index 0000000000..e977592df0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/InvalidServiceContractException.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.spi.idl; + +import org.apache.tuscany.api.TuscanyException; + +/** + * @version $Rev$ $Date$ + */ +public abstract class InvalidServiceContractException extends TuscanyException { + + public InvalidServiceContractException() { + } + + public InvalidServiceContractException(String message) { + super(message); + } + + protected InvalidServiceContractException(String message, String identifier) { + super(message, identifier); + } + + public InvalidServiceContractException(String message, Throwable cause) { + super(message, cause); + } + + protected InvalidServiceContractException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + public InvalidServiceContractException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/OverloadedOperationException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/OverloadedOperationException.java new file mode 100644 index 0000000000..b1d4cb4e7c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/OverloadedOperationException.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.spi.idl; + +import java.lang.reflect.Method; + +/** + * Exception thrown to indicate that a service contract specification contains an overloaded method. + * + * @version $Rev$ $Date$ + */ +public class OverloadedOperationException extends InvalidServiceContractException { + private static final long serialVersionUID = -4658711318608885638L; + private final Method operation; + + public OverloadedOperationException(Method operation) { + super(null, operation.getDeclaringClass().getName()); + this.operation = operation; + } + + public Method getOperation() { + return operation; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/InterfaceJavaIntrospector.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/InterfaceJavaIntrospector.java new file mode 100644 index 0000000000..08f22147b5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/InterfaceJavaIntrospector.java @@ -0,0 +1,46 @@ +/* + * 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.spi.idl.java; + +import org.apache.tuscany.spi.idl.InvalidServiceContractException; + +/** + * Processor for creating JavaServiceContract definitions from Java Classes. + * + * @version $Rev$ $Date$ + */ +public interface InterfaceJavaIntrospector { + + /** + * Introspect a Java interface and return a service contract definition. + * + * @param type the interface to inspect + * @return a JavaServiceContract corresponding to the Java interface + */ + <I> JavaServiceContract introspect(Class<I> type) throws InvalidServiceContractException; + + /** + * Introspect a Java interface and return a service contract definition. + * + * @param type the interface to inspect + * @param callback the callback interface to inspec + * @return a JavaServiceContract corresponding to the Java interface + */ + <I, C> JavaServiceContract introspect(Class<I> type, Class<C> callback) throws InvalidServiceContractException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaIDLUtils.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaIDLUtils.java new file mode 100644 index 0000000000..c7c7cb2aa8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaIDLUtils.java @@ -0,0 +1,96 @@ +/* + * 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.spi.idl.java; + +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.List; + +import org.apache.tuscany.spi.model.DataType; +import org.apache.tuscany.spi.model.Operation; + +/** + * Contains methods for mapping between an operation in a {@link org.apache.tuscany.spi.model.ServiceContract} and a + * method defined by a Java interface + * + * @version $Rev$ $Date$ + */ +public final class JavaIDLUtils { + + private JavaIDLUtils() { + } + + /** + * Searches an array of methods for a match against the given operation + * + * @param operation the operation to match + * @param methods the methods to match against + * @return a matching method or null + */ + public static Method findMethod(Operation<?> operation, Method[] methods) { + for (Method method : methods) { + if (match(operation, method)) { + return method; + } + } + return null; + } + + /** + * Searches a collection of operations for a match against the given method + * + * @param method the method to match + * @param operations the operations to match against + * @return a matching operation or null + */ + public static Operation findOperation(Method method, Collection<Operation<?>> operations) { + for (Operation<?> operation : operations) { + if (match(operation, method)) { + return operation; + } + } + return null; + } + + /** + * Determines if the given operation matches the given method + * + * @return true if the operation matches, false if does not + */ + private static <T> boolean match(Operation<T> operation, Method method) { + Class<?>[] params = method.getParameterTypes(); + DataType<List<DataType<T>>> inputType = operation.getInputType(); + List<DataType<T>> types = inputType.getLogical(); + boolean found = true; + if (types.size() == params.length && method.getName().equals(operation.getName())) { + for (int i = 0; i < params.length; i++) { + Class<?> clazz = params[i]; + if (!clazz.equals(operation.getInputType().getLogical().get(i).getPhysical())) { + found = false; + } + } + } else { + found = false; + } + return found; + + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessor.java new file mode 100644 index 0000000000..afe98f0773 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessor.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.spi.idl.java; + +import org.apache.tuscany.spi.idl.InvalidServiceContractException; + +/** + * Implementations introspect metadata on a Java interface, populating the + * corresponding {@link JavaServiceContract} + * + * @version $Rev$ $Date$ + */ +public interface JavaInterfaceProcessor { + + void visitInterface(Class<?> clazz, Class<?> callbackClass, JavaServiceContract contract) + throws InvalidServiceContractException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessorExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessorExtension.java new file mode 100644 index 0000000000..5c9ad40053 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessorExtension.java @@ -0,0 +1,46 @@ +/* + * 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.spi.idl.java; + +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; + +/** + * A convenience class for <code>JavaInterfaceProcessor</code> extensions that performs autowiring + * + * @version $Rev$ $Date$ + */ +@EagerInit +public abstract class JavaInterfaceProcessorExtension implements JavaInterfaceProcessor { + + protected JavaInterfaceProcessorRegistry registry; + + @Reference + public void setRegistry(JavaInterfaceProcessorRegistry registry) { + this.registry = registry; + } + + @Init + public void init() { + registry.registerProcessor(this); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessorRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessorRegistry.java new file mode 100644 index 0000000000..38c64e6f88 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaInterfaceProcessorRegistry.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.idl.java; + +/** + * A registry of {@link JavaInterfaceProcessor}s. Interface processors update a service contract definition based on a + * Java interface + * + * @version $Rev$ $Date$ + */ +public interface JavaInterfaceProcessorRegistry extends InterfaceJavaIntrospector { + + /** + * Registers the given processor + */ + void registerProcessor(JavaInterfaceProcessor processor); + + /** + * Deregisters the given processor + */ + void unregisterProcessor(JavaInterfaceProcessor processor); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaServiceContract.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaServiceContract.java new file mode 100644 index 0000000000..ee29846e26 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/idl/java/JavaServiceContract.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.idl.java; + +import java.lang.reflect.Type; + +import org.apache.tuscany.spi.model.ServiceContract; + +/** + * Represents a service contract specified using a Java interface + * + * @version $Rev$ $Date$ + */ +public class JavaServiceContract extends ServiceContract<Type> { + + public JavaServiceContract() { + } + + public JavaServiceContract(Class<?> interfaceClass) { + super(interfaceClass); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/AbstractPropertyProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/AbstractPropertyProcessor.java new file mode 100644 index 0000000000..d81ec73ba1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/AbstractPropertyProcessor.java @@ -0,0 +1,188 @@ +/* + * 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.spi.implementation.java; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Map; + +import org.apache.tuscany.spi.databinding.DataBinding; +import org.apache.tuscany.spi.deployer.DeploymentContext; + +import org.apache.tuscany.api.annotation.DataType; + +/** + * Base class for ImplementationProcessors that handle annotations that add Properties. + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractPropertyProcessor<A extends Annotation> extends ImplementationProcessorExtension { + private final Class<A> annotationClass; + private ImplementationProcessorService service; + + protected AbstractPropertyProcessor(Class<A> annotationClass, ImplementationProcessorService service) { + this.annotationClass = annotationClass; + this.service = service; + } + + public void visitMethod( + Method method, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + A annotation = method.getAnnotation(annotationClass); + if (annotation == null) { + return; + } + + if (!Void.TYPE.equals(method.getReturnType())) { + throw new IllegalPropertyException("Method does not have void return type", method.toString()); + } + Class[] paramTypes = method.getParameterTypes(); + if (paramTypes.length != 1) { + throw new IllegalPropertyException("Method must have a single parameter", method.toString()); + } + Class<?> javaType = paramTypes[0]; + + String name = getName(annotation); + if (name == null || name.length() == 0) { + name = method.getName(); + if (name.startsWith("set")) { + name = toPropertyName(method.getName()); + } + } + + Map<String, JavaMappedProperty<?>> properties = type.getProperties(); + if (properties.containsKey(name)) { + throw new DuplicatePropertyException(name); + } + + Class<?> baseType = getBaseType(javaType, method.getGenericParameterTypes()[0]); + JavaMappedProperty<?> property = createProperty(name, baseType, method); + if (javaType.isArray() || Collection.class.isAssignableFrom(javaType)) { + property.setMany(true); + } + + //add databinding available as annotations, as extensions + DataType propertyDataBinding = method.getAnnotation(DataType.class); + if (propertyDataBinding != null) { + property.getExtensions().put(DataBinding.class.getName(), propertyDataBinding.name()); + } + initProperty(property, annotation, context); + properties.put(name, property); + } + + public void visitField( + Field field, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + + A annotation = field.getAnnotation(annotationClass); + if (annotation == null) { + return; + } + + Class<?> javaType = field.getType(); + + String name = getName(annotation); + if (name == null || name.length() == 0) { + name = field.getName(); + } + + Map<String, JavaMappedProperty<?>> properties = type.getProperties(); + if (properties.containsKey(name)) { + throw new DuplicatePropertyException(name); + } + + Class<?> baseType = getBaseType(javaType, field.getGenericType()); + JavaMappedProperty<?> property = createProperty(name, baseType, field); + if (javaType.isArray() || Collection.class.isAssignableFrom(javaType)) { + property.setMany(true); + } + + //add databinding available as annotations, as extensions + DataType propertyDataBinding = field.getAnnotation(DataType.class); + if (propertyDataBinding != null) { + property.getExtensions().put(DataBinding.class.getName(), propertyDataBinding.name()); + } + + initProperty(property, annotation, context); + properties.put(name, property); + } + + public <T> void visitConstructor(Constructor<T> constructor, + PojoComponentType<JavaMappedService, + JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + + ConstructorDefinition<?> definition = type.getConstructorDefinition(); + Class[] params = constructor.getParameterTypes(); + Map<String, JavaMappedProperty<?>> properties = type.getProperties(); + Annotation[][] annotations = constructor.getParameterAnnotations(); + for (int i = 0; i < params.length; i++) { + Class<?> param = params[i]; + Annotation[] paramAnnotations = annotations[i]; + for (Annotation annotation : paramAnnotations) { + if (annotation.annotationType().equals(annotationClass)) { + if (definition == null) { + definition = new ConstructorDefinition<T>(constructor); + type.setConstructorDefinition(definition); + } + A monitorAnnot = annotationClass.cast(annotation); + String name = getName(monitorAnnot); + if (name == null || name.length() == 0) { + name = param.getName(); + } + + Class<?> baseType = getBaseType(param, constructor.getGenericParameterTypes()[i]); + JavaMappedProperty<?> property = createProperty(name, baseType, constructor); + if (param.isArray() || Collection.class.isAssignableFrom(param)) { + property.setMany(true); + } + initProperty(property, monitorAnnot, context); + properties.put(name, property); + service.addName(definition.getInjectionNames(), i, name); + } + } + } + } + + protected abstract String getName(A annotation); + + protected <T> void initProperty(JavaMappedProperty<T> property, A annotation, DeploymentContext context) + throws ProcessingException { + } + + protected <T> JavaMappedProperty<T> createProperty(String name, Class<T> javaType, Member member) + throws ProcessingException { + return new JavaMappedProperty<T>(name, null, javaType, member); + } + + + public static String toPropertyName(String name) { + if (!name.startsWith("set")) { + return name; + } + return Character.toLowerCase(name.charAt(3)) + name.substring(4); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ConstructorDefinition.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ConstructorDefinition.java new file mode 100644 index 0000000000..94c185966f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ConstructorDefinition.java @@ -0,0 +1,51 @@ +/* + * 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.spi.implementation.java; + +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; + +/** + * Hold injection information for the constructor used to instantiate a component implementation instance + * + * @version $Rev$ $Date$ + */ +public class ConstructorDefinition<T> { + + private Constructor<T> constructor; + private List<String> injectionNames; + + public ConstructorDefinition(Constructor<T> constructor) { + this.constructor = constructor; + injectionNames = new ArrayList<String>(); + } + + public Constructor<T> getConstructor() { + return constructor; + } + + public List<String> getInjectionNames() { + return injectionNames; + } + + public void setInjectionNames(List<String> injectionNames) { + this.injectionNames = injectionNames; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/DuplicatePropertyException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/DuplicatePropertyException.java new file mode 100644 index 0000000000..87c4074fe7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/DuplicatePropertyException.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.implementation.java; + +/** + * Thrown when an implementation has more than one property injection site with the same name + * + * @version $Rev$ $Date$ + */ +public class DuplicatePropertyException extends ProcessingException { + + public DuplicatePropertyException(String message) { + super(message); + } + + public DuplicatePropertyException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/IllegalPropertyException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/IllegalPropertyException.java new file mode 100644 index 0000000000..f251f60630 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/IllegalPropertyException.java @@ -0,0 +1,36 @@ +/* + * 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.spi.implementation.java; + +/** + * Denotes an illegal property definition in a component type + * + * @version $Rev$ $Date$ + */ +public class IllegalPropertyException extends ProcessingException { + + public IllegalPropertyException(String message) { + super(message); + } + + + public IllegalPropertyException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessor.java new file mode 100644 index 0000000000..e886eb7e6b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessor.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.spi.implementation.java; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.apache.tuscany.spi.deployer.DeploymentContext; + +/** + * Implementations process class-level metadata, typically parsing annotations and updating the corresponding + * <code>ComponentType</code>. A processor may, for example, create a {@link JavaMappedProperty} which is responsible + * for injecting a complex type on a component implementation instance when it is instantiated. + * <p/> + * Processors will receive callbacks as the implementation class is walked while evalauting an assembly. It is the + * responsibility of the parser to determine whether to perform an action during the callback. + * + * @version $Rev$ $Date$ + */ +public interface ImplementationProcessor { + + /** + * A callback received when the component implementation class is first loaded + * + * @param clazz the component implementation class + * @param type the incomplete component type associated with the implementation class + * @param context the current deployment context + * @throws ProcessingException if an error is encountered while processing metadata + */ + <T> void visitClass(Class<T> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException; + + /** + * A callback received as the component implementation class hierarchy is evaluated + * + * @param clazz the superclass in the component implmentation's class hierarchy + * @param type the incomplete component type associated with the implementation class + * @param context the current deployment context + * @throws ProcessingException if an error is encountered while processing metadata + */ + <T> void visitSuperClass( + Class<T> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException; + + /** + * A callback received as the component implementation's public and protected methods are evaluated + * + * @param method the current public or protected method being evaluated + * @param type the incomplete component type associated with the implementation class + * @param context the current deployment context + * @throws ProcessingException if an error is encountered while processing metadata + */ + void visitMethod( + Method method, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException; + + /** + * A callback received as the component implementation's constructor used for instantiation by the runtime is + * evaluated. If an implementation contains more than one constructor, the constructor passed to the callback will + * be chosen according to the algorithm described in the SCA Java Client and Implementation Model Specification. + * + * @param constructor the constructor used for instantiating component implementation instances + * @param type the incomplete component type associated with the implementation class + * @param context the current deployment context + * @throws ProcessingException if an error is encountered while processing metadata + */ + <T> void visitConstructor( + Constructor<T> constructor, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException; + + /** + * A callback received as the component implementation's public and protected fields are evaluated + * + * @param field the current public or protected field being evaluated + * @param type the incomplete component type associated with the implementation class + * @param context the current deployment context + * @throws ProcessingException if an error is encountered while processing metadata + */ + void visitField( + Field field, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException; + + /** + * The final callback received when all other callbacks during evaluation of the component implementation have been + * issued + * + * @param clazz the component implementation class + * @param type the incomplete component type associated with the implementation class + * @param context the current deployment context + * @throws ProcessingException if an error is encountered while processing metadata + */ + <T> void visitEnd( + Class<T> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessorExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessorExtension.java new file mode 100644 index 0000000000..66b973a179 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessorExtension.java @@ -0,0 +1,117 @@ +/* + * 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.spi.implementation.java; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Collection; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.deployer.DeploymentContext; + +/** + * A convenience class for annotation processors which alleviates the need to implement unused callbacks + * + * @version $Rev$ $Date$ + */ +@EagerInit +public abstract class ImplementationProcessorExtension implements ImplementationProcessor { + private IntrospectionRegistry registry; + + @Reference + public void setRegistry(IntrospectionRegistry registry) { + this.registry = registry; + } + + @Init + public void init() { + registry.registerProcessor(this); + } + + @Destroy + public void destroy() { + registry.unregisterProcessor(this); + } + + public <T> void visitClass(Class<T> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException { + } + + public <T> void visitSuperClass(Class<T> clazz, + PojoComponentType<JavaMappedService, + JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException { + } + + public void visitMethod(Method method, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException { + } + + public <T> void visitConstructor(Constructor<T> constructor, + PojoComponentType<JavaMappedService, + JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) + throws ProcessingException { + } + + public void visitField(Field field, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + } + + public <T> void visitEnd(Class<T> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException { + + } + + protected static Class<?> getBaseType(Class<?> cls, Type genericType) { + if (cls.isArray()) { + return cls.getComponentType(); + } else if (Collection.class.isAssignableFrom(cls)) { + if (genericType == cls) { + return Object.class; + } else { + ParameterizedType parameterizedType = (ParameterizedType) genericType; + Type baseType = parameterizedType.getActualTypeArguments()[0]; + if (baseType instanceof Class) { + return (Class<?>) baseType; + } else if (baseType instanceof ParameterizedType) { + return (Class<?>) ((ParameterizedType) baseType).getRawType(); + } else { + return null; + } + } + } else { + return cls; + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessorService.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessorService.java new file mode 100644 index 0000000000..9dccfad23f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ImplementationProcessorService.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.spi.implementation.java; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Member; +import java.lang.reflect.Type; +import java.util.List; + +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.model.ServiceContract; + +/** + * Provides utility methods for Java implementation processing + * + * @version $Rev$ $Date$ + */ +public interface ImplementationProcessorService { + + /** + * Introspects the given interface to produce a mapped service + */ + JavaMappedService createService(Class<?> interfaze) throws InvalidServiceContractException; + + JavaMappedReference createReference(String name, Member member, Class<?> paramType) throws ProcessingException; + + /** + * Processes the callback contract for a given interface type + * + * @param interfaze the interface type to examine + * @param contract the service contract the callback is associated wth + * @throws InvalidServiceContractException + * + */ + void processCallback(Class<?> interfaze, ServiceContract<?> contract) throws InvalidServiceContractException; + + /** + * Determines if all the members of a collection have unique types + * + * @param collection the collection to analyze + * @return true if the types are unique + */ + boolean areUnique(Class[] collection); + + /** + * Inserts a name at the specified position, paddiling the list if its size is less than the position + */ + void addName(List<String> names, int pos, String name); + + /** + * Processes a constructor parameter by introspecting its annotations + * + * @param param the parameter to process + * @param genericParam the generic type of the parameter + * @param paramAnnotations the parameter annotations + * @param constructorNames the array of constructorNames specified by + * @param pos the declaration position of the constructor parameter + * @param type the component type associated with implementation being reflected + * @param injectionNames the list of parameter constructorNames specified on parameter annotations + * @throws ProcessingException + */ + boolean processParam(Class<?> param, + Type genericParam, + Annotation[] paramAnnotations, + String[] constructorNames, + int pos, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + List<String> injectionNames) throws ProcessingException; + + /** + * Returns true if <code>@Property</code> or <code>@Reference</code> are present in the given array + * @return true if one of the annotations are present + */ + boolean injectionAnnotationsPresent(Annotation[][] annots); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/IntrospectionRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/IntrospectionRegistry.java new file mode 100644 index 0000000000..a6122a6ff1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/IntrospectionRegistry.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.spi.implementation.java; + +/** + * A system service which tracks {@link ImplementationProcessor}s + * + * @version $Rev$ $Date$ + */ +public interface IntrospectionRegistry extends Introspector { + + /** + * Registers the given processor and makes it available during assembly evaluation (i.e. build) + */ + void registerProcessor(ImplementationProcessor processor); + + /** + * Deregisters the given processor + */ + void unregisterProcessor(ImplementationProcessor processor); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/Introspector.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/Introspector.java new file mode 100644 index 0000000000..bb7550440b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/Introspector.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.spi.implementation.java; + +import org.apache.tuscany.spi.deployer.DeploymentContext; + +/** + * Implementations are responsible for walking a component implementation class, adding additional component type + * information as appropriate + * + * @version $Rev$ $Date$ + */ +public interface Introspector { + + /** + * Walks the given component implementation class + * + * @param clazz the component implementation class + * @param type the component type associated with the implementation class + * @return the updated component type + * @throws ProcessingException if an error is encountered evaluating the implementation class + */ + PojoComponentType introspect(Class<?> clazz, + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type, + DeploymentContext context) throws ProcessingException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedComponentType.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedComponentType.java new file mode 100644 index 0000000000..34ac8f53f9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedComponentType.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.spi.implementation.java; + +import org.apache.tuscany.spi.model.ComponentType; + +/** + * A specialized component type definition whose services, references and properties can be mapped to the Java + * programming model. + * + * @version $Rev$ $Date$ + */ +public class JavaMappedComponentType< + S extends JavaMappedService, + R extends JavaMappedReference, + P extends JavaMappedProperty<?> + > extends ComponentType<S, R, P> { + + private Class<?> implClass; + + public JavaMappedComponentType() { + } + + public JavaMappedComponentType(Class<?> implClass) { + this.implClass = implClass; + } + + /** + * Returns the implementation class associated with this component type. + * + * @return the implementation class associated with this component type + */ + public Class<?> getImplClass() { + return implClass; + } + + /** + * Sets the implementation class associated with this component type. + * + * @param implClass the implementation class associated with this component type + */ + public void setImplClass(Class<?> implClass) { + this.implClass = implClass; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedProperty.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedProperty.java new file mode 100644 index 0000000000..6d1715a035 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedProperty.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.spi.implementation.java; + +import java.lang.reflect.Member; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.model.Property; + +/** + * A Property definition that is mapped to a specific location in the implementation class. This location will typically + * be used to inject property values. + * + * @version $Rev$ $Date$ + */ +public class JavaMappedProperty<T> extends Property<T> { + private Member member; + + public JavaMappedProperty() { + } + + public JavaMappedProperty(String name, QName xmlType, Class<T> javaType) { + super(name, xmlType, javaType); + } + + public JavaMappedProperty(String name, QName xmlType, Class<T> javaType, Member member) { + super(name, xmlType, javaType); + this.member = member; + } + + /** + * Returns the Member that this property is mapped to. + * + * @return the Member that this property is mapped to + */ + public Member getMember() { + return member; + } + + /** + * Sets the Member that this property is mapped to + * + * @param member the Member that this property is mapped to + */ + public void setMember(Member member) { + this.member = member; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedReference.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedReference.java new file mode 100644 index 0000000000..26b79068c2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedReference.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.spi.implementation.java; + +import java.lang.reflect.Member; +import java.net.URI; + +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceContract; + +/** + * A ReferenceDefinition definition that is mapped to a specific location in the implementation class. This location + * will typically be used to inject reference values. + * + * @version $Rev$ $Date$ + */ +public class JavaMappedReference extends ReferenceDefinition { + private Member member; + + public JavaMappedReference() { + } + + public JavaMappedReference(URI name, ServiceContract serviceContract, Member member) { + super(name, serviceContract); + this.member = member; + } + + /** + * Returns the Member that this reference is mapped to. + * + * @return the Member that this reference is mapped to + */ + public Member getMember() { + return member; + } + + /** + * Sets the Member that this reference is mapped to + * + * @param member the Member that this reference is mapped to + */ + public void setMember(Member member) { + this.member = member; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedService.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedService.java new file mode 100644 index 0000000000..d7675da4e9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/JavaMappedService.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.spi.implementation.java; + +import java.lang.reflect.Member; +import java.net.URI; + +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.model.ServiceDefinition; + +/** + * A ServiceDefinition definition that is mapped to a Java interface. The mapped interface is not required to be the + * same as the interface specified in the service contract. This is to allow the service contract to be specified using + * different interface definition languages or, in the case were the IDL is Java, to allow the service definition to be + * loaded from a different classloader. + * + * @version $Rev$ $Date$ + */ +public class JavaMappedService extends ServiceDefinition { + private Class<?> serviceInterface; + private Member callbackMember; + + public JavaMappedService() { + } + + public JavaMappedService(Class<?> serviceInterface) { + this.serviceInterface = serviceInterface; + } + + public JavaMappedService(URI name, ServiceContract contract, boolean remotable) { + super(name, contract, remotable); + } + + public JavaMappedService(URI name, + ServiceContract contract, + boolean remotable, + String callbackRefName, + Member callbackMember) { + super(name, contract, remotable, callbackRefName); + this.callbackMember = callbackMember; + } + + /** + * Returns the Java interface for this service. This may be different from the interface that defines the service + * contract. + * + * @return the Java interface for this service + */ + public Class<?> getServiceInterface() { + return serviceInterface; + } + + /** + * Sets the Java interface for this service. This may be different from the interface used to define the service + * contract. + * + * @param serviceInterface the Java interface for this service + */ + public void setServiceInterface(Class<?> serviceInterface) { + this.serviceInterface = serviceInterface; + } + + public Member getCallbackMember() { + return callbackMember; + } + + public void setCallbackMember(Member callbackMember) { + this.callbackMember = callbackMember; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/PojoComponentType.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/PojoComponentType.java new file mode 100644 index 0000000000..795e37e288 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/PojoComponentType.java @@ -0,0 +1,148 @@ +/* + * 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.spi.implementation.java; + +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +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.ServiceDefinition; + +/** + * A component type specialization for POJO implementations + * + * @version $$Rev$$ $$Date$$ + */ +public class PojoComponentType<S extends ServiceDefinition, R extends ReferenceDefinition, P extends Property<?>> + extends ComponentType<S, R, P> { + private Class<?> implClass; + private ConstructorDefinition<?> constructorDefinition; + private Method initMethod; + private Method destroyMethod; + private final Map<String, Resource> resources = new HashMap<String, Resource>(); + private Member conversationIDMember; + + /** + * Deprecated no-arg constructor, replaced with one that takes the POJO class. + */ + @Deprecated + public PojoComponentType() { + } + + /** + * Constructor specifying the java class for the POJO this is describing. + * + * @param implClass the java class for the POJO this is describing + */ + public PojoComponentType(Class<?> implClass) { + this.implClass = implClass; + } + + /** + * Returns the java class for the POJO this is describing. + * + * @return the java class for the POJO this is describing + */ + public Class<?> getImplClass() { + return implClass; + } + + /** + * Sets the java class for the POJO this is describing. + * + * @param implClass the java class for the POJO this is describing + */ + public void setImplClass(Class<?> implClass) { + this.implClass = implClass; + } + + /** + * Returns the constructor used to instantiate implementation instances. + * + * @return the constructor used to instantiate implementation instances + */ + public ConstructorDefinition<?> getConstructorDefinition() { + return constructorDefinition; + } + + /** + * Sets the constructor used to instantiate implementation instances + * + * @param definition the constructor used to instantiate implementation instances + */ + public void setConstructorDefinition(ConstructorDefinition<?> definition) { + this.constructorDefinition = definition; + } + + /** + * Returns the component initializer method. + * + * @return the component initializer method + */ + public Method getInitMethod() { + return initMethod; + } + + /** + * Sets the component initializer method. + * + * @param initMethod the component initializer method + */ + public void setInitMethod(Method initMethod) { + this.initMethod = initMethod; + } + + /** + * Returns the component destructor method. + * + * @return the component destructor method + */ + public Method getDestroyMethod() { + return destroyMethod; + } + + /** + * Sets the component destructor method. + * + * @param destroyMethod the component destructor method + */ + public void setDestroyMethod(Method destroyMethod) { + this.destroyMethod = destroyMethod; + } + + public Map<String, Resource> getResources() { + return resources; + } + + public void add(Resource resource) { + resources.put(resource.getName(), resource); + } + + public Member getConversationIDMember() { + return this.conversationIDMember; + } + + public void setConversationIDMember(Member conversationIDMember) { + this.conversationIDMember = conversationIDMember; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ProcessingException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ProcessingException.java new file mode 100644 index 0000000000..40fd1dfd15 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/ProcessingException.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.spi.implementation.java; + +import java.lang.reflect.Member; + +import org.apache.tuscany.spi.loader.LoaderException; + +/** + * Denotes a problem processing annotations on a POJO implementation + * + * @version $Rev$ $Date$ + */ +public class ProcessingException extends LoaderException { + private Member member; + + public ProcessingException() { + } + + public ProcessingException(String message) { + super(message); + } + + public ProcessingException(String message, String identifier) { + super(message, identifier); + } + + public ProcessingException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + public ProcessingException(String message, Throwable cause) { + super(message, cause); + } + + public ProcessingException(Throwable cause) { + super(cause); + } + + + public Member getMemberName() { + return member; + } + + public void setMember(Member member) { + this.member = member; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/Resource.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/Resource.java new file mode 100644 index 0000000000..61e2970bec --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/implementation/java/Resource.java @@ -0,0 +1,145 @@ +/* + * 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.spi.implementation.java; + +import java.lang.reflect.Member; + +import org.apache.tuscany.spi.ObjectFactory; + +/** + * A resource dependency declared by a Java component implementation + * + * @version $Rev$ $Date$ + * @param <T> the Java type of the resource + */ +public class Resource<T> { + + private String name; + private String mappedName; + private boolean optional; + private Member member; + private Class<T> type; + private ObjectFactory<T> objectFactory; + + public Resource(String name, Class<T> type, Member member) { + this.name = name; + this.type = type; + this.member = member; + } + + /** + * The name of the resource + * + * @return the name of the resource + */ + public String getName() { + return name; + } + + /** + * Sets the name of the resource + * + * @param name the name of the resource + */ + public void setName(String name) { + this.name = name; + } + + /** + * Returns the URI of the resource + * + * @return the URI of the resource + */ + public String getMappedName() { + return mappedName; + } + + /** + * Sets the resource URI + */ + public void setMappedName(String mappedName) { + this.mappedName = mappedName; + } + + /** + * If true, the resource is optional + * + * @return true if the resource is optional + */ + public boolean isOptional() { + return optional; + } + + /** + * Sets whether the resource is optional + */ + public void setOptional(boolean optional) { + this.optional = optional; + } + + /** + * Returns the Member that this resource is mapped to. + * + * @return the Member that this resource is mapped to + */ + public Member getMember() { + return member; + } + + /** + * Sets the Member that this resource is mapped to + * + * @param member the Member that this resource is mapped to + */ + public void setMember(Member member) { + this.member = member; + } + + /** + * Returns the resource type + * + * @return the resource type + */ + public Class<T> getType() { + return type; + } + + /** + * Sets the resource type + */ + public void setType(Class<T> type) { + this.type = type; + } + + /** + * Returns the obeject factory + * + * @return the object factory + */ + public ObjectFactory<T> getObjectFactory() { + return objectFactory; + } + + /** + * Sets the object factory + */ + public void setObjectFactory(ObjectFactory<T> objectFactory) { + this.objectFactory = objectFactory; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/ComponentTypeLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/ComponentTypeLoader.java new file mode 100644 index 0000000000..f83b2fc5b3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/ComponentTypeLoader.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.spi.loader; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.Implementation; + +/** + * Loader that will load the ComponentType definition for the supplied implementation. The actual mechanism used to load + * that definition is determined by the Client and Implementation Specification for the implementaion type. In some + * cases the definition may be contained in a XML file related to the implementation artifact in some well defined + * manner; other implementations may obtain this information from introspection of the artifact itself (for example, by + * examining Java annotations). + * + * @version $Rev$ $Date$ + */ +public interface ComponentTypeLoader<I extends Implementation> { + /** + * Load the component type definition for the supplied implementation. + * + * @param implementation the implementation whose component type information should be loaded + * @param context the current deployment context + * @throws LoaderException if there was a problem loading the configuration type + */ + void load(I implementation, DeploymentContext context) throws LoaderException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/IllegalSCDLNameException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/IllegalSCDLNameException.java new file mode 100644 index 0000000000..7c944c6251 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/IllegalSCDLNameException.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.spi.loader; + +/** + * @version $Rev$ $Date$ + */ +public class IllegalSCDLNameException extends LoaderException { + public IllegalSCDLNameException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidConfigurationException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidConfigurationException.java new file mode 100644 index 0000000000..1c7f3e073d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidConfigurationException.java @@ -0,0 +1,36 @@ +/* + * 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.spi.loader; + +/** + * Denotes an invalid configuration artifact + * + * @version $Rev$ $Date$ + */ +public class InvalidConfigurationException extends LoaderException { + + public InvalidConfigurationException(String message) { + super(message); + } + + public InvalidConfigurationException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidReferenceException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidReferenceException.java new file mode 100644 index 0000000000..b2a5a26fec --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidReferenceException.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.spi.loader; + +/** + * @version $Rev$ $Date$ + */ +public class InvalidReferenceException extends LoaderException { + private static final long serialVersionUID = -4346666572527197558L; + + public InvalidReferenceException(String message) { + super(message); + } + + public InvalidReferenceException(String message, String identifier) { + super(message, identifier); + } + + public InvalidReferenceException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + public InvalidReferenceException(Throwable cause) { + super(cause); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidServiceException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidServiceException.java new file mode 100644 index 0000000000..1717cae0c3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidServiceException.java @@ -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.
+ */
+package org.apache.tuscany.spi.loader;
+
+/**
+ * @version $Rev: 430937 $ $Date: 2006-08-12 06:47:56 +0530 (Sat, 12 Aug 2006) $
+ */
+public class InvalidServiceException extends LoaderException {
+
+ public InvalidServiceException(String message, String identifier) {
+ super(message, identifier);
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidValueException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidValueException.java new file mode 100644 index 0000000000..b0ad8594ca --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidValueException.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.loader; + +/** + * Exception that indicates the loader encountered an invalid value. + * The message should be set to the invalid value. + * + * @version $Rev$ $Date$ + */ +public class InvalidValueException extends LoaderException { + + public InvalidValueException(String message) { + super(message); + } + + public InvalidValueException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidValueException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidWireException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidWireException.java new file mode 100644 index 0000000000..b26c81168f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/InvalidWireException.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.spi.loader;
+
+/**
+ * @version $Rev: 430937 $ $Date: 2006-08-12 06:47:56 +0530 (Sat, 12 Aug 2006) $
+ */
+public class InvalidWireException extends LoaderException {
+
+ public InvalidWireException() {
+ }
+
+ public InvalidWireException(String message) {
+ super(message);
+ }
+
+
+ public InvalidWireException(String message, String identifier) {
+ super(message, identifier);
+ }
+
+ public InvalidWireException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvalidWireException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/Loader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/Loader.java new file mode 100644 index 0000000000..14e5a0ec57 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/Loader.java @@ -0,0 +1,80 @@ +/* + * 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.spi.loader; + +import java.net.URL; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.ModelObject; + +/** + * System service for loading physical artifacts that represent SCDL configurations and creating the model objects that + * represent them. + * + * @version $Rev$ $Date$ + */ +public interface Loader { + /** + * Parse the supplied XML stream, dispatching to the appropriate registered loader for each element encountered in + * the stream. + * <p/> + * This method must be called with the XML cursor positioned on a START_ELEMENT event. When this method returns, the + * stream will be positioned on the corresponding END_ELEMENT event. + * + * @param object the model object to load configuration data into. If null, the loader dispatched to is + * responsible for creating a model object itself + * @param reader the XML stream to parse + * @param deploymentContext the current deployment context + * @return the model object obtained by parsing the current element on the stream + * @throws LoaderException if there was a problem loading the document + * @throws XMLStreamException if there was a problem reading the stream + */ + ModelObject load(ModelObject object, XMLStreamReader reader, DeploymentContext deploymentContext) + throws XMLStreamException, LoaderException; + + /** + * Load a model object from a specified location. + * + * @param object the model object to load configuration data into. If null, the loader dispatched to is responsible + * for creating a model object itself + * @param url the location of an XML document to be loaded + * @param type the type of ModelObject that is expected to be in the document + * @param context the current deployment context + * @return the model ojbect loaded from the document + * @throws LoaderException if there was a problem loading the document + */ + <MO extends ModelObject> MO load(ModelObject object, URL url, Class<MO> type, DeploymentContext context) + throws LoaderException; + + /** + * Load the component type definition for a given implementation. How the component type information is located is + * defined by the implementation specification. It may include loading from an XML sidefile, introspection of some + * artifact related to the implementation, some combination of those techniques or any other implementation-defined + * mechanism. + * + * @param implementation the implementation whose component type should be loaded + * @param context the current deployment context + * @throws LoaderException if there was a problem loading the component type definition + */ + <I extends Implementation<?>> void loadComponentType(I implementation, DeploymentContext context) + throws LoaderException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderException.java new file mode 100644 index 0000000000..defc6b06c9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderException.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.spi.loader; + +import org.apache.tuscany.api.TuscanyException; + +/** + * Base class for Exceptions raised during the loading process. Loader implementations should throw a subclass of this + * to indicate the actual problem. + * + * @version $Rev$ $Date$ + */ +public class LoaderException extends TuscanyException { + public static final int UNDEFINED = -1; + private static final long serialVersionUID = -7459051598906813461L; + private String resourceURI; + private int line = UNDEFINED; + private int column = UNDEFINED; + + public LoaderException() { + } + + public LoaderException(String message) { + super(message); + } + + public LoaderException(String message, String identifier) { + super(message, identifier); + } + + public LoaderException(String message, Throwable cause) { + super(message, cause); + } + + public LoaderException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + public LoaderException(Throwable cause) { + super(cause); + } + + /** + * Returns the location of the resource that was being loaded. + * + * @return the location of the resource that was being loaded + */ + public String getResourceURI() { + return resourceURI; + } + + /** + * Sets the location of the resource that was being loaded. + * + * @param resourceURI the location of the resource that was being loaded + */ + public void setResourceURI(String resourceURI) { + this.resourceURI = resourceURI; + } + + public int getLine() { + return line; + } + + public void setLine(int line) { + this.line = line; + } + + public int getColumn() { + return column; + } + + public void setColumn(int column) { + this.column = column; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderRegistry.java new file mode 100644 index 0000000000..ea88b99b22 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderRegistry.java @@ -0,0 +1,69 @@ +/* + * 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.spi.loader; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.model.Implementation; +import org.apache.tuscany.spi.model.ModelObject; + +/** + * Registry for XML loaders that can parse a StAX input stream and return model objects. + * <p/> + * Loaders will typically be contributed to the system by any extension that needs to handle extension specific + * information contained in some XML configuration file. The loader can be contributed as a system component with an + * autowire reference to this builderRegistry which is used during initialization to actually register. </p> This + * builderRegistry can also be used to parse an input stream, dispatching to the appropriate loader for each element + * accepted. Loaders can call back to the builderRegistry to load sub-elements that they are not able to handle + * directly. + * + * @version $Rev$ $Date$ + */ +public interface LoaderRegistry extends Loader { + /** + * Register a loader. This operation will typically be called by a loader during its initialization. + * + * @param element the element that should be delegated to the contibuted loader + * @param loader a loader that is being contributed to the system + */ + <T extends ModelObject> void registerLoader(QName element, StAXElementLoader<T> loader); + + /** + * Unregister a loader. This will typically be called by a loader as it is being destroyed. + * + * @param element the element that was being delegated to the contibuted loader + * @param loader a loader that should no longer be used + */ + <T extends ModelObject> void unregisterLoader(QName element, StAXElementLoader<T> loader); + + /** + * Regsiter a component type loader. + * + * @param key a type of implementation this loader can load component types for + * @param loader the loader that is being contributed to the system + */ + <I extends Implementation<?>> void registerLoader(Class<I> key, ComponentTypeLoader<I> loader); + + /** + * Unregister a component type loader form the system. + * + * @param key a type of implementation whose loader should be unregistered + */ + <I extends Implementation<?>> void unregisterLoader(Class<I> key); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderUtil.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderUtil.java new file mode 100644 index 0000000000..bf48f91a74 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/LoaderUtil.java @@ -0,0 +1,78 @@ +/* + * 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.spi.loader; + +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamConstants; + +/** + * Utility functions to support loader implementations. + * + * @version $Rev$ $Date$ + */ +public final class LoaderUtil { + private LoaderUtil() { + } + + /** + * Advance the stream to the next END_ELEMENT event skipping any nested content. + * + * @param reader the reader to advance + * @throws XMLStreamException if there was a problem reading the stream + */ + public static void skipToEndElement(XMLStreamReader reader) throws XMLStreamException { + int depth = 0; + while (true) { + int event = reader.next(); + if (event == XMLStreamConstants.START_ELEMENT) { + depth++; + } else if (event == XMLStreamConstants.END_ELEMENT) { + if (depth == 0) { + return; + } + depth--; + } + } + } + + /** + * Load the class using the supplied ClassLoader. + * The class will be defined so any initializers present will be fired. + * As the class is being loaded, the Thread context ClassLoader will be + * set to the supplied classloader. + * + * @param name the name of the class to load + * @param cl the classloader to use to load it + * @return the class + * @throws MissingResourceException if the class could not be found + */ + public static Class<?> loadClass(String name, ClassLoader cl) throws MissingResourceException { + final Thread thread = Thread.currentThread(); + final ClassLoader oldCL = thread.getContextClassLoader(); + try { + thread.setContextClassLoader(cl); + return Class.forName(name, true, cl); + } catch (ClassNotFoundException e) { + throw new MissingResourceException(name, e); + } finally { + thread.setContextClassLoader(oldCL); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingImplementationException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingImplementationException.java new file mode 100644 index 0000000000..89a44083cc --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingImplementationException.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.loader; + +/** + * Exception that indicates that an implementation was not provided. + * + * @version $Rev$ $Date$ + */ +public class MissingImplementationException extends LoaderException { + private static final long serialVersionUID = -2917278473974880124L; + + /** + * Default constructor. + */ + public MissingImplementationException() { + super(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingIncludeException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingIncludeException.java new file mode 100644 index 0000000000..10e40f9288 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingIncludeException.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.loader; + +/** + * Exception that indicates that an include was not provided. + * + * @version $Rev$ $Date$ + */ +public class MissingIncludeException extends LoaderException { + private static final long serialVersionUID = -2917278473974880124L; + + public MissingIncludeException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingPromoteException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingPromoteException.java new file mode 100644 index 0000000000..325de281a7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingPromoteException.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.spi.loader; + +/** + * Denotes a missing promote attribute in a SCDL configuration + * + * @version $Rev$ $Date$ + */ +public class MissingPromoteException extends LoaderException { + + public MissingPromoteException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingReferenceException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingReferenceException.java new file mode 100644 index 0000000000..7bc206de34 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingReferenceException.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.loader; + +/** + * Indicates a required reference was not configured + * + * @version $Rev$ $Date$ + */ +public class MissingReferenceException extends LoaderException { + + public MissingReferenceException(String message) { + super(message); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingRequiredPropertyException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingRequiredPropertyException.java new file mode 100644 index 0000000000..30955bb4e5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingRequiredPropertyException.java @@ -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. + */ +package org.apache.tuscany.spi.loader; + +/** + * @version $Rev$ $Date$ + */ +public class MissingRequiredPropertyException extends LoaderException { + + public MissingRequiredPropertyException(String name) { + super(name); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingResourceException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingResourceException.java new file mode 100644 index 0000000000..3b6a21aa74 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/MissingResourceException.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.loader; + +/** + * Exception that indicates an expected resource could not be found. The message should be set to the name of the + * resource. + * + * @version $Rev$ $Date$ + */ +public class MissingResourceException extends LoaderException { + private static final long serialVersionUID = 3775013318397916445L; + + /** + * Constructor that indicates which resource could not be found. The supplied parameter is also returned as the + * message. + * + * @param resource the resource that could not be found + */ + public MissingResourceException(String resource) { + super("Missing resource", resource); + } + + public MissingResourceException(String message, String identifier) { + super(message, identifier); + } + + /** + * Constructor that indicates which resource could not be found. The supplied parameter is also returned as the + * message. + * + * @param resource the resource that could not be found + * @param cause the error thrown resolving the resource + */ + public MissingResourceException(String resource, Throwable cause) { + super("Missing resource", resource, cause); + } + + + /** + * Constructor that indicates which resource could not be found. The supplied parameter is also returned as the + * message. + * + * @param message the message set on the exception + * @param identifier the resource that could not be found + * @param cause the error thrown resolving the resource + */ + public MissingResourceException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/PropertyObjectFactory.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/PropertyObjectFactory.java new file mode 100644 index 0000000000..8b569d76fb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/PropertyObjectFactory.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.loader; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.model.Property; +import org.apache.tuscany.spi.model.PropertyValue; + +/** + * A factory that will create an ObjectFactory for a property + * + * @version $Rev$ $Date$ + */ +public interface PropertyObjectFactory { + /** + * Return an ObjectFactory for instances of a property defined in an XML. The ObjectFactory must return instances + * that can safely be supplied to component implementations. If the instance is mutable and isolation between + * components is required, then the factory must clone or otherwise protect the implementation from unexpected + * modifications by other implementation instances. + * + * @param property the Property definition that the resulting ObjectFactory must be able to assign to + * @param propertyValue The component configuration of the property + * @return an ObjectFactory that can produce instances that can be assigned to the supplied Property + * @throws LoaderException if there is a problem creating the ObjectFactory + */ + <T> ObjectFactory<T> createObjectFactory(Property<T> property, PropertyValue<T> propertyValue) + throws LoaderException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/ReferenceMultiplicityViolationException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/ReferenceMultiplicityViolationException.java new file mode 100644 index 0000000000..ce9acb8750 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/ReferenceMultiplicityViolationException.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.spi.loader; + +import org.apache.tuscany.spi.model.Multiplicity; + +/** + * Denote the violation of multiplicity declaration for a reference + * + * @version $Rev $Date + */ +public class ReferenceMultiplicityViolationException extends LoaderException { + private static final long serialVersionUID = -4049116356211578827L; + + private final Multiplicity multiplicity; + private final int numberOfTargets; + + /** + * @param message + * @param identifier + * @param multiplicity + * @param numberOfTargets + */ + public ReferenceMultiplicityViolationException(String message, + String identifier, + Multiplicity multiplicity, + int numberOfTargets) { + super(message, identifier); + this.multiplicity = multiplicity; + this.numberOfTargets = numberOfTargets; + } + + /** + * @param identifier + * @param multiplicity + * @param numberOfTargets + */ + public ReferenceMultiplicityViolationException(String identifier, Multiplicity multiplicity, int numberOfTargets) { + this("Multiplicity is violated", identifier, multiplicity, numberOfTargets); + } + + /** + * Get the multiplicity for the reference definition + * + * @return multiplicity of the reference definition + */ + public Multiplicity getMultiplicity() { + return multiplicity; + } + + /** + * Get the number of targets defined for this reference + * @return number of targets for this reference + */ + public int getNumberOfTargets() { + return numberOfTargets; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/StAXElementLoader.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/StAXElementLoader.java new file mode 100644 index 0000000000..9f0ad909f9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/StAXElementLoader.java @@ -0,0 +1,46 @@ +/* + * 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.spi.loader; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.model.ModelObject; + +/** + * A loader that creates a model object from a StAX input stream. + * + * @version $Rev$ $Date$ + */ +public interface StAXElementLoader<T extends ModelObject> { + /** + * Create the model object for an element in an XML stream. When this method returns the stream will be positioned + * on the corresponding END_ELEMENT. + * + * @param object the model object to load configuration data into. An implementation may choose to return a + * different model object than the one passed in, in which case it is responsible for copying data. + * If null, the loader is responsible for creating a model object itself + * @param reader the XML stream reader positioned on the applicable START_ELEMENT + * @param context the context for the load operation + * @return the model object for that element + */ + T load(ModelObject object, XMLStreamReader reader, DeploymentContext context) + throws XMLStreamException, LoaderException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/UndefinedPropertyException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/UndefinedPropertyException.java new file mode 100644 index 0000000000..bf3aa205d2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/UndefinedPropertyException.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.spi.loader; + +/** + * @version $Rev$ $Date$ + */ +public class UndefinedPropertyException extends LoaderException { + public UndefinedPropertyException(String name) { + super("Property not found on implementation", name); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/UndefinedReferenceException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/UndefinedReferenceException.java new file mode 100644 index 0000000000..f9aa8812ac --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/UndefinedReferenceException.java @@ -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. + */ +package org.apache.tuscany.spi.loader; + +/** + * @version $Rev$ $Date$ + */ +public class UndefinedReferenceException extends LoaderException { + private static final long serialVersionUID = -2897448857974015706L; + + public UndefinedReferenceException(String name) { + super("Reference not found on implementation", name); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/UnrecognizedComponentTypeException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/UnrecognizedComponentTypeException.java new file mode 100644 index 0000000000..750762d839 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/UnrecognizedComponentTypeException.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.spi.loader; + +/** + * Exception that indicates an component type was encountered that could not be handled. + * + * @version $Rev$ $Date$ + */ +public class UnrecognizedComponentTypeException extends LoaderException { + private final Class<?> type; + + /** + * Constructor that indicates which component type loader could not be found. + * + * @param type the component type type that could not be handled + */ + public UnrecognizedComponentTypeException(Class<?> type) { + super("Unrecognized element", type.getName()); + this.type = type; + } + + public Class<?> getType() { + return type; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/UnrecognizedElementException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/UnrecognizedElementException.java new file mode 100644 index 0000000000..7991105da8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/loader/UnrecognizedElementException.java @@ -0,0 +1,46 @@ +/* + * 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.spi.loader; + +import javax.xml.namespace.QName; + +/** + * Exception that indicates an element was encountered that could not be handled. + * + * @version $Rev$ $Date$ + */ +public class UnrecognizedElementException extends LoaderException { + private static final long serialVersionUID = 2549543622209829032L; + private final QName element; + + /** + * Constructor that indicates which resource could not be found. The supplied parameter is also returned as the + * message. + * + * @param element the element that could not be handled + */ + public UnrecognizedElementException(QName element) { + super("Unrecognized element", element.toString()); + this.element = element; + } + + public QName getElement() { + return element; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/marshaller/MarshallException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/marshaller/MarshallException.java new file mode 100644 index 0000000000..783d0951cf --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/marshaller/MarshallException.java @@ -0,0 +1,49 @@ +/* + * 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.spi.marshaller; + +import org.apache.tuscany.api.TuscanyException; + +/** + * Super class for all marshalling/unmarshalling exceptions. + * + * @version $Rev$ $Date$ + */ +@SuppressWarnings("serial") +public class MarshallException extends TuscanyException { + + /** + * Initializes the exception message. + * + * @param message Message for the exception. + */ + public MarshallException(String message) { + super(message); + } + + /** + * Initializes the root cause. + * + * @param cause Root cause for the exception. + */ + public MarshallException(Throwable cause) { + super(cause); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/marshaller/ModelMarshaller.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/marshaller/ModelMarshaller.java new file mode 100644 index 0000000000..fb3ed463bf --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/marshaller/ModelMarshaller.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.spi.marshaller; + +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.spi.model.ModelObject; + +/** + * Interface for marshalling/unmarshalling internal physical component definitions. + * + * @version $Rev$ $Date$ + * + */ +public interface ModelMarshaller<MD extends ModelObject> { + + /** + * Marshalls the physical component definition to the specified stream writer. + * + * @param modelObject Physical component definition to be serialized. + * @param writer Stream writer to which the infoset is serialized. + * @throws MarshallException In case of any marshalling error. + */ + void marshall(MD modelObject, XMLStreamWriter writer) throws MarshallException; + + /** + * Unmarshalls an XML stream to a model object. + * + * @param reader XML stream from where the marshalled XML is read. + * @return Physical component definition. + * @throws MarshallException In case of any unmarshalling error. + */ + MD unmarshall(XMLStreamReader reader) throws MarshallException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/marshaller/ModelMarshallerRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/marshaller/ModelMarshallerRegistry.java new file mode 100644 index 0000000000..8b0f764275 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/marshaller/ModelMarshallerRegistry.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.marshaller; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.spi.model.ModelObject; + +/** + * A registry for model object marshallers. + * + * @version $Rev$ $Date$ + */ +public interface ModelMarshallerRegistry { + + /** + * Registers a model object marshaller. + * + * @param <MD> Model object type. + * @param modelClass Model obejct class. + * @param qname Qualified name of the root element of the marshalled XML. + * @param marshaller Model object marshaller. + */ + <MD extends ModelObject> void registerMarshaller(Class<MD> modelClass, QName qname, ModelMarshaller<MD> marshaller); + + /** + * Marshalls a model object. + * + * @param modelObject Model object to be marshalled. + * @param writer Writer to which marshalled information is written. + */ + void marshall(ModelObject modelObject, XMLStreamWriter writer) throws MarshallException; + + /** + * Unmarshalls an XML stream to a model object. + * + * @param reader Reader from which marshalled information is read. + * @return Model object from the marshalled stream. + */ + ModelObject unmarshall(XMLStreamReader reader) throws MarshallException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/AtomicImplementation.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/AtomicImplementation.java new file mode 100644 index 0000000000..8e12e970ae --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/AtomicImplementation.java @@ -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. + */ +package org.apache.tuscany.spi.model; + +/** + * The base representation of an atomic component implementation + * + * @version $Rev$ $Date$ + */ +public abstract class AtomicImplementation<T extends ComponentType> extends Implementation<T> { + protected AtomicImplementation() { + } + + protected AtomicImplementation(T componentType) { + super(componentType); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/BindingDefinition.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/BindingDefinition.java new file mode 100644 index 0000000000..4b17181442 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/BindingDefinition.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.spi.model; + +import java.net.URI; + +/** + * The base representation of a binding specified in an assembly + * + * @version $Rev$ $Date$ + */ +public abstract class BindingDefinition extends ModelObject { + private URI targetUri; + + protected BindingDefinition() { + } + + public BindingDefinition(URI targetUri) { + this.targetUri = targetUri; + } + + public URI getTargetUri() { + return targetUri; + } + + public void setTargetUri(URI targetUri) { + this.targetUri = targetUri; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ComponentDefinition.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ComponentDefinition.java new file mode 100644 index 0000000000..7c06dd5703 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ComponentDefinition.java @@ -0,0 +1,170 @@ +/* + * 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.spi.model; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +/** + * Represents a component. <p>A component is a configured instance of an implementation. The services provided and + * consumed and the available configuration properties are defined by the implementation (represented by its + * componentType).</p> <p>Every component has a name which uniquely identifies it within the scope of the composite that + * contains it; the name must be different from the names of all other components, services and references immediately + * contained in the composite (directly or through an <include> element).</p> <p>A component may define a {@link + * PropertyValue} that overrides the default value of a {@link Property} defined in the componentType.</p> <p>It may + * also define a {@link ReferenceTarget} for a {@link ReferenceDefinition} defined in the componentType. The + * ReferenceTarget must resolve to another component or a reference in the enclosing composite.</p> <p>Components may + * specify an initialization level that will determine the order in which it will be eagerly initialized relative to + * other components from the enclosing composite that are in the same scope. This can be used to define a startup + * sequence for components that are otherwise independent. Any initialization required to resolve references between + * components will override this initialization order.</p> + * + * @version $Rev$ $Date$ + */ +public class ComponentDefinition<I extends Implementation<?>> extends ModelObject { + private URI uri; + private boolean autowire; + private Integer initLevel; + private final I implementation; + private final Map<String, ReferenceTarget> referenceTargets = new HashMap<String, ReferenceTarget>(); + private final Map<String, PropertyValue<?>> propertyValues = new HashMap<String, PropertyValue<?>>(); + + /** + * Constructor specifying the component's name and implementation. + * + * @param uri the name of this component + * @param implementation the implementation of this component + */ + public ComponentDefinition(URI uri, I implementation) { + this.uri = uri; + this.implementation = implementation; + } + + /** + * Constructor specifying the implementation of this component. + * + * @param implementation the implementation of this component + */ + public ComponentDefinition(I implementation) { + this.implementation = implementation; + } + + /** + * Returns the {@link Implementation} of this component. + * + * @return the implementation of this component + */ + public I getImplementation() { + return implementation; + } + + /** + * Returns the name of this component. + * + * @return the name of this component + */ + public URI getUri() { + return uri; + } + + /** + * Sets the name of this component. + * + * @param uri the name of this component + */ + public void setUri(URI uri) { + this.uri = uri; + } + + /** + * Returns true if autowire is enabled for the component. + * + * @return true if autowire is enabled for the component. + */ + public boolean getAutowire() { + return autowire; + } + + /** + * Sets autowire enablement for the component. + * + * @param autowire true if autowire is enabled. + */ + public void setAutowire(boolean autowire) { + this.autowire = autowire; + } + + /** + * Returns the initialization level of this component. + * + * @return the initialization level of this component + */ + public Integer getInitLevel() { + return initLevel; + } + + /** + * Sets the initialization level of this component. If set to null then the level from the componentType is used. If + * set to zero or a negative value then the component will not be eagerly initialized. + * + * @param initLevel the initialization level of this component + */ + public void setInitLevel(Integer initLevel) { + this.initLevel = initLevel; + } + + /** + * Returns a live Map of the {@link ReferenceTarget targets} configured by this component definition. + * + * @return the reference targets configured by this component + */ + public Map<String, ReferenceTarget> getReferenceTargets() { + return referenceTargets; + } + + /** + * Add a reference target configuration to this component. Any existing configuration for the reference named in the + * target is replaced. + * + * @param target the target to add + */ + public void add(ReferenceTarget target) { + referenceTargets.put(target.getReferenceName().getFragment(), target); + } + + /** + * Returns a live Map of {@link PropertyValue property values} configured by this component definition. + * + * @return the property values configured by this component + */ + public Map<String, PropertyValue<?>> getPropertyValues() { + return propertyValues; + } + + /** + * Add a property value configuration to this component. Any existing configuration for the property names in the + * property value is replaced. + * + * @param value the property value to add + */ + public void add(PropertyValue<?> value) { + propertyValues.put(value.getName(), value); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ComponentType.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ComponentType.java new file mode 100644 index 0000000000..b4e2db485e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ComponentType.java @@ -0,0 +1,178 @@ +/* + * 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.spi.model; + +import java.util.HashMap; +import java.util.Map; + +/** + * <p>The definition of the configurable aspects of an implementation in terms of the services it exposes, the services + * it references, and properties that can be used to configure it.</p> <p>A service represents an addressable interface + * provided by the implementation. Such a service may be the target of a wire from another component.</p> <p>A reference + * represents a requirement that an implementation has on a service provided by another component or by a resource + * outside the SCA system. Such a reference may be the source of a wire to another component.</p> <p>A property allows + * the behaviour of the implementation to be configured through externally set values.</p> <p>A component type may also + * declare that it wishes to be initialized upon activation of the scope that contains it and may specify an order + * relative to other eagerly initializing components. For example, an implementation that pre-loads some form of cache + * could declare that it should be eagerly initialized at the start of the scope so that the cache load occured on + * startup rather than first use.</p> + * + * @version $Rev$ $Date$ + */ +public class ComponentType<S extends ServiceDefinition, R extends ReferenceDefinition, P extends Property<?>> + extends ModelObject { + protected Scope implementationScope = Scope.UNDEFINED; + private int initLevel; + private long maxAge = -1; + private long maxIdleTime = -1; + private final Map<String, S> services = new HashMap<String, S>(); + private final Map<String, R> references = new HashMap<String, R>(); + private final Map<String, P> properties = new HashMap<String, P>(); + + /** + * Returns the component implementation scope + */ + public Scope getImplementationScope() { + return implementationScope; + } + + /** + * Sets the component implementation scope + */ + public void setImplementationScope(Scope implementationScope) { + this.implementationScope = implementationScope; + } + + /** + * Returns the default initialization level for components of this type. A value greater than zero indicates that + * components should be eagerly initialized. + * + * @return the default initialization level + */ + public int getInitLevel() { + return initLevel; + } + + /** + * Sets the default initialization level for components of this type. A value greater than zero indicates that + * components should be eagerly initialized. + * + * @param initLevel default initialization level for components of this type + */ + public void setInitLevel(int initLevel) { + this.initLevel = initLevel; + } + + /** + * Returns true if this component should be eagerly initialized. + * + * @return true if this component should be eagerly initialized + */ + public boolean isEagerInit() { + return initLevel > 0; + } + + /** + * Returns the idle time allowed between operations in milliseconds if the implementation is conversational + * + * @return the idle time allowed between operations in milliseconds if the implementation is conversational + */ + public long getMaxIdleTime() { + return maxIdleTime; + } + + /** + * Sets the idle time allowed between operations in milliseconds if the implementation is conversational + */ + public void setMaxIdleTime(long maxIdleTime) { + this.maxIdleTime = maxIdleTime; + } + + /** + * Returns the maximum age a conversation may remain active in milliseconds if the implementation is conversational + * + * @return the maximum age a conversation may remain active in milliseconds if the implementation is conversational + */ + public long getMaxAge() { + return maxAge; + } + + /** + * Sets the maximum age a conversation may remain active in milliseconds if the implementation is conversational + */ + public void setMaxAge(long maxAge) { + this.maxAge = maxAge; + } + + /** + * Returns a live Map of the services provided by the implementation. + * + * @return a live Map of the services provided by the implementation + */ + public Map<String, S> getServices() { + return services; + } + + /** + * Add a service to those provided by the implementation. Any existing service with the same name is replaced. + * + * @param service a service provided by the implementation + */ + public void add(S service) { + services.put(service.getUri().getFragment(), service); + } + + /** + * Returns a live Map of references to services consumed by the implementation. + * + * @return a live Map of references to services consumed by the implementation + */ + public Map<String, R> getReferences() { + return references; + } + + /** + * Add a reference to a service consumed by the implementation. Any existing reference with the same name is + * replaced. + * + * @param reference a reference to a service consumed by the implementation + */ + public void add(R reference) { + references.put(reference.getUri().getFragment(), reference); + } + + /** + * Returns a live Map of properties that can be used to configure the implementation. + * + * @return a live Map of properties that can be used to configure the implementation + */ + public Map<String, P> getProperties() { + return properties; + } + + /** + * Add a property that can be used to configure the implementation. Any existing property with the same name is + * replaced. + * + * @param property a property that can be used to configure the implementation + */ + public void add(P property) { + properties.put(property.getName(), property); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/CompositeComponentType.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/CompositeComponentType.java new file mode 100644 index 0000000000..464b5758b7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/CompositeComponentType.java @@ -0,0 +1,236 @@ +/* + * 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.spi.model; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.util.UriHelper; + +/** + * A specialization of component type for composite components. + * + * @version $Rev$ $Date$ + */ +public class CompositeComponentType<S extends ServiceDefinition, + R extends ReferenceDefinition, + P extends Property<?>> extends ComponentType<S, R, P> { + + private QName name; + private boolean autowire; + private final Map<String, ComponentDefinition<? extends Implementation<?>>> components = + new HashMap<String, ComponentDefinition<? extends Implementation<?>>>(); + private final Map<String, Include> includes = new HashMap<String, Include>(); + private final List<WireDefinition> wires = new ArrayList<WireDefinition>(); + + public CompositeComponentType() { + implementationScope = Scope.SYSTEM; + } + + /** + * Constructor defining the composite name. + * + * @param name the qualified name of this composite + */ + public CompositeComponentType(QName name) { + this(); + this.name = name; + } + + /** + * Returns the qualified name of this composite. + * The namespace portion of this name is the targetNamespace for other qualified names used in the composite. + * + * @return the qualified name of this composite + */ + public QName getName() { + return name; + } + + /** + * Set the qualified name of this composite. + * + * @param name the qualified name of this composite + */ + public void setName(QName name) { + this.name = name; + } + + /** + * Returns if autowire is set of for composite + * + * @return true if autowire is set for the composite + */ + public boolean isAutowire() { + return autowire; + } + + /** + * Sets autowire for the composite + * + * @param autowire true if autowire is enabled for the composite + */ + public void setAutowire(boolean autowire) { + this.autowire = autowire; + } + + @Override + @SuppressWarnings("unchecked") + /** + * Get all properties including the ones are from included composites + * @return + */ + public Map<String, P> getProperties() { + Map<String, P> view = new HashMap<String, P>(super.getProperties()); + for (Include i : includes.values()) { + view.putAll(i.getIncluded().getProperties()); + } + return Collections.unmodifiableMap(view); + } + + @Override + @SuppressWarnings("unchecked") + /** + * Get all references including the ones are from included composites + * @return + */ + public Map<String, R> getReferences() { + Map<String, R> view = new HashMap<String, R>(super.getReferences()); + for (Include i : includes.values()) { + view.putAll(i.getIncluded().getReferences()); + } + return Collections.unmodifiableMap(view); + } + + @SuppressWarnings("unchecked") + @Override + /** + * Get all services including the ones are from included composites + * @return + */ + public Map<String, S> getServices() { + Map<String, S> view = new HashMap<String, S>(super.getServices()); + for (Include i : includes.values()) { + view.putAll(i.getIncluded().getServices()); + } + return Collections.unmodifiableMap(view); + } + + /** + * Get all components including the ones are from included composites + */ + @SuppressWarnings("unchecked") + public Map<String, ComponentDefinition<? extends Implementation<?>>> getComponents() { + Map<String, ComponentDefinition<? extends Implementation<?>>> view = + new HashMap<String, ComponentDefinition<? extends Implementation<?>>>(components); + for (Include i : includes.values()) { + view.putAll(i.getIncluded().getComponents()); + } + return Collections.unmodifiableMap(view); + } + + + /** + * Get all wires including the ones are from included composites + */ + @SuppressWarnings("unchecked") + public List<WireDefinition> getWires() { + List<WireDefinition> view = + new ArrayList<WireDefinition>(wires); + for (Include i : includes.values()) { + view.addAll(i.getIncluded().getWires()); + } + return Collections.unmodifiableList(view); + } + + /** + * Get declared properties in this composite type, included doesn't count + */ + public Map<String, P> getDeclaredProperties() { + return super.getProperties(); + } + + /** + * Get declared references in this composite type, included doesn't count + */ + public Map<String, R> getDeclaredReferences() { + return super.getReferences(); + } + + /** + * Get declared services in this composite type, included doesn't count + */ + public Map<String, S> getDeclaredServices() { + return super.getServices(); + } + + /** + * Get declared components in this composite type, included doesn't count + */ + public Map<String, ComponentDefinition<? extends Implementation<?>>> getDeclaredComponents() { + return components; + } + + /** + * Get declared wires in this composite type, included doesn't count + */ + public List<WireDefinition> getDeclaredWires() { + return wires; + } + + public void add(WireDefinition wireDefn) { + wires.add(wireDefn); + } + + + public void add(ComponentDefinition<? extends Implementation<?>> componentDefinition) { + components.put(UriHelper.getBaseName(componentDefinition.getUri()), componentDefinition); + } + + public Map<String, Include> getIncludes() { + return includes; + } + + public void add(Include include) { + includes.put(include.getName(), include); + } + + + public int hashCode() { + return name.hashCode(); + } + + + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + CompositeComponentType that = (CompositeComponentType) o; + return name.equals(that.name); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/CompositeImplementation.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/CompositeImplementation.java new file mode 100644 index 0000000000..6948c52286 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/CompositeImplementation.java @@ -0,0 +1,56 @@ +/* + * 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.spi.model; + +import java.net.URL; + +/** + * A specialization of an implementation associated with composite components + * + * @version $Rev$ $Date$ + */ +public class CompositeImplementation extends Implementation<CompositeComponentType> { + private String name; + private URL scdlLocation; + private ClassLoader classLoader; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public URL getScdlLocation() { + return scdlLocation; + } + + public void setScdlLocation(URL scdlLocation) { + this.scdlLocation = scdlLocation; + } + + public ClassLoader getClassLoader() { + return classLoader; + } + + public void setClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Contribution.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Contribution.java new file mode 100644 index 0000000000..8f8c4068b4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Contribution.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.spi.model; + +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.namespace.QName; + +/** + * The representation of a deployed contribution + * + * @version $Rev$ $Date$ + */ +public class Contribution extends DeployedArtifact { + public static final String SCA_CONTRIBUTION_META = "META-INF/sca-contribution.xml"; + public static final String SCA_CONTRIBUTION_GENERATED_META = "META-INF/sca-contribution-generated.xml"; + + protected List<String> exports = new ArrayList<String>(); + protected List<ContributionImport> imports = new ArrayList<ContributionImport>(); + protected List<QName> runnables = new ArrayList<QName>(); + + /** + * A list of artifacts in the contribution + */ + protected Map<URI, DeployedArtifact> artifacts = new HashMap<URI, DeployedArtifact>(); + + + /** + * @param uri + */ + public Contribution(URI uri) { + super(uri); + artifacts.put(uri, this); + } + + public URI getUri() { + return uri; + } + + public List<String> getExports() { + return exports; + } + + public List<ContributionImport> getImports() { + return imports; + } + + public List<QName> getRunnables() { + return runnables; + } + + public Map<URI, DeployedArtifact> getArtifacts() { + return Collections.unmodifiableMap(artifacts); + } + + public void addArtifact(DeployedArtifact artifact) { + artifact.setContribution(this); + artifacts.put(artifact.getUri(), artifact); + } + + public DeployedArtifact getArtifact(URI uri) { + return artifacts.get(uri); + } + + /** + * @return the location + */ + public URL getLocation() { + return location; + } + + /** + * @param location the location to set + */ + public void setLocation(URL location) { + this.location = location; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ContributionImport.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ContributionImport.java new file mode 100644 index 0000000000..a678adbdc8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ContributionImport.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.spi.model; + +import java.net.URI; + +/** + * The representation of an import for the contribution + * + * @version $Rev$ $Date$ + */ +public class ContributionImport extends ModelObject { + private String namespace; // The namespace to be imported + private URI location; // Optional location to hint the where it should be imported + + // TODO: We might need the field to point to the imported artifact/model + + public URI getLocation() { + return location; + } + + public void setLocation(URI location) { + this.location = location; + } + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/DataType.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/DataType.java new file mode 100644 index 0000000000..f36f3765ce --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/DataType.java @@ -0,0 +1,242 @@ +/* + * 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.spi.model; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +/** + * Representation of the type of data associated with an operation. Data is represented in two forms: the physical form + * used by the runtime and a logical form used by the assembly. The physical form is a Java Type because the runtime is + * written in Java. This may be the same form used by the application but it may not; for example, an application that + * is performing stream processing may want a physical form such as an {@link java.io.InputStream InputStream} to + * semantially operate on application data such as a purchase order. The logical description is that used by the + * assembly model and is an identifier into some well-known type space; examples may be a Java type represented by its + * Class or an XML type represented by its QName. Every data type may also contain metadata describing the expected + * data; for example, it could specify a preferred data binding technology or the size of a typical instance. + * + * @version $Rev$ $Date$ + */ +public class DataType<L> extends ModelObject implements Cloneable { + private String dataBinding = Object.class.getName(); + + private final Type physical; + + private final L logical; + + private Map<String, Object> metadata = new HashMap<String, Object>(); + + private Operation operation; + + /** + * Construct a data type specifying the physical and logical types. + * + * @param physical the physical class used by the runtime + * @param logical the logical type + * @see #getLogical() + */ + public DataType(Type physical, L logical) { + this.physical = physical; + this.logical = logical; + if (physical instanceof Class) { + this.dataBinding = ((Class) physical).getName(); + } + } + + public DataType(String dataBinding, Type physical, L logical) { + this.dataBinding = dataBinding; + this.physical = physical; + this.logical = logical; + } + + /** + * Returns the physical type used by the runtime. + * + * @return the physical type used by the runtime + */ + public Type getPhysical() { + return physical; + } + + /** + * Returns the logical identifier used by the assembly. The type of this value identifies the logical type system in + * use. Known values are: <ul> <li>a java.lang.reflect.Type identifies a Java type by name and ClassLoader; this + * includes Java Classes as they are specializations of Type</li> <li>a javax.xml.namespace.QName identifies an XML + * type by local name and namespace</li> </ul> + * + * @return the logical type name + */ + public L getLogical() { + return logical; + } + + /** + * Returns all metadata about this type. + * + * @return all metadata about this type + */ + public Map<String, ?> getMetadata() { + return metadata; + } + + /** + * Returns the specified metadata item or null if not present. + * + * @param name the name of the metadata item + * @return the value, or null if not present + */ + public Object getMetadata(String name) { + return metadata.get(name); + } + + /** + * Sets the specified metadata value. A null value undefines it. + * + * @param name the name of the metadata item + * @param value the value, or null to undefine + * @return the old value for the item, or null if not present + */ + public Object setMetadata(String name, Object value) { + if (value == null) { + return metadata.remove(name); + } else { + return metadata.put(name, value); + } + } + + public String getDataBinding() { + if (dataBinding == null) { + // databinding is not set at the DataType level, check the operation + Operation<?> operation = (Operation<?>) getOperation(); + if (operation != null) { + return operation.getDataBinding(); + } + } + return dataBinding; + } + + /** + * @param dataBinding the dataBinding to set + */ + public void setDataBinding(String dataBinding) { + this.dataBinding = dataBinding; + } + + public int hashCode() { + int result; + result = dataBinding != null ? dataBinding.hashCode() : 0; + result = 29 * result + (physical != null ? physical.hashCode() : 0); + result = 29 * result + (logical != null ? logical.hashCode() : 0); + // Commented the following line out since it causes infinite loop from Operation.hashCode() + // if the metadata map contains the Operation + // result = 29 * result + (metadata != null ? metadata.hashCode() : 0); + return result; + } + + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final DataType dataType = (DataType) o; + + if (dataBinding != null ? !dataBinding.equals(dataType.dataBinding) : dataType.dataBinding != null) { + return false; + } + if (logical != null ? !logical.equals(dataType.logical) : dataType.logical != null) { + return false; + } + return !(physical != null ? !physical.equals(dataType.physical) : dataType.physical != null); + + } + +// @SuppressWarnings("unchecked") +// public boolean equals(Object o) { +// if (this == o) { +// return true; +// } +// if (o == null || getClass() != o.getClass()) { +// return false; +// } +// +// final DataType dataType = (DataType) o; +// +// if (logical instanceof Class && dataType.logical instanceof Class) { +// Class<?> logicalClass = (Class<?>) logical; +// Class<?> targetLogicalClass = (Class<?>) dataType.logical; +// if (!logicalClass.isAssignableFrom(targetLogicalClass)) { +// return false; +// } +// } else { +// if (logical != null ? !logical.equals(dataType.logical) : dataType.logical != null) { +// return false; +// } +// } +// if (physical instanceof Class && dataType.physical instanceof Class) { +// Class<?> physicalClass = (Class<?>) physical; +// Class<?> physicalTargetClass = (Class<?>) dataType.physical; +// if (dataBinding != null +// && dataType.dataBinding != null +// && dataBinding.equals(physicalClass.getName()) +// && dataType.dataBinding.equals(physicalTargetClass.getName())) { +// return physicalClass.isAssignableFrom(physicalTargetClass); +// } +// if (!physicalClass.isAssignableFrom(physicalTargetClass)) { +// return false; +// } +// return !(dataBinding != null ? !dataBinding.equals(dataType.dataBinding) : dataType.dataBinding != null); +// +// +// } +// +// if (dataBinding != null ? !dataBinding.equals(dataType.dataBinding) : dataType.dataBinding != null) { +// return false; +// } +// +// return !(physical != null ? !physical.equals(dataType.physical) : dataType.physical != null); +// } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(physical).append(" ").append(dataBinding).append(" ").append(logical); + return sb.toString(); + } + + @SuppressWarnings("unchecked") + @Override + public Object clone() throws CloneNotSupportedException { + DataType<L> copy = (DataType<L>) super.clone(); + assert this.metadata instanceof HashMap; + copy.metadata = (HashMap<String, Object>) ((HashMap) this.metadata).clone(); + return copy; + } + + public Operation getOperation() { + return operation; + } + + public void setOperation(Operation operation) { + this.operation = operation; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/DeployedArtifact.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/DeployedArtifact.java new file mode 100644 index 0000000000..ecda99b4de --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/DeployedArtifact.java @@ -0,0 +1,108 @@ +/* + * 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.spi.model; + +import java.net.URI; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +/** + * Representation of a deployed artifact + * + * @version $Rev$ $Date$ + */ +public class DeployedArtifact extends ModelObject { + protected Contribution contribution; + protected final URI uri; + protected URL location; + /** + * The map keeps all the model objects loaded/introspected from this artifact. The objects are keyed by the java + * type of the model such as javax.wsdl.ModelObject. The value is also a map with namespace as the key and the model + * object as the value. + */ + protected Map<Class, Map<String, Object>> modelObjects = new HashMap<Class, Map<String, Object>>(); + + /** + * @param uri the artifact uri + */ + public DeployedArtifact(URI uri) { + super(); + this.uri = uri; + } + + public Contribution getContribution() { + return contribution; + } + + public void setContribution(Contribution contribution) { + this.contribution = contribution; + } + + /** + * Get the absolute URI as the unique id for the artifact + * + * @return the uri for the artifact + */ + public URI getUri() { + return uri; + } + + public Map<Class, Map<String, Object>> getModelObjects() { + return modelObjects; + } + + public Map<String, Object> getModelObjects(Class type) { + return modelObjects.get(type); + } + + public Object getModelObject(Class type, String namespace) { + Map<String, Object> map = modelObjects.get(type); + if (map == null) { + return null; + } else { + return map.get(namespace); + } + } + + public void addModelObject(Class type, String namespace, Object modelObject) { + Map<String, Object> map = modelObjects.get(type); + if (map == null) { + map = new HashMap<String, Object>(); + modelObjects.put(type, map); + } + map.put(namespace, modelObject); + } + + /** + * @return the location + */ + public URL getLocation() { + return location; + } + + /** + * @param location the location to set + */ + public void setLocation(URL location) { + this.location = location; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ElementInfo.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ElementInfo.java new file mode 100644 index 0000000000..31c2f9428f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ElementInfo.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.spi.model; + +import javax.xml.namespace.QName; + +/** + * An abstraction of XML schema elements + */ +public class ElementInfo { + private QName name; + private TypeInfo type; + + /** + * @param name + * @param type + */ + public ElementInfo(QName name, TypeInfo type) { + super(); + this.name = name; + this.type = type; + } + + /** + * @return the name + */ + public QName getQName() { + return name; + } + + /** + * @return the type + */ + public TypeInfo getType() { + return type; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("Element: ").append(name).append(" ").append(type); + return sb.toString(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Implementation.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Implementation.java new file mode 100644 index 0000000000..8520ab49e8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Implementation.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.spi.model; + +/** + * Represents a component implementation + * + * @version $Rev$ $Date$ + */ +public abstract class Implementation<T extends ComponentType> extends ModelObject { + private T componentType; + + protected Implementation() { + } + + protected Implementation(T componentType) { + this.componentType = componentType; + } + + public T getComponentType() { + return componentType; + } + + public void setComponentType(T componentType) { + this.componentType = componentType; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Include.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Include.java new file mode 100644 index 0000000000..ac320a2b5c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Include.java @@ -0,0 +1,80 @@ +/* + * 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.spi.model; + +import java.net.URL; + +/** + * Model object that represents the include of a composite by value. + * + * @version $Rev$ $Date$ + */ +public class Include extends ModelObject { + private String name; + private URL scdlLocation; + private CompositeComponentType included; + + /** + * Returns the name of the composite that is being included. + * @return the name of the composite that is being included + */ + public String getName() { + return name; + } + + /** + * Sets the name of the composite that is being included. + * @param name the name of the composite that is being included + */ + public void setName(String name) { + this.name = name; + } + + /** + * Returns the location of the SCDL for composite being included. + * @return the location of the SCDL for composite being included + */ + public URL getScdlLocation() { + return scdlLocation; + } + + /** + * Sets the location of the SCDL for composite being included. + * @param scdlLocation the location of the SCDL for composite being included + */ + public void setScdlLocation(URL scdlLocation) { + this.scdlLocation = scdlLocation; + } + + /** + * Returns the composite that was included. + * @return the composite that was included + */ + public CompositeComponentType getIncluded() { + return included; + } + + /** + * Sets the composite that was included. + * @param included the composite that was included + */ + public void setIncluded(CompositeComponentType included) { + this.included = included; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Intent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Intent.java new file mode 100644 index 0000000000..9f3ee78a23 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Intent.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.spi.model; + +import java.util.ArrayList; +import static java.util.Collections.unmodifiableList; +import java.util.List; +import javax.xml.namespace.QName; + +/** + * Model representation for intent. This class is used by intent loader only, other SCA model classes will not reference + * this class directly. + * + * @version $Rev$ $Date$ + */ +public class Intent { + + /** + * name of intent. + */ + protected IntentName name; + + /** + * Description for this intent + */ + protected String description; + + /** + * QNames of artifacts this intent can apply to + */ + protected List<QName> appliedArtifacts = new ArrayList<QName>(); + + /** + * intents required by this intent, only useful when this intent is a profile intent + */ + protected List<IntentName> requriedIntents = new ArrayList<IntentName>(); + + /** + * Create a policy intent. + * + * @param name name of the intent. + * @param description description of the intent. + */ + public Intent(IntentName name, String description) { + this.name = name; + this.description = description; + } + + public List<QName> getAppliedArtifacts() { + return unmodifiableList(appliedArtifacts); + } + + public String getDescription() { + return description; + } + + public IntentName getName() { + return name; + } + + public List<IntentName> getRequriedIntents() { + return unmodifiableList(requriedIntents); + } + + public void addRequriedIntents(IntentName intent) { + requriedIntents.add(intent); + } + + public void addAppliedArtifacts(QName artifactName) { + appliedArtifacts.add(artifactName); + } + + public boolean isProfileIntent() { + return !requriedIntents.isEmpty(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/IntentMap.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/IntentMap.java new file mode 100644 index 0000000000..cbfba86dfe --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/IntentMap.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.spi.model; + +import java.util.ArrayList; +import java.util.Collection; +import static java.util.Collections.unmodifiableCollection; + +/** + * Represents an IntentMap within PolicySet. + * + * @version $Rev$ $Date$ + */ +public class IntentMap extends PolicyModel { + + /* Name of default intent provied by this IntentMap */ + private String defaultProvideIntent; + + /* Name of intent provided by this IntentMap */ + private Collection<String> provideIntents = new ArrayList<String>(); + + /* Qualifiers of this IntentMap */ + private Collection<Qualifier> qualifiers = new ArrayList<Qualifier>(); + + public IntentMap(String defaultProvideIntent, Collection<String> provideIntents) { + super(); + this.defaultProvideIntent = defaultProvideIntent; + this.provideIntents.addAll(provideIntents); + } + + public Collection<String> getProvideIntents() { + return unmodifiableCollection(provideIntents); + } + + public void addQualifier(Qualifier qualifier) { + qualifiers.add(qualifier); + } + + public Collection<Qualifier> getQualifiers() { + return unmodifiableCollection(qualifiers); + } + + public String getDefaultProvideIntent() { + return defaultProvideIntent; + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/IntentName.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/IntentName.java new file mode 100644 index 0000000000..eb69b44b37 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/IntentName.java @@ -0,0 +1,140 @@ +/* + * 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.spi.model; + +import java.util.Arrays; + +/** + * Model class represents a name of a intent. An intent name has a domain name and one or more qualified names. For + * example, in "sec.confidentiality/message/body", the domain name is sec, and the qualified names are confidentiality, + * message and body + */ +@SuppressWarnings({"SerializableHasSerializationMethods"}) +public class IntentName implements java.io.Serializable { + private static final String QUALIFIED_SEPARATOR = "/"; + private static final String DOMAIN_SEPARATOR = "."; + private static final long serialVersionUID = -7030021353149084879L; + + /** + * domain of the intent + */ + private String domain; + + private String[] qualifiedNames; + + /** + * Construct a IntentName from a string representation. + * + * @param intent string representation for a intent. + */ + public IntentName(String intent) { + parse(intent); + } + + /** + * Construct a IntentName from domain name and qualified names + * + * @param domain domain name of the intent + * @param qualifiedNames qualified names of the intent + */ + public IntentName(String domain, String[] qualifiedNames) { + this.domain = domain; + this.qualifiedNames = qualifiedNames; + } + + public String getDomain() { + return domain; + } + + public String[] getQualifiedNames() { + String[] results = new String[qualifiedNames.length]; + System.arraycopy(qualifiedNames, 0, results, 0, qualifiedNames.length); + return results; + } + + @Override + public String toString() { + return getName(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final IntentName other = (IntentName) obj; + if (domain == null) { + if (other.domain != null) { + return false; + } + } else if (!domain.equals(other.domain)) { + return false; + } + return Arrays.equals(qualifiedNames, other.qualifiedNames); + } + + @Override + public int hashCode() { + final int PRIME = 17; + int result = 1; + result = PRIME * result + ((domain == null) ? 0 : domain.hashCode()); + result = PRIME * result + Arrays.hashCode(qualifiedNames); + return result; + } + + private String getName() { + StringBuilder sbd = new StringBuilder(domain); + for (int i = 0; i < qualifiedNames.length; i++) { + if (i == 0) { + sbd.append(DOMAIN_SEPARATOR); + } else { + sbd.append(QUALIFIED_SEPARATOR); + } + sbd.append(qualifiedNames[i]); + } + + return sbd.toString(); + } + + /** + * Parse a string representation of intent. + * + * @param intent string representation of intent + */ + private void parse(String intent) { + String iname = validateFormat(intent); + int domainIdx = iname.indexOf(DOMAIN_SEPARATOR); + domain = iname.substring(0, domainIdx); + String qualifNamesStr = iname.substring(domainIdx + 1); + qualifiedNames = qualifNamesStr.split(QUALIFIED_SEPARATOR); + + } + + private String validateFormat(String intent) { + // TODO validate and canonicalize intent name + return intent; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ModelObject.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ModelObject.java new file mode 100644 index 0000000000..2d5a0802e6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ModelObject.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.spi.model; + +import java.util.HashMap; +import java.util.Map; + +/** + * The base class for assembly model subtypes + * + * @version $Rev$ $Date$ + */ +public abstract class ModelObject { + private final Map<Object, Object> extensions = new HashMap<Object, Object>(); + + protected ModelObject() { + } + + public Map<Object, Object> getExtensions() { + return extensions; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Multiplicity.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Multiplicity.java new file mode 100644 index 0000000000..f7ec8759f8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Multiplicity.java @@ -0,0 +1,47 @@ +/* + * 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.spi.model; + +/** + * Enumeration for multiplicity. + */ +public enum Multiplicity { + /** + * Indicates a relationship that is optionally connected to the requestor and which, if supplied, must be connected + * to exactly one provider. + */ + ZERO_ONE, + + /** + * Indicates a relationship that must be connected between exactly one requestor and exactly one provider. + */ + ONE_ONE, + + /** + * Indicates a relationship that is optionally connects the requestor to zero to unbounded providers. + */ + ZERO_N, + + /** + * Indicates a relationship that must be connected at the requestor and which connects it to zero to unbounded + * providers. + */ + ONE_N + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Operation.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Operation.java new file mode 100644 index 0000000000..ebd975ad45 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Operation.java @@ -0,0 +1,408 @@ +/* + * 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.spi.model; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Represents an operation that is part of a service contract. The type paramter of this operation identifies the + * logical type system for all data types. + * + * @version $Rev$ $Date$ + */ +public class Operation<T> extends ModelObject implements Cloneable { + public static final int NO_CONVERSATION = -1; + public static final int CONVERSATION_CONTINUE = 1; + public static final int CONVERSATION_END = 2; + + protected Map<String, Object> metaData; + private final String name; + private ServiceContract<T> contract; + private final DataType<T> outputType; + private final DataType<List<DataType<T>>> inputType; + private final List<DataType<T>> faultTypes; + private String dataBinding; + private boolean wrapperStyle; + private WrapperInfo wrapper; + private boolean callback; + private boolean nonBlocking; + private int conversationSequence = NO_CONVERSATION; + + /** + * Construct a minimally-specified operation + * + * @param name the name of the operation + * @param inputType the data types of parameters passed to the operation + * @param outputType the data type returned by the operation + * @param faultTypes the data type of faults raised by the operation + */ + public Operation(String name, + DataType<List<DataType<T>>> inputType, + DataType<T> outputType, + List<DataType<T>> faultTypes) { + this(name, inputType, outputType, faultTypes, false, null, NO_CONVERSATION); + } + + /** + * Construct an operation + * + * @param name the name of the operation + * @param inputType the data types of parameters passed to the operation + * @param outputType the data type returned by the operation + * @param faultTypes the data type of faults raised by the operation + * @param nonBlocking if the operation is non-blocking + * @param dataBinding the data-binding type required by the operation + * @param sequence the conversational attributes of the operation {@link #CONVERSATION_CONTINUE}, or {@link + * #CONVERSATION_END} + */ + public Operation(final String name, + final DataType<List<DataType<T>>> inputType, + final DataType<T> outputType, + final List<DataType<T>> faultTypes, + boolean nonBlocking, + String dataBinding, + int sequence) { + super(); + this.name = name; + List<DataType<T>> types = Collections.emptyList(); + this.inputType = (inputType != null) ? inputType : new DataType<List<DataType<T>>>(Object[].class, types); + this.outputType = (outputType != null) ? outputType : new DataType<T>(void.class, null); + this.faultTypes = (faultTypes == null) ? types : faultTypes; + this.nonBlocking = nonBlocking; + this.dataBinding = dataBinding; + this.conversationSequence = sequence; + // Register the operation with the types + this.inputType.setOperation(this); + for (DataType<?> d : this.inputType.getLogical()) { + d.setOperation(this); + } + this.outputType.setOperation(this); + for (DataType<?> d : this.faultTypes) { + d.setOperation(this); + } + } + + /** + * Returns the service contract the operation is part of. + * + * @return the service contract the operation is part of. + */ + public ServiceContract<T> getServiceContract() { + return contract; + } + + /** + * Sets the service contract the operation is part of. + * + * @param contract the service contract the operation is part of. + */ + public void setServiceContract(ServiceContract<T> contract) { + this.contract = contract; + } + + /** + * Returns true if the operation is part of the callback contract. + * + * @return true if the operation is part of the callback contract. + */ + public boolean isCallback() { + return callback; + } + + /** + * Sets whether the operation is part of the callback contract. + * + * @param callback whether the operation is part of the callback contract. + */ + public void setCallback(boolean callback) { + this.callback = callback; + } + + /** + * Returns the name of the operation. + * + * @return the name of the operation + */ + public String getName() { + return name; + } + + /** + * Returns the data type returned by the operation. + * + * @return the data type returned by the operation + */ + public DataType<T> getOutputType() { + return outputType; + } + + /** + * Returns the data types of the parameters passed to the operation. + * <p/> + * The inputType's logical type is a list of DataTypes which describes the parameter types + * + * @return the data types of the parameters passed to the operation + */ + public DataType<List<DataType<T>>> getInputType() { + return inputType; + } + + /** + * Returns the data types of the faults raised by the operation. + * + * @return the data types of the faults raised by the operation + */ + public List<DataType<T>> getFaultTypes() { + if (faultTypes == null) { + return Collections.emptyList(); + } + return faultTypes; + } + + /** + * Returns true if the operation is non-blocking. A non-blocking operation may not have completed execution at the + * time an invocation of the operation returns. + * + * @return true if the operation is non-blocking + */ + public boolean isNonBlocking() { + return nonBlocking; + } + + /** + * Sets if the operation is non-blocking + */ + public void setNonBlocking(boolean nonBlocking) { + this.nonBlocking = nonBlocking; + } + + /** + * Returns the sequence the operation is called in a conversation, {@link #CONVERSATION_CONTINUE}, or {@link + * #CONVERSATION_END} + * + * @return the sequence the operation is called in a conversation + */ + public int getConversationSequence() { + return conversationSequence; + } + + /** + * Sets the sequence the operation is called in a conversation, {@link #CONVERSATION_CONTINUE}, or {@link + * #CONVERSATION_END} + */ + public void setConversationSequence(int conversationSequence) { + this.conversationSequence = conversationSequence; + } + + /** + * Returns the data binding type specified for the operation or null. + * + * @return the data binding type specified for the operation or null. + */ + public String getDataBinding() { + return (dataBinding == null && contract != null) ? contract.getDataBinding() : dataBinding; + } + + /** + * Set the databinding for this operation + * + * @param dataBinding The databinding + */ + public void setDataBinding(String dataBinding) { + this.dataBinding = dataBinding; + } + + /** + * Returns a map of metadata key to value mappings for the operation. + * + * @return a map of metadata key to value mappings for the operation. + */ + public Map<String, Object> getMetaData() { + if (metaData == null) { + return Collections.emptyMap(); + } + return metaData; + } + + /** + * Adds metadata associated with the operation. + * + * @param key the metadata key + * @param val the metadata value + */ + public void setMetaData(String key, Object val) { + if (metaData == null) { + metaData = new HashMap<String, Object>(); + } + metaData.put(key, val); + } + + public String toString() { + return name; + } + + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final Operation operation = (Operation) o; + + if (name != null ? !name.equals(operation.name) : operation.name != null) { + return false; + } + + // HACK: If the operation is mappable, then the equality test is relaxed + if (isMappable()) { + return true; + } + + if (faultTypes == null && operation.faultTypes != null) { + return false; + } else if (faultTypes != null + && operation.faultTypes != null + && faultTypes.size() != 0 + && operation.faultTypes.size() != 0) { + if (faultTypes.size() < operation.faultTypes.size()) { + return false; + } else { + //noinspection ForLoopReplaceableByForEach + for (int i = 0; i < operation.faultTypes.size(); i++) { + if (!faultTypes.get(i).equals(operation.faultTypes.get(i))) { + return false; + } + } + } + } + + if (inputType != null ? !inputType.equals(operation.inputType) : operation.inputType != null) { + return false; + } + return !(outputType != null ? !outputType.equals(operation.outputType) : operation.outputType != null); + } + + public int hashCode() { + int result; + result = name != null ? name.hashCode() : 0; + // HACK: + if (isMappable()) { + return result; + } + result = 29 * result + (outputType != null ? outputType.hashCode() : 0); + result = 29 * result + (inputType != null ? inputType.hashCode() : 0); + result = 29 * result + (faultTypes != null ? faultTypes.hashCode() : 0); + return result; + } + + /** + * Returns true if the operation may be mapped to another target operation through an mediation + */ + private boolean isMappable() { + if (contract != null) { + return contract.isRemotable(); + } else { + return false; + } + } + + /** + * Returns true if the operation is wrapper style + * + * @return the wrapperStyle + */ + public boolean isWrapperStyle() { + return wrapperStyle; + } + + /** + * Return the Wrapper information for this operation is it's wrapper style + * + * @return The Wrapper + */ + public WrapperInfo getWrapper() { + if (!isWrapperStyle()) { + throw new IllegalStateException("The operation is not wrapper style."); + } else { + return wrapper; + } + } + + /** + * @param wrapper the wrapper to set + */ + public void setWrapper(WrapperInfo wrapper) { + this.wrapper = wrapper; + } + + /** + * @param wrapperStyle the wrapperStyle to set + */ + public void setWrapperStyle(boolean wrapperStyle) { + this.wrapperStyle = wrapperStyle; + } + + @SuppressWarnings({"unchecked", "CloneDoesntCallSuperClone"}) + @Override + public Operation<T> clone() throws CloneNotSupportedException { + final List<DataType<T>> clonedFaultTypes = new ArrayList<DataType<T>>(this.faultTypes.size()); + for (DataType<T> t : this.faultTypes) { + clonedFaultTypes.add((DataType<T>) t.clone()); + } + + List<DataType<T>> clonedTypes = new ArrayList<DataType<T>>(); + for (DataType<T> t : inputType.getLogical()) { + DataType<T> type = (DataType<T>) t.clone(); + clonedTypes.add(type); + } + + DataType<List<DataType<T>>> clonedInputType = + new DataType<List<DataType<T>>>(inputType.getPhysical(), clonedTypes); + clonedInputType.setDataBinding(inputType.getDataBinding()); + + DataType<T> outputType = (DataType<T>) this.outputType.clone(); + Operation<T> copy = + new Operation<T>(name, + clonedInputType, + outputType, + clonedFaultTypes, + nonBlocking, + dataBinding, + conversationSequence); + + copy.callback = this.callback; + copy.contract = this.contract; + copy.wrapper = this.wrapper; + copy.wrapperStyle = this.wrapperStyle; + + if (this.metaData != null) { + assert this.metaData instanceof HashMap; + copy.metaData = (HashMap) ((HashMap) this.metaData).clone(); + } + return copy; + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicyAttachable.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicyAttachable.java new file mode 100644 index 0000000000..fee13f7205 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicyAttachable.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.model; + +import java.util.Collection; +/** +* +* Represents capability of being attached with Intent and PolicySet. +* +*/ +public interface PolicyAttachable { + /** + * Get the name of PolicySet attached + * @return the name of PolicySet + */ + String getPolicySet(); + /** + * Get collection contains <code>IntentName</code> required. + * @return collection contains <code>IntentName</code> required. + */ + Collection<IntentName> getRequiredIntents(); + +}
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicyAttachableModel.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicyAttachableModel.java new file mode 100644 index 0000000000..3ebbfb16d7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicyAttachableModel.java @@ -0,0 +1,49 @@ +/* + * 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.spi.model; + +import java.util.Collection; + +/** + * Base class for model classes which can be associated with Intent and PolicySet by specifing requires and policySet + * attributes on xml element. + */ + +public abstract class PolicyAttachableModel extends ModelObject implements PolicyAttachable { + protected Collection<IntentName> requiredIntent; + protected String policySet; + + public String getPolicySet() { + return policySet; + } + + public void setPolicySet(String policySet) { + this.policySet = policySet; + } + + public Collection<IntentName> getRequiredIntents() { + return requiredIntent; + } + + public void addRequiredIntent(IntentName requiredIntent) { + this.requiredIntent.add(requiredIntent); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicyContentModel.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicyContentModel.java new file mode 100644 index 0000000000..7d2412ee8d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicyContentModel.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.spi.model; + +import java.util.ArrayList; +import java.util.Collection; +import static java.util.Collections.unmodifiableCollection; + +/** + * PolicyModel which contains concrete policy content in form of WSPolicyAttachment or other extensions. + */ +public abstract class PolicyContentModel extends PolicyModel { + /* WSPolicyAttachment contained in this Model */ + protected Collection<WSPolicyAttachment> wsPolicyAttachments = new ArrayList<WSPolicyAttachment>(); + /* Any policy model extensions besides standard intentMap, ws-policyattachment, etc. */ + protected Collection<PolicyModel> extensions = new ArrayList<PolicyModel>(); + + public Collection<PolicyModel> getPolicyExtensions() { + return extensions; + } + + public Collection<WSPolicyAttachment> getWsPolicyAttachments() { + return unmodifiableCollection(wsPolicyAttachments); + } + + public void addWsPolicyAttachment(WSPolicyAttachment attachment) { + wsPolicyAttachments.add(attachment); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicyModel.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicyModel.java new file mode 100644 index 0000000000..17bd8f0b7e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicyModel.java @@ -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. + */ +package org.apache.tuscany.spi.model; + + +/** + * An abstract base class for all policy model representations. + * <p/> + * $Version$ $Date$ + */ +public abstract class PolicyModel extends ModelObject { + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicySet.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicySet.java new file mode 100644 index 0000000000..7545f234e1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicySet.java @@ -0,0 +1,99 @@ +/* + * 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.spi.model; + +import java.util.ArrayList; +import java.util.Collection; +import static java.util.Collections.unmodifiableCollection; +import static java.util.Collections.unmodifiableList; +import java.util.List; +import javax.xml.namespace.QName; + +/** + * Model representation for PolicySet. + * <p/> + * $Rev$ $Date$ + */ +public class PolicySet extends PolicyContentModel { + + /** + * QNames of artifacts to which this Policy can apply + */ + protected List<QName> appliedArtifacts = new ArrayList<QName>(); + + /** + * IntentMap contained in this PolicySet + */ + private Collection<IntentMap> intentMaps = new ArrayList<IntentMap>(); + + /** + * Name for PolicySet, corresponding to name attribute of PolicySet element in SCDL + */ + private QName name; + + /** + * References to other PolicySet + */ + private Collection<PolicySetReference> policySetReferences = new ArrayList<PolicySetReference>(); + + /** + * Name of intents provided by this PolicySet + */ + private Collection<IntentName> provideIntents = new ArrayList<IntentName>(); + + public PolicySet(QName name, List<IntentName> providesIntent) { + super(); + this.name = name; + this.provideIntents.addAll(providesIntent); + } + + + public void addPolicySetReference(PolicySetReference ref) { + policySetReferences.add(ref); + } + + public void addAppliedArtifacts(QName artifactName) { + appliedArtifacts.add(artifactName); + } + + public List<QName> getAppliedArtifacts() { + return unmodifiableList(appliedArtifacts); + } + + public void addIntentMap(IntentMap intentMap) { + intentMaps.add(intentMap); + } + + public Collection<IntentMap> getIntentMaps() { + return unmodifiableCollection(intentMaps); + } + + public QName getName() { + return name; + } + + public Collection<PolicySetReference> getPolicySetReferences() { + return unmodifiableCollection(policySetReferences); + } + + public Collection<IntentName> getProvideIntents() { + return unmodifiableCollection(provideIntents); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicySetReference.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicySetReference.java new file mode 100644 index 0000000000..46924910d0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PolicySetReference.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.spi.model; + +import javax.xml.namespace.QName; + +/** + * Presents a PolicySetReference. + */ +public class PolicySetReference extends PolicyModel { + + private QName reference; + + public PolicySetReference(QName reference) { + super(); + this.reference = reference; + } + + public QName getReference() { + return reference; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Property.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Property.java new file mode 100644 index 0000000000..9b6e192c17 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Property.java @@ -0,0 +1,105 @@ +/* + * 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.spi.model; + +import javax.xml.namespace.QName; + +import org.w3c.dom.Document; + +import org.apache.tuscany.spi.ObjectFactory; + +/** + * A component property + * + * @version $Rev$ $Date$ + */ +public class Property<T> extends ModelObject { + private String name; + private boolean required; + private ObjectFactory<T> defaultValueFactory; + private QName xmlType; + private Class<T> javaType; + private boolean many; + private Document defaultValue; + + public Property() { + } + + public Property(String name, QName xmlType, Class<T> javaType) { + this.name = name; + this.xmlType = xmlType; + this.javaType = javaType; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isRequired() { + return required; + } + + public void setRequired(boolean required) { + this.required = required; + } + + public ObjectFactory<T> getDefaultValueFactory() { + return defaultValueFactory; + } + + public void setDefaultValueFactory(ObjectFactory<T> factory) { + this.defaultValueFactory = factory; + } + + public QName getXmlType() { + return xmlType; + } + + public void setXmlType(QName xmlType) { + this.xmlType = xmlType; + } + + public Class<T> getJavaType() { + return javaType; + } + + public void setJavaType(Class<T> javaType) { + this.javaType = javaType; + } + + public boolean isMany() { + return many; + } + + public void setMany(boolean many) { + this.many = many; + } + + public Document getDefaultValue() { + return defaultValue; + } + + public void setDefaultValue(Document defaultValue) { + this.defaultValue = defaultValue; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PropertyValue.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PropertyValue.java new file mode 100644 index 0000000000..93eaa74f52 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/PropertyValue.java @@ -0,0 +1,128 @@ +/* + * 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.spi.model; + +import org.apache.tuscany.spi.ObjectFactory; +import org.w3c.dom.Document; + +/** + * Represents a configured component property + * + * @version $Rev$ $Date$ + */ +public class PropertyValue<T> extends ModelObject { + private String name; + private String source; + private String file; + private Document value; + private ObjectFactory<T> valueFactory; + + public PropertyValue() { + } + + /** + * Constructor specifying the name of a property and the XPath source expression. + * + * @param name the name of the property which this value is for + * @param source an XPath expression whose result will be the actual value + * @param file A URI that the property value can be loaded from + */ + public PropertyValue(String name, String source, String file) { + this.name = name; + this.source = source; + this.file = file; + } + + /** + * @param name + * @param value + */ + public PropertyValue(String name, Document value) { + this.name = name; + this.value = value; + } + + public PropertyValue(String name, ObjectFactory<T> valueFactory) { + this.name = name; + this.valueFactory = valueFactory; + } + + /** + * Returns the name of the property that this value is for. + * @return the name of the property that this value is for + */ + public String getName() { + return name; + } + + /** + * Sets the name of the property that this value is for. + * @param name the name of the property that this value is for + */ + public void setName(String name) { + this.name = name; + } + + /** + * Returns an XPath expression that should be evaluated to get the actual property value. + * + * @return an XPath expression that should be evaluated to get the actual property value + */ + public String getSource() { + return source; + } + + /** + * Sets an XPath expression that should be evaluated to get the actual property value. + * @param source an XPath expression that should be evaluated to get the actual property value + */ + public void setSource(String source) { + this.source = source; + } + + public ObjectFactory<T> getValueFactory() { + return valueFactory; + } + + public void setValueFactory(ObjectFactory<T> valueFactory) { + this.valueFactory = valueFactory; + } + + public Document getValue() { + return value; + } + + public void setValue(Document value) { + this.value = value; + } + + /** + * @return the file + */ + public String getFile() { + return file; + } + + /** + * @param file the file to set + */ + public void setFile(String file) { + this.file = file; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Qualifier.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Qualifier.java new file mode 100644 index 0000000000..8a7d709bd9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Qualifier.java @@ -0,0 +1,51 @@ +/* + * 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.spi.model; + +/** + * Model reprentation for qualifier + */ + +public class Qualifier extends PolicyContentModel { + + private String name; + + /** + * IntentMap contained in this Qualifier + */ + private IntentMap intentMap; + + public Qualifier(String name) { + super(); + this.name = name; + } + + public String getName() { + return name; + } + + public IntentMap getIntentMap() { + return intentMap; + } + + public void setIntentMap(IntentMap intentMap) { + this.intentMap = intentMap; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ReferenceDefinition.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ReferenceDefinition.java new file mode 100644 index 0000000000..46dfd8e0a0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ReferenceDefinition.java @@ -0,0 +1,96 @@ +/* + * 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.spi.model; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Represents a component reference + * + * @version $Rev$ $Date$ + */ +public class ReferenceDefinition extends ModelObject { + private URI uri; + private ServiceContract serviceContract; + private Multiplicity multiplicity; + private boolean required; + private List<BindingDefinition> bindings; + + public ReferenceDefinition() { + multiplicity = Multiplicity.ONE_ONE; + bindings = new ArrayList<BindingDefinition>(); + } + + public ReferenceDefinition(URI uri, ServiceContract serviceContract) { + this.uri = uri; + this.serviceContract = serviceContract; + bindings = new ArrayList<BindingDefinition>(); + multiplicity = Multiplicity.ONE_ONE; + } + + public ReferenceDefinition(URI uri, ServiceContract serviceContract, Multiplicity multiplicity) { + this.uri = uri; + this.serviceContract = serviceContract; + this.multiplicity = multiplicity; + bindings = new ArrayList<BindingDefinition>(); + } + + public URI getUri() { + return uri; + } + + public void setUri(URI uri) { + this.uri = uri; + } + + public ServiceContract<?> getServiceContract() { + return serviceContract; + } + + public void setServiceContract(ServiceContract serviceContract) { + this.serviceContract = serviceContract; + } + + public Multiplicity getMultiplicity() { + return multiplicity; + } + + public void setMultiplicity(Multiplicity multiplicity) { + this.multiplicity = multiplicity; + } + + public boolean isRequired() { + return required; + } + + public void setRequired(boolean required) { + this.required = required; + } + + public List<BindingDefinition> getBindings() { + return Collections.unmodifiableList(bindings); + } + + public void addBinding(BindingDefinition binding) { + this.bindings.add(binding); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ReferenceTarget.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ReferenceTarget.java new file mode 100644 index 0000000000..bc721ea02c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ReferenceTarget.java @@ -0,0 +1,69 @@ +/* + * 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.spi.model; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +/** + * Represents the set of targets configured on a reference + * + * @version $Rev$ $Date$ + */ +public class ReferenceTarget extends ModelObject { + private URI referenceName; + private boolean autowire; + private List<URI> targets = new ArrayList<URI>(); + + public URI getReferenceName() { + return referenceName; + } + + public void setReferenceName(URI referenceName) { + this.referenceName = referenceName; + } + + /** + * Returns true if autowire is enabled for the reference. + * + * @return true if autowire is enabled for the reference. + */ + public boolean isAutowire() { + return autowire; + } + + /** + * Sets autowire enablement for the reference. + * + * @param autowire true if autowire is enabled. + */ + public void setAutowire(boolean autowire) { + this.autowire = autowire; + } + + public List<URI> getTargets() { + return targets; + } + + public void addTarget(URI target) { + targets.add(target); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Scope.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Scope.java new file mode 100644 index 0000000000..a53b26d2ba --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/Scope.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.spi.model; + +/** + * The default implementation scopes supported by assemblies. + * + * @version $Rev$ $Date$ + */ +public class Scope { + public static final Scope STATELESS = new Scope("STATELESS"); + public static final Scope REQUEST = new Scope("REQUEST"); + public static final Scope SESSION = new Scope("SESSION"); + public static final Scope CONVERSATION = new Scope("CONVERSATION"); + public static final Scope COMPOSITE = new Scope("COMPOSITE"); + public static final Scope SYSTEM = new Scope("SYSTEM"); + public static final Scope UNDEFINED = new Scope("UNDEFINED"); + + private String scope; + + public Scope(String scope) { + this.scope = scope.toUpperCase().intern(); + } + + public String getScope() { + return scope; + } + + @SuppressWarnings({"StringEquality"}) + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Scope scope1 = (Scope) o; + return !(scope != null ? scope != scope1.scope.intern() : scope1.scope != null); + } + + public int hashCode() { + return scope != null ? scope.hashCode() : 0; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ServiceContract.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ServiceContract.java new file mode 100644 index 0000000000..748c8eb4a6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ServiceContract.java @@ -0,0 +1,279 @@ +/* + * 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.spi.model; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Base class representing service contract information + * + * @version $Rev$ $Date$ + */ +public abstract class ServiceContract<T> extends ModelObject implements Cloneable { + protected boolean conversational; + protected boolean remotable; + protected Class<?> interfaceClass; + protected String interfaceName; + protected String callbackName; + protected Class<?> callbackClass; + protected Map<String, Operation<T>> operations; + protected Map<String, Operation<T>> callbackOperations; + protected String dataBinding; + protected Map<String, Object> metaData; + + protected ServiceContract() { + } + + protected ServiceContract(Class<?> interfaceClass) { + this.interfaceClass = interfaceClass; + } + + protected ServiceContract(String interfaceName) { + this.interfaceName = interfaceName; + } + + /** + * Returns the interface name for the contract + * + * @return the interface name for the contract + */ + public String getInterfaceName() { + return interfaceName; + } + + /** + * Sets the interface name for the contract + */ + public void setInterfaceName(String interfaceName) { + this.interfaceName = interfaceName; + } + + /** + * Returns the class used to represent the service contract + */ + public Class<?> getInterfaceClass() { + return interfaceClass; + } + + /** + * Sets the class used to represent the service contract + */ + public void setInterfaceClass(Class<?> interfaceClass) { + this.interfaceClass = interfaceClass; + } + + /** + * Returns true if the service contract is conversational + * + * @return true if the service contract is conversational + */ + public boolean isConversational() { + return conversational; + } + + /** + * Sets if the service contract is conversational + * + * @param conversational the conversational attribute + */ + public void setConversational(boolean conversational) { + this.conversational = conversational; + } + + /** + * @return the remotable + */ + public boolean isRemotable() { + return remotable; + } + + /** + * @param remotable the remotable to set + */ + public void setRemotable(boolean remotable) { + this.remotable = remotable; + } + + /** + * Returns the name of the callback or null if the contract is unidirectional + */ + public String getCallbackName() { + return callbackName; + } + + /** + * Sets the name of the callback service + */ + public void setCallbackName(String callbackName) { + this.callbackName = callbackName; + } + + /** + * Returns the name of the callback service + */ + public Class<?> getCallbackClass() { + return callbackClass; + } + + public void setCallbackClass(Class<?> callbackClass) { + this.callbackClass = callbackClass; + } + + public Map<String, Operation<T>> getOperations() { + if (operations == null) { + return Collections.emptyMap(); + } + return Collections.unmodifiableMap(operations); + } + + public void setOperations(Map<String, Operation<T>> operations) { + for (Operation<T> operation : operations.values()) { + operation.setServiceContract(this); + } + this.operations = operations; + } + + public Map<String, Operation<T>> getCallbackOperations() { + if (callbackOperations == null) { + return Collections.emptyMap(); + } + return Collections.unmodifiableMap(callbackOperations); + } + + public void setCallbackOperations(Map<String, Operation<T>> callbacksOperations) { + for (Operation<T> operation : callbacksOperations.values()) { + operation.setServiceContract(this); + operation.setCallback(true); + } + this.callbackOperations = callbacksOperations; + } + + public String getDataBinding() { + return dataBinding; + } + + public void setDataBinding(String dataBinding) { + this.dataBinding = dataBinding; + } + + /** + * Returns a map of metadata key to value mappings for the operation. + * + * @return a map of metadata key to value mappings for the operation. + */ + public Map<String, Object> getMetaData() { + if (metaData == null) { + return Collections.emptyMap(); + } + return metaData; + } + + /** + * Adds metadata associated with the operation. + * + * @param key the metadata key + * @param val the metadata value + */ + public void setMetaData(String key, Object val) { + if (metaData == null) { + metaData = new HashMap<String, Object>(); + } + metaData.put(key, val); + } + + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final ServiceContract that = (ServiceContract) o; + + if (callbackName != null ? !callbackName.equals(that.callbackName) : that.callbackName != null) { + return false; + } + if (callbackOperations != null ? !callbackOperations.equals(that.callbackOperations) + : that.callbackOperations != null) { + return false; + } + if (interfaceClass != null ? !interfaceClass.equals(that.interfaceClass) : that.interfaceClass != null) { + return false; + } + if (interfaceName != null ? !interfaceName.equals(that.interfaceName) : that.interfaceName != null) { + return false; + } + return !(operations != null ? !operations.equals(that.operations) : that.operations != null); + + } + + public int hashCode() { + int result; + result = interfaceClass != null ? interfaceClass.hashCode() : 0; + result = 29 * result + (interfaceName != null ? interfaceName.hashCode() : 0); + result = 29 * result + (callbackName != null ? callbackName.hashCode() : 0); + result = 29 * result + (operations != null ? operations.hashCode() : 0); + result = 29 * result + (callbackOperations != null ? callbackOperations.hashCode() : 0); + return result; + } + + public String toString() { + if (interfaceName != null) { + return new StringBuilder().append("ServiceContract[").append(interfaceName).append("]").toString(); + } else if (interfaceClass != null) { + return new StringBuilder().append("ServiceContract[").append(interfaceClass.getName()).append("]") + .toString(); + } else { + return super.toString(); + } + + } + + @SuppressWarnings("unchecked") + @Override + public Object clone() throws CloneNotSupportedException { + ServiceContract<T> copy = (ServiceContract<T>) super.clone(); + + if (operations != null) { + Map<String, Operation<T>> clonedOperations = new HashMap<String, Operation<T>>(); + for (Operation<T> o : operations.values()) { + clonedOperations.put(o.getName(), (Operation<T>)o.clone()); + } + copy.setOperations(clonedOperations); + } + + if (callbackOperations != null) { + Map<String, Operation<T>> clonedCallbackOperations = new HashMap<String, Operation<T>>(); + for (Operation<T> o : callbackOperations.values()) { + clonedCallbackOperations.put(o.getName(), (Operation<T>)o.clone()); + } + copy.setCallbackOperations(clonedCallbackOperations); + } + + if (this.metaData != null) { + assert this.metaData instanceof HashMap; + copy.metaData = (HashMap) ((HashMap) this.metaData).clone(); + } + + return copy; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ServiceDefinition.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ServiceDefinition.java new file mode 100644 index 0000000000..25c1beffe1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/ServiceDefinition.java @@ -0,0 +1,163 @@ +/* + * 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.spi.model; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Represents a service offered by a component + * + * @version $Rev$ $Date$ + */ +public class ServiceDefinition extends ModelObject { + private URI uri; + private ServiceContract serviceContract; + private boolean remotable; + private String callbackRefName; + private List<BindingDefinition> bindings; + private URI target; + + public ServiceDefinition() { + bindings = new ArrayList<BindingDefinition>(); + } + + public ServiceDefinition(URI uri, ServiceContract serviceContract, boolean remotable) { + bindings = new ArrayList<BindingDefinition>(); + this.uri = uri; + this.serviceContract = serviceContract; + this.remotable = remotable; + } + + public ServiceDefinition(URI uri, ServiceContract serviceContract, boolean remotable, String callbackRefName) { + bindings = new ArrayList<BindingDefinition>(); + this.uri = uri; + this.serviceContract = serviceContract; + this.remotable = remotable; + this.callbackRefName = callbackRefName; + } + + /** + * Returns the service name + * + * @return the service name + */ + public URI getUri() { + return uri; + } + + /** + * Sets the service name + * + * @param uri the service name + */ + public void setUri(URI uri) { + this.uri = uri; + } + + /** + * Returns the service contract + * + * @return the service contract + */ + public ServiceContract<?> getServiceContract() { + return serviceContract; + } + + /** + * Sets the service contract + * + * @param contract the service contract + */ + public void setServiceContract(ServiceContract contract) { + this.serviceContract = contract; + } + + /** + * Returns true if the service is remotable + * + * @return true if the service is remotable + */ + public boolean isRemotable() { + return remotable; + } + + /** + * Sets if the service is remotable + * + * @param remotable if the service is remotable + */ + public void setRemotable(boolean remotable) { + this.remotable = remotable; + } + + /** + * Returns the callback name. + */ + public String getCallbackReferenceName() { + return callbackRefName; + } + + /** + * Sets the callback name + */ + public void setCallbackReferenceName(String name) { + this.callbackRefName = name; + } + + /** + * Returns the bindings configured for the service + * + * @return the bindings configured for the service + */ + public List<BindingDefinition> getBindings() { + return Collections.unmodifiableList(bindings); + } + + /** + * Configures the service with a binding + * + * @param binding the binding + */ + public void addBinding(BindingDefinition binding) { + this.bindings.add(binding); + } + + /** + * Returns the target URI the service is wired to + * + * @return the target URI the service is wired to + */ + public URI getTarget() { + return target; + } + + /** + * Sets the target URI the service is wired to + * + * @param target the target URI the service is wired to + */ + public void setTarget(URI target) { + this.target = target; + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/TypeInfo.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/TypeInfo.java new file mode 100644 index 0000000000..12ea9fa8ce --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/TypeInfo.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.spi.model; + +import javax.xml.namespace.QName; + +/** + * An abstraction of XML schema types + */ +public class TypeInfo { + private QName name; + + private boolean isSimpleType; + + private TypeInfo baseType; + + /** + * @param name + * @param isSimpleType + */ + public TypeInfo(QName name, boolean isSimpleType, TypeInfo baseType) { + super(); + this.name = name; + this.isSimpleType = isSimpleType; + this.baseType = baseType; + } + + /** + * @return the isSimpleType + */ + public boolean isSimpleType() { + return isSimpleType; + } + + /** + * @return the name + */ + public QName getQName() { + return name; + } + + /** + * @return the baseType + */ + public TypeInfo getBaseType() { + return baseType; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("Type: ").append(name); + return sb.toString(); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/WSPolicyAttachment.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/WSPolicyAttachment.java new file mode 100644 index 0000000000..ff1a6cf791 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/WSPolicyAttachment.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.model; + +/* + * Presents a ws-policy attachment. + */ +public class WSPolicyAttachment<T> extends PolicyModel { + private T content; + + public T getContent() { + return content; + } + + public void setContent(T content) { + this.content = content; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/WireDefinition.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/WireDefinition.java new file mode 100644 index 0000000000..7ae91811b6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/WireDefinition.java @@ -0,0 +1,47 @@ +/* + * 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.spi.model; + +import java.net.URI; + +/** + * Represents a wire specified in an assembly + * + * @version $Rev$ $Date$ + */ +public class WireDefinition extends ModelObject { + private URI source; + private URI target; + + public URI getSource() { + return source; + } + + public void setSource(URI source) { + this.source = source; + } + + public URI getTarget() { + return target; + } + + public void setTarget(URI target) { + this.target = target; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/WrapperInfo.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/WrapperInfo.java new file mode 100644 index 0000000000..6dcf21fb52 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/WrapperInfo.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.spi.model; + +import java.util.List; +import javax.xml.namespace.QName; + +/** + * The "Wrapper Style" WSDL operation is defined by The Java API for XML-Based Web Services (JAX-WS) 2.0 specification, + * section 2.3.1.2 Wrapper Style. + * <p/> + * A WSDL operation qualifies for wrapper style mapping only if the following criteria are met: <ul> <li>(i) The + * operation’s input and output messages (if present) each contain only a single part <li>(ii) The input message part + * refers to a global element declaration whose localname is equal to the operation name <li>(iii) The output message + * part refers to a global element declaration <li>(iv) The elements referred to by the input and output message parts + * (henceforth referred to as wrapper elements) are both complex types defined using the xsd:sequence compositor <li>(v) + * The wrapper elements only contain child elements, they must not contain other structures such as wildcards (element + * or attribute), xsd:choice, substitution groups (element references are not permitted) or attributes; furthermore, + * they must not be nillable. </ul> + * + * @version $Rev$ $Date$ + */ +public class WrapperInfo { + private ElementInfo inputWrapperElement; + + private ElementInfo outputWrapperElement; + + private List<ElementInfo> inputChildElements; + + private List<ElementInfo> outputChildElements; + + private DataType<List<DataType<QName>>> unwrappedInputType; + + private DataType<QName> unwrappedOutputType; + + public WrapperInfo(ElementInfo inputWrapperElement, + ElementInfo outputWrapperElement, + List<ElementInfo> inputElements, + List<ElementInfo> outputElements, + DataType<List<DataType<QName>>> unwrappedInputType, + DataType<QName> unwrappedOutputType) { + super(); + this.inputWrapperElement = inputWrapperElement; + this.outputWrapperElement = outputWrapperElement; + this.inputChildElements = inputElements; + this.outputChildElements = outputElements; + this.unwrappedInputType = unwrappedInputType; + this.unwrappedOutputType = unwrappedOutputType; + } + + /** + * @return the inputElements + */ + public List<ElementInfo> getInputChildElements() { + return inputChildElements; + } + + /** + * @return the inputWrapperElement + */ + public ElementInfo getInputWrapperElement() { + return inputWrapperElement; + } + + /** + * @return the outputElements + */ + public List<ElementInfo> getOutputChildElements() { + return outputChildElements; + } + + /** + * @return the outputWrapperElement + */ + public ElementInfo getOutputWrapperElement() { + return outputWrapperElement; + } + + /** + * @return the unwrappedInputType + */ + public DataType<List<DataType<QName>>> getUnwrappedInputType() { + return unwrappedInputType; + } + + /** + * @return the unwrappedOutputType + */ + public DataType<QName> getUnwrappedOutputType() { + return unwrappedOutputType; + } +}
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/Operations.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/Operations.java new file mode 100644 index 0000000000..5db76906e0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/Operations.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.spi.model.physical; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.tuscany.spi.model.ModelObject; + +/** + * Aggregates a collection of operations. + * + * @version $Revison$ $Date$ + * + */ +public class Operations extends ModelObject { + + // Collection of operations + private Set<PhysicalOperationDefinition> operations = new HashSet<PhysicalOperationDefinition>(); + + /** + * Returns a read-only view of the available operations. + * @return Collection of operations. + */ + public Set<PhysicalOperationDefinition> getOperations() { + return Collections.unmodifiableSet(operations); + } + + /** + * Adds an operation definition. + * @param operation Operation to be added. + */ + public void addOperation(PhysicalOperationDefinition operation) { + operations.add(operation); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalChangeSet.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalChangeSet.java new file mode 100644 index 0000000000..658800769a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalChangeSet.java @@ -0,0 +1,73 @@ +/* + * 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.spi.model.physical; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.tuscany.spi.model.ModelObject; + +/** + * Models a physical change set, sent from the master to the slave. + * + * @version $Revsion$ $Date$ + * + */ +public class PhysicalChangeSet extends ModelObject { + + // Set of physical component definitions + private Set<PhysicalComponentDefinition> componentDefinitions = new HashSet<PhysicalComponentDefinition>(); + + // Set of wire definitions + private Set<PhysicalWireDefinition> wireDefinitions = new HashSet<PhysicalWireDefinition>(); + + /** + * Get all the physical component definitions. + * @return Physical component definitions in the changeset. + */ + public Set<PhysicalComponentDefinition> getComponentDefinitions() { + return Collections.unmodifiableSet(componentDefinitions); + } + + /** + * Get all the wire definitions. + * @return Wire definitions in the changeset. + */ + public Set<PhysicalWireDefinition> getWireDefinitions() { + return Collections.unmodifiableSet(wireDefinitions); + } + + /** + * Adds a physical component definition to the physical change set. + * @param componentDefinition Physical component definition. + */ + public void addComponentDefinition(PhysicalComponentDefinition componentDefinition) { + componentDefinitions.add(componentDefinition); + } + + /** + * Adds a physical wire definition to the physical change set. + * @param wireDefinition Physical wire definition. + */ + public void addWireDefinition(PhysicalWireDefinition wireDefinition) { + wireDefinitions.add(wireDefinition); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalComponentDefinition.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalComponentDefinition.java new file mode 100644 index 0000000000..5a05410d4b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalComponentDefinition.java @@ -0,0 +1,100 @@ +/* + * 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.spi.model.physical; + +import java.net.URI; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.tuscany.spi.model.ModelObject; + +/** + * Represents a physical component model. + * + * @version $Rev$ $Date$ + */ +public abstract class PhysicalComponentDefinition<PSD extends PhysicalServiceDefinition, + PRD extends PhysicalReferenceDefinition> + extends ModelObject { + + // Component Id. + private URI componentId; + + // Services exposed by this component + private Set<PSD> services = new HashSet<PSD>(); + + // References exposed by this component + private Set<PRD> references = new HashSet<PRD>(); + + /** + * Gets the component id. + * + * @return Component id. + */ + public URI getComponentId() { + return componentId; + } + + /** + * Sets the component id. + * + * @param componentId + */ + public void setComponentId(URI componentId) { + this.componentId = componentId; + } + + /** + * Returns the service definitions available for this component. + * + * @return Service definitions for this operation. + */ + public Set<PSD> getServices() { + return Collections.unmodifiableSet(services); + } + + /** + * Adds a service definition to the component. + * + * @param service Service definition to be added to the component. + */ + public void addService(PSD service) { + services.add(service); + } + + /** + * Returns the reference definitions available for this component. + * + * @return Reference definitions for this operation. + */ + public Set<PRD> getReferences() { + return Collections.unmodifiableSet(references); + } + + /** + * Adds a reference definition to the component. + * + * @param reference Reference definition to be added to the component. + */ + public void addReference(PRD reference) { + references.add(reference); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalInterceptorDefinition.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalInterceptorDefinition.java new file mode 100644 index 0000000000..858eddccbe --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalInterceptorDefinition.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.spi.model.physical; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.model.ModelObject; + +/** + * Model class representing the portable definition of an interceptor. This class + * is used to describe the interceptors around inbound and outbound wires on a + * physical component definition. + * + * @version $Rev$ $Date$ + * + */ +public class PhysicalInterceptorDefinition extends ModelObject { + + // The qualified name of the interceptor builder + private QName builder; + + /** + * Gets the qualified name of the builder. + * @return Qualified name of the builder. + */ + public QName getBuilder() { + return builder; + } + + /** + * Sets the qualified name of the builder. + * @param builder Qualified name of the builder. + */ + public void setBuilder(QName builder) { + this.builder = builder; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalOperationDefinition.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalOperationDefinition.java new file mode 100644 index 0000000000..3d7d115bcd --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalOperationDefinition.java @@ -0,0 +1,144 @@ +/* + * 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.spi.model.physical; + +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.apache.tuscany.spi.model.ModelObject; + +/** + * Represents an operation. + * + * @version $Revision$ $Date$ + * <p/> + * TODO Discuss with Jeremy/Jim on how to model MEPs, INOUT parameters, faults etc + */ +public class PhysicalOperationDefinition extends ModelObject { + + // Parameters + private List<Class<?>> parameterTypes = new LinkedList<Class<?>>(); + + // Return + private Class<?> returnType; + + // Name of the operation + private String name; + + // Callback + private boolean callback; + + // Interceptors defined against the operation + private Set<PhysicalInterceptorDefinition> interceptors = new HashSet<PhysicalInterceptorDefinition>(); + + /** + * Returns the parameter types for this operation. + * + * @return Parameter types. + */ + public List<Class<?>> getParameters() { + return Collections.unmodifiableList(parameterTypes); + } + + /** + * Adds a parameter type. + * + * @param parameter Parameter type to be added. + */ + public void addParameter(Class<?> parameter) { + parameterTypes.add(parameter); + } + + /** + * Gets the return type for this operation. + * + * @return Return type for this operation. + */ + public Class<?> getReturnType() { + return returnType; + } + + /** + * Sets the return type for this operation. + * + * @param returnType Return type for this operation. + */ + public void setReturnType(Class<?> returnType) { + this.returnType = returnType; + } + + /** + * Returns the interceptor definitions available for this operation. + * + * @return Inteceptor definitions for this operation. + */ + public Set<PhysicalInterceptorDefinition> getInterceptors() { + return Collections.unmodifiableSet(interceptors); + } + + /** + * Adds an interceptor definition to the operation. + * + * @param interceptor Interceptor definition to be added. + */ + public void addInterceptor(PhysicalInterceptorDefinition interceptor) { + interceptors.add(interceptor); + } + + /** + * Gets the name of the operation. + * + * @return Operation name. + */ + public String getName() { + return name; + } + + /** + * Sets the name of the operation. + * + * @param name Operation name. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Checks whether the operation is a callback. + * + * @return True if this is a callback. + */ + public boolean isCallback() { + return callback; + } + + /** + * Sets whether this is a callback operation or not. + * + * @param callback True if this is a callback. + */ + public void setCallback(boolean callback) { + this.callback = callback; + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalReferenceDefinition.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalReferenceDefinition.java new file mode 100644 index 0000000000..5221356ccb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalReferenceDefinition.java @@ -0,0 +1,49 @@ +/* + * 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.spi.model.physical; + + +/** + * Represents a physical reference. + * + * @version $Revision$ $Date$ + * + */ +public class PhysicalReferenceDefinition extends Operations { + + // The name of the reference + private String name; + + /** + * Sets the name of the reference. + * @param name Name of the reference. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Gets the name of the reference. + * @return Name of the reference. + */ + public String getName() { + return name; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalServiceDefinition.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalServiceDefinition.java new file mode 100644 index 0000000000..518ee9b734 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalServiceDefinition.java @@ -0,0 +1,49 @@ +/* + * 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.spi.model.physical; + + +/** + * Represents a physical service. + * + * @version $Revision$ $Date$ + * + */ +public class PhysicalServiceDefinition extends Operations { + + // The name of the service + private String name; + + /** + * Sets the name of the service. + * @param name Name of the service. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Gets the name of the service. + * @return Name of the service. + */ + public String getName() { + return name; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalWireDefinition.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalWireDefinition.java new file mode 100644 index 0000000000..3a337b683c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/model/physical/PhysicalWireDefinition.java @@ -0,0 +1,84 @@ +/* + * 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.spi.model.physical; + +import java.net.URI; + +import javax.xml.namespace.QName; + +/** + * Model class representing the portable definition of a wire. This class is used to describe the inbound and outbound + * wires on a physical component definition. + * + * @version $Rev$ $Date$ + */ +public class PhysicalWireDefinition extends Operations { + + // TODO this should be removed + @Deprecated + private QName bindingType; + + // The resolved source URI of the wire + private URI sourceUri; + + // The resolved source URI of the wire + private URI targetUri; + + /** + * Returns the wire binding type. + * @return the binding type of the wire. + */ + @Deprecated + public QName getBindingType() { + return bindingType; + } + + /** + * Sets the Wire source URI. + * @param sourceUri Wire source URI. + */ + public void setSourceUri(URI sourceUri) { + this.sourceUri = sourceUri; + } + + /** + * Gets the Wire source URI. + * @return Wire source URI. + */ + public URI getSourceUri() { + return sourceUri; + } + + /** + * Sets the Wire target URI. + * @param targetUri Wire source URI. + */ + public void setTargetUri(URI targetUri) { + this.targetUri = targetUri; + } + + /** + * Gets the Wire target URI. + * @return Wire target URI. + */ + public URI getTargetUri() { + return targetUri; + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/package-info.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/package-info.java new file mode 100644 index 0000000000..710c0984be --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/package-info.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Overview of Apache Tuscany SPI for extensions. + */ +package org.apache.tuscany.spi;
\ No newline at end of file diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/IntentRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/IntentRegistry.java new file mode 100644 index 0000000000..8517977f0d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/IntentRegistry.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.spi.policy; + +import java.util.Collection; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.model.Intent; +import org.apache.tuscany.spi.model.IntentName; + +/** + * The registry for intents. + * + * @version $Rev$ $Date$ + */ +public interface IntentRegistry { + + /** + * Register a intent. + * + * @param intent intent to register + */ + void register(Intent intent); + + /** + * Unregister a intent. + * + * @param intent intent to unregister + */ + void unRegister(Intent intent); + + /** + * Replace the profile intents in intentNameList with the real concrete intent. + * + * @param intentNameList intent list that may contains profile intents + * @param artifact QName of SCA artifact + * @return concrete intents list + */ + Collection<IntentName> inlineProfileIntent(Collection<IntentName> intentNameList, QName artifact); + + /** + * Whether the intent is appplicable for specified SCA artifact. + * + * @param intentName name of intent + * @param artifact QName of SCA artifact + * @return Whether the intent is appplicable for specified SCA artifact + */ + boolean isApplicable(IntentName intentName, QName artifact); + + /** + * Get a list including all qualified intents for a qulifiable intent. + * + * @param qualifiable qualifiable intent + * @param artifact QName of SCA artifact + * @return list including all qualified intents for a qulifiable intent. + */ + Collection<IntentName> getQualifiedIntents(IntentName qualifiable, QName artifact); + + /** + * Whether the intent is a qualified. + * + * @param name intent name. + * @return whether the intent is a qualified + */ + boolean isQualifiedIntent(IntentName name); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/PolicyBuilderRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/PolicyBuilderRegistry.java new file mode 100644 index 0000000000..c7f8016cfa --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/PolicyBuilderRegistry.java @@ -0,0 +1,49 @@ +/* + * 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.spi.policy; + +/** + * A registry for policy builders that dispatches to the appropriate builder when converting an assembly to runtime + * artifacts. Policy builders operate on either a source- or target-side wires. + * + * @version $Rev$ $Date$ + * @deprecated + */ +public interface PolicyBuilderRegistry { + + int INITIAL = 0; + int EXTENSION = 1; + int FINAL = 2; + + /** + * Registers a target-side policy builder. Called by extensions to register their builders. + * + * @param phase the phase hwne the builder must be run + * @param builder the builder to register + */ + void registerTargetBuilder(int phase, TargetPolicyBuilder builder); + + /** + * Registers a source-side policy builder. Called by extensions to register their builders. + * + * @param phase the phase hwne the builder must be run + * @param builder the builder to register + */ + void registerSourceBuilder(int phase, SourcePolicyBuilder builder); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/PolicyEngine.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/PolicyEngine.java new file mode 100644 index 0000000000..fd4ba129d5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/PolicyEngine.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.spi.policy; + +import java.util.Collection; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.model.IntentName; +import org.apache.tuscany.spi.model.PolicyModel; + +/** + * Responsible for matching concrete policy artifacts required by abstract intent name. + */ +public interface PolicyEngine { + + /** + * Retrieve policies which match the intents requirement on a SCA artifact. See SCA policy frame spec. 1.4.5 Guided + * Selection of PolicySets using Intents + * + * @param requires Intent names requred by the SCA artifact + * @param policySetName PolicySet names specify on the SCA artifact explicitly + * @param artifactType QName of SCA artifact type, which may be a abstract artifact type + * @return Collection contains all policy matching the intent requirement + */ + Collection<PolicyModel> getPolicy(IntentName[] requires, QName[] policySetName, QName artifactType); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/PolicySetContainer.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/PolicySetContainer.java new file mode 100644 index 0000000000..f7a9e0922a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/PolicySetContainer.java @@ -0,0 +1,46 @@ +/* + * 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.spi.policy; + +import java.util.Collection; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.model.PolicySet; + +/** + * The host for PolicySet. + */ +public interface PolicySetContainer { + + /** + * Get all PolicySet of this container + * + * @return Collection contains all PolicySet of this container + */ + Collection<PolicySet> getAllPolicySet(); + + /** + * Get PolicySet by name. + * + * @param name QName of PolicySet. + * @return PolicySet with specified name + */ + PolicySet getPolicySet(QName name); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/SCATypeManager.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/SCATypeManager.java new file mode 100644 index 0000000000..3a5127f014 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/SCATypeManager.java @@ -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. + */ +package org.apache.tuscany.spi.policy; + +import javax.xml.namespace.QName; + +public interface SCATypeManager { + + /** + * Whether the <code>subType</code> is a sub type of <code>type</code> or the type itself. + */ + boolean isTypeOf(QName subType, QName type); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/SourcePolicyBuilder.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/SourcePolicyBuilder.java new file mode 100644 index 0000000000..677ceaab30 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/SourcePolicyBuilder.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.spi.policy; + +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import org.apache.tuscany.spi.wire.Wire; + +/** + * Implementations contribute {@link org.apache.tuscany.spi.wire.Interceptor}s to handle source-side policy on a wire. + * + * @version $$Rev$$ $$Date$$ + * @deprecated + */ +public interface SourcePolicyBuilder { + + /** + * Callback for attaching policy to a source-side wire + * + * @param definition the service definition + * @param wire the wire to attach policy to + * @throws BuilderException + */ + void build(ReferenceDefinition definition, Wire wire) throws BuilderException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/SourcePolicyBuilderExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/SourcePolicyBuilderExtension.java new file mode 100644 index 0000000000..d577ae97bf --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/SourcePolicyBuilderExtension.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.spi.policy; + +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; + +/** + * A runtime extension point for {@link SourcePolicyBuilder}s + * + * @version $Rev$ $Date$ + */ +@EagerInit +public abstract class SourcePolicyBuilderExtension implements SourcePolicyBuilder { + protected int phase = PolicyBuilderRegistry.EXTENSION; + private PolicyBuilderRegistry registry; + + @Reference + public void setRegistry(PolicyBuilderRegistry registry) { + this.registry = registry; + } + + @Property + public void setPhase(int phase) { + this.phase = phase; + } + + @Init + public void init() { + registry.registerSourceBuilder(phase, this); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/TargetPolicyBuilder.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/TargetPolicyBuilder.java new file mode 100644 index 0000000000..f26c7fc4ad --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/TargetPolicyBuilder.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.spi.policy; + +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.model.ServiceDefinition; +import org.apache.tuscany.spi.wire.Wire; + +/** + * Implementations contribute {@link org.apache.tuscany.spi.wire.Interceptor}s to handle target-side policy on a wire. + * + * @version $$Rev$$ $$Date$$ + * @deprecated + */ +public interface TargetPolicyBuilder { + + /** + * Callback for attaching policy to a target-side wire + * + * @param definition the service definition + * @param wire the wire to attach policy to + * @throws BuilderException + */ + void build(ServiceDefinition definition, Wire wire) throws BuilderException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/TargetPolicyBuilderExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/TargetPolicyBuilderExtension.java new file mode 100644 index 0000000000..3b01cd457f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/policy/TargetPolicyBuilderExtension.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.spi.policy; + +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; + +/** + * A runtime extension point for {@link org.apache.tuscany.spi.policy.SourcePolicyBuilder}s + * + * @version $Rev$ $Date$ + */ +@EagerInit +public abstract class TargetPolicyBuilderExtension implements TargetPolicyBuilder { + protected int phase = PolicyBuilderRegistry.EXTENSION; + private PolicyBuilderRegistry registry; + + @Reference + public void setRegistry(PolicyBuilderRegistry registry) { + this.registry = registry; + } + + @Property + public void setPhase(int phase) { + this.phase = phase; + } + + @Init + public void init() { + registry.registerTargetBuilder(phase, this); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/resolver/ResolutionException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/resolver/ResolutionException.java new file mode 100644 index 0000000000..fd7394b6dd --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/resolver/ResolutionException.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.spi.resolver; + +import org.apache.tuscany.api.TuscanyException; + +/** + * Denotes an error during the resolve phase as an assembly is evaluated + * + * @version $Rev$ $Date$ + */ +public abstract class ResolutionException extends TuscanyException { + + public ResolutionException() { + } + + public ResolutionException(String message) { + super(message); + } + + public ResolutionException(String message, String identifier) { + super(message, identifier); + } + + public ResolutionException(String message, Throwable cause) { + super(message, cause); + } + + public ResolutionException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + public ResolutionException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/resolver/Resolver.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/resolver/Resolver.java new file mode 100644 index 0000000000..30ccfb2c2e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/resolver/Resolver.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.spi.resolver; + +import org.apache.tuscany.spi.model.ModelObject; + +/** + * Implementations are responsible for resolving resources referenced by an assembly model object + * + * @version $Rev$ $Date$ + */ +public interface Resolver<T extends ModelObject> { + + /** + * Processes a model object, resolving resources referenced by it + * + * @param registry the resolver registry to callback when processing sub-elements + * @param object the model object to process + * @throws ResolutionException + */ + void resolve(ResolverRegistry registry, T object) throws ResolutionException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/resolver/ResolverRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/resolver/ResolverRegistry.java new file mode 100644 index 0000000000..c0c7fdbbab --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/resolver/ResolverRegistry.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.spi.resolver; + +import org.apache.tuscany.spi.model.ModelObject; + +/** + * Registry for resolvers that handle resolution of resources referenced by assembly model elements + * <p/> + * Resolvers are contributed by system extensions + * + * @version $Rev$ $Date$ + */ +public interface ResolverRegistry { + /** + * Register a resolver for a model type. + * + * @param modelClass the type model element the resolver handles + * @param resolver the resolver to be registered + */ + <T extends ModelObject> void register(Class<T> modelClass, Resolver<T> resolver); + + /** + * Unregister a resolver for a model type. + * + * @param modelClass the model type whose builder should be unregistered + */ + <T extends ModelObject> void unregister(Class<T> modelClass); + + /** + * Initiates the resolution process + * + * @param object the top-level element to resolve + */ + <T extends ModelObject> void resolve(T object) throws ResolutionException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/VoidService.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/VoidService.java new file mode 100644 index 0000000000..777cfbd3e9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/VoidService.java @@ -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. + */ +package org.apache.tuscany.spi.services; + +import org.osoa.sca.annotations.Service; + +/** + * Empty interface for a service component that has no operations. + * This can be used as a default service interface by components that + * do not wish the base class to be used as the interface as specified + * by the defaulting rules. + * + * @version $Rev$ $Date$ + */ +@Service +public interface VoidService { +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/artifact/Artifact.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/artifact/Artifact.java new file mode 100644 index 0000000000..4da522d196 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/artifact/Artifact.java @@ -0,0 +1,197 @@ +/* + * 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.spi.services.artifact; + +import java.net.URL; +import java.util.HashSet; +import java.util.Set; + +/** + * Description of some packaged artifact such as a JAR file or a Composite. + * + * @version $Rev$ $Date$ + */ +public class Artifact { + + /* Artifact group */ + private String group; + + /* Artifact name */ + private String name; + + /* Artifact version */ + private String version; + + /* Artifact classifier */ + private String classifier; + + /* Artifact type */ + private String type; + + /* Artifact url */ + private URL url; + + /* Transitive dependencies */ + private Set<Artifact> dependencies = new HashSet<Artifact>(); + + /** + * Adds a transitive dependency to the artifact. + * + * @param artifact Dependency to be added. + */ + public void addDependency(Artifact artifact) { + dependencies.add(artifact); + } + + /** + * Gets the URLs for all the transitive dependencies. + * + * @return Sets of URLs for all the transitive dependencies. + */ + public Set<URL> getUrls() { + + Set<URL> urls = new HashSet<URL>(); + + for (Artifact artifact : dependencies) { + urls.add(artifact.getUrl()); + } + urls.add(getUrl()); + + return urls; + + } + + /** + * Returns the name of a logical grouping to which this artifact belongs. For example, this might represent the + * original publisher of the artifact. + * + * @return the name of a logical grouping to which this artifact belongs + */ + public String getGroup() { + return group; + } + + /** + * Sets the name of a logical grouping to which this artifact belongs. + * + * @param group the name of a logical grouping to which this artifact belongs + */ + public void setGroup(String group) { + this.group = group; + } + + /** + * Returns the name of an artifact. + * + * @return the name of an artifact + */ + public String getName() { + return name; + } + + /** + * Sets the name of an artifact. + * + * @param name the name of an artifact + */ + public void setName(String name) { + this.name = name; + } + + /** + * Returns the version of an artifact. + * + * @return the version of an artifact + */ + public String getVersion() { + return version; + } + + /** + * Sets the version of an artifact. + * + * @param version the version of an artifact + */ + public void setVersion(String version) { + this.version = version; + } + + /** + * Returns a way of classifying an artifact. This can be used to distinguish variants of an artifact that provide + * the same function but which may have platform specific requirements. For example, it may contain the name of a + * hardware platform for artifacts that contain native code. + * + * @return a way of classifying an artifact + */ + public String getClassifier() { + return classifier; + } + + /** + * Sets a way of classifying an artifact + * + * @param classifier a way of classifying an artifact + */ + public void setClassifier(String classifier) { + this.classifier = classifier; + } + + /** + * Returns the type of artifact. + * + * @return the type of artifact + */ + public String getType() { + return type; + } + + /** + * Sets the type of artifact. + * + * @param type the type of artifact + */ + public void setType(String type) { + this.type = type; + } + + /** + * Returns a URL from which the artifact can be obtained. + * + * @return a URL from which the artifact can be obtained + */ + public URL getUrl() { + return url; + } + + /** + * Sets a URL from which the artifact can be obtained. + * + * @param url a URL from which the artifact can be obtained + */ + public void setUrl(URL url) { + this.url = url; + } + + + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(group).append(':').append(name).append(':').append(version).append(':').append(type); + return buf.toString(); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/artifact/ArtifactRepository.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/artifact/ArtifactRepository.java new file mode 100644 index 0000000000..b0f590e163 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/artifact/ArtifactRepository.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.spi.services.artifact; + +import java.util.Collection; + +/** + * Abstraction for a repository of SCA and other artifacts. + * + * @version $Rev$ $Date$ + */ +public interface ArtifactRepository { + /** + * Resolve an artifact. + * This ensures that the information associated with an artifact is fully populated; + * Specifically, after this operation the URL should contain a location where the artifact can be obtained. + * + * @param artifact the artifact to be resolved + */ + void resolve(Artifact artifact); + + /** + * Resolve a collection of Artifacts. + * + * @param artifacts a collection of artifacts to be resolved + * @see #resolve(Artifact) + */ + void resolve(Collection<? extends Artifact> artifacts); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/classloading/ClassLoaderRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/classloading/ClassLoaderRegistry.java new file mode 100644 index 0000000000..f74d66268b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/classloading/ClassLoaderRegistry.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.spi.services.classloading; + +import java.net.URI; + +/** + * Registry for classloaders available to the local runtime. + * + * @version $Rev$ $Date$ + */ +public interface ClassLoaderRegistry { + /** + * Register a ClassLoader with the runtime. + * + * @param id a unique id for the classloader + * @param classLoader the classloader to register + * @throws DuplicateClassLoaderException if there is already a classloader registered with the same id + */ + void register(URI id, ClassLoader classLoader) throws DuplicateClassLoaderException; + + /** + * Returns the classloader registered with the supplied id, or null if none is registered. + * + * @param id the id for the classloader + * @return the ClassLoader registered with that id, or null + */ + ClassLoader getClassLoader(URI id); + + /** + * Unregister the specified classloader from the system. + * + * @param id the id for the classloader + * @return the classloader that was registed with the id, or null if none + */ + ClassLoader unregister(URI id); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/classloading/DuplicateClassLoaderException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/classloading/DuplicateClassLoaderException.java new file mode 100644 index 0000000000..77cc836811 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/classloading/DuplicateClassLoaderException.java @@ -0,0 +1,36 @@ +/* + * 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.spi.services.classloading; + +import org.apache.tuscany.spi.CoreRuntimeException; + +/** + * @version $Rev$ $Date$ + */ +public class DuplicateClassLoaderException extends CoreRuntimeException { + /** + * Constructor specifying message and the ID of the duplicate classloader. + * + * @param message exception message + * @param identifier the id of the classloader that is already present + */ + public DuplicateClassLoaderException(String message, String identifier) { + super(message, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/discovery/AbstractDiscoveryService.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/discovery/AbstractDiscoveryService.java new file mode 100644 index 0000000000..c42493340f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/discovery/AbstractDiscoveryService.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.spi.services.discovery; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamReader; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.host.RuntimeInfo; + +/** + * Abstract implementation of the discovery service. + * + * @version $Revision$ $Date$ + */ +@EagerInit +public abstract class AbstractDiscoveryService implements DiscoveryService { + + /** + * Runtime info. + */ + private RuntimeInfo runtimeInfo; + + /** + * Request listeners. + */ + private Map<QName, RequestListener> requestListenerMap = new ConcurrentHashMap<QName, RequestListener>(); + + /** + * Response listeners. + */ + private Map<QName, ResponseListener> responseListenerMap = new ConcurrentHashMap<QName, ResponseListener>(); + + /** + * Registers a request listener for async messages. + * + * @param messageType Message type that can be handled by the listener. + * @param listener Recipient of the async message. + */ + public void registerRequestListener(QName messageType, RequestListener listener) { + requestListenerMap.put(messageType, listener); + } + + /** + * Registers a response listener for async messages. + * + * @param messageType Message type that can be handled by the listener. + * @param listener Recipient of the async message. + */ + public void registerResponseListener(QName messageType, ResponseListener listener) { + responseListenerMap.put(messageType, listener); + } + + /** + * Sets the runtime info for the runtime using the discovery service. + * + * @param runtimeInfo Runtime info for the runtime using the discovery service. + */ + @Reference + public final void setRuntimeInfo(RuntimeInfo runtimeInfo) { + this.runtimeInfo = runtimeInfo; + } + + /** + * Starts the discovery service. + */ + @Init + public final void start() throws DiscoveryException { + onStart(); + } + + /** + * Stops the discovery service. + */ + @Destroy + public final void stop() throws DiscoveryException { + onStop(); + } + + /** + * Gets the runtime info for the runtime using the discovery service. + * + * @return Runtime info for the runtime using the discovery service. + */ + protected final RuntimeInfo getRuntimeInfo() { + return runtimeInfo; + } + + /** + * Returns the request listener for the specified message type. + * + * @param messageType Message type for the incoming message. + * @return Listener interested in the message type. + */ + public final RequestListener getRequestListener(QName messageType) { + return requestListenerMap.get(messageType); + } + + /** + * Returns the request listener for the specified message type. + * + * @param messageType Message type for the incoming message. + * @return Listener interested in the message type. + */ + public final ResponseListener getResponseListener(QName messageType) { + return responseListenerMap.get(messageType); + } + + /** + * Broadcasts the messages to all runtimes in the domain. + * + * @param content Message content. + * @return The message id. + * @throws DiscoveryException In case of discovery errors. + */ + public int broadcastMessage(XMLStreamReader content) throws DiscoveryException { + return sendMessage(null, content); + } + + /** + * Required to be overridden by sub-classes. + */ + protected abstract void onStart() throws DiscoveryException; + + /** + * Required to be overridden by sub-classes. + */ + protected abstract void onStop() throws DiscoveryException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/discovery/DiscoveryException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/discovery/DiscoveryException.java new file mode 100644 index 0000000000..f093321e26 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/discovery/DiscoveryException.java @@ -0,0 +1,49 @@ +/* + * 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.spi.services.discovery; + +import org.apache.tuscany.api.TuscanyException; + +/** + * Checked exception thrown during discovery operations. + * + * @version $Revision$ $Date$ + */ +@SuppressWarnings("serial") +public class DiscoveryException extends TuscanyException { + + /** + * Initialises the exception message. + * + * @param message Message for the exception. + */ + public DiscoveryException(String message) { + super(message); + } + + /** + * Initialises the exception root cause. + * + * @param cause Root cause for the exception. + */ + public DiscoveryException(Throwable cause) { + super(cause); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/discovery/DiscoveryService.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/discovery/DiscoveryService.java new file mode 100644 index 0000000000..5c0a518323 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/discovery/DiscoveryService.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.spi.services.discovery; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamReader; + +/** + * Defines the abstraction that allows runtimes participating + * in the domain to discover each other and broadcast liveness + * to the admin server that holds the domain's runtime physical + * model and the domain-wide assembly model.. + * + * @version $Revision$ $Date$ + * + */ +public interface DiscoveryService { + + /** + * Sends a message to the specified runtime. The method returns a unique + * message id for the sent message. The consumers can use the message id for + * correlating responses to sent messages. + * + * @param runtimeId Runtime id of recipient. + * @param content Message content. + * @return The message id. + * @throws DiscoveryException In case of discovery errors. + */ + int sendMessage(String runtimeId, XMLStreamReader content) throws DiscoveryException; + + /** + * Broadcasts the messages to all runtimes in the domain. + * + * @param content Message content. + * @return The message id. + * @throws DiscoveryException In case of discovery errors. + */ + int broadcastMessage(XMLStreamReader content) throws DiscoveryException; + + /** + * Registers a request listener for async messages. Request listeners handle + * unslolicited async messages sent by recipients. + * + * @param messageType Message type that can be handled by the listener. + * @param listener Recipient of the async message. + */ + void registerRequestListener(QName messageType, RequestListener listener); + + /** + * Registers a response listener for async messages. Response listeners handle + * async meesages that are received in response to a request message that was + * originally sent. + * + * @param messageType Message type that can be handled by the listener. + * @param listener Recipient of the async message. + */ + void registerResponseListener(QName messageType, ResponseListener listener); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/discovery/RequestListener.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/discovery/RequestListener.java new file mode 100644 index 0000000000..8729757a6b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/discovery/RequestListener.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.services.discovery; + +import javax.xml.stream.XMLStreamReader; + +/** + * Message listener for propogating callbacks. Request listeners handle + * unslolicited async messages sent by recipients. + * + * @version $Revision$ $Date$ + * + */ +public interface RequestListener { + + /** + * Callback for propogating async messages. + * @param content Message content. + * @return Response to the request message. + */ + XMLStreamReader onRequest(XMLStreamReader content); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/discovery/ResponseListener.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/discovery/ResponseListener.java new file mode 100644 index 0000000000..88411ac660 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/discovery/ResponseListener.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.services.discovery; + +import javax.xml.stream.XMLStreamReader; + +/** + * Message listener for propogating callbacks. Response listeners handle async meesages that are received in response to + * a request message that was originally sent. + * + * @version $Revision$ $Date$ + */ +public interface ResponseListener { + + /** + * Callback for propogating async messages. + * + * @param content Message content. + * @param messageId optional message id if this was in response to a message that was sent. + */ + void onResponse(XMLStreamReader content, int messageId); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/management/TuscanyManagementService.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/management/TuscanyManagementService.java new file mode 100644 index 0000000000..10c2215bf6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/management/TuscanyManagementService.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.services.management; + +import org.apache.tuscany.host.management.ManagementService; +import org.apache.tuscany.spi.component.Component; + +/** + * Interface for the management service abstraction. The implementaion + * could be based on a variety of technologies including JMX, WSDM, + * SNMP etc. + * + * @version $Revision$ $Date$ + */ +public interface TuscanyManagementService extends ManagementService<Component> { + + /** + * Registers a component for management. + * + * @param name Name of the component. + * @param component Component to be registered. + */ + void registerComponent(String name, Component component); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/DuplicateRecordException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/DuplicateRecordException.java new file mode 100644 index 0000000000..1210d05f5a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/DuplicateRecordException.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.spi.services.store; + +/** + * thrown when a record already exists during an insert operation + * + * @version $Rev$ $Date$ + */ +public class DuplicateRecordException extends StoreWriteException { + + public DuplicateRecordException(String owner, String identifier) { + super(null, owner, identifier); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/RecoveryListener.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/RecoveryListener.java new file mode 100644 index 0000000000..186d741c04 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/RecoveryListener.java @@ -0,0 +1,46 @@ +/* + * 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.spi.services.store; + +import java.util.UUID; + +/** + * Implementations receive callback events during a store recovery operation + * + * @version $Rev$ $Date$ + */ +public interface RecoveryListener { + + /** + * Signals the start of a recovery + */ + void onBegin(); + + /** + * Received when a record is recovered + * + * @param id + */ + void onRecord(UUID id); + + /** + * Signals the end of recovery + */ + void onEnd(); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/Store.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/Store.java new file mode 100644 index 0000000000..7a09f90811 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/Store.java @@ -0,0 +1,96 @@ +/* + * 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.spi.services.store; + +import org.apache.tuscany.spi.component.SCAObject; +import org.apache.tuscany.spi.event.EventPublisher; + +/** + * Implementations provide a persistent store for runtime data such as conversational state. A persistent store could be + * implemented in a durable fashion using JDBC or a journaling system, or using a non-durable mechanism such as an + * in-memory map. + * + * @version $Rev$ $Date$ + */ +public interface Store extends EventPublisher { + + /* Used to indicate an the default expiration offset for records for the store */ + long DEFAULT_EXPIRATION_OFFSET = -1; + + /* Used to indicate an entry should not expire */ + long NEVER = -2; + + /** + * Adds the given record to the store. Implementations may choose different strategies for writing data such as + * write-through or write-behind. + * + * @param owner the instance owner + * @param id the unique id of the record + * @param object the object representing the data to write + * @param expiration the time in milliseconds when the entry expires + * @throws StoreWriteException if an error occurs during the write operation + */ + void insertRecord(SCAObject owner, String id, Object object, long expiration) throws StoreWriteException; + + /** + * Updates a given record in the store, overwriting previous information. + * + * @param owner the instance owner + * @param id the unique id of the record + * @param object the object representing the data to write + * @param expiration the time in milliseconds when the entry expires + * @throws StoreWriteException + */ + void updateRecord(SCAObject owner, String id, Object object, long expiration) throws StoreWriteException; + + /** + * Returns the deserialized object in the store corresponding to the given id + * + * @param owner the instance owner + * @param id the unique id of the record + * @return the deserialized object or null if one is not found + * @throws StoreReadException + */ + Object readRecord(SCAObject owner, String id) throws StoreReadException; + + /** + * Removes a record from the store + * + * @param owner the instance owner + * @param id the unique id of the record + * @throws StoreWriteException + */ + void removeRecord(SCAObject owner, String id) throws StoreWriteException; + + /** + * Removes all records from the store + * + * @throws StoreWriteException + */ + void removeRecords() throws StoreWriteException; + + /** + * Initiates a recovery operation, for example during restart after a crash + * + * @param listener the listener to receive recovery callback events + * @throws StoreReadException + */ + void recover(RecoveryListener listener) throws StoreReadException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/StoreException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/StoreException.java new file mode 100644 index 0000000000..59f1797490 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/StoreException.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.spi.services.store; + +import org.apache.tuscany.api.TuscanyException; + +/** + * Represents a generic exception thrown by a <code>Store</code> + * + * @version $Rev$ $Date$ + */ +public class StoreException extends TuscanyException { + private final String owner; + + public StoreException(String message, String owner, String identifier) { + super(message, identifier); + this.owner = owner; + } + + public StoreException(String message, String owner, String identifier, Throwable cause) { + super(message, identifier, cause); + this.owner = owner; + } + + public StoreException(String message, String owner, Throwable cause) { + super(message, cause); + this.owner = owner; + } + + public StoreException(Throwable cause) { + super(cause); + owner = null; + } + + public String getOwner() { + return owner; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/StoreExpirationEvent.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/StoreExpirationEvent.java new file mode 100644 index 0000000000..fbb38dd362 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/StoreExpirationEvent.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.spi.services.store; + +import org.apache.tuscany.spi.component.SCAObject; +import org.apache.tuscany.spi.event.Event; + +/** + * Fired when a store implementation expires a resource + * + * @version $Rev$ $Date$ + */ +public class StoreExpirationEvent implements Event { + private Object source; + private SCAObject owner; + private Object instance; + + /** + * Constructor. + * + * @param source the source of the event + * @param owner the owner of the expiring object + * @param instance the expiring object + */ + public StoreExpirationEvent(Object source, SCAObject owner, Object instance) { + assert source != null; + assert owner != null; + assert instance != null; + this.source = source; + this.owner = owner; + this.instance = instance; + } + + public Object getSource() { + return source; + } + + /** + * Returns the owner of the expiring object. + * + * @return the owner of the expiring object. + */ + public SCAObject getOwner() { + return owner; + } + + /** + * Returns the expiring object. + * + * @return the expiring object. + */ + public Object getInstance() { + return instance; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/StoreMonitor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/StoreMonitor.java new file mode 100644 index 0000000000..f3bbbf0b73 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/StoreMonitor.java @@ -0,0 +1,74 @@ +/* + * 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.spi.services.store; + +import org.apache.tuscany.api.annotation.LogLevel; + +/** + * A generic monintor interface for services to log events + * + * @version $Rev$ $Date$ + */ +public interface StoreMonitor { + + /** + * Signals the service has started + * + * @param msg + */ + @LogLevel("DEBUG") + void start(String msg); + + /** + * Signals the service has been shutdown + * + * @param msg + */ + @LogLevel("DEBUG") + void stop(String msg); + + /** + * Fired when recovery is started + */ + @LogLevel("DEBUG") + void beginRecover(); + + /** + * Fired when recovery is completed + */ + @LogLevel("DEBUG") + void endRecover(); + + /** + * Fired when a record is processed during recovery + * + * @param recordId the id of the record being recovered + */ + @LogLevel("DEBUG") + void recover(Object recordId); + + /** + * Signals an error event + * + * @param e the error + */ + @LogLevel("ERROR") + void error(Throwable e); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/StoreReadException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/StoreReadException.java new file mode 100644 index 0000000000..0f46ac6878 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/StoreReadException.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.spi.services.store; + +/** + * Thrown when an error occurs reading from persistent storage + * + * @version $Rev$ $Date$ + */ +public class StoreReadException extends StoreException { + + public StoreReadException(Throwable cause) { + super(cause); + } + + public StoreReadException(String message, String owner, String identifier) { + super(message, owner, identifier); + } + + public StoreReadException(String owner, String identifier, Throwable throwable) { + super(owner, identifier, throwable); + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/StoreWriteException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/StoreWriteException.java new file mode 100644 index 0000000000..9eef91db9a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/store/StoreWriteException.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.spi.services.store; + +/** + * Thrown when an error occurs writing to persistent storage + * + * @version $Rev$ $Date$ + */ +public class StoreWriteException extends StoreException { + + public StoreWriteException(String message, String owner, String identifier) { + super(message, owner, identifier); + } + + public StoreWriteException(String message, String owner, String identifier, Throwable cause) { + super(message, owner, identifier, cause); + } + + public StoreWriteException(String message, String owner, Throwable cause) { + super(message, owner, cause); + } + + public StoreWriteException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/work/NotificationListener.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/work/NotificationListener.java new file mode 100644 index 0000000000..9675cdce53 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/work/NotificationListener.java @@ -0,0 +1,66 @@ +/* + * 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.spi.services.work; + +/** + * A callback inyterface that can be optionally used for registering + * interest in status of asynchronously scheduled unit of work. + * + */ +public interface NotificationListener<T extends Runnable> { + + /** + * Callback method when the unit of work is accepted. + * + * @param work Work that was accepted. + */ + void workAccepted(T work); + + /** + * Callback method when the unit of work is successfully completed. + * + * @param work Work that was succesfully completed. + */ + void workCompleted(T work); + + /** + * Callback when the unit of work is started. + * + * @param work Unit of work that was started. + */ + void workStarted(T work); + + /** + * Callback when the unit of work is rejected. + * + * @param work Unit of work that was rejected. + */ + void workRejected(T work); + + /** + * Callnack when the unit of work fails to complete. + * + * @param work Unit of work that failed to complete. + * @param error Error that caused the unit of work to fail. + */ + void workFailed(T work, Throwable error); + + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/work/WorkScheduler.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/work/WorkScheduler.java new file mode 100644 index 0000000000..0824990c93 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/work/WorkScheduler.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.spi.services.work; + +/** + * Defines the contract for scheduling asychronous units of work. + * + * <p> + * Units of work can be scheduled with an optional <code>NotificationListener</code>. + * If a notification listener is specified, the caller will be notified regarding the + * status of the work. The unit of work can either be completed, rejected or completed + * with an error. If the work completed with an error, the caller is notfied with the + * error details. + * </p> + * + */ +public interface WorkScheduler { + + /** + * Schedules a unit of work for future execution. The notification listener + * is used to register interest in callbacks regarding the status of the work. + * + * @param work The unit of work that needs to be asynchronously executed. + * @param listener Notification listener for callbacks. + */ + <T extends Runnable>void scheduleWork(T work, NotificationListener<T> listener); + + /** + * Schedules a unit of work for future execution. The notification listener + * is used to register interest in callbacks regarding the status of the work. + * + * @param work The unit of work that needs to be asynchronously executed. + */ + <T extends Runnable>void scheduleWork(T work); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/work/WorkSchedulerException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/work/WorkSchedulerException.java new file mode 100644 index 0000000000..d13edab6a7 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/services/work/WorkSchedulerException.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.spi.services.work; + +import org.apache.tuscany.api.TuscanyRuntimeException; + +/** + * Exception thrown by the work scheduler in case of unexpected exceptions. + * + * @version $Rev$ $Date$ + * + */ +@SuppressWarnings("serial") +public class WorkSchedulerException extends TuscanyRuntimeException { + + /** + * Wraps the root cause. + * + * @param cause Root cause for the exception. + */ + public WorkSchedulerException(Throwable cause) { + super(cause); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/util/UriHelper.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/util/UriHelper.java new file mode 100644 index 0000000000..07067a59cf --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/util/UriHelper.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.spi.util; + +import java.net.URI; + +/** + * Utility methods for handling URIs + * + * @version $Rev$ $Date$ + */ +public final class UriHelper { + + private UriHelper() { + } + + /** + * Returns the base name for a component URI, e.g. 'Bar' for 'sca://foo/Bar' + * + * @param uri the URI to parse + * @return the base name + */ + public static String getBaseName(URI uri) { + String s = uri.toString(); + int pos = s.lastIndexOf('/'); + if (pos > -1) { + return s.substring(pos + 1); + } else { + return s; + } + } + + public static URI getDefragmentedName(URI uri) { + if (uri.getFragment() == null) { + return uri; + } + String s = uri.toString(); + int pos = s.lastIndexOf('#'); + return URI.create(s.substring(0, pos)); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/util/stax/StaxUtil.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/util/stax/StaxUtil.java new file mode 100644 index 0000000000..9b99c78ab2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/util/stax/StaxUtil.java @@ -0,0 +1,204 @@ +/* + * 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.spi.util.stax; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +/** + * Utility for stax operations. + * + * @version $Revision$ $Date$ + */ +public abstract class StaxUtil { + + /** + * XML input factory. + */ + private static final XMLInputFactory XML_FACTORY = + XMLInputFactory.newInstance("javax.xml.stream.XMLInputFactory", StaxUtil.class.getClassLoader()); + + private StaxUtil() { + } + + /** + * Serializes the infoset in the stream reader. + * + * @param reader Stream reader. + * @return Serialized XML. + * @throws XMLStreamException In case of an xml stream error. + */ + public static String serialize(XMLStreamReader reader) throws XMLStreamException { + + try { + + StringBuffer xml = new StringBuffer(); + + int event = reader.getEventType(); + while (true) { + + switch (event) { + case XMLStreamConstants.START_ELEMENT: + onStartElement(reader, xml); + onNsMappings(reader, xml); + onAttributes(reader, xml); + xml.append(">"); + break; + case XMLStreamConstants.CHARACTERS: + if (reader.isWhiteSpace()) { + break; + } + xml.append(reader.getText()); + break; + case XMLStreamConstants.END_ELEMENT: + onEndElement(reader, xml); + break; + } + + if (!reader.hasNext()) { + break; + } + event = reader.next(); + + } + return xml.toString(); + + } finally { + reader.close(); + } + + } + + /** + * Creates a stream reader to the serialized XML. + * + * @param xml Serialized XML to which reader is to be created. + * @return XML stream reader instance. + * @throws XMLStreamException In case of an xml stream error. + */ + public static XMLStreamReader createReader(String xml) throws XMLStreamException { + + InputStream in = new ByteArrayInputStream(xml.getBytes()); + return XML_FACTORY.createXMLStreamReader(in); + + } + + /** + * Creates a stream reader to the serialized XML. + * + * @param xml XML stream to which reader is to be created. + * @return XML stream reader instance. + * @throws XMLStreamException In case of an xml stream error. + */ + public static XMLStreamReader createReader(InputStream xml) throws XMLStreamException { + + return XML_FACTORY.createXMLStreamReader(xml); + + } + + /** + * Returns the qualified name of the document element. + * + * @param xml Serialized xml that needs to be checked. + * @return Qualified name of the document element. + * @throws XMLStreamException In case of an xml stream error. + */ + public static QName getDocumentElementQName(String xml) throws XMLStreamException { + + XMLStreamReader reader = null; + try { + reader = createReader(xml); + reader.next(); + return reader.getName(); + } finally { + if (reader != null) { + reader.close(); + } + } + + } + + /* + * Renders end element markup. + */ + private static void onEndElement(XMLStreamReader reader, StringBuffer xml) { + String name = getName(reader); + xml.append("</"); + xml.append(name); + xml.append(">"); + } + + /* + * Gets the fully-qualified name of the element. + */ + private static String getName(XMLStreamReader reader) { + QName qname = reader.getName(); + String namePrefix = qname.getPrefix(); + String localPart = qname.getLocalPart(); + return namePrefix == null || "".equals(namePrefix) ? localPart : namePrefix + ":" + localPart; + } + + /* + * Render the attributes. + */ + private static void onAttributes(XMLStreamReader reader, StringBuffer xml) { + int n = reader.getAttributeCount(); + for (int i = 0; i < n; ++i) { + xml.append(' '); + xml.append(reader.getAttributeLocalName(i)); + xml.append('='); + xml.append('\''); + xml.append(reader.getAttributeValue(i)); + xml.append('\''); + } + } + + /* + * Renedr namespace mappings. + */ + private static void onNsMappings(XMLStreamReader reader, StringBuffer xml) { + int n = reader.getNamespaceCount(); + for (int i = 0; i < n; ++i) { + String prefix = reader.getNamespacePrefix(i); + xml.append(" xmlns"); + if (prefix != null) { + xml.append(':').append(prefix); + } + xml.append('='); + xml.append('\''); + xml.append(reader.getNamespaceURI(i)); + xml.append('\''); + } + } + + /* + * Render start element. + */ + private static void onStartElement(XMLStreamReader reader, StringBuffer xml) { + xml.append("<"); + String name = getName(reader); + xml.append(name); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/AbstractInvocationHandler.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/AbstractInvocationHandler.java new file mode 100644 index 0000000000..c8cab49191 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/AbstractInvocationHandler.java @@ -0,0 +1,93 @@ +/* + * 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.spi.wire; + +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.LinkedList; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; + +/** + * Base class for performing invocations on a wire. Subclasses are responsible for retrieving and supplying the + * appropriate chain, target invoker, and invocation arguments. + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractInvocationHandler { + private boolean conversationStarted; + + protected Object invoke(InvocationChain chain, + TargetInvoker invoker, + Object[] args, + Object correlationId, + LinkedList<URI> callbackUris) + throws Throwable { + Interceptor headInterceptor = chain.getHeadInterceptor(); + if (headInterceptor == null) { + try { + // short-circuit the dispatch and invoke the target directly + TargetInvoker targetInvoker = chain.getTargetInvoker(); + if (targetInvoker == null) { + String name = chain.getOperation().getName(); + throw new AssertionError("No target invoker [" + name + "]"); + } + return targetInvoker.invokeTarget(args, TargetInvoker.NONE); + } catch (InvocationTargetException e) { + // the cause was thrown by the target so throw it + throw e.getCause(); + } + } else { + Message msg = new MessageImpl(); + msg.setTargetInvoker(invoker); + if (correlationId != null) { + msg.setCorrelationId(correlationId); + } + if (callbackUris != null) { + msg.setCallbackUris(callbackUris); + } + Operation operation = chain.getOperation(); + ServiceContract contract = operation.getServiceContract(); + if (contract.isConversational()) { + int sequence = chain.getOperation().getConversationSequence(); + if (sequence == Operation.CONVERSATION_END) { + msg.setConversationSequence(TargetInvoker.END); + conversationStarted = false; + } else if (sequence == Operation.CONVERSATION_CONTINUE) { + if (conversationStarted) { + msg.setConversationSequence(TargetInvoker.CONTINUE); + } else { + conversationStarted = true; + msg.setConversationSequence(TargetInvoker.START); + } + } + } + msg.setBody(args); + // dispatch the wire down the chain and get the response + Message resp = headInterceptor.invoke(msg); + Object body = resp.getBody(); + if (resp.isFault()) { + throw (Throwable) body; + } + return body; + } + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/ChainHolder.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/ChainHolder.java new file mode 100644 index 0000000000..817599225e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/ChainHolder.java @@ -0,0 +1,56 @@ +/* + * 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.spi.wire; + +/** + * A holder used to associate an wire chain with a local copy of a target invoker that was previously cloned from the + * chain master + * + * @version $Rev$ $Date$ + */ +public class ChainHolder implements Cloneable { + InvocationChain chain; + TargetInvoker cachedInvoker; + + public ChainHolder(InvocationChain config) { + this.chain = config; + } + + public InvocationChain getChain() { + return chain; + } + + public TargetInvoker getCachedInvoker() { + return cachedInvoker; + } + + public void setCachedInvoker(TargetInvoker invoker) { + this.cachedInvoker = invoker; + } + + @SuppressWarnings({"CloneDoesntDeclareCloneNotSupportedException"}) + @Override + public ChainHolder clone() { + try { + return (ChainHolder) super.clone(); + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/IncompatibleServiceContractException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/IncompatibleServiceContractException.java new file mode 100644 index 0000000000..114df5a55c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/IncompatibleServiceContractException.java @@ -0,0 +1,74 @@ +/* + * 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.spi.wire; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; + +import org.apache.tuscany.api.TuscanyException; + +/** + * Denotes imcompatible service contracts for a wire + * + * @version $Rev$ $Date$ + */ +public class IncompatibleServiceContractException extends TuscanyException { + private static final long serialVersionUID = 5127478601823295587L; + private final ServiceContract<?> source; + private final ServiceContract<?> target; + private final Operation<?> sourceOperation; + private final Operation<?> targetOperation; + + public IncompatibleServiceContractException(String message, ServiceContract<?> source, ServiceContract<?> target) { + super(message, (String) null); + this.source = source; + this.target = target; + this.sourceOperation = null; + this.targetOperation = null; + } + + + public IncompatibleServiceContractException(String message, + ServiceContract<?> source, + ServiceContract<?> target, + Operation<?> sourceOperation, Operation<?> targetOperation) { + super(message, (String) null); + this.source = source; + this.target = target; + this.sourceOperation = sourceOperation; + this.targetOperation = targetOperation; + } + + public ServiceContract<?> getTarget() { + return target; + } + + public ServiceContract<?> getSource() { + return source; + } + + public Operation<?> getSourceOperation() { + return sourceOperation; + } + + public Operation<?> getTargetOperation() { + return targetOperation; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/Interceptor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/Interceptor.java new file mode 100644 index 0000000000..ad38ed1cf1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/Interceptor.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.spi.wire; + +/** + * Synchronous, around-style mediation associated with a client- or target- side wire. + * + * @version $Rev$ $Date$ + */ +public interface Interceptor { + + /** + * Process a synchronous wire + * + * @param msg the request Message for the wire + * @return the response Message from the wire + */ + Message invoke(Message msg); + + /** + * Sets the next interceptor + */ + void setNext(Interceptor next); + + /** + * Returns the next interceptor or null + */ + Interceptor getNext(); + + /** + * Returns true if the interceptor can be optimized away from a wire + */ + boolean isOptimizable(); +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/InvocationChain.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/InvocationChain.java new file mode 100644 index 0000000000..640bb88ca5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/InvocationChain.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.spi.wire; + +import org.apache.tuscany.spi.model.Operation; + +/** + * A wire consists of 1..n invocation chains associated with the operations of its source service contract. + * <p/> + * Invocation chains may contain </ode>Interceptors</code> that process invocations in an around-style manner. + * Invocation chains are also associated with a <code>TargetInvoker</code> which is responsible for dispatching on the + * target service provider. + * <p/> + * A <code>Message</code> is used to pass data associated with an invocation through the chain. The TargetInvoker is + * passed with the Message through the interceptor stack, if one is present. At last interceptor in the stack, must call + * the TargetInvoker. + * <p/> + * In certain circumstances, the TargetInvoker may be cached in the source-side proxy. Caching allows various + * optimizations such as avoiding target instance resolution when the client-side lifecycle scope is a shorter duration + * than the target. + * + * @version $Rev$ $Date$ + */ +public interface InvocationChain { + /** + * Returns the target operation for this invocation chain + */ + Operation getOperation(); + + /** + * Sets the target invoker to pass down the chain + */ + void setTargetInvoker(TargetInvoker invoker); + + /** + * Returns the target invoker that is passed down the chain + */ + TargetInvoker getTargetInvoker(); + + /** + * Adds an interceptor to the chain + */ + void addInterceptor(Interceptor interceptor); + + /** + * Adds an interceptor at the given position in the interceptor stack + * + * @param index the position in the interceptor stack to add the interceptor + * @param interceptor the interceptor to add + */ + void addInterceptor(int index, Interceptor interceptor); + + /** + * Returns the first interceptor in the chain + */ + Interceptor getHeadInterceptor(); + + /** + * Returns the last interceptor in the chain + */ + Interceptor getTailInterceptor(); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/InvocationRuntimeException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/InvocationRuntimeException.java new file mode 100644 index 0000000000..c2ba19c48a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/InvocationRuntimeException.java @@ -0,0 +1,46 @@ +/* + * 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.spi.wire; + +import org.osoa.sca.ServiceRuntimeException; + +/** + * Denotes a runtime exception thrown during an invocation over a wire + * + * @version $Rev$ $Date$ + */ +public class InvocationRuntimeException extends ServiceRuntimeException { + + public InvocationRuntimeException() { + super(); + } + + public InvocationRuntimeException(String message) { + super(message); + } + + public InvocationRuntimeException(String message, Throwable cause) { + super(message, cause); + } + + public InvocationRuntimeException(Throwable cause) { + super(cause); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/Message.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/Message.java new file mode 100644 index 0000000000..acc3b79748 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/Message.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.spi.wire; + +import java.net.URI; +import java.util.LinkedList; + +/** + * Represents a request, response, or exception flowing through a wire + * + * @version $Rev $Date + */ +public interface Message { + + /** + * Returns the body of the message, which will be the payload or parameters associated with the wire + */ + Object getBody(); + + /** + * Sets the body of the message. + */ + void setBody(Object body); + + /** + * Sets the target invoker to dispatch to when the message passes through the request side of the invocation chain + */ + void setTargetInvoker(TargetInvoker invoker); + + /** + * Sets the target invoker to dispatch to when the message passes through the request side of the invocation chain + */ + TargetInvoker getTargetInvoker(); + + /** + * Adds a URI to the ordered list of callback URIs. Callback URIs are used to resolve the correct wire for a + * callback. + */ + void pushCallbackUri(URI uri); + + /** + * Returns the ordered list of callback URIs. Callback URIs are used to resolve the correct wire for a callback. + */ + LinkedList<URI> getCallbackUris(); + + /** + * Sets the ordered list of callback URIs. Callback URIs are used to resolve the correct wire for a callback. + */ + void setCallbackUris(LinkedList<URI> uris); + + /** + * Returns the id of the message + */ + Object getMessageId(); + + /** + * Sets the id of the message + */ + void setMessageId(Object messageId); + + /** + * Returns the correlation id of the message or null if one is not available. Correlation ids are used by transports + * for message routing. + */ + Object getCorrelationId(); + + /** + * Sets the correlation id of the message. Correlation ids are used by transports for message routing. + */ + void setCorrelationId(Object correlationId); + + /** + * Determines if the message represents a fault/exception + * + * @return true if the message body is a fault object, false if the body is a normal payload + */ + boolean isFault(); + + /** + * Set the message body with a fault object. After this method is called, isFault() returns true. + * + * @param fault The fault object represents an exception + */ + void setBodyWithFault(Object fault); + + /** + * Returns the conversational sequence the message is associated with, NONE, START, CONTINUE, or END on {@link + * TargetInvoker} + * + * @return the conversational sequence the message is associated with + */ + short getConversationSequence(); + + /** + * Returns the conversational sequence the message is associated with, NONE, START, CONTINUE, or END on {@link + * TargetInvoker} + * + * @param sequence the conversational sequence + */ + void setConversationSequence(short sequence); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/MessageId.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/MessageId.java new file mode 100644 index 0000000000..f179eb79b1 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/MessageId.java @@ -0,0 +1,56 @@ +/* + * 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.spi.wire; + +/** + * A unique identifier for a message flowing on a wire, potentially end-to-end (ie, through more than one SCAObject to + * SCAObject hop). + */ +public class MessageId { + + private long timestamp; + + public MessageId() { + this.timestamp = System.currentTimeMillis(); + } + + public long getTimestamp() { + return timestamp; + } + + public String toString() { + return "MsgId[" + timestamp + "]"; + } + + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final MessageId messageId = (MessageId) o; + return timestamp == messageId.timestamp; + } + + public int hashCode() { + return (int) (timestamp ^ (timestamp >>> 32)); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/MessageImpl.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/MessageImpl.java new file mode 100644 index 0000000000..1e18f8247f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/MessageImpl.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.spi.wire; + +import java.net.URI; +import java.util.LinkedList; + +/** + * The default implementation of a message flowed through a wire during an invocation + * + * @version $Rev $Date + */ +public class MessageImpl implements Message { + private Object body; + private TargetInvoker invoker; + private LinkedList<URI> callbackUris; + private Object messageId; + private Object correlationId; + private boolean isFault; + private short conversationSequence; + + public MessageImpl() { + } + + public Object getBody() { + return body; + } + + public void setBody(Object body) { + this.isFault = false; + this.body = body; + } + + public void setTargetInvoker(TargetInvoker invoker) { + this.invoker = invoker; + } + + public TargetInvoker getTargetInvoker() { + return invoker; + } + + public void pushCallbackUri(URI uri) { + if (callbackUris == null) { + callbackUris = new LinkedList<URI>(); + } + callbackUris.add(uri); + } + + public LinkedList<URI> getCallbackUris() { + return callbackUris; + } + + public void setCallbackUris(LinkedList<URI> callbackRoutingChain) { + this.callbackUris = callbackRoutingChain; + } + + public Object getMessageId() { + return messageId; + } + + public void setMessageId(Object messageId) { + this.messageId = messageId; + } + + public Object getCorrelationId() { + return correlationId; + } + + public void setCorrelationId(Object correlationId) { + this.correlationId = correlationId; + } + + public boolean isFault() { + return isFault; + } + + public void setBodyWithFault(Object fault) { + this.isFault = true; + this.body = fault; + } + + public TargetInvoker getInvoker() { + return invoker; + } + + public void setInvoker(TargetInvoker invoker) { + this.invoker = invoker; + } + + public short getConversationSequence() { + return conversationSequence; + } + + public void setConversationSequence(short conversationSequence) { + this.conversationSequence = conversationSequence; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/ProxyCreationException.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/ProxyCreationException.java new file mode 100644 index 0000000000..4805c75252 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/ProxyCreationException.java @@ -0,0 +1,51 @@ +/* + * 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.spi.wire; + +import org.apache.tuscany.spi.CoreRuntimeException; + +/** + * Denotes an error creating a proxy + * + * @version $$Rev$$ $$Date$$ + */ +public class ProxyCreationException extends CoreRuntimeException { + public ProxyCreationException() { + } + + public ProxyCreationException(String message) { + super(message); + } + + public ProxyCreationException(String message, String identifier) { + super(message, identifier); + } + + public ProxyCreationException(String message, Throwable cause) { + super(message, cause); + } + + public ProxyCreationException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + public ProxyCreationException(Throwable cause) { + super(cause); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/ProxyService.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/ProxyService.java new file mode 100644 index 0000000000..9008331dd2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/ProxyService.java @@ -0,0 +1,108 @@ +/* + * 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.spi.wire; + +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; + +import org.osoa.sca.CallableReference; + +import org.apache.tuscany.spi.model.ServiceContract; + +/** + * Creates proxies that implement Java interfaces and invocation handlers for fronting wires + * + * @version $$Rev$$ $$Date$$ + */ + +public interface ProxyService { + + /** + * Creates a Java proxy for the given wire + * + * @param interfaze the interface the proxy implements + * @param wire the wire to proxy @return the proxy + * @throws ProxyCreationException + */ + <T> T createProxy(Class<T> interfaze, Wire wire) throws ProxyCreationException; + + /** + * Creates a Java proxy for the given wire + * + * @param interfaze the interface the proxy implements + * @param wire the wire to proxy @return the proxy + * @param mapping the method to chain holder mapping to use in creating the proxy. Clients may cache and resuse + * this mapping for performance. + * @throws ProxyCreationException + */ + <T> T createProxy(Class<T> interfaze, Wire wire, Map<Method, ChainHolder> mapping) + throws ProxyCreationException; + + /** + * Creates a Java proxy for the service contract callback + * + * @param interfaze the interface the proxy should implement + * @return the proxy + * @throws ProxyCreationException + */ + Object createCallbackProxy(Class<?> interfaze, List<Wire> wires) throws ProxyCreationException; + + /** + * Cast a proxy to a CallableReference. + * + * @param target a proxy generated by this implementation + * @return a CallableReference (or subclass) equivalent to this prozy + * @throws IllegalArgumentException if the object supplied is not a proxy + */ + <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException; + + /** + * Check the compatiblity of the source and the target service contracts.<p> A wire may only connect a source to a + * target if the target implements an interface that is compatible with the interface required by the source. The + * source and the target are compatible if: + * <p/> + * <ol> <li>the source interface and the target interface MUST either both be remotable or they are both local + * <li>the methods on the target interface MUST be the same as or be a superset of the methods in the interface + * specified on the source <li>compatibility for the individual method is defined as compatibility of the signature, + * that is method name, input types, and output types MUST BE the same. <li>the order of the input and output types + * also MUST BE the same. <li>the set of Faults and Exceptions expected by the source MUST BE the same or be a + * superset of those specified by the service. <li>other specified attributes of the two interfaces MUST match, + * including Scope and Callback interface </ol> + * <p/> + * <p>Please note this test is not symetric: the success of checkCompatibility(A, B) does NOT imply + * checkCompatibility(B, A) + * + * @param source The source service contract + * @param target The target service contract + * @param ignoreCallback Indicate the callback should be checked + * @param silent if true, errors will be thrown if the service contracts are not compatible + * @return true if the service contracts are compatible + * @throws IncompatibleServiceContractException + * If the source service contract is not compatible with the target one + * <p> + * TODO JFM this method should be moved from this interface to the allocator phase + */ + boolean checkCompatibility(ServiceContract<?> source, + ServiceContract<?> target, + boolean ignoreCallback, + boolean silent) + throws IncompatibleServiceContractException; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/TargetInvoker.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/TargetInvoker.java new file mode 100644 index 0000000000..f452daec90 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/TargetInvoker.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.spi.wire; + +import java.lang.reflect.InvocationTargetException; + +/** + * Implementations are responsible for resolving a target and performing the actual invocation on it, for example, a + * component implementation instance or a service client. + * + * @version $Rev$ $Date$ + */ +public interface TargetInvoker extends Cloneable { + /* indicates that no conversational sequence is associated with the message */ + short NONE = 0; + /* indicates that the message initiates a conversation */ + short START = 1; + /* indicates that the message continues a conversation */ + short CONTINUE = 2; + /* indicates that the message ends a conversation */ + short END = 3; + + /** + * Invokes an operation on a target with the given payload. Used in optmized cases where messages do not need to be + * flowed such as in non-proxied wires. + * + * @param payload the invocation payload, typically an array of parameters + * @param sequence if the invocation is part of a conversation, the sequence. Valid values are {@link #NONE} for + * non-conversational, {@link #START} to begin a conversation, {@link #CONTINUE} to continue a + * conversation, or {@link #END} to end a conversation + * @throws InvocationTargetException + */ + Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException; + + /** + * Invokes an operation on a target with the given message + * + * @throws InvocationRuntimeException + */ + Message invoke(Message msg) throws InvocationRuntimeException; + + /** + * Determines whether the proxy can be cached on the client/source side + */ + boolean isCacheable(); + + /** + * Sets whether the target service instance may be cached by the invoker. This is a possible optimization when a + * wire is configured for a "down-scope" reference, i.e. a reference from a source of a shorter lifetime to a source + * of greater lifetime. + */ + void setCacheable(boolean cacheable); + + /** + * Determines if the target invoker can be discarded during wire optimization + */ + boolean isOptimizable(); + + /** + * Implementations must support deep cloning + */ + Object clone() throws CloneNotSupportedException; +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/Wire.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/Wire.java new file mode 100644 index 0000000000..35b266fe2e --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/Wire.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.spi.wire; + +import java.net.URI; +import java.util.Map; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.component.AtomicComponent; +import org.apache.tuscany.spi.component.TargetResolutionException; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; + +/** + * The base wire type used to connect references and serviceBindings + * + * @version $$Rev$$ $$Date$$ + */ +public interface Wire { + QName LOCAL_BINDING = new QName("http://tuscany.apache.org/xmlns/sca/binding/1.0", "binding.local"); + + /** + * Returns the URI of the wire source + * + * @return the wire source URI + */ + URI getSourceUri(); + + /** + * Sets the URI of the wire source + * + * @param uri the source uri + */ + void setSourceUri(URI uri); + + /** + * Returns the URI of the wire target + * + * @return the URI of the wire target + */ + URI getTargetUri(); + + /** + * Sets the URI of the wire target + * + * @param uri the URI of the wire target + */ + void setTargetUri(URI uri); + + /** + * Returns the wire binding type + * + * @return the wire binding type + */ + QName getBindingType(); + + /** + * Returns the service contract associated with the the source side of the wire + * + * @return the service contract associated with the wire + */ + ServiceContract getSourceContract(); + + /** + * Sets the contract associated with the source side of the wire + * + * @param contract the contract associated with the wire + */ + void setSourceContract(ServiceContract contract); + + /** + * Returns the service contract associated with the the target side of the wire + * + * @return the service contract associated with the wire + */ + ServiceContract getTargetContract(); + + /** + * Sets the contract associated with the the target side of the wire + * + * @param contract the contract associated with the wire + */ + void setTargetContract(ServiceContract contract); + + /** + * Returns true if the wire is optimizable and its invocation chains may be bypassed + * + * @return true if the wire is optimizable and its invocation chains may be bypassed + */ + boolean isOptimizable(); + + /** + * Determines if the wire may be optimized + * + * @param optimizable true if the wire is optimizable + */ + void setOptimizable(boolean optimizable); + + /** + * Returns the non-proxied target instance for this wire + * + * @return the non-proxied target instance for this wire + */ + Object getTargetInstance() throws TargetResolutionException; + + /** + * Sets the target for the wire for optimizations + * + * @param target the target for the wire + */ + void setTarget(AtomicComponent target); + + /** + * Returns the invocation chains for service operations associated with the wire + * + * @return the invocation chains for service operations associated with the wire + */ + Map<Operation<?>, InvocationChain> getInvocationChains(); + + /** + * Adds the invocation chain associated with the given operation + * + * @param operation the service operation + * @param chain the invocation chain + */ + void addInvocationChain(Operation<?> operation, InvocationChain chain); + + /** + * Returns the invocation chains for callback service operations associated with the wire + * + * @return the invocation chains for callback service operations associated with the wire + */ + Map<Operation<?>, InvocationChain> getCallbackInvocationChains(); + + /** + * Adds the callback invocation chain associated with the given operation + * + * @param operation the service operation + * @param chain the invocation chain + */ + void addCallbackInvocationChain(Operation<?> operation, InvocationChain chain); + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/WireInvocationHandler.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/WireInvocationHandler.java new file mode 100644 index 0000000000..325f26ba91 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/WireInvocationHandler.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.wire; + +import java.lang.reflect.Method; + +/** + * Implementations are responsible for dispatching an operation down an invocation chain + * + * @version $$Rev$$ $$Date$$ + */ +public interface WireInvocationHandler { + + Object invoke(Method method, Object[] args) throws Throwable; + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/WirePostProcessor.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/WirePostProcessor.java new file mode 100644 index 0000000000..e3ccb155cd --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/WirePostProcessor.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.spi.wire; + +/** + * Implementations are called after wires are decorated with policy and before they are connected. + * + * @version $Rev$ $Date$ + * @deprecated + */ +public interface WirePostProcessor { + + void process(Wire wire); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/WirePostProcessorExtension.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/WirePostProcessorExtension.java new file mode 100644 index 0000000000..d335df87b9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/WirePostProcessorExtension.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.spi.wire; + +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; + +/** + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +@EagerInit +public abstract class WirePostProcessorExtension implements WirePostProcessor { + protected WirePostProcessorRegistry registry; + + @Reference + public void setRegistry(WirePostProcessorRegistry registry) { + this.registry = registry; + } + + @Init + public void init() { + registry.register(this); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/WirePostProcessorRegistry.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/WirePostProcessorRegistry.java new file mode 100644 index 0000000000..f012d119c3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/main/java/org/apache/tuscany/spi/wire/WirePostProcessorRegistry.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.wire; + +/** + * Acts as a delegating <code>WirePostProcessor</code>, delegating post-processing of wires after policies have been + * applied and source an targets have been matched but before they are connected. + * + * @version $Rev$ $Date$ + */ +public interface WirePostProcessorRegistry extends WirePostProcessor { + + + /** + * Registers a post-processor in the runtime + * + * @param processor the processor to register + */ + void register(WirePostProcessor processor); + + /** + * De-registers a post-processor in the runtime + * + * @param processor the processor to de-register + */ + void unregister(WirePostProcessor processor); + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/AssertionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/AssertionTestCase.java new file mode 100644 index 0000000000..72739d56c4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/AssertionTestCase.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.spi; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class AssertionTestCase extends TestCase { + /** + * test case that confirms that JRE assertions are enabled + */ + public void testAssertionsAreEnabled() { + try { + assert false; + fail("assertions are not enabled"); + } catch (AssertionError e) { + // ok + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/QualifiedNameTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/QualifiedNameTestCase.java new file mode 100644 index 0000000000..1e7b2ab67c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/QualifiedNameTestCase.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.spi; + +import junit.framework.TestCase; + +/** + * Tests parsing of naming patters + * + * @version $Rev$ $Date$ + */ +public class QualifiedNameTestCase extends TestCase { + + public void testSimpleName() throws Exception { + QualifiedName name = new QualifiedName("Foo"); + assertEquals("Foo", name.getPartName()); + assertEquals(null, name.getPortName()); + assertEquals("Foo", name.getQualifiedName()); + assertEquals("Foo", name.getFragment()); + assertEquals("Foo", name.toString()); + } + + public void testCompoundName() throws Exception { + QualifiedName name = new QualifiedName("Foo/Bar"); + assertEquals("Foo", name.getPartName()); + assertEquals("Bar", name.getPortName()); + assertEquals("Foo/Bar", name.getQualifiedName()); + assertEquals("Foo#Bar", name.getFragment()); + assertEquals("Foo/Bar", name.toString()); + } + + public void testCompoundMultiName() throws Exception { + try { + new QualifiedName("Foo/Bar/Baz"); + fail("Invalid name exception not thrown"); + } catch (InvalidNameException e) { + // ok; + } + } + + public void testInvalidName() throws Exception { + try { + new QualifiedName("/Foo/Bar"); + fail("Invalid name exception not thrown"); + } catch (InvalidNameException e) { + //expected + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/TuscanyRuntimeExceptionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/TuscanyRuntimeExceptionTestCase.java new file mode 100644 index 0000000000..593b5a992b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/TuscanyRuntimeExceptionTestCase.java @@ -0,0 +1,49 @@ +/* + * 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.spi; + +import junit.framework.TestCase; + +import org.apache.tuscany.api.TuscanyRuntimeException; + +/** + * @version $Rev$ $Date$ + */ +public class TuscanyRuntimeExceptionTestCase extends TestCase { + + public void testIdentifier() throws Exception { + TuscanyRuntimeException e = new TestException("bar", "foo"); + assertEquals("foo", e.getIdentifier()); + } + + public void testEmptyGetMessage() throws Exception { + TuscanyRuntimeException e = new TestException(); + e.getMessage(); + } + + private class TestException extends TuscanyRuntimeException { + + public TestException() { + } + + public TestException(String message, String identifier) { + super(message, identifier); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/component/AbstractSCAObjectTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/component/AbstractSCAObjectTestCase.java new file mode 100644 index 0000000000..210997b8c8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/component/AbstractSCAObjectTestCase.java @@ -0,0 +1,106 @@ +/* + * 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.spi.component; + +import java.net.URI; + +import org.apache.tuscany.spi.event.Event; +import org.apache.tuscany.spi.event.EventFilter; +import org.apache.tuscany.spi.event.RuntimeEventListener; +import org.apache.tuscany.spi.event.TrueFilter; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class AbstractSCAObjectTestCase extends TestCase { + + public void testFireListener() throws Exception { + SCAObject object = new TestSCAObject(new URI("foo")); + Event event = new TestEvent(); + RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class); + listener.onEvent(EasyMock.same(event)); + EasyMock.expectLastCall(); + EasyMock.replay(listener); + object.addListener(listener); + object.publish(event); + } + + public void testRemoveListener() throws Exception { + SCAObject object = new TestSCAObject(new URI("foo")); + Event event = new TestEvent(); + RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class); + EasyMock.replay(listener); + object.addListener(listener); + object.removeListener(listener); + object.publish(event); + } + + public void testFalseFilterListener() throws Exception { + SCAObject object = new TestSCAObject(new URI("foo")); + Event event = new TestEvent(); + RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class); + EasyMock.replay(listener); + object.addListener(new FalseFilter(), listener); + object.publish(event); + } + + public void testTrueFilterListener() throws Exception { + SCAObject object = new TestSCAObject(new URI("foo")); + Event event = new TestEvent(); + RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class); + listener.onEvent(EasyMock.same(event)); + EasyMock.expectLastCall(); + EasyMock.replay(listener); + object.addListener(new TrueFilter(), listener); + object.publish(event); + } + + public void testToString() throws Exception { + SCAObject object = new TestSCAObject(new URI("foo")); + assertNotNull(object.toString()); + } + + private class TestSCAObject extends AbstractSCAObject { + public TestSCAObject(URI name) { + super(name); + } + + } + + private class TestEvent implements Event { + public Object getSource() { + return null; + } + } + + private class FalseFilter implements EventFilter { + + public boolean match(Event event) { + return false; + } + } + + +} + + + diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/component/MockSCAExternalizable.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/component/MockSCAExternalizable.java new file mode 100644 index 0000000000..510e6e4390 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/component/MockSCAExternalizable.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.spi.component; + +import java.io.Serializable; + +/** + * @version $Rev$ $Date$ + */ +@SuppressWarnings({"SerializableHasSerializationMethods"}) +public class MockSCAExternalizable implements Serializable, SCAExternalizable { + private static final long serialVersionUID = 5071815222959279772L; + + private WorkContext context; + private boolean activated; + + public void setWorkContext(WorkContext context) { + this.context = context; + } + + public WorkContext getContext() { + return context; + } + + public void reactivate() throws ReactivationException { + activated = true; + } + + public boolean isActivated() { + return activated; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/component/MockSerializable.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/component/MockSerializable.java new file mode 100644 index 0000000000..c853f427fb --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/component/MockSerializable.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.spi.component; + +import java.io.Serializable; + +/** + * @version $Rev$ $Date$ + */ +@SuppressWarnings({"SerializableHasSerializationMethods"}) +public class MockSerializable implements Serializable { + private static final long serialVersionUID = 4013396228070042469L; + + private MockSCAExternalizable externalizable; + + public MockSerializable() { + } + + public MockSCAExternalizable getExternalizable() { + return externalizable; + } + + public void setExternalizable(MockSCAExternalizable externalizable) { + this.externalizable = externalizable; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/component/SCAObjectInputStreamTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/component/SCAObjectInputStreamTestCase.java new file mode 100644 index 0000000000..ae316bc441 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/component/SCAObjectInputStreamTestCase.java @@ -0,0 +1,49 @@ +/* + * 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.spi.component; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class SCAObjectInputStreamTestCase extends TestCase { + + public void testSCAExternalizable() throws Exception { + WorkContext context = EasyMock.createMock(WorkContext.class); + MockSCAExternalizable ext = new MockSCAExternalizable(); + MockSerializable serializable = new MockSerializable(); + serializable.setExternalizable(ext); + ByteArrayOutputStream bas = new ByteArrayOutputStream(); + ObjectOutputStream o = new ObjectOutputStream(bas); + o.writeObject(serializable); + o.close(); + ByteArrayInputStream bytes = new ByteArrayInputStream(bas.toByteArray()); + SCAObjectInputStream stream = new SCAObjectInputStream(bytes, context); + MockSerializable deserialized = (MockSerializable) stream.readObject(); + MockSCAExternalizable deserializedExt = deserialized.getExternalizable(); + assertTrue(deserializedExt.isActivated()); + assertEquals(context, deserializedExt.getContext()); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/databinding/extension/DOMHelperTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/databinding/extension/DOMHelperTestCase.java new file mode 100644 index 0000000000..40843dea94 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/databinding/extension/DOMHelperTestCase.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.spi.databinding.extension; + +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import junit.framework.TestCase; + +/** + * + */ +public class DOMHelperTestCase extends TestCase { + private static final QName FOO_NAME = new QName("http://foo", "foo"); + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + } + + public void testDOM() throws Exception { + DocumentBuilder builder = DOMHelper.newDocumentBuilder(); + assertNotNull(builder); + Document document = DOMHelper.newDocument(); + assertNotNull(document); + Element element = DOMHelper.createElement(document, FOO_NAME); + document.appendChild(element); + QName name = DOMHelper.getQName(element); + assertEquals(FOO_NAME, name); + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/databinding/extension/DataBindingExtensionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/databinding/extension/DataBindingExtensionTestCase.java new file mode 100644 index 0000000000..b4b5f6a39a --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/databinding/extension/DataBindingExtensionTestCase.java @@ -0,0 +1,80 @@ +/* + * 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.spi.databinding.extension; + +import junit.framework.TestCase; + +import org.apache.tuscany.spi.databinding.DataBindingRegistry; +import org.easymock.EasyMock; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * + */ +public class DataBindingExtensionTestCase extends TestCase { + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + } + + public void testExtension() { + DataBinding1 binding1 = new DataBinding1(Node.class); + assertEquals(Node.class.getName(), binding1.getName()); + assertNotNull(binding1.introspect(Element.class)); + assertNull(binding1.introspect(String.class)); + assertNull(binding1.getWrapperHandler()); + + DataBindingRegistry registry = EasyMock.createMock(DataBindingRegistry.class); + registry.register(binding1); + EasyMock.expect(registry.getDataBinding(Node.class.getName())).andReturn(binding1); + EasyMock.replay(registry); + + binding1.setDataBindingRegistry(registry); + binding1.init(); + assertNotNull(registry.getDataBinding(Node.class.getName())); + + DataBinding1 binding2 = new DataBinding1("dom", Node.class); + assertEquals("dom", binding2.getName()); + } + + private static class DataBinding1 extends DataBindingExtension { + + /** + * @param baseType + */ + public DataBinding1(Class<?> baseType) { + super(baseType); + } + + /** + * @param name + * @param baseType + */ + public DataBinding1(String name, Class<?> baseType) { + super(name, baseType); + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/databinding/extension/SimpleTypeMapperExtensionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/databinding/extension/SimpleTypeMapperExtensionTestCase.java new file mode 100644 index 0000000000..6ff7909fa3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/databinding/extension/SimpleTypeMapperExtensionTestCase.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.spi.databinding.extension; + +import java.util.HashMap; +import java.util.Map; + +import javax.xml.namespace.NamespaceContext; + +import junit.framework.TestCase; + +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.model.TypeInfo; + +import org.easymock.EasyMock; + +/** + * + */ +public class SimpleTypeMapperExtensionTestCase extends TestCase { + + private static final Map<String, Object> SAMPLE_VALUES = new HashMap<String, Object>(); + + static { + SAMPLE_VALUES.put("anyURI", "http://www.w3.com"); + SAMPLE_VALUES.put("boolean", new String[] {"true", "false", "1", "0"}); + SAMPLE_VALUES.put("byte", new String[] {"-128", "127"}); + SAMPLE_VALUES.put("date", new String[] {"2004-03-15", "2002-09-24-06:00"}); + SAMPLE_VALUES.put("dateTime", "2003-12-25T08:30:00"); + SAMPLE_VALUES.put("decimal", "3.1415292"); + SAMPLE_VALUES.put("double", new String[] {"3.1415292", "INF", "NaN"}); + SAMPLE_VALUES.put("duration", new String[] {"P8M3DT7H33M2S", "P5Y2M10DT15H"}); + SAMPLE_VALUES.put("float", new String[] {"3.1415292", "INF", "NaN"}); + SAMPLE_VALUES.put("gDay", "---11"); + /* + * The value space of xsd:gMonth is the period of one calendar month recurring + * each calendar year (such as the month of April). Its lexical space should + * follow the ISO 8601 syntax for such periods (i.e., -- MM) with an optional + * time zone. + * Tip: There's a typo in the W3C XML Schema Recommendation, in which the format + * is defined as -- MM -- --. Even though an erratum should be published to + * bring the W3C XML Schema inline with ISO 8601, most current schema processors + * expect the (bogus) -- MM -- -- format. + * + * The test might be broken in JDK 1.6 + */ + SAMPLE_VALUES.put("gMonth", "--02--"); + SAMPLE_VALUES.put("gMonthDay", "--02-14"); + SAMPLE_VALUES.put("gYear", "1999"); + SAMPLE_VALUES.put("gYearMonth", "1972-08"); + SAMPLE_VALUES.put("ID", "id-102"); + SAMPLE_VALUES.put("IDREF", "id-102"); + SAMPLE_VALUES.put("IDREFS", "id-102 id-103 id-100"); + SAMPLE_VALUES.put("int", "77"); + SAMPLE_VALUES.put("integer", "77"); + SAMPLE_VALUES.put("long", "214"); + SAMPLE_VALUES.put("negativeInteger", "-123"); + SAMPLE_VALUES.put("nonNegativeInteger", "2"); + SAMPLE_VALUES.put("nonPositiveInteger", "0"); + SAMPLE_VALUES.put("positiveInteger", "500"); + SAMPLE_VALUES.put("short", "476"); + SAMPLE_VALUES.put("string", "Joeseph"); + SAMPLE_VALUES.put("time", "13:02:00"); + SAMPLE_VALUES.put("base64Binary", "TWFu"); + SAMPLE_VALUES.put("hexBinary", "2CDB5F"); + SAMPLE_VALUES.put("QName", "f:foo"); + SAMPLE_VALUES.put("NOTATION", "f:bar"); + } + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + } + + public void testMap() throws Exception { + SimpleTypeMapperExtension extension = new SimpleTypeMapperExtension(); + TransformationContext context = EasyMock.createMock(TransformationContext.class); + Map<Class<?>, Object> metaData = new HashMap<Class<?>, Object>(); + EasyMock.expect(context.getMetadata()).andReturn(metaData).anyTimes(); + EasyMock.replay(context); + + NamespaceContext namespaceContext = EasyMock.createMock(NamespaceContext.class); + EasyMock.expect(namespaceContext.getNamespaceURI(EasyMock.eq("f"))).andReturn("http://foo") + .anyTimes(); + EasyMock.expect(namespaceContext.getPrefix(EasyMock.eq("http://foo"))).andReturn("f").anyTimes(); + EasyMock.replay(namespaceContext); + context.getMetadata().put(NamespaceContext.class, namespaceContext); + for (TypeInfo simpleType : SimpleTypeMapperExtension.XSD_SIMPLE_TYPES.values()) { + String name = simpleType.getQName().getLocalPart(); + Object value = SAMPLE_VALUES.get(name); + if (value instanceof String[]) { + for (String s : (String[])value) { + Object obj = extension.toJavaObject(simpleType, s, context); + String str = extension.toXMLLiteral(simpleType, obj, context); + assertNotNull(str); + // assertTrue("[" + name + "] " + s + " " + str, + // str.contains((String) s)); + } + } else if (value instanceof String) { + Object obj = extension.toJavaObject(simpleType, (String)value, context); + String str = extension.toXMLLiteral(simpleType, obj, context); + assertNotNull(str); + // assertTrue("[" + name + "] " + value + " " + str, + // str.contains((String) value)); + } + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/databinding/extension/TransformerExtensionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/databinding/extension/TransformerExtensionTestCase.java new file mode 100644 index 0000000000..6f5dfc90e2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/databinding/extension/TransformerExtensionTestCase.java @@ -0,0 +1,74 @@ +/* + * 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.spi.databinding.extension; + +import javax.xml.stream.XMLStreamReader; + +import junit.framework.TestCase; + +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.TransformerRegistry; +import org.easymock.EasyMock; +import org.w3c.dom.Node; + +/** + * Test case for TransformerExtension + */ +public class TransformerExtensionTestCase extends TestCase { + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + } + + public void testExtension() { + MyTransformer transformer = new MyTransformer(); + assertEquals(Node.class.getName(), transformer.getSourceDataBinding()); + assertEquals(XMLStreamReader.class.getName(), transformer.getTargetDataBinding()); + assertEquals(50, transformer.getWeight()); + TransformerRegistry registry = EasyMock.createMock(TransformerRegistry.class); + registry.registerTransformer(EasyMock.isA(Transformer.class)); + EasyMock + .expect(registry.getTransformer(transformer.getSourceDataBinding(), transformer.getTargetDataBinding())) + .andReturn(transformer); + EasyMock.replay(registry); + transformer.setTransformerRegistry(registry); + transformer.init(); + assertSame(transformer, registry.getTransformer(transformer.getSourceDataBinding(), transformer + .getTargetDataBinding())); + } + + private static class MyTransformer extends TransformerExtension<Node, XMLStreamReader> { + + @Override + protected Class getSourceType() { + return Node.class; + } + + @Override + protected Class getTargetType() { + return XMLStreamReader.class; + } + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/databinding/extension/XSDDataTypeConverterTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/databinding/extension/XSDDataTypeConverterTestCase.java new file mode 100644 index 0000000000..4693025c11 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/databinding/extension/XSDDataTypeConverterTestCase.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.spi.databinding.extension; + +import java.math.BigInteger; +import java.util.Calendar; +import java.util.GregorianCalendar; + +import junit.framework.TestCase; + +/** + * + */ +public class XSDDataTypeConverterTestCase extends TestCase { + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + } + + public void testConvert() throws Exception { + XSDDataTypeConverter c = new XSDDataTypeConverter(); + assertEquals("123", c.parseAnySimpleType(c.printAnySimpleType("123"))); + assertEquals(true, c.parseBoolean(c.printBoolean(true))); + assertEquals(false, c.parseBoolean(c.printBoolean(false))); + assertEquals(123.0, c.parseDouble(c.printDouble(123.0))); + assertEquals(123.0f, c.parseFloat(c.printFloat(123.0f))); + assertEquals(64, c.parseByte(c.printByte((byte)64))); + assertEquals(123, c.parseInt(c.printInt(123))); + assertEquals(new BigInteger("123456"), c.parseInteger(c.printInteger(new BigInteger("123456")))); + assertEquals(123456L, c.parseLong(c.printLong(123456L))); + assertEquals((short)123, c.parseShort(c.printShort((short)123))); + + Calendar calendar = new GregorianCalendar(); + String s = c.printDate(calendar); + calendar = (GregorianCalendar)c.parseDate(s); + assertEquals(s, c.printDate(calendar)); + + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/event/AbstractEventPublisherTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/event/AbstractEventPublisherTestCase.java new file mode 100644 index 0000000000..6efd61bea6 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/event/AbstractEventPublisherTestCase.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.spi.event; + + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class AbstractEventPublisherTestCase extends TestCase { + EventPublisher publisher; + + public void testFireListener() { + Event event = new TestEvent(); + RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class); + listener.onEvent(EasyMock.same(event)); + EasyMock.expectLastCall(); + EasyMock.replay(listener); + publisher.addListener(listener); + publisher.publish(event); + EasyMock.verify(publisher); + } + + public void testRemoveListener() { + Event event = new TestEvent(); + RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class); + EasyMock.replay(listener); + publisher.addListener(listener); + publisher.removeListener(listener); + publisher.publish(event); + EasyMock.verify(publisher); + } + + public void testFalseFilterListener() { + Event event = new TestEvent(); + RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class); + EasyMock.replay(listener); + publisher.addListener(new FalseFilter(), listener); + publisher.publish(event); + EasyMock.verify(publisher); + } + + public void testTrueFilterListener() { + Event event = new TestEvent(); + RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class); + listener.onEvent(EasyMock.same(event)); + EasyMock.expectLastCall(); + EasyMock.replay(listener); + publisher.addListener(new TrueFilter(), listener); + publisher.publish(event); + EasyMock.verify(publisher); + } + + protected void setUp() throws Exception { + super.setUp(); + publisher = new AbstractEventPublisher() { + }; + } + + private class TestEvent implements Event { + public Object getSource() { + return null; + } + } + + private class FalseFilter implements EventFilter { + + public boolean match(Event event) { + return false; + } + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/AbstractComponentExtensionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/AbstractComponentExtensionTestCase.java new file mode 100644 index 0000000000..382a43f4ca --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/AbstractComponentExtensionTestCase.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.spi.extension; + +import java.net.URI; +import java.util.List; + +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.component.Reference; +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.component.TargetInvokerCreationException; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class AbstractComponentExtensionTestCase extends TestCase { + private Component composite; + + public void testGetService() throws Exception { + Service service = EasyMock.createMock(Service.class); + EasyMock.expect(service.getUri()).andReturn(URI.create("composite#service")).atLeastOnce(); + EasyMock.replay(service); + composite.register(service); + assertNotNull(composite.getService("service")); + } + + public void testGetDefaultService() throws Exception { + Service service = EasyMock.createMock(Service.class); + EasyMock.expect(service.getUri()).andReturn(URI.create("composite#service")).atLeastOnce(); + EasyMock.replay(service); + composite.register(service); + assertNotNull(composite.getService(null)); + } + + public void testGetReference() throws Exception { + Reference reference = EasyMock.createMock(Reference.class); + EasyMock.expect(reference.getUri()).andReturn(URI.create("composite#service")).atLeastOnce(); + EasyMock.replay(reference); + composite.register(reference); + assertNotNull(composite.getReference("service")); + } + + public void testDefaultReference() throws Exception { + Reference reference = EasyMock.createMock(Reference.class); + EasyMock.expect(reference.getUri()).andReturn(URI.create("composite#service")).atLeastOnce(); + EasyMock.replay(reference); + composite.register(reference); + assertNotNull(composite.getReference(null)); + } + + protected void setUp() throws Exception { + super.setUp(); + composite = new AbstractComponentExtension(new URI("foo")) { + + public Scope getScope() { + return null; + } + + public List<Wire> getWires(String name) { + throw new UnsupportedOperationException(); + } + + public void attachWire(Wire wire) { + throw new UnsupportedOperationException(); + } + + public void attachWires(List<Wire> wires) { + throw new UnsupportedOperationException(); + } + + public void attachCallbackWire(Wire wire) { + throw new UnsupportedOperationException(); + } + + public TargetInvoker createTargetInvoker(String targetName, Operation operation) + throws TargetInvokerCreationException { + return null; + } + }; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/AtomicComponentExtensionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/AtomicComponentExtensionTestCase.java new file mode 100644 index 0000000000..ce3bee99f5 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/AtomicComponentExtensionTestCase.java @@ -0,0 +1,99 @@ +/* + * 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.spi.extension; + +import java.net.URI; +import java.util.List; + +import org.apache.tuscany.spi.ObjectCreationException; +import org.apache.tuscany.spi.component.ScopeContainer; +import org.apache.tuscany.spi.component.TargetInvokerCreationException; +import org.apache.tuscany.spi.component.TargetResolutionException; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class AtomicComponentExtensionTestCase extends TestCase { + private AtomicComponentExtension ext; + private URI uri; + + public void testURI() { + assertSame(uri, ext.getUri()); + } + + public void testRemoveInstance() throws Exception { + ScopeContainer scopeContainer = EasyMock.createMock(ScopeContainer.class); + EasyMock.expect(scopeContainer.getScope()).andReturn(Scope.COMPOSITE); + scopeContainer.remove(ext); + EasyMock.replay(scopeContainer); + ext.setScopeContainer(scopeContainer); + ext.removeInstance(); + EasyMock.verify(scopeContainer); + } + + protected void setUp() throws Exception { + super.setUp(); + uri = URI.create("http://example.com/foo"); + ext = new TestExtension(uri); + } + + private static class TestExtension extends AtomicComponentExtension { + + public TestExtension(URI uri) { + super(uri, null, null, 0, -1, -1); + } + + public TargetInvoker createTargetInvoker(String targetName, Operation operation) + throws TargetInvokerCreationException { + throw new AssertionFailedError(); + } + + public List<Wire> getWires(String name) { + throw new AssertionFailedError(); + } + + public void attachWire(Wire wire) { + throw new AssertionFailedError(); + } + + public void attachWires(List<Wire> wires) { + throw new AssertionFailedError(); + } + + public void attachCallbackWire(Wire wire) { + throw new AssertionFailedError(); + } + + public Object createInstance() throws ObjectCreationException { + throw new AssertionFailedError(); + } + + public Object getTargetInstance() throws TargetResolutionException { + throw new AssertionFailedError(); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/ComponentTypeLoaderExtensionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/ComponentTypeLoaderExtensionTestCase.java new file mode 100644 index 0000000000..3aefb37b7f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/ComponentTypeLoaderExtensionTestCase.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.spi.extension; + +import junit.framework.TestCase; +import org.easymock.EasyMock; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.eq; + +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.model.Implementation; + +/** + * @version $Rev$ $Date$ + */ +public class ComponentTypeLoaderExtensionTestCase extends TestCase { + + public void testRegistrationDeregistration() throws Exception { + Extension loader = new Extension(); + LoaderRegistry registry = createMock(LoaderRegistry.class); + registry.registerLoader(eq(Implementation.class), eq(loader)); + registry.unregisterLoader(eq(Implementation.class)); + EasyMock.replay(registry); + loader.setLoaderRegistry(registry); + loader.start(); + loader.stop(); + } + + + private class Extension extends ComponentTypeLoaderExtension<Implementation> { + + protected Class<Implementation> getImplementationClass() { + return Implementation.class; + } + + public void load(Implementation implementation, DeploymentContext context) throws LoaderException { + + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/CompositeComponentExtensionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/CompositeComponentExtensionTestCase.java new file mode 100644 index 0000000000..bf7bdc1f6f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/CompositeComponentExtensionTestCase.java @@ -0,0 +1,81 @@ +/* + * 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.spi.extension; + +import java.lang.reflect.Type; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.spi.component.Service; +import org.apache.tuscany.spi.component.ServiceBinding; +import org.apache.tuscany.spi.component.Component; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class CompositeComponentExtensionTestCase extends TestCase { + private Component composite; + + + public void testCreateTargetInvoker() throws Exception { + ServiceBinding binding = EasyMock.createMock(ServiceBinding.class); + EasyMock.expect(binding.createTargetInvoker(EasyMock.eq("service"), EasyMock.isA(Operation.class))) + .andReturn(null); + EasyMock.replay(binding); + List<ServiceBinding> bindings = new ArrayList<ServiceBinding>(); + bindings.add(binding); + Service service = EasyMock.createMock(Service.class); + EasyMock.expect(service.getUri()).andReturn(URI.create("composite#service")).atLeastOnce(); + EasyMock.expect(service.getServiceBindings()).andReturn(bindings).atLeastOnce(); + EasyMock.replay(service); + composite.register(service); + Operation<Type> operation = new Operation<Type>("op", null, null, null); + composite.createTargetInvoker("service", operation); + EasyMock.verify(binding); + + } + + protected void setUp() throws Exception { + super.setUp(); + composite = new CompositeComponentExtension(new URI("foo")) { + + public List<Wire> getWires(String name) { + throw new UnsupportedOperationException(); + } + + public void attachWire(Wire wire) { + throw new UnsupportedOperationException(); + } + + public void attachWires(List<Wire> wires) { + throw new UnsupportedOperationException(); + } + + public void attachCallbackWire(Wire wire) { + throw new UnsupportedOperationException(); + } + }; + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/LoaderExtensionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/LoaderExtensionTestCase.java new file mode 100644 index 0000000000..bf6e1d998d --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/LoaderExtensionTestCase.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.spi.extension; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +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.model.ModelObject; + +import junit.framework.TestCase; +import org.easymock.EasyMock; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.isA; + +/** + * @version $Rev$ $Date$ + */ +public class LoaderExtensionTestCase extends TestCase { + + @SuppressWarnings("unchecked") + public void testRegistrationDeregistration() throws Exception { + LoaderRegistry registry = EasyMock.createMock(LoaderRegistry.class); + registry.registerLoader(isA(QName.class), isA(Extension.class)); + expectLastCall(); + registry.unregisterLoader(isA(QName.class), isA(Extension.class)); + expectLastCall(); + EasyMock.replay(registry); + Extension loader = new Extension(registry); + loader.start(); + loader.stop(); + } + + + private static class Extension extends LoaderExtension { + + public Extension(LoaderRegistry registry) { + super(registry); + } + + public QName getXMLType() { + return new QName(""); + } + + public ModelObject load( + ModelObject object, XMLStreamReader reader, + DeploymentContext deploymentContext) throws XMLStreamException, LoaderException { + throw new AssertionError(); + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/TargetInvokerExtensionSequenceTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/TargetInvokerExtensionSequenceTestCase.java new file mode 100644 index 0000000000..2691e06f3c --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/TargetInvokerExtensionSequenceTestCase.java @@ -0,0 +1,169 @@ +/* + * 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.spi.extension; + +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.LinkedList; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class TargetInvokerExtensionSequenceTestCase extends TestCase { + + @SuppressWarnings("unchecked") + public void testStart() { + URI from = URI.create("foo"); + Wire wire = EasyMock.createMock(Wire.class); + EasyMock.replay(wire); + WorkContext context; + context = EasyMock.createMock(WorkContext.class); + context.setCallbackUris(EasyMock.isA(LinkedList.class)); + EasyMock.replay(context); + ExecutionMonitor monitor = EasyMock.createNiceMock(ExecutionMonitor.class); + Target target = EasyMock.createMock(Target.class); + target.invokeStart("test"); + EasyMock.replay(target); + Invoker invoker = new Invoker(context, monitor, target); + Message msg = new MessageImpl(); + msg.pushCallbackUri(from); + msg.setBody("test"); + msg.setConversationSequence(Invoker.START); + invoker.invoke(msg); + EasyMock.verify(wire); + EasyMock.verify(context); + EasyMock.verify(target); + } + + @SuppressWarnings("unchecked") + public void testContinue() { + URI from = URI.create("foo"); + Wire wire = EasyMock.createMock(Wire.class); + EasyMock.replay(wire); + WorkContext context; + context = EasyMock.createMock(WorkContext.class); + context.setCallbackUris(EasyMock.isA(LinkedList.class)); + EasyMock.replay(context); + ExecutionMonitor monitor = EasyMock.createNiceMock(ExecutionMonitor.class); + Target target = EasyMock.createMock(Target.class); + target.invokeContinue("test"); + EasyMock.replay(target); + Invoker invoker = new Invoker(context, monitor, target); + Message msg = new MessageImpl(); + msg.pushCallbackUri(from); + msg.setBody("test"); + msg.setConversationSequence(Invoker.CONTINUE); + invoker.invoke(msg); + EasyMock.verify(wire); + EasyMock.verify(context); + EasyMock.verify(target); + } + + @SuppressWarnings("unchecked") + public void testEnd() { + URI from = URI.create("foo"); + Wire wire = EasyMock.createMock(Wire.class); + EasyMock.replay(wire); + WorkContext context; + context = EasyMock.createMock(WorkContext.class); + context.setCallbackUris(EasyMock.isA(LinkedList.class)); + EasyMock.replay(context); + ExecutionMonitor monitor = EasyMock.createNiceMock(ExecutionMonitor.class); + Target target = EasyMock.createMock(Target.class); + target.invokeEnd("test"); + EasyMock.replay(target); + Invoker invoker = new Invoker(context, monitor, target); + Message msg = new MessageImpl(); + msg.pushCallbackUri(from); + msg.setBody("test"); + msg.setConversationSequence(Invoker.END); + invoker.invoke(msg); + EasyMock.verify(wire); + EasyMock.verify(context); + EasyMock.verify(target); + } + + @SuppressWarnings("unchecked") + public void testNone() { + URI from = URI.create("foo"); + Wire wire = EasyMock.createMock(Wire.class); + EasyMock.replay(wire); + WorkContext context; + context = EasyMock.createMock(WorkContext.class); + context.setCallbackUris(EasyMock.isA(LinkedList.class)); + EasyMock.replay(context); + ExecutionMonitor monitor = EasyMock.createNiceMock(ExecutionMonitor.class); + Target target = EasyMock.createMock(Target.class); + target.invokeNone("test"); + EasyMock.replay(target); + Invoker invoker = new Invoker(context, monitor, target); + Message msg = new MessageImpl(); + msg.pushCallbackUri(from); + msg.setBody("test"); + invoker.invoke(msg); + EasyMock.verify(wire); + EasyMock.verify(context); + EasyMock.verify(target); + } + + protected void setUp() throws Exception { + super.setUp(); + + } + + private class Invoker extends TargetInvokerExtension { + private Target target; + + public Invoker(WorkContext workContext, ExecutionMonitor monitor, Target target) { + super(workContext); + this.target = target; + } + + public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException { + if (sequence == NONE) { + target.invokeNone((String) payload); + } else if (sequence == START) { + target.invokeStart((String) payload); + } else if (sequence == CONTINUE) { + target.invokeContinue((String) payload); + } else if (sequence == END) { + target.invokeEnd((String) payload); + } + return null; + } + } + + private interface Target { + void invokeStart(String msg); + + void invokeContinue(String msg); + + void invokeEnd(String msg); + + void invokeNone(String msg); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/TargetInvokerExtensionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/TargetInvokerExtensionTestCase.java new file mode 100644 index 0000000000..262cb2413f --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/extension/TargetInvokerExtensionTestCase.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.spi.extension; + +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.LinkedList; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class TargetInvokerExtensionTestCase extends TestCase { + + @SuppressWarnings("unchecked") + public void testNonBlockingDispatch() { + URI from = URI.create("foo"); + Wire wire = EasyMock.createMock(Wire.class); + EasyMock.replay(wire); + WorkContext context; + context = EasyMock.createMock(WorkContext.class); + context.setCallbackUris(EasyMock.isA(LinkedList.class)); + EasyMock.replay(context); + ExecutionMonitor monitor = EasyMock.createNiceMock(ExecutionMonitor.class); + Target target = EasyMock.createMock(Target.class); + target.invoke("test"); + EasyMock.replay(target); + Invoker invoker = new Invoker(context, monitor, target); + Message msg = new MessageImpl(); + msg.pushCallbackUri(from); + msg.setBody("test"); + invoker.invoke(msg); + EasyMock.verify(wire); + EasyMock.verify(context); + EasyMock.verify(target); + } + + protected void setUp() throws Exception { + super.setUp(); + + } + + private class Invoker extends TargetInvokerExtension { + private Target target; + + public Invoker(WorkContext workContext, ExecutionMonitor monitor, Target target) { + super(workContext); + this.target = target; + } + + public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException { + target.invoke((String) payload); + return null; + } + } + + private interface Target { + void invoke(String msg); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/idl/java/JavaIDLUtilsTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/idl/java/JavaIDLUtilsTestCase.java new file mode 100644 index 0000000000..e50c1e32a2 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/idl/java/JavaIDLUtilsTestCase.java @@ -0,0 +1,178 @@ +/* + * 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.spi.idl.java; + +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +import static org.apache.tuscany.spi.idl.java.JavaIDLUtils.findMethod; +import static org.apache.tuscany.spi.idl.java.JavaIDLUtils.findOperation; +import org.apache.tuscany.spi.model.DataType; +import org.apache.tuscany.spi.model.Operation; +import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class JavaIDLUtilsTestCase extends TestCase { + private Method[] methods; + private List<Operation<?>> operations; + + public void testNoParamsFindMethod() { + List<DataType<Type>> types = new ArrayList<DataType<Type>>(); + DataType<List<DataType<Type>>> inputType = new DataType<List<DataType<Type>>>(Object[].class, types); + Operation<Type> operation = new Operation<Type>("foo", inputType, null, null, false, null, NO_CONVERSATION); + Method method = findMethod(operation, methods); + assertEquals("foo", method.getName()); + assertEquals(0, method.getParameterTypes().length); + } + + public void testNoParamsFindOperation() throws Exception { + Method method = Foo.class.getMethod("foo"); + Operation ret = findOperation(method, operations); + assertEquals("foo", ret.getName()); + assertEquals(0, method.getParameterTypes().length); + } + + public void testParamsFindMethod() { + List<DataType<Type>> types = new ArrayList<DataType<Type>>(); + DataType<Type> type = new DataType<Type>(String.class, Object.class); + types.add(type); + DataType<List<DataType<Type>>> inputType = new DataType<List<DataType<Type>>>(Object[].class, types); + Operation<Type> operation = new Operation<Type>("foo", inputType, null, null, false, null, NO_CONVERSATION); + Method method = findMethod(operation, methods); + assertEquals("foo", method.getName()); + assertEquals(String.class, method.getParameterTypes()[0]); + } + + public void testParamsFindOperation() throws Exception { + Method method = Foo.class.getMethod("foo", String.class); + Operation ret = findOperation(method, operations); + assertEquals("foo", ret.getName()); + assertEquals(String.class, method.getParameterTypes()[0]); + } + + + public void testTooManyParamsFindMethod() { + List<DataType<Type>> types = new ArrayList<DataType<Type>>(); + DataType<Type> type = new DataType<Type>(String.class, Object.class); + DataType<Type> type2 = new DataType<Type>(String.class, Object.class); + types.add(type); + types.add(type2); + DataType<List<DataType<Type>>> inputType = new DataType<List<DataType<Type>>>(Object[].class, types); + Operation<Type> operation = new Operation<Type>("foo", inputType, null, null, false, null, NO_CONVERSATION); + Method method = findMethod(operation, methods); + assertNull(method); + } + + public void testDifferentParamsFindMethod() { + List<DataType<Type>> types = new ArrayList<DataType<Type>>(); + DataType<Type> type = new DataType<Type>(Integer.class, Object.class); + types.add(type); + DataType<List<DataType<Type>>> inputType = new DataType<List<DataType<Type>>>(Object[].class, types); + Operation<Type> operation = new Operation<Type>("foo", inputType, null, null, false, null, NO_CONVERSATION); + Method method = findMethod(operation, methods); + assertNull(method); + } + + public void testPrimitiveParamNoFindMethod() { + List<DataType<Type>> types = new ArrayList<DataType<Type>>(); + DataType<Type> type = new DataType<Type>(Integer.class, Object.class); + types.add(type); + DataType<List<DataType<Type>>> inputType = new DataType<List<DataType<Type>>>(Object[].class, types); + Operation<Type> operation = new Operation<Type>("foo", inputType, null, null, false, null, NO_CONVERSATION); + Method method = findMethod(operation, methods); + assertNull(method); + } + + public void testPrimitiveParamFindMethod() { + List<DataType<Type>> types = new ArrayList<DataType<Type>>(); + DataType<Type> type = new DataType<Type>(Integer.TYPE, Object.class); + types.add(type); + DataType<List<DataType<Type>>> inputType = new DataType<List<DataType<Type>>>(Object[].class, types); + Operation<Type> operation = new Operation<Type>("foo", inputType, null, null, false, null, NO_CONVERSATION); + Method method = findMethod(operation, methods); + assertEquals("foo", method.getName()); + assertEquals(Integer.TYPE, method.getParameterTypes()[0]); + } + + public void testPrimitiveParamFindOperation() throws NoSuchMethodException { + Method method = Foo.class.getMethod("foo", Integer.TYPE); + Operation<?> operation = findOperation(method, operations); + assertEquals(Integer.TYPE, operation.getInputType().getLogical().get(0).getPhysical()); + } + + + public void testNotFoundMethod() { + Operation<Type> operation = new Operation<Type>("not there", null, null, null, false, null, NO_CONVERSATION); + assertNull(findMethod(operation, methods)); + } + + protected void setUp() throws Exception { + super.setUp(); + methods = Foo.class.getMethods(); + + Operation<Type> operation = new Operation<Type>("foo", null, null, null, false, null, NO_CONVERSATION); + operations = new ArrayList<Operation<?>>(); + operations.add(operation); + + List<DataType<Type>> types = new ArrayList<DataType<Type>>(); + DataType<List<DataType<Type>>> inputType = new DataType<List<DataType<Type>>>(Object[].class, types); + DataType<Type> type = new DataType<Type>(String.class, Object.class); + types.add(type); + operation = new Operation<Type>("foo", inputType, null, null, false, null, NO_CONVERSATION); + operations.add(operation); + + types = new ArrayList<DataType<Type>>(); + type = new DataType<Type>(String.class, Object.class); + DataType<Type> type2 = new DataType<Type>(String.class, Object.class); + types.add(type); + types.add(type2); + inputType = new DataType<List<DataType<Type>>>(Object[].class, types); + operation = new Operation<Type>("foo", inputType, null, null, false, null, NO_CONVERSATION); + operations.add(operation); + + types = new ArrayList<DataType<Type>>(); + type = new DataType<Type>(Integer.class, Object.class); + types.add(type); + inputType = new DataType<List<DataType<Type>>>(Object[].class, types); + operation = new Operation<Type>("foo", inputType, null, null, false, null, NO_CONVERSATION); + operations.add(operation); + + types = new ArrayList<DataType<Type>>(); + type = new DataType<Type>(Integer.TYPE, Object.class); + types.add(type); + inputType = new DataType<List<DataType<Type>>>(Object[].class, types); + operation = new Operation<Type>("foo", inputType, null, null, false, null, NO_CONVERSATION); + operations.add(operation); + + } + + private interface Foo { + void foo(); + + void foo(String foo); + + void foo(int b); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/implementation/java/AbstractPropertyProcessorTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/implementation/java/AbstractPropertyProcessorTestCase.java new file mode 100644 index 0000000000..45a3bd4d68 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/implementation/java/AbstractPropertyProcessorTestCase.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.spi.implementation.java; + +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.List; + +import org.apache.tuscany.spi.ObjectFactory; +import org.apache.tuscany.spi.deployer.DeploymentContext; + +import junit.framework.TestCase; +import org.easymock.EasyMock; +import org.easymock.IAnswer; + +/** + * @version $Rev$ $Date$ + */ +public class AbstractPropertyProcessorTestCase extends TestCase { + + private ImplementationProcessor processor; + + + public void testVisitMethod() throws Exception { + Method method = Foo.class.getMethod("setBar", String.class); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitMethod(method, type, null); + JavaMappedProperty<?> prop = type.getProperties().get("test"); + assertNotNull(prop.getDefaultValueFactory()); + } + + public void testVisitNoParamsMethod() throws Exception { + Method method = Foo.class.getMethod("setNoParamsBar"); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + try { + processor.visitMethod(method, type, null); + fail(); + } catch (IllegalPropertyException e) { + //expected + } + } + + public void testVisitNonVoidMethod() throws Exception { + Method method = Foo.class.getMethod("setBadBar", String.class); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + try { + processor.visitMethod(method, type, null); + fail(); + } catch (IllegalPropertyException e) { + //expected + } + } + + public void testDuplicateMethod() throws Exception { + Method method = Foo.class.getMethod("setBar", String.class); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitMethod(method, type, null); + try { + processor.visitMethod(method, type, null); + fail(); + } catch (DuplicatePropertyException e) { + //expected + } + } + + public void testVisitField() throws Exception { + Field field = Foo.class.getDeclaredField("d"); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitField(field, type, null); + JavaMappedProperty<?> prop = type.getProperties().get("test"); + assertNotNull(prop.getDefaultValueFactory()); + } + + public void testVisitConstructor() throws Exception { + Constructor<Foo> ctor = Foo.class.getConstructor(String.class); + PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type = + new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(); + processor.visitConstructor(ctor, type, null); + ConstructorDefinition def = type.getConstructorDefinition(); + assertEquals("test", def.getInjectionNames().get(0)); + assertNotNull(type.getProperties().get("test")); + } + + @SuppressWarnings("unchecked") + protected void setUp() throws Exception { + super.setUp(); + ImplementationProcessorService service = EasyMock.createMock(ImplementationProcessorService.class); + service.addName(EasyMock.isA(List.class), EasyMock.eq(0), EasyMock.eq("test")); + EasyMock.expectLastCall().andStubAnswer(new IAnswer() { + public Object answer() throws Throwable { + ((List<Object>) EasyMock.getCurrentArguments()[0]).add("test"); + return null; + } + }); + EasyMock.replay(service); + processor = new TestProcessor(service); + } + + @Retention(RUNTIME) + private @interface Bar { + + } + + private class TestProcessor extends AbstractPropertyProcessor<Bar> { + + public TestProcessor(ImplementationProcessorService service) { + super(Bar.class, service); + } + + @SuppressWarnings("unchecked") + protected <T> void initProperty(JavaMappedProperty<T> property, + Bar annotation, + DeploymentContext context) { + property.setDefaultValueFactory(EasyMock.createMock(ObjectFactory.class)); + property.setName("test"); + } + + protected String getName(Bar annotation) { + return "test"; + } + } + + + private static class Foo { + + @Bar + protected String d; + + public Foo(String a, @Bar String b) { + } + + public Foo(@Bar String d) { + this.d = d; + } + + @Bar + public void setBar(String d) { + this.d = d; + } + + @Bar + public void setNoParamsBar() { + } + + @Bar + public String setBadBar(String d) { + return null; + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/loader/LoaderExceptionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/loader/LoaderExceptionTestCase.java new file mode 100644 index 0000000000..f8c991f7d4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/loader/LoaderExceptionTestCase.java @@ -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. + */ +package org.apache.tuscany.spi.loader; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class LoaderExceptionTestCase extends TestCase { + + public void testResourceURI() throws Exception { + LoaderException e = new LoaderException(); + e.setResourceURI("test"); + assertEquals("test", e.getResourceURI()); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/ComponentTypeTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/ComponentTypeTestCase.java new file mode 100644 index 0000000000..c7170e0597 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/ComponentTypeTestCase.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.spi.model; + +import java.net.URI; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class ComponentTypeTestCase extends TestCase { + + /** + * Verifies fragments are used to retrieve service names + */ + public void testSetServiceName() { + ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + ServiceDefinition definition = new ServiceDefinition(); + definition.setUri(URI.create("foo#bar")); + type.add(definition); + assertEquals(definition, type.getServices().get("bar")); + } + + /** + * Verifies fragments are used to retrieve service names + */ + public void testSetReferenceName() { + ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>> type = + new ComponentType<ServiceDefinition, ReferenceDefinition, Property<?>>(); + ReferenceDefinition definition = new ReferenceDefinition(); + definition.setUri(URI.create("foo#bar")); + type.add(definition); + assertEquals(definition, type.getReferences().get("bar")); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/CompositeComponentTypeTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/CompositeComponentTypeTestCase.java new file mode 100644 index 0000000000..d348d2b3c8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/CompositeComponentTypeTestCase.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.spi.model;
+
+import junit.framework.TestCase;
+
+public class CompositeComponentTypeTestCase extends TestCase {
+
+ public void testWireCreationAndRetrieval() throws Exception {
+ WireDefinition wire1 = new WireDefinition();
+ WireDefinition wire2 = new WireDefinition();
+
+ CompositeComponentType composite = new CompositeComponentType();
+ CompositeComponentType includedComposite = new CompositeComponentType();
+ includedComposite.add(wire1);
+ Include compositeInclude = new Include();
+ compositeInclude.setIncluded(includedComposite);
+
+ composite.add(compositeInclude);
+ composite.add(wire1);
+
+ assertEquals(1, composite.getDeclaredWires().size());
+ assertEquals(wire1, composite.getDeclaredWires().get(0));
+ assertEquals(2, composite.getWires().size());
+ }
+
+}
diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/IntentNameTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/IntentNameTestCase.java new file mode 100644 index 0000000000..698b7835d9 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/IntentNameTestCase.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.spi.model; + +import java.util.Arrays; + +import junit.framework.TestCase; + +public class IntentNameTestCase extends TestCase { + + public void testConstructor() throws Exception { + String case1 = "sec.confidentiality/message/body"; + IntentName intentName = new IntentName(case1); + assertEquals("sec", intentName.getDomain()); + assertEquals(case1, intentName.toString()); + assertTrue(Arrays.equals(new String[]{"confidentiality", "message", "body"}, intentName.getQualifiedNames())); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/OperationTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/OperationTestCase.java new file mode 100644 index 0000000000..de5f1719b0 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/OperationTestCase.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.spi.model; + +import java.util.ArrayList; +import java.util.List; + +import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class OperationTestCase extends TestCase { + + public void testClone() throws Exception { + DataType<Class> stringType = new DataType<Class>("xml:string", String.class, String.class); + List<DataType<Class>> inputTypes = new ArrayList<DataType<Class>>(); + inputTypes.add(stringType); + DataType<List<DataType<Class>>> inputType = + new DataType<List<DataType<Class>>>("xml:string", Object[].class, inputTypes); + + DataType<Class> faultType = new DataType<Class>("xml:foo", String.class, String.class); + List<DataType<Class>> faultTypes = new ArrayList<DataType<Class>>(); + faultTypes.add(faultType); + + Operation<Class> operation1 = + new Operation<Class>("call", inputType, stringType, faultTypes, true, "xml:string", NO_CONVERSATION); + Operation<Class> operation2 = operation1.clone(); + assertEquals(operation1, operation2); + assertEquals(NO_CONVERSATION, operation2.getConversationSequence()); + assertEquals("call", operation2.getName()); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/ScopeTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/ScopeTestCase.java new file mode 100644 index 0000000000..a8a88626ec --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/ScopeTestCase.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.spi.model; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class ScopeTestCase extends TestCase { + + public void testEquals() throws Exception { + Scope scope = new Scope("COMPOSITE"); + assertTrue(scope.equals(Scope.COMPOSITE)); + } + + public void testEqualsNew() throws Exception { + Scope foo = new Scope("foo"); + Scope foo2 = new Scope("FOO"); + assertTrue(foo.equals(foo2)); + } + + public void testNotEquals() throws Exception { + Scope foo = new Scope("BAR"); + Scope foo2 = new Scope("FOO"); + assertFalse(foo.equals(foo2)); + } + + public void testNotEqualsDifferent() throws Exception { + Scope foo = new Scope("FOO"); + assertFalse(foo.equals(new Bar("FOO"))); + } + + public class Bar { + private String scope; + + public Bar(String scope) { + this.scope = scope; + } + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/ServiceContractTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/ServiceContractTestCase.java new file mode 100644 index 0000000000..4cf98d1542 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/model/ServiceContractTestCase.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.spi.model; + +import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION; + +import java.util.Map; +import java.util.HashMap; +import java.lang.reflect.Type; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class ServiceContractTestCase extends TestCase { + + @SuppressWarnings("unchecked") + public void testAddOperation() throws Exception { + ServiceContract<Type> contract = new TestContract(); + Operation<Type> operation = new Operation<Type>("foo", null, null, null, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> ops = new HashMap<String, Operation<Type>>(); + ops.put("foo", operation); + contract.setOperations(ops); + assertEquals(contract, operation.getServiceContract()); + assertFalse(operation.isCallback()); + } + + public void testAddCallbackOperation() throws Exception { + ServiceContract<Type> contract = new TestContract(); + Operation<Type> operation = new Operation<Type>("foo", null, null, null, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> ops = new HashMap<String, Operation<Type>>(); + ops.put("foo", operation); + contract.setCallbackOperations(ops); + assertEquals(contract, operation.getServiceContract()); + assertTrue(operation.isCallback()); + } + + @SuppressWarnings("unchecked") + public void testClone() throws Exception { + ServiceContract<Type> contract = new TestContract(); + Operation<Type> operation = new Operation<Type>("foo", null, null, null, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> ops = new HashMap<String, Operation<Type>>(); + ops.put("foo", operation); + contract.setOperations(ops); + + operation = new Operation<Type>("bar", null, null, null, false, null, NO_CONVERSATION); + Map<String, Operation<Type>> callbackOps = new HashMap<String, Operation<Type>>(); + ops.put("bar", operation); + contract.setCallbackOperations(callbackOps); + + ServiceContract<Type> copy = (ServiceContract<Type>) contract.clone(); + assertEquals(contract, copy); + } + + + private class TestContract extends ServiceContract<Type> { + + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/policy/SourcePolicyBuilderExtensionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/policy/SourcePolicyBuilderExtensionTestCase.java new file mode 100644 index 0000000000..be0d96f3ea --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/policy/SourcePolicyBuilderExtensionTestCase.java @@ -0,0 +1,51 @@ +/* + * 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.spi.policy; + +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.model.ReferenceDefinition; +import static org.apache.tuscany.spi.policy.PolicyBuilderRegistry.EXTENSION; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + * @deprecated + */ +public class SourcePolicyBuilderExtensionTestCase extends TestCase { + + public void testRegister() throws Exception { + PolicyBuilderRegistry registry = EasyMock.createMock(PolicyBuilderRegistry.class); + registry.registerSourceBuilder(EasyMock.eq(EXTENSION), EasyMock.isA(MockPolicyBuilderExtension.class)); + EasyMock.replay(registry); + SourcePolicyBuilderExtension extension = new MockPolicyBuilderExtension(); + extension.setRegistry(registry); + extension.init(); + EasyMock.verify(registry); + } + + private static class MockPolicyBuilderExtension extends SourcePolicyBuilderExtension { + + public void build(ReferenceDefinition definition, Wire wire) throws BuilderException { + + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/policy/TargetPolicyBuilderExtensionTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/policy/TargetPolicyBuilderExtensionTestCase.java new file mode 100644 index 0000000000..a044f6e507 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/policy/TargetPolicyBuilderExtensionTestCase.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.spi.policy; + +import org.apache.tuscany.spi.builder.BuilderException; +import org.apache.tuscany.spi.model.ServiceDefinition; +import static org.apache.tuscany.spi.policy.PolicyBuilderRegistry.EXTENSION; +import org.apache.tuscany.spi.wire.Wire; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class TargetPolicyBuilderExtensionTestCase extends TestCase { + + public void testRegister() throws Exception { + PolicyBuilderRegistry registry = EasyMock.createMock(PolicyBuilderRegistry.class); + registry.registerTargetBuilder(EasyMock.eq(EXTENSION), EasyMock.isA(MockPolicyBuilderExtension.class)); + EasyMock.replay(registry); + TargetPolicyBuilderExtension extension = new MockPolicyBuilderExtension(); + extension.setRegistry(registry); + extension.init(); + EasyMock.verify(registry); + } + + private static class MockPolicyBuilderExtension extends TargetPolicyBuilderExtension { + + public void build(ServiceDefinition definition, Wire wire) throws BuilderException { + + } + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/util/URIHelperTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/util/URIHelperTestCase.java new file mode 100644 index 0000000000..832e3eb3a8 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/util/URIHelperTestCase.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.spi.util; + +import java.net.URI; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +public class URIHelperTestCase extends TestCase { + + public void testBaseName() throws Exception { + URI uri = new URI("foo"); + assertEquals("foo", UriHelper.getBaseName(uri)); + } + + public void testBaseNameScheme() throws Exception { + URI uri = new URI("sca://foo"); + assertEquals("foo", UriHelper.getBaseName(uri)); + } + + public void testBaseNameSchemePath() throws Exception { + URI uri = new URI("sca://bar/foo"); + assertEquals("foo", UriHelper.getBaseName(uri)); + } + + public void testBaseNamePath() throws Exception { + URI uri = new URI("bar/foo"); + assertEquals("foo", UriHelper.getBaseName(uri)); + } + + public void testBaseNameFragment() throws Exception { + URI uri = new URI("#foo"); + assertEquals("#foo", UriHelper.getBaseName(uri)); + } + + public void testDefragmentedNameScheme() throws Exception { + URI uri = new URI("sca://foo/bar#bar"); + assertEquals("sca://foo/bar", UriHelper.getDefragmentedName(uri).toString()); + } + + public void testDefragmentedName() throws Exception { + URI uri = new URI("foo/bar#bar"); + assertEquals("foo/bar", UriHelper.getDefragmentedName(uri).toString()); + } + + public void testDefragmentedNoName() throws Exception { + URI uri = new URI("#bar"); + assertEquals("", UriHelper.getDefragmentedName(uri).toString()); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/util/stax/StaxUtilTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/util/stax/StaxUtilTestCase.java new file mode 100644 index 0000000000..87be31b23b --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/util/stax/StaxUtilTestCase.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.spi.util.stax; + +import java.io.InputStream; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import junit.framework.TestCase; + +/** + * Test case for StaxHelper + * + * @version $Revision$ $Date$ + * + */ +public class StaxUtilTestCase extends TestCase { + + public StaxUtilTestCase(String name) { + super(name); + } + + public void testSerialize() throws XMLStreamException { + + InputStream in = getClass().getClassLoader().getResourceAsStream("test.scdl"); + XMLStreamReader reader = StaxUtil.createReader(in); + StaxUtil.serialize(reader); + // TODO Do assertions + } + + public void testGetDocumentElementQName() throws XMLStreamException { + InputStream in = getClass().getClassLoader().getResourceAsStream("test.scdl"); + XMLStreamReader reader = StaxUtil.createReader(in); + String xml = StaxUtil.serialize(reader); + QName qname = StaxUtil.getDocumentElementQName(xml); + assertEquals("http://www.osoa.org/xmlns/sca/1.0", qname.getNamespaceURI()); + assertEquals("composite", qname.getLocalPart()); + } + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/wire/AbstractInvocationHandlerTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/wire/AbstractInvocationHandlerTestCase.java new file mode 100644 index 0000000000..1b1b550ad3 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/wire/AbstractInvocationHandlerTestCase.java @@ -0,0 +1,121 @@ +/* + * 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.spi.wire; + +import java.lang.reflect.Array; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.LinkedList; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class AbstractInvocationHandlerTestCase extends TestCase { + + public void testInvocation() throws Throwable { + InvocationHandler handler = new InvocationHandler(); + Interceptor interceptor = new MockInterceptor(); + TargetInvoker invoker = EasyMock.createMock(TargetInvoker.class); + EasyMock.replay(invoker); + InvocationChain chain = EasyMock.createMock(InvocationChain.class); + EasyMock.expect(chain.getHeadInterceptor()).andReturn(interceptor); + EasyMock.replay(chain); + Object resp = handler.invoke(chain, invoker, new String[]{"foo"}, null, new LinkedList<URI>()); + assertEquals("response", resp); + } + + public void testShortCircuitInvocation() throws Throwable { + InvocationHandler handler = new InvocationHandler(); + TargetInvoker invoker = new MockInvoker(); + InvocationChain chain = EasyMock.createMock(InvocationChain.class); + EasyMock.expect(chain.getHeadInterceptor()).andReturn(null); + EasyMock.expect(chain.getTargetInvoker()).andReturn(invoker); + EasyMock.replay(chain); + Object resp = handler.invoke(chain, invoker, new String[]{"foo"}, null, new LinkedList<URI>()); + assertEquals("response", resp); + } + + + private class MockInvoker implements TargetInvoker { + + public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException { + assertEquals("foo", Array.get(payload, 0)); + return "response"; + } + + public Message invoke(Message msg) throws InvocationRuntimeException { + fail(); + return null; + } + + public boolean isCacheable() { + return false; + } + + public void setCacheable(boolean cacheable) { + + } + + public boolean isOptimizable() { + return false; + } + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } + + private class InvocationHandler extends AbstractInvocationHandler { + + protected URI getFromAddress() { + return URI.create("from"); + } + + } + + private class MockInterceptor implements Interceptor { + + public Message invoke(Message msg) { + assertNotNull(msg.getCorrelationId()); + assertNotNull(msg.getTargetInvoker()); + assertNotNull(msg.getMessageId()); + assertNotNull(msg.getCallbackUris()); + assertEquals("foo", Array.get(msg.getBody(), 0)); + msg.setBody("response"); + return msg; + } + + public void setNext(Interceptor next) { + + } + + public Interceptor getNext() { + return null; + } + + public boolean isOptimizable() { + return false; + } + } + + +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/wire/ChainHolderTestCase.java b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/wire/ChainHolderTestCase.java new file mode 100644 index 0000000000..9b67ec53e4 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/java/org/apache/tuscany/spi/wire/ChainHolderTestCase.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.spi.wire; + +import junit.framework.TestCase; +import org.easymock.EasyMock; + +/** + * @version $Rev$ $Date$ + */ +public class ChainHolderTestCase extends TestCase { + + public void testClone() { + InvocationChain chain = EasyMock.createMock(InvocationChain.class); + EasyMock.replay(chain); + ChainHolder holder = new ChainHolder(chain); + assertNotNull(holder.clone()); + } +} diff --git a/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/resources/test.scdl b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/resources/test.scdl new file mode 100644 index 0000000000..337ec02f06 --- /dev/null +++ b/sca-java-1.x/tags/kernel/2.0-alpha-incubating/spi/src/test/resources/test.scdl @@ -0,0 +1,34 @@ +<?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. +--> +<!-- + Test for stax. + + $Rev$ $Date$ +--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://tuscany.apache.org/xmlns/sca/system/2.0-alpha" + name="test.scdl"> + + <component name="test.component"> + <system:implementation.system class="test.class"/> + <property name="testProperty">123</property> + </component> + +</composite> |