diff options
author | dims <dims@13f79535-47bb-0310-9956-ffa450edef68> | 2008-06-17 00:23:01 +0000 |
---|---|---|
committer | dims <dims@13f79535-47bb-0310-9956-ffa450edef68> | 2008-06-17 00:23:01 +0000 |
commit | bdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a (patch) | |
tree | 38a92061c0793434c4be189f1d70c3458b6bc41d /branches/sca-java-0.99/modules/contribution-impl |
Move Tuscany from Incubator to top level.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'branches/sca-java-0.99/modules/contribution-impl')
43 files changed, 4247 insertions, 0 deletions
diff --git a/branches/sca-java-0.99/modules/contribution-impl/.checkstyle b/branches/sca-java-0.99/modules/contribution-impl/.checkstyle new file mode 100644 index 0000000000..ace5fe6f53 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/.checkstyle @@ -0,0 +1,25 @@ +<?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="Sun Checks" local="false">
+ <file-match-pattern match-pattern="." include-pattern="true"/>
+ </fileset>
+</fileset-config>
diff --git a/branches/sca-java-0.99/modules/contribution-impl/.pmd b/branches/sca-java-0.99/modules/contribution-impl/.pmd new file mode 100644 index 0000000000..84af2f4d5d --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/.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/branches/sca-java-0.99/modules/contribution-impl/.ruleset b/branches/sca-java-0.99/modules/contribution-impl/.ruleset new file mode 100644 index 0000000000..ac8671859d --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/.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/branches/sca-java-0.99/modules/contribution-impl/DISCLAIMER b/branches/sca-java-0.99/modules/contribution-impl/DISCLAIMER new file mode 100644 index 0000000000..d68a410903 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/DISCLAIMER @@ -0,0 +1,8 @@ +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.
+
diff --git a/branches/sca-java-0.99/modules/contribution-impl/LICENSE b/branches/sca-java-0.99/modules/contribution-impl/LICENSE new file mode 100644 index 0000000000..8aa906c321 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/LICENSE @@ -0,0 +1,205 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + diff --git a/branches/sca-java-0.99/modules/contribution-impl/NOTICE b/branches/sca-java-0.99/modules/contribution-impl/NOTICE new file mode 100644 index 0000000000..94481d6cfa --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/NOTICE @@ -0,0 +1,6 @@ +${pom.name} +Copyright (c) 2005 - 2007 The Apache Software Foundation + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + diff --git a/branches/sca-java-0.99/modules/contribution-impl/pom.xml b/branches/sca-java-0.99/modules/contribution-impl/pom.xml new file mode 100644 index 0000000000..26619c94cc --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/pom.xml @@ -0,0 +1,57 @@ +<?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> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-modules</artifactId> + <version>0.99-incubating-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + <artifactId>tuscany-contribution-impl</artifactId> + <name>Apache Tuscany SCA Contribution Service Implementation</name> + + <dependencies> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-contribution</artifactId> + <version>0.99-incubating-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-contribution-java</artifactId> + <version>0.99-incubating-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-contribution-namespace</artifactId> + <version>0.99-incubating-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>org.codehaus.woodstox</groupId> + <artifactId>wstx-asl</artifactId> + <version>3.2.1</version> + <scope>runtime</scope> + </dependency> + </dependencies> +</project> diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ArtifactImpl.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ArtifactImpl.java new file mode 100644 index 0000000000..f7600e5a83 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ArtifactImpl.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.sca.contribution.impl; + +import org.apache.tuscany.sca.contribution.Artifact; + + +/** + * Base Artifact interface to accomodate common properties between Contribution and Deployed Artifact + * + * @version $Rev$ $Date$ + */ +public abstract class ArtifactImpl implements Artifact { + private String uri; + private String location; + + protected ArtifactImpl() { + } + + public String getLocation() { + return this.location; + } + + public void setLocation(String location) { + this.location = location; + } + + public String getURI() { + return this.uri; + } + + public void setURI(String uri) { + this.uri = uri; + } + + @Override + public int hashCode() { + return uri.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } else { + if (obj instanceof Artifact) { + return uri.equals(((Artifact)obj).getURI()); + } else { + return false; + } + } + } + +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionFactoryImpl.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionFactoryImpl.java new file mode 100644 index 0000000000..1ef7a98f9e --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionFactoryImpl.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.sca.contribution.impl; + +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ContributionFactory; +import org.apache.tuscany.sca.contribution.DeployedArtifact; + + +/** + * Contribution model object factory + * + * @version $Rev$ $Date$ + */ +public class ContributionFactoryImpl implements ContributionFactory { + + public Contribution createContribution() { + return new ContributionImpl(); + } + + public DeployedArtifact createDeployedArtifact() { + return new DeployedArtifactImpl(); + } +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImpl.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImpl.java new file mode 100644 index 0000000000..1e4688584b --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImpl.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.sca.contribution.impl; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.Export; +import org.apache.tuscany.sca.contribution.Import; +import org.apache.tuscany.sca.contribution.DeployedArtifact; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * The representation of a deployed contribution + * + * @version $Rev$ $Date$ + */ +public class ContributionImpl extends ArtifactImpl implements Contribution { + private List<Export> exports = new ArrayList<Export>(); + private List<Import> imports = new ArrayList<Import>(); + private List<Composite> deployables = new ArrayList<Composite>(); + private ModelResolver modelResolver; + + /** + * A list of artifacts in the contribution + */ + private List<DeployedArtifact> artifacts = new ArrayList<DeployedArtifact>(); + + protected ContributionImpl() { + } + + public List<Export> getExports() { + return exports; + } + + public List<Import> getImports() { + return imports; + } + + public List<Composite> getDeployables() { + return deployables; + } + + public List<DeployedArtifact> getArtifacts() { + return artifacts; + } + + public ModelResolver getModelResolver() { + return modelResolver; + } + + public void setModelResolver(ModelResolver modelResolver) { + this.modelResolver = modelResolver; + } +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/DeployedArtifactImpl.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/DeployedArtifactImpl.java new file mode 100644 index 0000000000..f3a688140c --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/DeployedArtifactImpl.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.contribution.impl; + +import org.apache.tuscany.sca.contribution.DeployedArtifact; + +/** + * Representation of a deployed artifact + * + * @version $Rev$ $Date$ + */ +public class DeployedArtifactImpl extends ArtifactImpl implements DeployedArtifact { + private Object modelObject; + + protected DeployedArtifactImpl() { + super(); + } + + public Object getModel() { + return modelObject; + } + + public void setModel(Object modelObject) { + this.modelObject = modelObject; + } +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/FolderContributionProcessor.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/FolderContributionProcessor.java new file mode 100644 index 0000000000..03abd92123 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/FolderContributionProcessor.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.sca.contribution.processor.impl; + +import java.io.File; +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 org.apache.tuscany.sca.contribution.ContentType; +import org.apache.tuscany.sca.contribution.processor.PackageProcessor; +import org.apache.tuscany.sca.contribution.service.ContributionException; +import org.apache.tuscany.sca.contribution.service.util.FileHelper; + +/** + * Folder contribution package processor + * + * @version $Rev$ $Date$ + */ +public class FolderContributionProcessor implements PackageProcessor { + /** + * Package-type that this package processor can handle + */ + public static final String PACKAGE_TYPE = ContentType.FOLDER; + + public FolderContributionProcessor() { + } + + public String getPackageType() { + return PACKAGE_TYPE; + } + + /** + * Recursively traverse a root directory + * + * @param fileList + * @param file + * @throws IOException + */ + private void traverse(List<URI> fileList, File file, File root) throws IOException { + if (file.isFile()) { + fileList.add(root.toURI().relativize(file.toURI())); + + } else if (file.isDirectory()) { + // FIXME: Maybe we should externalize it as a property + // Regular expression to exclude .xxx files + + String uri = root.toURI().relativize(file.toURI()).toString(); + if (uri.endsWith("/")) { + uri = uri.substring(0, uri.length() - 1); + } + fileList.add(URI.create(uri)); + + File[] files = file.listFiles(FileHelper.getFileFilter("[^\u002e].*", true)); + for (int i = 0; i < files.length; i++) { + traverse(fileList, files[i], root); + } + } + } + + public URL getArtifactURL(URL sourceURL, URI artifact) throws MalformedURLException { + return new URL(sourceURL, artifact.toString()); + } + + /** + * Get a list of artifact URI from the folder + * + * @return The list of artifact URI for the folder + * @throws IOException + */ + public List<URI> getArtifacts(URL packageSourceURL, InputStream inputStream) throws ContributionException, + IOException { + if (packageSourceURL == null) { + throw new IllegalArgumentException("Invalid null package source URL."); + } + + List<URI> artifacts = new ArrayList<URI>(); + + // Assume the root is a jar file + File rootFolder; + + try { + rootFolder = new File(packageSourceURL.toURI()); + if (rootFolder.isDirectory()) { + if (!rootFolder.exists()) { + throw new InvalidFolderContributionException(rootFolder.getAbsolutePath()); + } + + this.traverse(artifacts, rootFolder, rootFolder); + } + + } catch (URISyntaxException e) { + throw new InvalidFolderContributionURIException(packageSourceURL.toExternalForm(), e); + } + + return artifacts; + } +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/InvalidFolderContributionException.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/InvalidFolderContributionException.java new file mode 100644 index 0000000000..6dbab56553 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/InvalidFolderContributionException.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.sca.contribution.processor.impl; + +import org.apache.tuscany.sca.contribution.service.ContributionException; + +/** + * Exception that indicates that the supplied XML Document invalid. + * + */ +public class InvalidFolderContributionException extends ContributionException { + + /** + * + */ + private static final long serialVersionUID = 1564255850052593282L; + + protected InvalidFolderContributionException(String componentDefinitionLocatoin) { + super(componentDefinitionLocatoin); + } + + protected InvalidFolderContributionException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/InvalidFolderContributionURIException.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/InvalidFolderContributionURIException.java new file mode 100644 index 0000000000..8022834438 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/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.sca.contribution.processor.impl; + +import org.apache.tuscany.sca.contribution.service.ContributionException; + +/** + * Exception that indicates that the supplied XML Document invalid. + * + */ +public class InvalidFolderContributionURIException extends ContributionException { + + /** + * + */ + private static final long serialVersionUID = 1564255850052593282L; + + protected InvalidFolderContributionURIException(String componentDefinitionLocatoin) { + super(componentDefinitionLocatoin); + } + + protected InvalidFolderContributionURIException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/JarContributionProcessor.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/JarContributionProcessor.java new file mode 100644 index 0000000000..fb7dbb89a4 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/JarContributionProcessor.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.sca.contribution.processor.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +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.sca.contribution.ContentType; +import org.apache.tuscany.sca.contribution.processor.PackageProcessor; +import org.apache.tuscany.sca.contribution.service.ContributionException; + +/** + * Jar Contribution package processor + * + * @version $Rev$ $Date$ + */ +public class JarContributionProcessor implements PackageProcessor { + /** + * Package-type that this package processor can handle + */ + public static final String PACKAGE_TYPE = ContentType.JAR; + + public JarContributionProcessor() { + } + + public String getPackageType() { + return PACKAGE_TYPE; + } + + public URL getArtifactURL(URL sourceURL, URI artifact) throws MalformedURLException { + if (sourceURL.toString().startsWith("jar:")) { + return new URL(sourceURL, artifact.toString()); + } else { + return new URL("jar:" + sourceURL.toExternalForm() + "!/" + artifact); + } + } + + public List<URI> getArtifacts(URL packageSourceURL, InputStream inputStream) throws ContributionException, + IOException { + if (packageSourceURL == null) { + throw new IllegalArgumentException("Invalid null package source URL."); + } + + if (inputStream == null) { + throw new IllegalArgumentException("Invalid null source inputstream."); + } + + List<URI> artifacts = new ArrayList<URI>(); + + // Assume the root is a jar file + JarInputStream jar = new JarInputStream(inputStream); + try { + while (true) { + JarEntry entry = jar.getNextJarEntry(); + if (entry == null) { + // EOF + break; + } + + // FIXME: Maybe we should externalize the filter as a property + if (!entry.getName().startsWith(".")) { + artifacts.add(URI.create(entry.getName())); + } + } + } finally { + jar.close(); + } + return artifacts; + } +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/resolver/impl/ModelResolverImpl.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/resolver/impl/ModelResolverImpl.java new file mode 100644 index 0000000000..6c2257803a --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/resolver/impl/ModelResolverImpl.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.sca.contribution.resolver.impl; + +import java.lang.ref.WeakReference; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.sca.contribution.resolver.ClassReference; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * A default implementation of an artifact resolver, based on a map. + * + * @version $Rev$ $Date$ + */ +public class ModelResolverImpl implements ModelResolver { + private static final long serialVersionUID = -7826976465762296634L; + + private Map<Object, Object> map = new HashMap<Object, Object>(); + + private WeakReference<ClassLoader> classLoader; + + public ModelResolverImpl(ClassLoader classLoader) { + this.classLoader = new WeakReference<ClassLoader>(classLoader); + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + Object resolved = map.get(unresolved); + if (resolved != null) { + + // Return the resolved object + return modelClass.cast(resolved); + + } else if (unresolved instanceof ClassReference) { + + // Load a class on demand + ClassReference classReference = (ClassReference)unresolved; + Class clazz; + try { + clazz = Class.forName(classReference.getClassName(), true, classLoader.get()); + } catch (ClassNotFoundException e) { + + // Return the unresolved object + return unresolved; + } + + // Store a new ClassReference wrappering the loaded class + resolved = new ClassReference(clazz); + map.put(resolved, resolved); + + // Return the resolved ClassReference + return modelClass.cast(resolved); + + } else { + + // Return the unresolved object + return unresolved; + } + } + + public void addModel(Object resolved) { + map.put(resolved, resolved); + } + + public Object removeModel(Object resolved) { + return map.remove(resolved); + } + + public Collection<Object> getModels() { + return map.values(); + } + +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ArtifactTypeDescriberImpl.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ArtifactTypeDescriberImpl.java new file mode 100644 index 0000000000..76318c6021 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ArtifactTypeDescriberImpl.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.sca.contribution.service.impl; + +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.sca.contribution.ContentType; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.service.TypeDescriber; +import org.apache.tuscany.sca.contribution.service.util.FileHelper; + +/** + * Implementation of the content describer for files + * + * @version $Rev$ $Date$ + */ +public class ArtifactTypeDescriberImpl implements TypeDescriber { + private final Map<String, String> contentTypeRegistry = new HashMap<String, String>(); + + public ArtifactTypeDescriberImpl() { + super(); + init(); + } + + /** + * Initialize contentType registry with know types based on known file extensions + */ + private void init() { + contentTypeRegistry.put("COMPOSITE", ContentType.COMPOSITE); + contentTypeRegistry.put("SCDL", ContentType.COMPOSITE); + contentTypeRegistry.put("WSDL", ContentType.WSDL); + contentTypeRegistry.put("JAR", ContentType.JAR); + } + + 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 resourceURL The artifact url + * @param defaultContentType The default content type if we can't find the correc one + * @return The content type + */ + public String getType(URL resourceURL, String defaultContentType) { + URLConnection connection = null; + String contentType = defaultContentType; + + if (resourceURL.getProtocol().equals("file") && FileHelper.toFile(resourceURL).isDirectory()) { + // Special case : contribution is a folder + contentType = ContentType.FOLDER; + } else if (resourceURL.toExternalForm().endsWith(Contribution.SCA_CONTRIBUTION_META) + || resourceURL.toExternalForm().endsWith(Contribution.SCA_CONTRIBUTION_GENERATED_META)) { + // Special case : contribution metadata + contentType = ContentType.CONTRIBUTION_METADATA; + } else { + 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 and it's not a special file + // 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/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionMetadataDocumentProcessor.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionMetadataDocumentProcessor.java new file mode 100644 index 0000000000..2885d7c3d7 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionMetadataDocumentProcessor.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.sca.contribution.service.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ContributionFactory; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; + +/** + * Loader that handles contribution metadata files + * + * @version $Rev$ $Date$ + */ +public class ContributionMetadataDocumentProcessor { + protected final URLClassLoader classLoader; + protected final StAXArtifactProcessor staxProcessor; + protected final AssemblyFactory assemblyFactory; + protected final ContributionFactory contributionFactory; + protected final XMLInputFactory inputFactory; + + public ContributionMetadataDocumentProcessor(URLClassLoader classLoader, StAXArtifactProcessor staxProcessor, AssemblyFactory assemblyFactory, ContributionFactory contributionFactory, XMLInputFactory inputFactory) { + super(); + this.classLoader = classLoader; + this.staxProcessor = staxProcessor; + this.assemblyFactory = assemblyFactory; + this.contributionFactory = contributionFactory; + this.inputFactory = inputFactory; + } + + private Contribution mergeContributionMetadata(Contribution contrib1, Contribution contrib2 ) { + contrib1.getDeployables().addAll(contrib2.getDeployables()); + contrib1.getImports().addAll(contrib2.getImports()); + contrib1.getExports().addAll(contrib2.getExports()); + + return contrib1; + } + + public void read(Contribution contribution) throws XMLStreamException, ContributionReadException { + List<URL> artifactList = new ArrayList<URL>(2); + //set generated first, as the user created one ovverrides generated information + artifactList.add(this.classLoader.getResource(Contribution.SCA_CONTRIBUTION_GENERATED_META)); + artifactList.add(this.classLoader.getResource(Contribution.SCA_CONTRIBUTION_META)); + + URL artifactURL = null; + InputStream artifactStream = null; + Iterator artifactIterator = artifactList.iterator(); + while( artifactIterator.hasNext() ){ + + try { + artifactURL = (URL) artifactIterator.next(); + if( artifactURL != null) { + artifactStream = artifactURL.openStream(); + XMLStreamReader reader = inputFactory.createXMLStreamReader(artifactStream); + reader.nextTag(); + + Contribution contributionMetadata = (Contribution) staxProcessor.read(reader); + if (contributionMetadata != null) { + this.mergeContributionMetadata(contribution, contributionMetadata); + } + } + + } catch (XMLStreamException e) { + throw new ContributionReadException(e); + } catch (IOException e) { + throw new ContributionReadException(e); + } finally { + try { + if (artifactStream != null) { + artifactStream.close(); + artifactStream = null; + } + } catch (IOException ioe) { + //ignore + } + } + } + } +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionMetadataProcessor.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionMetadataProcessor.java new file mode 100644 index 0000000000..e4cc2c552f --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionMetadataProcessor.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.sca.contribution.service.impl; + +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ContributionFactory; +import org.apache.tuscany.sca.contribution.Export; +import org.apache.tuscany.sca.contribution.Import; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.contribution.service.ContributionResolveException; +import org.apache.tuscany.sca.contribution.service.ContributionWriteException; + +/** + * Loader that handles contribution metadata files + * + * @version $Rev$ $Date$ + */ +public class ContributionMetadataProcessor implements StAXArtifactProcessor<Contribution> { + private static final String SCA10_NS = "http://www.osoa.org/xmlns/sca/1.0"; + private static final String TARGET_NAMESPACE = "targetNamespace"; + + private static final QName CONTRIBUTION = new QName(SCA10_NS, "contribution"); + private static final QName DEPLOYABLE = new QName(SCA10_NS, "deployable"); + + private final AssemblyFactory assemblyFactory; + private final ContributionFactory contributionFactory; + + private final StAXArtifactProcessor extensionProcessor; + + public ContributionMetadataProcessor(AssemblyFactory assemblyFactory, ContributionFactory contributionFactory, StAXArtifactProcessor extensionProcessor) { + super(); + this.assemblyFactory = assemblyFactory; + this.contributionFactory = contributionFactory; + this.extensionProcessor = extensionProcessor; + } + + + public QName getArtifactType() { + return CONTRIBUTION; + } + + public Class<Contribution> getModelType() { + return Contribution.class; + } + + public Contribution read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException { + Contribution contribution = this.contributionFactory.createContribution(); + String targetNameSpaceURI = null; + QName element = null; + + + while (reader.hasNext()) { + int event = reader.getEventType(); + switch (event) { + case START_ELEMENT: + element = reader.getName(); + + if (CONTRIBUTION.equals(element)) { + targetNameSpaceURI = reader.getAttributeValue(null, TARGET_NAMESPACE); + } else if (DEPLOYABLE.equals(element)) { + String name = reader.getAttributeValue(null, "composite"); + if (name == null) { + throw new ContributionReadException("Attribute 'composite' is missing"); + } + QName compositeName = null; + + int index = name.indexOf(':'); + if (index != -1) { + String prefix = name.substring(0, index); + String localPart = name.substring(index + 1); + String ns = reader.getNamespaceContext().getNamespaceURI(prefix); + if (ns == null) { + throw new ContributionReadException("Invalid prefix: " + prefix); + } + compositeName = new QName(targetNameSpaceURI, localPart, prefix); + } else { + String prefix = ""; + String localPart = name; + compositeName = new QName(targetNameSpaceURI, localPart, prefix); + } + + Composite composite = assemblyFactory.createComposite(); + composite.setName(compositeName); + composite.setUnresolved(true); + + contribution.getDeployables().add(composite); + } else{ + //process extension + Object extension = extensionProcessor.read(reader); + if (extension != null) { + if (extension instanceof Import) { + contribution.getImports().add((Import)extension); + }else if (extension instanceof Export) { + contribution.getExports().add((Export)extension); + } + } + } + break; + case XMLStreamConstants.END_ELEMENT: + if (CONTRIBUTION.equals(reader.getName())) { + return contribution; + } + break; + } + + //Read the next element + if (reader.hasNext()) { + reader.next(); + } + } + + return contribution; + } + + public void write(Contribution model, XMLStreamWriter outputSource) throws ContributionWriteException, XMLStreamException { + // TODO Auto-generated method stub + + } + + public void resolve(Contribution model, ModelResolver resolver) throws ContributionResolveException { + // TODO Auto-generated method stub + + } +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionRepositoryImpl.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionRepositoryImpl.java new file mode 100644 index 0000000000..51276d5f56 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionRepositoryImpl.java @@ -0,0 +1,296 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.contribution.service.impl; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.service.ContributionRepository; +import org.apache.tuscany.sca.contribution.service.util.FileHelper; +import org.apache.tuscany.sca.contribution.service.util.IOHelper; + +/** + * The default implementation of ContributionRepository + * + * @version $Rev$ $Date$ + */ +public class ContributionRepositoryImpl implements ContributionRepository { + private static final String NS = "http://tuscany.apache.org/xmlns/1.0-SNAPSHOT"; + private static final String DOMAIN_INDEX_FILENAME = "sca-domain.xml"; + private final File rootFile; + private Map<String, String> contributionLocations = new HashMap<String, String>(); + + private Map<String, Contribution> contributionMap = new HashMap<String, Contribution>(); + private List<Contribution> contributions = new ArrayList<Contribution>(); + + private URI domain; + private XMLInputFactory factory; + + /** + * Constructor with repository root + * + * @param repository + */ + public ContributionRepositoryImpl(final String repository) throws IOException { + String root = repository; + if (repository == null) { + root = AccessController.doPrivileged(new PrivilegedAction<String>() { + public String run() { + // Default to <user.home>/.tuscany/domains/local/ + String userHome = System.getProperty("user.home"); + String slash = File.separator; + return userHome + slash + ".tuscany" + slash + "domains" + slash + "local" + slash; + } + }); + } + this.rootFile = new File(root); + this.domain = rootFile.toURI(); + FileHelper.forceMkdir(rootFile); + if (!rootFile.exists() || !rootFile.isDirectory() || !rootFile.canRead()) { + throw new IOException("The root is not a directory: " + repository); + } + factory = XMLInputFactory.newInstance("javax.xml.stream.XMLInputFactory", getClass().getClassLoader()); + } + + public URI getDomain() { + return domain; + } + + /** + * Resolve contribution location in the repository -> root repository / + * contribution file -> contribution group id / artifact id / version + * + * @param contribution + * @return + */ + private File mapToFile(URL sourceURL) { + String fileName = FileHelper.toFile(sourceURL).getName(); + return new File(rootFile, "contributions" + File.separator + fileName); + } + + /** + * 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(String contribution, URL sourceURL, InputStream contributionStream) throws IOException { + // where the file should be stored in the repository + File location = mapToFile(sourceURL); + FileHelper.forceMkdir(location.getParentFile()); + + copy(contributionStream, location); + + // add contribution to repositoryContent + URL contributionURL = location.toURL(); + URI relative = rootFile.toURI().relativize(location.toURI()); + contributionLocations.put(contribution, relative.toString()); + saveMap(); + + return contributionURL; + } + + public URL store(String contribution, URL sourceURL) throws IOException { + // where the file should be stored in the repository + File location = mapToFile(sourceURL); + File source = FileHelper.toFile(sourceURL); + if (source == null || source.isFile()) { + InputStream is = sourceURL.openStream(); + try { + return store(contribution, sourceURL, is); + } finally { + IOHelper.closeQuietly(is); + } + } + + FileHelper.forceMkdir(location); + FileHelper.copyDirectory(source, location); + + // add contribution to repositoryContent + URI relative = rootFile.toURI().relativize(location.toURI()); + contributionLocations.put(contribution, relative.toString()); + saveMap(); + + return location.toURL(); + } + + public URL find(String contribution) { + if (contribution == null) { + return null; + } + String location = contributionLocations.get(contribution); + if (location == null) { + return null; + } + try { + return new File(rootFile, location).toURL(); + } catch (MalformedURLException e) { + // Should not happen + throw new AssertionError(e); + } + } + + public void remove(String contribution) { + URL contributionURL = this.find(contribution); + if (contributionURL != null) { + // remove + try { + FileHelper.forceDelete(FileHelper.toFile(contributionURL)); + this.contributionLocations.remove(contribution); + saveMap(); + } catch (IOException ioe) { + // handle file could not be removed + } + } + } + + public List<String> list() { + return new ArrayList<String>(contributionLocations.keySet()); + } + + public void init() { + File domainFile = new File(rootFile, "sca-domain.xml"); + if (!domainFile.isFile()) { + return; + } + FileInputStream is; + try { + is = new FileInputStream(domainFile); + } catch (FileNotFoundException e) { + return; + } + try { + XMLStreamReader reader = factory.createXMLStreamReader(new InputStreamReader(is, "UTF-8")); + while (reader.hasNext()) { + switch (reader.getEventType()) { + case XMLStreamConstants.START_ELEMENT: + String name = reader.getName().getLocalPart(); + if ("domain".equals(name)) { + String uri = reader.getAttributeValue(null, "uri"); + if (uri != null) { + domain = URI.create(uri); + } + } + if ("contribution".equals(name)) { + String uri = reader.getAttributeValue(null, "uri"); + String location = reader.getAttributeValue(null, "location"); + contributionLocations.put(uri, location); + } + break; + default: + break; + } + reader.next(); + } + } catch (Exception e) { + // Ignore + } finally { + IOHelper.closeQuietly(is); + } + } + + private void saveMap() { + File domainFile = new File(rootFile, DOMAIN_INDEX_FILENAME); + FileOutputStream os = null; + try { + os = new FileOutputStream(domainFile); + PrintWriter writer = new PrintWriter(new OutputStreamWriter(os, "UTF-8")); + writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); + writer.println("<domain uri=\"" + getDomain() + "\" xmlns=\"" + NS + "\">"); + for (Map.Entry<String, String> e : contributionLocations.entrySet()) { + writer.println(" <contribution uri=\"" + e.getKey() + "\" location=\"" + e.getValue() + "\"/>"); + } + writer.println("</domain>"); + writer.flush(); + } catch (IOException e) { + throw new IllegalArgumentException(e); + } finally { + IOHelper.closeQuietly(os); + } + } + + public void destroy() { + } + + public void addContribution(Contribution contribution) { + contributionMap.put(contribution.getURI(), contribution); + contributions.add(contribution); + } + + public void removeContribution(Contribution contribution) { + contributionMap.remove(contribution.getURI()); + contributions.remove(contribution); + } + + public void updateContribution(Contribution contribution) { + Contribution oldContribution = contributionMap.remove(contribution.getURI()); + contributions.remove(oldContribution); + contributionMap.put(contribution.getURI(), contribution); + contributions.add(contribution); + } + + public Contribution getContribution(String uri) { + return contributionMap.get(uri); + } + + public List<Contribution> getContributions() { + return Collections.unmodifiableList(contributions); + } + +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionServiceImpl.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionServiceImpl.java new file mode 100644 index 0000000000..4a1487e62a --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionServiceImpl.java @@ -0,0 +1,406 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.contribution.service.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ContributionFactory; +import org.apache.tuscany.sca.contribution.DeployedArtifact; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.ContributionPostProcessor; +import org.apache.tuscany.sca.contribution.processor.PackageProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor; +import org.apache.tuscany.sca.contribution.resolver.ExtensibleModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint; +import org.apache.tuscany.sca.contribution.service.ContributionException; +import org.apache.tuscany.sca.contribution.service.ContributionRepository; +import org.apache.tuscany.sca.contribution.service.ContributionService; +import org.apache.tuscany.sca.contribution.service.ExtensibleContributionListener; +import org.apache.tuscany.sca.contribution.service.util.IOHelper; + +/** + * Service interface that manages artifacts contributed to a Tuscany runtime. + * + * @version $Rev$ $Date$ + */ +/** + * + */ +public class ContributionServiceImpl implements ContributionService { + + /** + * Repository where contributions are stored. Usually set by injection. + */ + private ContributionRepository contributionRepository; + + /** + * Registry of available package processors. + */ + private PackageProcessor packageProcessor; + + /** + * Registry of available artifact processors + */ + + private URLArtifactProcessor artifactProcessor; + + /** + * Registry of available stax processors, + * used for loading contribution metadata in a extensible way + */ + private StAXArtifactProcessor staxProcessor; + + /** + * Event listener for contribution operations + */ + private ExtensibleContributionListener contributionListener; + + /** + * Registry of available model resolvers + */ + + private ModelResolverExtensionPoint modelResolvers; + + /** + * Model factory extension point + */ + + private ModelFactoryExtensionPoint modelFactories; + + /** + * Contribution post processor + */ + private ContributionPostProcessor postProcessor; + + /** + * xml factory used to create reader instance to load contribution metadata + */ + private XMLInputFactory xmlFactory; + + /** + * Assembly factory + */ + private AssemblyFactory assemblyFactory; + + /** + * Contribution model facotry + */ + private ContributionFactory contributionFactory; + + private ModelResolver domainResolver; + + + public ContributionServiceImpl(ContributionRepository repository, + PackageProcessor packageProcessor, + URLArtifactProcessor documentProcessor, + StAXArtifactProcessor staxProcessor, + ExtensibleContributionListener contributionListener, + ContributionPostProcessor postProcessor, + ModelResolver domainResolver, + ModelResolverExtensionPoint modelResolvers, + ModelFactoryExtensionPoint modelFactories, + AssemblyFactory assemblyFactory, + ContributionFactory contributionFactory, + XMLInputFactory xmlFactory) { + super(); + this.contributionRepository = repository; + this.packageProcessor = packageProcessor; + this.artifactProcessor = documentProcessor; + this.staxProcessor = staxProcessor; + this.contributionListener = contributionListener; + this.postProcessor = postProcessor; + this.modelResolvers = modelResolvers; + this.modelFactories = modelFactories; + this.xmlFactory = xmlFactory; + this.assemblyFactory = assemblyFactory; + this.contributionFactory = contributionFactory; + this.domainResolver = domainResolver; + } + + public Contribution contribute(String contributionURI, URL sourceURL, boolean storeInRepository) + throws ContributionException, IOException { + if (contributionURI == null) { + throw new IllegalArgumentException("URI for the contribution is null"); + } + if (sourceURL == null) { + throw new IllegalArgumentException("Source URL for the contribution is null"); + } + + return addContribution(contributionURI, sourceURL, null, null, storeInRepository); + } + + public Contribution contribute(String contributionURI, URL sourceURL, ModelResolver modelResolver, boolean storeInRepository) throws ContributionException, + IOException { + if (contributionURI == null) { + throw new IllegalArgumentException("URI for the contribution is null"); + } + if (sourceURL == null) { + throw new IllegalArgumentException("Source URL for the contribution is null"); + } + + return addContribution(contributionURI, sourceURL, null, modelResolver, storeInRepository); + } + + public Contribution contribute(String contributionURI, URL sourceURL, InputStream input) + throws ContributionException, IOException { + + return addContribution(contributionURI, sourceURL, input, null, true); + } + + public Contribution contribute(String contributionURI, URL sourceURL, InputStream input, ModelResolver modelResolver) + throws ContributionException, IOException { + + return addContribution(contributionURI, sourceURL, input, modelResolver, true); + } + + public Contribution getContribution(String uri) { + return this.contributionRepository.getContribution(uri); + } + + /** + * Remove a contribution and notify listener that contribution was removed + */ + public void remove(String uri) throws ContributionException { + Contribution contribution = contributionRepository.getContribution(uri); + this.contributionRepository.removeContribution(contribution); + this.contributionListener.contributionRemoved(this.contributionRepository, contribution); + } + + /** + * Add a composite model to the contribution + */ + public void addDeploymentComposite(Contribution contribution, Composite composite) throws ContributionException { + DeployedArtifact artifact = this.contributionFactory.createDeployedArtifact(); + artifact.setURI(composite.getURI()); + artifact.setModel(composite); + + contribution.getArtifacts().add(artifact); + + contribution.getDeployables().add(composite); + } + + /** + * Utility/Helper methods for contribution service + */ + + /** + * Perform read of the contribution metada loader (sca-contribution.xml and sca-contribution-generated.xml) + * When the two metadata files are available, the information provided are merged, and the sca-contribution has priorities + * + * @param sourceURL + * @return Contribution + * @throws ContributionException + */ + private Contribution readContributionMetadata(URL sourceURL) throws ContributionException { + Contribution contributionMetadata = null; + + URL[] clUrls = {sourceURL}; + URLClassLoader cl = new URLClassLoader(clUrls, null); + + + ContributionMetadataDocumentProcessor metadataDocumentProcessor = + new ContributionMetadataDocumentProcessor(cl, this.staxProcessor, this.assemblyFactory, this.contributionFactory, this.xmlFactory); + contributionMetadata = contributionFactory.createContribution(); + try { + metadataDocumentProcessor.read(contributionMetadata); + } catch (XMLStreamException e) { + throw new InvalidContributionMetadataException("Invalid contribution metadata for contribution."); + + } + + return contributionMetadata; + } + + /** + * Note: + * + * @param contributionURI ContributionID + * @param sourceURL contribution location + * @param contributionStream contribution content + * @param storeInRepository flag if we store the contribution into the + * repository or not + * @return the contribution model representing the contribution + * @throws IOException + * @throws DeploymentException + */ + private Contribution addContribution(String contributionURI, + URL sourceURL, + InputStream contributionStream, + ModelResolver modelResolver, + boolean storeInRepository) throws IOException, ContributionException { + + if (contributionStream == null && sourceURL == null) { + throw new IllegalArgumentException("The content of the contribution is null."); + } + + // store the contribution in the contribution repository + URL locationURL = sourceURL; + if (contributionRepository != null && storeInRepository) { + if (contributionStream == null) { + locationURL = contributionRepository.store(contributionURI, sourceURL); + } else { + locationURL = contributionRepository.store(contributionURI, sourceURL, contributionStream); + } + } + + //initialize contribution based on it's metadata if available + Contribution contribution = readContributionMetadata(locationURL); + + // Create contribution model resolver + if (modelResolver == null) { + modelResolver = new ExtensibleModelResolver(contribution, modelResolvers, modelFactories); + } + + if ( modelResolver instanceof ExtensibleModelResolver ) { + ((ExtensibleModelResolver)modelResolver).setDomainResolver(domainResolver); + } + + //set contribution initial information + contribution.setURI(contributionURI.toString()); + contribution.setLocation(locationURL.toString()); + contribution.setModelResolver(modelResolver); + + List<URI> contributionArtifacts = null; + + //NOTE: if a contribution is stored on the repository + //the stream would be consumed at this point + if (storeInRepository || contributionStream == null) { + contributionStream = sourceURL.openStream(); + try { + // process the contribution + contributionArtifacts = this.packageProcessor.getArtifacts(locationURL, contributionStream); + } finally { + IOHelper.closeQuietly(contributionStream); + contributionStream = null; + } + } else { + // process the contribution + contributionArtifacts = this.packageProcessor.getArtifacts(locationURL, contributionStream); + } + + // Read all artifacts in the contribution + processReadPhase(contribution, contributionArtifacts); + + // + this.contributionListener.contributionAdded(this.contributionRepository, contribution); + + // Resolve them + processResolvePhase(contribution); + + // Add all composites under META-INF/sca-deployables to the + // list of deployables + String prefix = Contribution.SCA_CONTRIBUTION_DEPLOYABLES; + for (DeployedArtifact artifact : contribution.getArtifacts()) { + if (artifact.getModel() instanceof Composite) { + if (artifact.getURI().startsWith(prefix)) { + Composite composite = (Composite)artifact.getModel(); + if (!contribution.getDeployables().contains(composite)) { + contribution.getDeployables().add(composite); + } + } + } + } + + //post process contribution + this.postProcessor.visit(contribution); + + // store the contribution on the registry + this.contributionRepository.addContribution(contribution); + + return contribution; + } + + /** + * This utility method process each artifact and delegates to proper + * artifactProcessor to read the model and generate the in-memory representation + * + * @param contribution + * @param artifacts + * @throws ContributionException + * @throws MalformedURLException + */ + private void processReadPhase(Contribution contribution, List<URI> artifacts) throws ContributionException, + MalformedURLException { + + ModelResolver modelResolver = contribution.getModelResolver(); + URL contributionURL = new URL(contribution.getLocation()); + for (URI a : artifacts) { + URL artifactURL = packageProcessor.getArtifactURL(new URL(contribution.getLocation()), a); + + // Add the deployed artifact model to the resolver + DeployedArtifact artifact = this.contributionFactory.createDeployedArtifact(); + artifact.setURI(a.toString()); + artifact.setLocation(artifactURL.toString()); + contribution.getArtifacts().add(artifact); + modelResolver.addModel(artifact); + + // Let the artifact processor read the artifact into a model + Object model = this.artifactProcessor.read(contributionURL, a, artifactURL); + if (model != null) { + artifact.setModel(model); + + // Add the loaded model to the model resolver + modelResolver.addModel(model); + } + } + } + + /** + * This utility method process each artifact and delegates to proper + * artifactProcessor to resolve the model references + * + * @param contribution + * @throws ContributionException + */ + @SuppressWarnings("unchecked") + private void processResolvePhase(Contribution contribution) throws ContributionException { + // for each artifact that was processed on the contribution + for (DeployedArtifact artifact : contribution.getArtifacts()) { + // resolve the model object + if (artifact.getModel() != null) { + this.artifactProcessor.resolve(artifact.getModel(), contribution.getModelResolver()); + } + } + + //resolve deployables from contribution metadata + List<Composite> resolvedDeployables = new ArrayList<Composite>(); + for (Composite deployableComposite : contribution.getDeployables()) { + Composite resolvedDeployable = contribution.getModelResolver().resolveModel(Composite.class, deployableComposite); + + resolvedDeployables.add(resolvedDeployable); + } + contribution.getDeployables().clear(); + contribution.getDeployables().addAll(resolvedDeployables); + } +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/InvalidContributionMetadataException.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/InvalidContributionMetadataException.java new file mode 100644 index 0000000000..a1250dc777 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/InvalidContributionMetadataException.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.contribution.service.impl; + +import org.apache.tuscany.sca.contribution.service.ContributionException; + +/** + * Exception that indicates that the supplied XML Document invalid. + * + * @version $Rev$ $Date$ + */ +public class InvalidContributionMetadataException extends ContributionException { + + /** + * + */ + private static final long serialVersionUID = -3184477070625689942L; + + protected InvalidContributionMetadataException() { + } + + protected InvalidContributionMetadataException(String message) { + super(message); + } + + protected InvalidContributionMetadataException(String message, String identifier) { + super(message, identifier); + } + + protected InvalidContributionMetadataException(String message, Throwable cause) { + super(message, cause); + } + + protected InvalidContributionMetadataException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + protected InvalidContributionMetadataException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/InvalidContributionURIException.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/InvalidContributionURIException.java new file mode 100644 index 0000000000..80be4c3f00 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/InvalidContributionURIException.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.contribution.service.impl; + +import org.apache.tuscany.sca.contribution.service.ContributionException; + +/** + * Exception that indicates that the supplied contribution URI is invalid or inexistent. + * + * @version $Rev$ $Date$ + */ +public class InvalidContributionURIException extends ContributionException { + + /** + * + */ + private static final long serialVersionUID = -3184477070625689942L; + + protected InvalidContributionURIException() { + } + + protected InvalidContributionURIException(String message) { + super(message); + } + + protected InvalidContributionURIException(String message, String identifier) { + super(message, identifier); + } + + protected InvalidContributionURIException(String message, Throwable cause) { + super(message, cause); + } + + protected InvalidContributionURIException(String message, String identifier, Throwable cause) { + super(message, identifier, cause); + } + + protected InvalidContributionURIException(Throwable cause) { + super(cause); + } +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/PackageTypeDescriberImpl.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/PackageTypeDescriberImpl.java new file mode 100644 index 0000000000..165c9d0616 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/PackageTypeDescriberImpl.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.sca.contribution.service.impl; + +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.sca.contribution.ContentType; +import org.apache.tuscany.sca.contribution.service.TypeDescriber; +import org.apache.tuscany.sca.contribution.service.util.FileHelper; + +/** + * Implementation of the content describer for contribution packages + * + * @version $Rev$ $Date$ + */ +public class PackageTypeDescriberImpl implements TypeDescriber { + private final Map<String, String> contentTypeRegistry = new HashMap<String, String>(); + + public PackageTypeDescriberImpl() { + super(); + init(); + } + + /** + * Initialize contentType registry with know types based on known file extensions + */ + private void init() { + contentTypeRegistry.put("JAR", ContentType.JAR); + } + + 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 resourceURL The artifact url + * @param defaultContentType The default content type if we can't find the correc one + * @return The content type + */ + public String getType(URL resourceURL, String defaultContentType) { + URLConnection connection = null; + String contentType = defaultContentType; + + if (resourceURL.getProtocol().equals("file") && FileHelper.toFile(resourceURL).isDirectory()) { + // Special case : contribution is a folder + contentType = ContentType.FOLDER; + } else { + 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 and it's not a special file + // 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/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/ConcurrentHashList.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/ConcurrentHashList.java new file mode 100644 index 0000000000..1eee0a2c42 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/ConcurrentHashList.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.sca.contribution.service.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class ConcurrentHashList <K,T> { + private Map<K, List<T>> hashList; + + public ConcurrentHashList() { + hashList = new ConcurrentHashMap<K, List<T>>(); + } + + public ConcurrentHashList(int initialCapacity) { + hashList = new ConcurrentHashMap<K, List<T>>(initialCapacity); + } + + public void clear() { + hashList.clear(); + } + + public List<T> get(K key) { + List<T> resultList = hashList.get(key); + if( resultList == null) { + resultList = new ArrayList<T>(); + hashList.put(key, resultList); + } + return resultList; + } + + public boolean isEmpty() { + return hashList.isEmpty(); + } + + public T put(K key, T value) { + this.get(key).add(value); + return value; + } + + public int size() { + return hashList.size(); + } + + + public static void main(String args[]) { + ConcurrentHashList<String, String> list = new ConcurrentHashList<String, String>(); + list.put("a", "a1"); + list.put("a", "a2"); + list.put("a", "a3"); + + for(String s : list.get("a")) { + System.out.println("Key a - " + s); + } + } + +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/FileHelper.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/FileHelper.java new file mode 100644 index 0000000000..bc63dca4a8 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/FileHelper.java @@ -0,0 +1,704 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.contribution.service.util; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; +import java.util.regex.Pattern; + +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); + } + } + } + + /** + * 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); + } + } + + public static FileFilter getFileFilter(String regExp, boolean ignoreCase) { + return new RegExpFilter(regExp, ignoreCase); + } + + /** + * A regular-expression based resource filter + */ + public static class RegExpFilter implements FileFilter { + private Pattern pattern; + + public RegExpFilter(Pattern pattern) { + this.pattern = pattern; + } + + public RegExpFilter(String patternStr, boolean ignoreCase) { + this.pattern = Pattern.compile(patternStr, ignoreCase ? Pattern.CASE_INSENSITIVE : 0); + } + + public boolean accept(File file) { + return pattern.matcher(file.getName()).matches(); + } + + /** + * Convert wildcard into a regex pattern + * + * @param str + * @return + */ + public static RegExpFilter getWildcardFilter(String str, boolean ignoreCase) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < str.length(); i++) { + char ch = str.charAt(i); + if (ch == '?') { + buffer.append('.'); + } else if (ch == '*') { + buffer.append(".*"); + } else { + buffer.append(ch); + } + } + return new RegExpFilter(buffer.toString(), ignoreCase); + } + + } + + /** + * 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; + } + } + + /** + * Clean a directory without deleting it. + * + * @param directory directory to clean, must not be <code>null</code> + * @throws NullPointerException if the directory is <code>null</code> + * @throws IOException in case cleaning is unsuccessful + */ + private static void cleanDirectoryOnExit(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 { + forceDeleteOnExit(file); + } catch (IOException ioe) { + exception = ioe; + } + } + + if (null != exception) { + throw exception; + } + } + + /** + * Copies a whole directory to a new location preserving the file dates. + * <p> + * This method copies the specified directory and all its child directories + * and files to the specified destination. The destination is the new + * location and name of the directory. + * <p> + * The destination directory is created if it does not exist. If the + * destination directory did exist, then this method merges the source with + * the destination, with the source taking precedence. + * + * @param srcDir an existing directory to copy, must not be + * <code>null</code> + * @param destDir the new directory, must not be <code>null</code> + * @throws NullPointerException if source or destination is + * <code>null</code> + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @since Commons IO 1.1 + */ + public static void copyDirectory(File srcDir, File destDir) throws IOException { + copyDirectory(srcDir, destDir, true); + } + + /** + * Copies a whole directory to a new location. + * <p> + * This method copies the contents of the specified source directory to + * within the specified destination directory. + * <p> + * The destination directory is created if it does not exist. If the + * destination directory did exist, then this method merges the source with + * the destination, with the source taking precedence. + * + * @param srcDir an existing directory to copy, must not be + * <code>null</code> + * @param destDir the new directory, must not be <code>null</code> + * @param preserveFileDate true if the file date of the copy should be the + * same as the original + * @throws NullPointerException if source or destination is + * <code>null</code> + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @since Commons IO 1.1 + */ + public static void copyDirectory(File srcDir, File destDir, boolean preserveFileDate) throws IOException { + if (srcDir == null) { + throw new NullPointerException("Source must not be null"); + } + if (destDir == null) { + throw new NullPointerException("Destination must not be null"); + } + if (!srcDir.exists()) { + throw new FileNotFoundException("Source '" + srcDir + "' does not exist"); + } + if (!srcDir.isDirectory()) { + throw new IOException("Source '" + srcDir + "' exists but is not a directory"); + } + if (srcDir.getCanonicalPath().equals(destDir.getCanonicalPath())) { + throw new IOException("Source '" + srcDir + "' and destination '" + destDir + "' are the same"); + } + doCopyDirectory(srcDir, destDir, preserveFileDate); + } + + // ----------------------------------------------------------------------- + /** + * Copies a directory to within another directory preserving the file dates. + * <p> + * This method copies the source directory and all its contents to a + * directory of the same name in the specified destination directory. + * <p> + * The destination directory is created if it does not exist. If the + * destination directory did exist, then this method merges the source with + * the destination, with the source taking precedence. + * + * @param srcDir an existing directory to copy, must not be + * <code>null</code> + * @param destDir the directory to place the copy in, must not be + * <code>null</code> + * @throws NullPointerException if source or destination is + * <code>null</code> + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @since Commons IO 1.2 + */ + public static void copyDirectoryToDirectory(File srcDir, File destDir) throws IOException { + if (srcDir == null) { + throw new NullPointerException("Source must not be null"); + } + if (!(srcDir.exists() && srcDir.isDirectory())) { + throw new IllegalArgumentException("Source '" + destDir + "' is not a directory"); + } + if (destDir == null) { + throw new NullPointerException("Destination must not be null"); + } + if (!(destDir.exists() && destDir.isDirectory())) { + throw new IllegalArgumentException("Destination '" + destDir + "' is not a directory"); + } + copyDirectory(srcDir, new File(destDir, srcDir.getName()), true); + } + + /** + * Copies a file to a new location preserving the file date. + * <p> + * This method copies the contents of the specified source file to the + * specified destination file. The directory holding the destination file is + * created if it does not exist. If the destination file exists, then this + * method will overwrite it. + * + * @param srcFile an existing file to copy, must not be <code>null</code> + * @param destFile the new file, must not be <code>null</code> + * @throws NullPointerException if source or destination is + * <code>null</code> + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @see #copyFileToDirectory(File, File) + */ + public static void copyFile(File srcFile, File destFile) throws IOException { + copyFile(srcFile, destFile, true); + } + + /** + * Copies a file to a new location. + * <p> + * This method copies the contents of the specified source file to the + * specified destination file. The directory holding the destination file is + * created if it does not exist. If the destination file exists, then this + * method will overwrite it. + * + * @param srcFile an existing file to copy, must not be <code>null</code> + * @param destFile the new file, must not be <code>null</code> + * @param preserveFileDate true if the file date of the copy should be the + * same as the original + * @throws NullPointerException if source or destination is + * <code>null</code> + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @see #copyFileToDirectory(File, File, boolean) + */ + public static void copyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException { + if (srcFile == null) { + throw new NullPointerException("Source must not be null"); + } + if (destFile == null) { + throw new NullPointerException("Destination must not be null"); + } + if (!srcFile.exists()) { + throw new FileNotFoundException("Source '" + srcFile + "' does not exist"); + } + if (srcFile.isDirectory()) { + throw new IOException("Source '" + srcFile + "' exists but is a directory"); + } + if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) { + throw new IOException("Source '" + srcFile + "' and destination '" + destFile + "' are the same"); + } + if (!(destFile.getParentFile() != null && destFile.getParentFile().exists())) { + if (!destFile.getParentFile().mkdirs()) { //NOPMD + throw new IOException("Destination '" + destFile + "' directory cannot be created"); + } + } + if (!(destFile.exists() && destFile.canWrite())) { + throw new IOException("Destination '" + destFile + "' exists but is read-only"); + } + doCopyFile(srcFile, destFile, preserveFileDate); + } + + // ----------------------------------------------------------------------- + /** + * Copies a file to a directory preserving the file date. + * <p> + * This method copies the contents of the specified source file to a file of + * the same name in the specified destination directory. The destination + * directory is created if it does not exist. If the destination file + * exists, then this method will overwrite it. + * + * @param srcFile an existing file to copy, must not be <code>null</code> + * @param destDir the directory to place the copy in, must not be + * <code>null</code> + * @throws NullPointerException if source or destination is null + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @see #copyFile(File, File, boolean) + */ + public static void copyFileToDirectory(File srcFile, File destDir) throws IOException { + copyFileToDirectory(srcFile, destDir, true); + } + + /** + * Copies a file to a directory optionally preserving the file date. + * <p> + * This method copies the contents of the specified source file to a file of + * the same name in the specified destination directory. The destination + * directory is created if it does not exist. If the destination file + * exists, then this method will overwrite it. + * + * @param srcFile an existing file to copy, must not be <code>null</code> + * @param destDir the directory to place the copy in, must not be + * <code>null</code> + * @param preserveFileDate true if the file date of the copy should be the + * same as the original + * @throws NullPointerException if source or destination is + * <code>null</code> + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @see #copyFile(File, File, boolean) + * @since Commons IO 1.3 + */ + public static void copyFileToDirectory(File srcFile, File destDir, boolean preserveFileDate) throws IOException { + if (destDir == null) { + throw new NullPointerException("Destination must not be null"); + } + if (!(destDir.exists() && destDir.isDirectory())) { + throw new IllegalArgumentException("Destination '" + destDir + "' is not a directory"); + } + copyFile(srcFile, new File(destDir, srcFile.getName()), preserveFileDate); + } + + // ----------------------------------------------------------------------- + /** + * 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); + } + } + + /** + * Recursively schedule directory for deletion on JVM exit. + * + * @param directory directory to delete, must not be <code>null</code> + * @throws NullPointerException if the directory is <code>null</code> + * @throws IOException in case deletion is unsuccessful + */ + private static void deleteDirectoryOnExit(File directory) throws IOException { + if (!directory.exists()) { + return; + } + + cleanDirectoryOnExit(directory); + directory.deleteOnExit(); + } + + /** + * Internal copy directory method. + * + * @param srcDir the validated source directory, must not be + * <code>null</code> + * @param destDir the validated destination directory, must not be + * <code>null</code> + * @param preserveFileDate whether to preserve the file date + * @throws IOException if an error occurs + * @since Commons IO 1.1 + */ + private static void doCopyDirectory(File srcDir, File destDir, boolean preserveFileDate) throws IOException { + if (destDir.exists()) { + if (!destDir.isDirectory()) { + throw new IOException("Destination '" + destDir + "' exists but is not a directory"); + } + } else { + if (!destDir.mkdirs()) { + throw new IOException("Destination '" + destDir + "' directory cannot be created"); + } + if (preserveFileDate) { + destDir.setLastModified(srcDir.lastModified()); + } + } + if (!destDir.canWrite()) { + throw new IOException("Destination '" + destDir + "' cannot be written to"); + } + // recurse + File[] files = srcDir.listFiles(); + if (files == null) { // null if security restricted + throw new IOException("Failed to list contents of " + srcDir); + } + for (int i = 0; i < files.length; i++) { + File copiedFile = new File(destDir, files[i].getName()); + if (files[i].isDirectory()) { + doCopyDirectory(files[i], copiedFile, preserveFileDate); + } else { + doCopyFile(files[i], copiedFile, preserveFileDate); + } + } + } + + /** + * Internal copy file method. + * + * @param srcFile the validated source file, must not be <code>null</code> + * @param destFile the validated destination file, must not be + * <code>null</code> + * @param preserveFileDate whether to preserve the file date + * @throws IOException if an error occurs + */ + private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException { + if (destFile.exists() && destFile.isDirectory()) { + throw new IOException("Destination '" + destFile + "' exists but is a directory"); + } + + FileInputStream input = new FileInputStream(srcFile); + try { + FileOutputStream output = new FileOutputStream(destFile); + try { + IOHelper.copy(input, output); + } finally { + IOHelper.closeQuietly(output); + } + } finally { + IOHelper.closeQuietly(input); + } + + if (srcFile.length() != destFile.length()) { + throw new IOException("Failed to copy full contents from '" + srcFile + "' to '" + destFile + "'"); + } + if (preserveFileDate) { + destFile.setLastModified(srcFile.lastModified()); + } + } + + /** + * Schedule a file to be deleted when JVM exits. If file is directory delete + * it and all sub-directories. + * + * @param file file or directory to delete, must not be <code>null</code> + * @throws NullPointerException if the file is <code>null</code> + * @throws IOException in case deletion is unsuccessful + */ + public static void forceDeleteOnExit(File file) throws IOException { + if (file.isDirectory()) { + deleteDirectoryOnExit(file); + } else { + file.deleteOnExit(); + } + } + +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/IOHelper.java b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/IOHelper.java new file mode 100644 index 0000000000..c8cc056b8f --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/IOHelper.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.sca.contribution.service.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.JarURLConnection; +import java.net.URL; +import java.util.jar.JarFile; + +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; + } + + public static InputStream getInputStream(URL url) throws IOException { + return new SafeURLInputStream(url); + } + + /** + * This class is a workaround for URL stream issue as illustrated below. + * InputStream is=url.getInputStream(); is.close(); // This line doesn't close + * the JAR file if the URL is a jar entry like "jar:file:/a.jar!/my.composite" We + * also need to turn off the JarFile cache. + * + * @see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4950148 + * + * @version $Rev$ $Date$ + */ + public static class SafeURLInputStream extends InputStream { + private JarFile jarFile; + private InputStream is; + + public SafeURLInputStream(URL url) throws IOException { + String protocol = url.getProtocol(); + if (protocol != null && (protocol.equals("jar"))) { + JarURLConnection connection = (JarURLConnection)url.openConnection(); + // We cannot use cache + connection.setUseCaches(false); + try { + is = connection.getInputStream(); + } catch (IOException e) { + throw e; + } + jarFile = connection.getJarFile(); + } else { + is = url.openStream(); + } + } + + public SafeURLInputStream(JarURLConnection connection) throws IOException { + // We cannot use cache + connection.setUseCaches(false); + is = connection.getInputStream(); + jarFile = connection.getJarFile(); + } + + @Override + public int available() throws IOException { + return is.available(); + } + + @Override + public void close() throws IOException { + is.close(); + // We need to close the JAR file + if (jarFile != null) { + jarFile.close(); + } + } + + @Override + public synchronized void mark(int readlimit) { + is.mark(readlimit); + } + + @Override + public boolean markSupported() { + return is.markSupported(); + } + + @Override + public int read() throws IOException { + return is.read(); + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + return is.read(b, off, len); + } + + @Override + public int read(byte[] b) throws IOException { + return is.read(b); + } + + @Override + public synchronized void reset() throws IOException { + is.reset(); + } + + @Override + public long skip(long n) throws IOException { + return is.skip(n); + } + } +}
\ No newline at end of file diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.ContributionFactory b/branches/sca-java-0.99/modules/contribution-impl/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.ContributionFactory new file mode 100644 index 0000000000..e935f6eb63 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.ContributionFactory @@ -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.
+
+org.apache.tuscany.sca.contribution.impl.ContributionFactoryImpl
\ No newline at end of file diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.PackageProcessor b/branches/sca-java-0.99/modules/contribution-impl/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.PackageProcessor new file mode 100644 index 0000000000..b644709266 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.PackageProcessor @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+org.apache.tuscany.sca.contribution.processor.impl.FolderContributionProcessor;type=application/vnd.tuscany.folder
+org.apache.tuscany.sca.contribution.processor.impl.JarContributionProcessor;type=application/x-compressed
diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/FolderContributionPackageProcessorTestCase.java b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/FolderContributionPackageProcessorTestCase.java new file mode 100644 index 0000000000..7daf302487 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/FolderContributionPackageProcessorTestCase.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.sca.contribution.processor; + +import java.io.File; +import java.net.URI; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.processor.impl.FolderContributionProcessor; + +/** + * Folder Package Processor test case + * Verifies proper handle of File System structured contributions + * + * @version $Rev$ $Date$ + */ +public class FolderContributionPackageProcessorTestCase extends TestCase { + private static final String FOLDER_CONTRIBUTION = "."; + + private File contributionRoot; + + @Override + protected void setUp() throws Exception { + this.contributionRoot = new File(FOLDER_CONTRIBUTION); + } + + public final void testProcessPackageArtifacts() throws Exception { + FolderContributionProcessor folderProcessor = new FolderContributionProcessor(); + + List<URI> artifacts = folderProcessor.getArtifacts(contributionRoot.toURL(), null); + assertNotNull(artifacts); + } +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/JarContributionPackageProcessorTestCase.java b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/JarContributionPackageProcessorTestCase.java new file mode 100644 index 0000000000..6ed735292f --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/JarContributionPackageProcessorTestCase.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.sca.contribution.processor; + +import java.io.InputStream; +import java.net.URI; +import java.net.URL; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.processor.impl.JarContributionProcessor; +import org.apache.tuscany.sca.contribution.service.util.IOHelper; + +/** + * JAR Package Processor test case + * Verifies proper handle of JAR Archives contributions + * + * @version $Rev$ $Date$ + */ + +public class JarContributionPackageProcessorTestCase extends TestCase { + private static final String JAR_CONTRIBUTION = "/repository/sample-calculator.jar"; + + @Override + protected void setUp() throws Exception { + } + + public final void testProcessPackageArtifacts() throws Exception { + JarContributionProcessor jarProcessor = new JarContributionProcessor(); + + URL jarURL = getClass().getResource(JAR_CONTRIBUTION); + InputStream jarStream = jarURL.openStream(); + List<URI> artifacts = null; + try { + artifacts = jarProcessor.getArtifacts(jarURL, jarStream); + } finally { + IOHelper.closeQuietly(jarStream); + } + + assertNotNull(artifacts); + } +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/URLartifactProcessorExtensionPointTestCase.java b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/URLartifactProcessorExtensionPointTestCase.java new file mode 100644 index 0000000000..d3dd49ca5f --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/URLartifactProcessorExtensionPointTestCase.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.sca.contribution.processor; + +import java.net.URI; +import java.net.URL; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.contribution.service.ContributionResolveException; + + +/** + * URL Artifact Processor Extension Point test case + * Verifies the right registration and lookup for processors that handle filename and file types + * + * @version $Rev$ $Date$ + */ +public class URLartifactProcessorExtensionPointTestCase extends TestCase { + URLArtifactProcessorExtensionPoint artifactProcessors; + + @Override + protected void setUp() throws Exception { + artifactProcessors = new DefaultURLArtifactProcessorExtensionPoint(null); + artifactProcessors.addArtifactProcessor(new FileTypeArtifactProcessor()); + artifactProcessors.addArtifactProcessor(new FileNameArtifactProcessor()); + } + + + public final void testFileTypeProcessor() { + URLArtifactProcessor processor = null; + + processor = artifactProcessors.getProcessor(".m1"); + assertNotNull(processor); + } + + + public final void testFileNameProcessor() { + URLArtifactProcessor processor = null; + + processor = artifactProcessors.getProcessor("file.m2"); + assertNotNull(processor); + + } + + @Override + protected void tearDown() throws Exception { + } + + /** + * Internal mock classes + * + */ + + class M1 { + + } + + class M2 { + + } + + class FileTypeArtifactProcessor implements URLArtifactProcessor<M1> { + public FileTypeArtifactProcessor() { + } + + public M1 read(URL contributionURL, URI uri, URL url) throws ContributionReadException { + return null; + } + + public void resolve(M1 m1, ModelResolver resolver) throws ContributionResolveException { + //stub + } + + public String getArtifactType() { + return ".m1"; + } + + public Class<M1> getModelType() { + return M1.class; + } + } + + class FileNameArtifactProcessor implements URLArtifactProcessor<M2> { + public FileNameArtifactProcessor() { + } + + public M2 read(URL contributionURL, URI uri, URL url) throws ContributionReadException { + return null; + } + + public void resolve(M2 m2, ModelResolver resolver) throws ContributionResolveException { + //stub + } + + public String getArtifactType() { + return "file.m2"; + } + + public Class<M2> getModelType() { + return M2.class; + } + } + +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/ArtifactResolverTestCase.java b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/ArtifactResolverTestCase.java new file mode 100644 index 0000000000..510febf07a --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/ArtifactResolverTestCase.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.sca.contribution.resolver; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.ContributionFactory; +import org.apache.tuscany.sca.contribution.DeployedArtifact; +import org.apache.tuscany.sca.contribution.impl.ContributionFactoryImpl; +import org.apache.tuscany.sca.contribution.resolver.impl.ModelResolverImpl; + +/** + * Test DefaultArtifactResolver. + * + * @version $Rev$ $Date$ + */ +public class ArtifactResolverTestCase extends TestCase { + + private ModelResolver resolver; + private ContributionFactory factory; + + @Override + protected void setUp() throws Exception { + resolver = new ModelResolverImpl(getClass().getClassLoader()); + factory = new ContributionFactoryImpl(); + } + + @Override + protected void tearDown() throws Exception { + } + + public void testResolved() { + Model a = new Model("a"); + resolver.addModel(a); + Model x = new Model("a"); + x = resolver.resolveModel(Model.class, x); + assertTrue(x == a); + } + + public void testUnresolved() { + Model x = new Model("a"); + Model y = resolver.resolveModel(Model.class, x); + assertTrue(x == y); + } + + public void testResolveClass() { + ClassReference ref = new ClassReference(getClass().getName()); + ClassReference clazz = resolver.resolveModel(ClassReference.class, ref); + assertTrue(clazz.getJavaClass() == getClass()); + } + + public void testUnresolvedClass() { + ClassReference ref = new ClassReference("NonExistentClass"); + ClassReference clazz = resolver.resolveModel(ClassReference.class, ref); + assertTrue(clazz.isUnresolved()); + assertTrue(clazz.getJavaClass() == null); + } + + public void testResolvedArtifact() { + DeployedArtifact artifact = factory.createDeployedArtifact(); + artifact.setURI("foo/bar"); + resolver.addModel(artifact); + DeployedArtifact x = factory.createDeployedArtifact(); + x.setURI("foo/bar"); + x = resolver.resolveModel(DeployedArtifact.class, x); + assertTrue(x == artifact); + } + + class Model { + private String name; + + Model(String name) { + this.name = name; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return name.equals(((Model)obj).name); + } + } + +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleArtifactResolverTestCase.java b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleArtifactResolverTestCase.java new file mode 100644 index 0000000000..c76c859a25 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleArtifactResolverTestCase.java @@ -0,0 +1,130 @@ + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.contribution.resolver; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.ContributionFactory; +import org.apache.tuscany.sca.contribution.DefaultModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.DeployedArtifact; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.impl.ContributionFactoryImpl; + +/** + * Test DefaultArtifactResolver. + * + * @version $Rev$ $Date$ + */ +public class ExtensibleArtifactResolverTestCase extends TestCase { + private ExtensibleModelResolver resolver; + + private ContributionFactory factory; + + @Override + protected void setUp() throws Exception { + + ModelResolverExtensionPoint resolvers = new DefaultModelResolverExtensionPoint(); + resolvers.addResolver(Model.class, TestModelResolver.class); + + ModelFactoryExtensionPoint factories = new DefaultModelFactoryExtensionPoint(); + + resolver = new ExtensibleModelResolver(null, resolvers, factories); + + factory = new ContributionFactoryImpl(); + } + + @Override + protected void tearDown() throws Exception { + } + + public void testResolvedDefault() { + OtherModel a = new OtherModel("a"); + resolver.addModel(a); + OtherModel x = new OtherModel("a"); + x = resolver.resolveModel(OtherModel.class, x); + assertTrue(x == a); + } + + public void testResolvedRegisteredClass() { + Model a = new Model("a"); + resolver.addModel(a); + Model x = new Model("a"); + x = resolver.resolveModel(Model.class, x); + assertTrue(x == a); + } + + public void testUnresolvedDefault() { + OtherModel x = new OtherModel("a"); + OtherModel y = resolver.resolveModel(OtherModel.class, x); + assertTrue(x == y); + } + + public void testUnresolved() { + Model x = new Model("a"); + Model y = resolver.resolveModel(Model.class, x); + assertTrue(x == y); + } + + public void testResolvedArtifact() { + DeployedArtifact artifact = factory.createDeployedArtifact(); + artifact.setURI("foo/bar"); + resolver.addModel(artifact); + DeployedArtifact x = factory.createDeployedArtifact(); + x.setURI("foo/bar"); + x = resolver.resolveModel(DeployedArtifact.class, x); + assertTrue(x == artifact); + } + + class Model { + private String name; + + Model(String name) { + this.name = name; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return name.equals(((Model)obj).name); + } + } + + class OtherModel { + private String name; + + OtherModel(String name) { + this.name = name; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return name.equals(((OtherModel)obj).name); + } + } +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/TestModelResolver.java b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/TestModelResolver.java new file mode 100644 index 0000000000..d0db01fc09 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/TestModelResolver.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.sca.contribution.resolver; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; + +/** + * A default implementation of an artifact resolver, based on a map. + * + * @version $Rev$ $Date$ + */ +public class TestModelResolver implements ModelResolver { + private static final long serialVersionUID = -7826976465762296634L; + + private Map<Object, Object> map = new HashMap<Object, Object>(); + + protected Contribution contribution; + + public TestModelResolver(Contribution contribution, ModelFactoryExtensionPoint modelFactories) { + this.contribution = contribution; + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + Object resolved = map.get(unresolved); + if (resolved != null) { + // Return the resolved object + return modelClass.cast(resolved); + } + // Return the unresolved object + return unresolved; + } + + public void addModel(Object resolved) { + map.put(resolved, resolved); + } + + public Object removeModel(Object resolved) { + return map.remove(resolved); + } + +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContentTypeDescriberImplTestCase.java b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContentTypeDescriberImplTestCase.java new file mode 100644 index 0000000000..e5e84afe7d --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContentTypeDescriberImplTestCase.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.contribution.services; + +import java.net.URL; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.ContentType; +import org.apache.tuscany.sca.contribution.service.impl.ArtifactTypeDescriberImpl; + +public class ContentTypeDescriberImplTestCase extends TestCase { + private ArtifactTypeDescriberImpl contentTypeDescriber; + + public void testResolveContentType() throws Exception { + URL artifactURL = getClass().getResource("/test.composite"); + assertEquals(ContentType.COMPOSITE, contentTypeDescriber.getType(artifactURL, null)); + } + + + public void testResolveUnknownContentType() throws Exception { + URL artifactURL = getClass().getResource("/test.ext"); + assertNull(contentTypeDescriber.getType(artifactURL, null)); + } + + public void testDefaultContentType() throws Exception { + URL artifactURL = getClass().getResource("/test.ext"); + assertEquals("application/vnd.tuscany.ext", + contentTypeDescriber.getType(artifactURL, "application/vnd.tuscany.ext")); + } + + @Override + protected void setUp() throws Exception { + contentTypeDescriber = new ArtifactTypeDescriberImpl(); + } + +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContributionMetadataDocumentProcessorTestCaseFIXME.java b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContributionMetadataDocumentProcessorTestCaseFIXME.java new file mode 100644 index 0000000000..0ebee35df7 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContributionMetadataDocumentProcessorTestCaseFIXME.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.sca.contribution.services; + +import junit.framework.TestCase; + +/** + * @version $Rev$ $Date$ + */ +//FIXME Why is this test case all commented out? +public class ContributionMetadataDocumentProcessorTestCaseFIXME extends TestCase { + +// private static final String VALID_XML = +// "<?xml version=\"1.0\" encoding=\"ASCII\"?>" +// + "<contribution xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:ns=\"http://ns\">" +// + "<deployable composite=\"ns:Composite1\"/>" +// + "<deployable composite=\"ns:Composite2\"/>" +// + "<import namespace=\"http://ns2\" location=\"sca://contributions/002/\"/>" +// + "<export namespace=\"http://ns1\"/>" +// + "</contribution>"; +// +// private static final String INVALID_XML = +// "<?xml version=\"1.0\" encoding=\"ASCII\"?>" +// + "<contribution xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:ns=\"http://ns\">" +// + "<deployable composite=\"ns:Composite1\"/>" +// + "<deployable composite=\"ns3:Composite1\"/>" +// + "<import namespace=\"http://ns2\" location=\"sca://contributions/002/\"/>" +// + "<export namespace=\"http://ns1\"/>" +// + "</contribution>"; + +// private XMLInputFactory xmlFactory; + + @Override + protected void setUp() throws Exception { +// xmlFactory = XMLInputFactory.newInstance(); + } + + public void testLoad() throws Exception { +// XMLStreamReader reader = xmlFactory.createXMLStreamReader(new StringReader(VALID_XML)); +// +// ContributionFactory factory = new ContributionFactoryImpl(); +// ContributionMetadataLoaderImpl loader = +// new ContributionMetadataLoaderImpl(new DefaultAssemblyFactory(), factory); +// Contribution contribution = factory.createContribution(); +// contribution.setModelResolver(new ModelResolverImpl(getClass().getClassLoader())); +// loader.load(contribution, reader); +// assertNotNull(contribution); +// assertEquals(1, contribution.getImports().size()); +// assertEquals(1, contribution.getExports().size()); +// assertEquals(2, contribution.getDeployables().size()); + } + + public void testLoadInvalid() throws Exception { +// XMLStreamReader reader = xmlFactory.createXMLStreamReader(new StringReader(INVALID_XML)); +// ContributionFactory factory = new ContributionFactoryImpl(); +// ContributionMetadataLoaderImpl loader = +// new ContributionMetadataLoaderImpl(new DefaultAssemblyFactory(), factory); +// Contribution contribution = factory.createContribution(); +// contribution.setModelResolver(new ModelResolverImpl(getClass().getClassLoader())); +// try { +// loader.load(contribution, reader); +// fail("InvalidException should have been thrown"); +// } catch (InvalidValueException e) { +// assertTrue(true); +// } + } +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContributionRepositoryTestCase.java b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContributionRepositoryTestCase.java new file mode 100644 index 0000000000..8a476a86bc --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContributionRepositoryTestCase.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.sca.contribution.services; + +import java.io.File; +import java.io.InputStream; +import java.net.URL; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.service.impl.ContributionRepositoryImpl; +import org.apache.tuscany.sca.contribution.service.util.FileHelper; + +public class ContributionRepositoryTestCase extends TestCase { + private ContributionRepositoryImpl repository; + + @Override + protected void setUp() throws Exception { + // create repository (this should re-create the root directory) + this.repository = new ContributionRepositoryImpl("target/repository/"); + repository.init(); + } + + public void testStore() throws Exception { + String resourceLocation = "/repository/sample-calculator.jar"; + String contribution = "sample-calculator.jar"; + URL contributionLocation = getClass().getResource(resourceLocation); + InputStream contributionStream = getClass().getResourceAsStream(resourceLocation); + repository.store(contribution, contributionLocation, contributionStream); + + URL contributionURL = repository.find(contribution); + assertNotNull(contributionURL); + } + + public void testRemove() throws Exception { + String resourceLocation = "/repository/sample-calculator.jar"; + String contribution = "sample-calculator.jar"; + URL contributionLocation = getClass().getResource(resourceLocation); + InputStream contributionStream = getClass().getResourceAsStream(resourceLocation); + repository.store(contribution, contributionLocation, contributionStream); + + repository.remove(contribution); + URL contributionURL = repository.find(contribution); + assertNull(contributionURL); + } + + public void testList() throws Exception { + String resourceLocation = "/repository/sample-calculator.jar"; + String contribution = "sample-calculator.jar"; + URL contributionLocation = getClass().getResource(resourceLocation); + InputStream contributionStream = getClass().getResourceAsStream(resourceLocation); + repository.store(contribution, contributionLocation, contributionStream); + + assertEquals(1, repository.list().size()); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + FileHelper.deleteDirectory(new File("target/repository")); + } +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/PackageTypeDescriberImplTestCase.java b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/PackageTypeDescriberImplTestCase.java new file mode 100644 index 0000000000..13d3e45d66 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/PackageTypeDescriberImplTestCase.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.sca.contribution.services; + +import java.net.URL; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.ContentType; +import org.apache.tuscany.sca.contribution.service.impl.PackageTypeDescriberImpl; + +public class PackageTypeDescriberImplTestCase extends TestCase { + private PackageTypeDescriberImpl packageTypeDescriber; + + public void testResolveArchivePackageType() throws Exception { + URL artifactURL = getClass().getResource("/deployables/sample-calculator.jar"); + assertEquals(ContentType.JAR, this.packageTypeDescriber.getType(artifactURL, null)); + } + + public void testResolveFolderPackageType() throws Exception { + URL artifactURL = getClass().getResource("/deployables/"); + assertEquals(ContentType.FOLDER, this.packageTypeDescriber.getType(artifactURL, null)); + } + + public void testResolveFolder2PackageType() throws Exception { + URL artifactURL = getClass().getResource("/deployables"); + assertEquals(ContentType.FOLDER, this.packageTypeDescriber.getType(artifactURL, null)); + } + + + public void testResolveUnknownPackageType() throws Exception { + URL artifactURL = getClass().getResource("/test.ext"); + assertNull(this.packageTypeDescriber.getType(artifactURL, null)); + } + + public void testDefaultPackageType() throws Exception { + URL artifactURL = getClass().getResource("/test.ext"); + assertEquals("application/vnd.tuscany.ext", + packageTypeDescriber.getType(artifactURL, "application/vnd.tuscany.ext")); + } + + @Override + protected void setUp() throws Exception { + packageTypeDescriber = new PackageTypeDescriberImpl(); + } + +} diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/test/resources/deployables/sample-calculator.jar b/branches/sca-java-0.99/modules/contribution-impl/src/test/resources/deployables/sample-calculator.jar Binary files differnew file mode 100644 index 0000000000..0ca3a1b781 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/test/resources/deployables/sample-calculator.jar diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/test/resources/repository/sample-calculator.jar b/branches/sca-java-0.99/modules/contribution-impl/src/test/resources/repository/sample-calculator.jar Binary files differnew file mode 100644 index 0000000000..9c46c679d2 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/test/resources/repository/sample-calculator.jar diff --git a/branches/sca-java-0.99/modules/contribution-impl/src/test/resources/test.composite b/branches/sca-java-0.99/modules/contribution-impl/src/test/resources/test.composite new file mode 100644 index 0000000000..1e09549194 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/test/resources/test.composite @@ -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/branches/sca-java-0.99/modules/contribution-impl/src/test/resources/test.ext b/branches/sca-java-0.99/modules/contribution-impl/src/test/resources/test.ext new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/branches/sca-java-0.99/modules/contribution-impl/src/test/resources/test.ext |