summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl')
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/.checkstyle25
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/.pmd20
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/.ruleset190
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/DISCLAIMER8
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/LICENSE205
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/NOTICE6
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/pom.xml45
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ArtifactImpl.java52
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionExportImpl.java52
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionFactoryImpl.java51
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImpl.java74
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImportImpl.java61
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/DeployedArtifactImpl.java43
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/FolderContributionProcessor.java112
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/InvalidFolderContributionException.java41
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/InvalidFolderContributionURIException.java41
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/JarContributionProcessor.java97
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/resolver/impl/ModelResolverImpl.java87
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ArtifactTypeDescriberImpl.java106
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionMetadataLoaderImpl.java132
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionRepositoryImpl.java266
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionServiceImpl.java332
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/InvalidContributionMetadataException.java57
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/InvalidContributionURIException.java57
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/InvalidValueException.java46
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/PackageTypeDescriberImpl.java98
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/FileHelper.java704
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/IOHelper.java182
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/FolderContributionPackageProcessorTestCase.java45
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/JarContributionPackageProcessorTestCase.java52
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/ArtifactResolverTestCase.java88
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContentTypeDescriberImplTestCase.java53
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContributionMetadataLoaderTestCase.java96
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContributionRepositoryTestCase.java79
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/PackageTypeDescriberImplTestCase.java52
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/resources/deployables/sample-calculator.jarbin0 -> 26901 bytes
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/resources/repository/sample-calculator.jarbin0 -> 29164 bytes
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/resources/test.composite22
-rw-r--r--sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/resources/test.ext0
39 files changed, 3677 insertions, 0 deletions
diff --git a/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/.checkstyle b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/.checkstyle
new file mode 100644
index 0000000000..ace5fe6f53
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/.pmd b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/.pmd
new file mode 100644
index 0000000000..84af2f4d5d
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/.ruleset b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/.ruleset
new file mode 100644
index 0000000000..ac8671859d
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/DISCLAIMER b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/DISCLAIMER
new file mode 100644
index 0000000000..d68a410903
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/LICENSE b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/LICENSE
new file mode 100644
index 0000000000..8aa906c321
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/NOTICE b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/NOTICE
new file mode 100644
index 0000000000..94481d6cfa
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/pom.xml b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/pom.xml
new file mode 100644
index 0000000000..9dbc9bb569
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-modules</artifactId>
+ <version>0.90-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.90-incubating-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.woodstox</groupId>
+ <artifactId>wstx-asl</artifactId>
+ <version>3.2.0</version>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ArtifactImpl.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ArtifactImpl.java
new file mode 100644
index 0000000000..daf9f2289f
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ArtifactImpl.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.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;
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionExportImpl.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionExportImpl.java
new file mode 100644
index 0000000000..90bde0f67e
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionExportImpl.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.contribution.impl;
+
+import org.apache.tuscany.sca.contribution.ContributionExport;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+
+/**
+ * The representation of an export for the contribution
+ *
+ * @version $Rev$ $Date$
+ */
+public class ContributionExportImpl implements ContributionExport {
+ private String namespace; // The namespace to be imported
+ private ModelResolver modelResolver;
+
+ protected ContributionExportImpl() {
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+
+ public ModelResolver getModelResolver() {
+ return modelResolver;
+ }
+
+ public void setModelResolver(ModelResolver modelResolver) {
+ this.modelResolver = modelResolver;
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionFactoryImpl.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionFactoryImpl.java
new file mode 100644
index 0000000000..a349939a0e
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionFactoryImpl.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.impl;
+
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.ContributionExport;
+import org.apache.tuscany.sca.contribution.ContributionFactory;
+import org.apache.tuscany.sca.contribution.ContributionImport;
+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();
+ }
+
+ public ContributionImport createContributionImport() {
+ return new ContributionImportImpl();
+ }
+
+ public ContributionExport createContributionExport() {
+ return new ContributionExportImpl();
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImpl.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImpl.java
new file mode 100644
index 0000000000..8d246eaf1c
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/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.ContributionExport;
+import org.apache.tuscany.sca.contribution.ContributionImport;
+import org.apache.tuscany.sca.contribution.DeployedArtifact;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+
+/**
+ * The representation of a deployed contribution
+ *
+ * @version $Rev: 531146 $ $Date: 2007-04-21 22:40:50 -0700 (Sat, 21 Apr 2007) $
+ */
+public class ContributionImpl extends ArtifactImpl implements Contribution {
+ private List<ContributionExport> exports = new ArrayList<ContributionExport>();
+ private List<ContributionImport> imports = new ArrayList<ContributionImport>();
+ 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<ContributionExport> getExports() {
+ return exports;
+ }
+
+ public List<ContributionImport> 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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImportImpl.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImportImpl.java
new file mode 100644
index 0000000000..3f241ff3d0
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImportImpl.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.contribution.impl;
+
+import org.apache.tuscany.sca.contribution.ContributionImport;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+
+/**
+ * The representation of an import for the contribution
+ *
+ * @version $Rev: 527398 $ $Date: 2007-04-10 23:43:31 -0700 (Tue, 10 Apr 2007) $
+ */
+public class ContributionImportImpl implements ContributionImport {
+ private String namespace; // The namespace to be imported
+ private String location; // Optional location to hint the where it should be imported
+ private ModelResolver modelResolver;
+
+ protected ContributionImportImpl() {
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public void setLocation(String location) {
+ this.location = location;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+
+ public ModelResolver getModelResolver() {
+ return modelResolver;
+ }
+
+ public void setModelResolver(ModelResolver modelResolver) {
+ this.modelResolver = modelResolver;
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/DeployedArtifactImpl.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/DeployedArtifactImpl.java
new file mode 100644
index 0000000000..1d9bb04114
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/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: 527398 $ $Date: 2007-04-10 23:43:31 -0700 (Tue, 10 Apr 2007) $
+ */
+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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/FolderContributionProcessor.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/FolderContributionProcessor.java
new file mode 100644
index 0000000000..5e22363f41
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/FolderContributionProcessor.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.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
+ 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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/InvalidFolderContributionException.java b/sca-java-1.x/branches/sca-java-0.90/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/sca-java-1.x/branches/sca-java-0.90/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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/InvalidFolderContributionURIException.java b/sca-java-1.x/branches/sca-java-0.90/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/sca-java-1.x/branches/sca-java-0.90/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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/JarContributionProcessor.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/JarContributionProcessor.java
new file mode 100644
index 0000000000..4ffec693d0
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/JarContributionProcessor.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.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;
+ }
+ if (entry.isDirectory()) {
+ continue;
+ }
+
+ // 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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/resolver/impl/ModelResolverImpl.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/resolver/impl/ModelResolverImpl.java
new file mode 100644
index 0000000000..ffc82b908f
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/resolver/impl/ModelResolverImpl.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.contribution.resolver.impl;
+
+import java.lang.ref.WeakReference;
+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);
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ArtifactTypeDescriberImpl.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ArtifactTypeDescriberImpl.java
new file mode 100644
index 0000000000..174a09a0c6
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionMetadataLoaderImpl.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionMetadataLoaderImpl.java
new file mode 100644
index 0000000000..a089756308
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionMetadataLoaderImpl.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.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 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.ContributionExport;
+import org.apache.tuscany.sca.contribution.ContributionFactory;
+import org.apache.tuscany.sca.contribution.ContributionImport;
+import org.apache.tuscany.sca.contribution.service.ContributionMetadataLoader;
+import org.apache.tuscany.sca.contribution.service.ContributionMetadataLoaderException;
+
+/**
+ * Loader that handles contribution metadata files
+ *
+ * @version $Rev: 515261 $ $Date: 2007-03-06 11:22:46 -0800 (Tue, 06 Mar 2007) $
+ */
+public class ContributionMetadataLoaderImpl implements ContributionMetadataLoader {
+ 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 static final QName IMPORT = new QName(SCA10_NS, "import");
+ private static final QName EXPORT = new QName(SCA10_NS, "export");
+
+ private final AssemblyFactory assemblyFactory;
+ private final ContributionFactory contributionFactory;
+
+ public ContributionMetadataLoaderImpl(AssemblyFactory assemblyFactory, ContributionFactory contributionFactory) {
+ super();
+ this.assemblyFactory = assemblyFactory;
+ this.contributionFactory = contributionFactory;
+ }
+
+ public QName getXMLType() {
+ return CONTRIBUTION;
+ }
+
+ public void load(Contribution contribution, XMLStreamReader reader) throws XMLStreamException, ContributionMetadataLoaderException {
+ String targetNameSpaceURI = null;
+
+ while (true) {
+ int event = reader.next();
+ switch (event) {
+ case START_ELEMENT:
+ QName 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 InvalidValueException("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 InvalidValueException("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 if (IMPORT.equals(element)) {
+ String ns = reader.getAttributeValue(null, "namespace");
+ if (ns == null) {
+ throw new InvalidValueException("Attribute 'namespace' is missing");
+ }
+ String location = reader.getAttributeValue(null, "location");
+ ContributionImport contributionImport = this.contributionFactory.createContributionImport();
+ if (location != null) {
+ contributionImport.setLocation(location);
+ }
+ contributionImport.setNamespace(ns);
+ contribution.getImports().add(contributionImport);
+ } else if (EXPORT.equals(element)) {
+ String ns = reader.getAttributeValue(null, "namespace");
+ if (ns == null) {
+ throw new InvalidValueException("Attribute 'namespace' is missing");
+ }
+ ContributionExport contributionExport = this.contributionFactory.createContributionExport();
+ contributionExport.setNamespace(ns);
+ contribution.getExports().add(contributionExport);
+ }
+ break;
+ case XMLStreamConstants.END_ELEMENT:
+ if (CONTRIBUTION.equals(reader.getName())) {
+ return;
+ }
+ break;
+
+ }
+ }
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionRepositoryImpl.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionRepositoryImpl.java
new file mode 100644
index 0000000000..e2dc89782d
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionRepositoryImpl.java
@@ -0,0 +1,266 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.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.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> contributionMap = new HashMap<String, String>();
+
+ 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());
+ contributionMap.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());
+ contributionMap.put(contribution, relative.toString());
+ saveMap();
+
+ return location.toURL();
+ }
+
+ public URL find(String contribution) {
+ if (contribution == null) {
+ return null;
+ }
+ String location = contributionMap.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.contributionMap.remove(contribution);
+ saveMap();
+ } catch (IOException ioe) {
+ // handle file could not be removed
+ }
+ }
+ }
+
+ public List<String> list() {
+ return new ArrayList<String>(contributionMap.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");
+ contributionMap.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 : contributionMap.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() {
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionServiceImpl.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionServiceImpl.java
new file mode 100644
index 0000000000..196c9bc15a
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionServiceImpl.java
@@ -0,0 +1,332 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.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.processor.PackageProcessor;
+import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.contribution.service.ContributionException;
+import org.apache.tuscany.sca.contribution.service.ContributionMetadataLoaderException;
+import org.apache.tuscany.sca.contribution.service.ContributionRepository;
+import org.apache.tuscany.sca.contribution.service.ContributionService;
+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;
+
+ /**
+ * xml factory used to create reader instance to load contribution metadata
+ */
+ private XMLInputFactory xmlFactory;
+
+ /**
+ * contribution metadata loader
+ */
+ private ContributionMetadataLoaderImpl contributionLoader;
+
+ /**
+ * Contribution registry This is a registry of processed Contributions indexed by URI
+ */
+ private Map<String, Contribution> contributionRegistry = new ConcurrentHashMap<String, Contribution>();
+
+ /**
+ * Contribution model facotry
+ */
+ private ContributionFactory contributionFactory;
+
+
+ public ContributionServiceImpl(ContributionRepository repository,
+ PackageProcessor packageProcessor,
+ URLArtifactProcessor artifactProcessor,
+ AssemblyFactory assemblyFactory,
+ ContributionFactory contributionFactory,
+ XMLInputFactory xmlFactory) {
+ super();
+ this.contributionRepository = repository;
+ this.packageProcessor = packageProcessor;
+ this.artifactProcessor = artifactProcessor;
+ this.xmlFactory = xmlFactory;
+
+ this.contributionFactory = contributionFactory;
+ this.contributionLoader = new ContributionMetadataLoaderImpl(assemblyFactory, contributionFactory);
+ }
+
+ 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, ModelResolver modelResolver)
+ throws ContributionException, IOException {
+
+ return addContribution(contributionURI, sourceURL, input, modelResolver, true);
+ }
+
+ private Contribution initializeContributionMetadata(URL sourceURL, ModelResolver modelResolver) throws ContributionException {
+ Contribution contributionMetadata = null;
+ URL contributionMetadataURL;
+ URL generatedContributionMetadataURL;
+ InputStream metadataStream = null;
+
+ URL[] clUrls = {sourceURL};
+ URLClassLoader cl = new URLClassLoader(clUrls);
+
+ contributionMetadataURL = cl.getResource(Contribution.SCA_CONTRIBUTION_META);
+ generatedContributionMetadataURL = cl.getResource(Contribution.SCA_CONTRIBUTION_GENERATED_META);
+
+ try {
+ contributionMetadata = this.contributionFactory.createContribution();
+ contributionMetadata.setModelResolver(modelResolver);
+ if (contributionMetadataURL != null || generatedContributionMetadataURL != null) {
+ URL metadataURL = contributionMetadataURL != null ? contributionMetadataURL
+ : generatedContributionMetadataURL;
+
+ try {
+ metadataStream = metadataURL.openStream();
+ XMLStreamReader xmlReader = this.xmlFactory.createXMLStreamReader(metadataStream);
+ this.contributionLoader.load(contributionMetadata, xmlReader);
+
+ } catch (IOException ioe) {
+ throw new InvalidContributionMetadataException(ioe.getMessage(), metadataURL.toExternalForm(), ioe);
+ } catch (XMLStreamException xmle) {
+ throw new InvalidContributionMetadataException(xmle.getMessage(), metadataURL.toExternalForm(),
+ xmle);
+ } catch (ContributionMetadataLoaderException le) {
+ throw new InvalidContributionMetadataException(le.getMessage(), metadataURL.toExternalForm(), le);
+ }
+ }
+ } finally {
+ IOHelper.closeQuietly(metadataStream);
+ metadataStream = null;
+ }
+
+ if (contributionMetadata == null) {
+ contributionMetadata = this.contributionFactory.createContribution();
+ }
+
+ return contributionMetadata;
+
+ }
+
+ public Contribution getContribution(String id) {
+ return this.contributionRegistry.get(id);
+ }
+
+ public void remove(String contribution) throws ContributionException {
+ this.contributionRegistry.remove(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
+ */
+
+ /**
+ * 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);
+ }
+ }
+
+ Contribution contribution = initializeContributionMetadata(locationURL, modelResolver);
+ contribution.setURI(contributionURI.toString());
+ contribution.setLocation(locationURL.toString());
+
+ 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);
+
+ // 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);
+ }
+ }
+ }
+ }
+
+ // store the contribution on the registry
+ this.contributionRegistry.put(contribution.getURI(), 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 {
+ URL contributionURL = new URL(contribution.getLocation());
+ for (URI a : artifacts) {
+ URL artifactURL = packageProcessor.getArtifactURL(new URL(contribution.getLocation()), a);
+ Object model = this.artifactProcessor.read(contributionURL, a, artifactURL);
+
+ if (model != null) {
+ contribution.getModelResolver().addModel(model);
+
+ DeployedArtifact artifact = this.contributionFactory.createDeployedArtifact();
+ artifact.setURI(a.toString());
+ artifact.setLocation(artifactURL.toString());
+ artifact.setModel(model);
+ contribution.getArtifacts().add(artifact);
+ }
+ }
+ }
+
+ /**
+ * 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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/InvalidContributionMetadataException.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/InvalidContributionMetadataException.java
new file mode 100644
index 0000000000..a7e0e2f2f5
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/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: 511466 $ $Date: 2007-02-25 00:45:22 -0800 (Sun, 25 Feb 2007) $
+ */
+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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/InvalidContributionURIException.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/InvalidContributionURIException.java
new file mode 100644
index 0000000000..e3109e795b
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/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: 511466 $ $Date: 2007-02-25 00:45:22 -0800 (Sun, 25 Feb 2007) $
+ */
+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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/InvalidValueException.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/InvalidValueException.java
new file mode 100644
index 0000000000..ce0fb59476
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/InvalidValueException.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.contribution.service.impl;
+
+import org.apache.tuscany.sca.contribution.service.ContributionMetadataLoaderException;
+
+/**
+ * Denotate invalid value found during parsing of the contribution metadata sidefile
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidValueException extends ContributionMetadataLoaderException {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1447696740893397938L;
+
+ public InvalidValueException(String message) {
+ super(message);
+ }
+
+ public InvalidValueException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvalidValueException(String message, String identifier, Throwable cause) {
+ super(message, identifier, cause);
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/PackageTypeDescriberImpl.java b/sca-java-1.x/branches/sca-java-0.90/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/sca-java-1.x/branches/sca-java-0.90/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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/FileHelper.java b/sca-java-1.x/branches/sca-java-0.90/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/sca-java-1.x/branches/sca-java-0.90/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 --&gt; c.txt
+ * a.txt --&gt; a.txt
+ * a/b/c --&gt; c
+ * a/b/c/ --&gt; &quot;&quot;
+ * </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 --&gt; &quot;txt&quot;
+ * a/b/c.jpg --&gt; &quot;jpg&quot;
+ * a/b.txt/c --&gt; &quot;&quot;
+ * a/b/c --&gt; &quot;&quot;
+ * </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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/IOHelper.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/IOHelper.java
new file mode 100644
index 0000000000..f8ea93ae5e
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/IOHelper.java
@@ -0,0 +1,182 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.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();
+ }
+
+ public int available() throws IOException {
+ return is.available();
+ }
+
+ public void close() throws IOException {
+ is.close();
+ // We need to close the JAR file
+ if (jarFile != null) {
+ jarFile.close();
+ }
+ }
+
+ public synchronized void mark(int readlimit) {
+ is.mark(readlimit);
+ }
+
+ public boolean markSupported() {
+ return is.markSupported();
+ }
+
+ public int read() throws IOException {
+ return is.read();
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException {
+ return is.read(b, off, len);
+ }
+
+ public int read(byte[] b) throws IOException {
+ return is.read(b);
+ }
+
+ public synchronized void reset() throws IOException {
+ is.reset();
+ }
+
+ public long skip(long n) throws IOException {
+ return is.skip(n);
+ }
+ }
+} \ No newline at end of file
diff --git a/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/FolderContributionPackageProcessorTestCase.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/FolderContributionPackageProcessorTestCase.java
new file mode 100644
index 0000000000..6a2f2ac3cc
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/FolderContributionPackageProcessorTestCase.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.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;
+
+public class FolderContributionPackageProcessorTestCase extends TestCase {
+ private static final String FOLDER_CONTRIBUTION = ".";
+
+ private File contributionRoot;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ 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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/JarContributionPackageProcessorTestCase.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/JarContributionPackageProcessorTestCase.java
new file mode 100644
index 0000000000..8765423dbe
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/JarContributionPackageProcessorTestCase.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.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;
+
+public class JarContributionPackageProcessorTestCase extends TestCase {
+ private static final String JAR_CONTRIBUTION = "/repository/sample-calculator.jar";
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ 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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/ArtifactResolverTestCase.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/ArtifactResolverTestCase.java
new file mode 100644
index 0000000000..ef0fd892c2
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/ArtifactResolverTestCase.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.contribution.resolver;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.contribution.resolver.impl.ModelResolverImpl;
+
+/**
+ * Test DefaultArtifactResolver.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ArtifactResolverTestCase extends TestCase {
+
+ private ModelResolver resolver;
+
+ protected void setUp() throws Exception {
+ resolver = new ModelResolverImpl(getClass().getClassLoader());
+ }
+
+ protected void tearDown() throws Exception {
+ resolver = null;
+ }
+
+ 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);
+ }
+
+
+
+ class Model {
+ private String name;
+
+ Model(String name) {
+ this.name = name;
+ }
+
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ public boolean equals(Object obj) {
+ return name.equals(((Model)obj).name);
+ }
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContentTypeDescriberImplTestCase.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContentTypeDescriberImplTestCase.java
new file mode 100644
index 0000000000..4f924225ae
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/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"));
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ contentTypeDescriber = new ArtifactTypeDescriberImpl();
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContributionMetadataLoaderTestCase.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContributionMetadataLoaderTestCase.java
new file mode 100644
index 0000000000..ac1d968f39
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContributionMetadataLoaderTestCase.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.contribution.services;
+
+import java.io.StringReader;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.assembly.DefaultAssemblyFactory;
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.ContributionFactory;
+import org.apache.tuscany.sca.contribution.impl.ContributionFactoryImpl;
+import org.apache.tuscany.sca.contribution.resolver.impl.ModelResolverImpl;
+import org.apache.tuscany.sca.contribution.service.impl.ContributionMetadataLoaderImpl;
+import org.apache.tuscany.sca.contribution.service.impl.InvalidValueException;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ContributionMetadataLoaderTestCase 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;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ 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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContributionRepositoryTestCase.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContributionRepositoryTestCase.java
new file mode 100644
index 0000000000..98f69b9aa1
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/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;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ // 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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/PackageTypeDescriberImplTestCase.java b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/PackageTypeDescriberImplTestCase.java
new file mode 100644
index 0000000000..7ee873b9a3
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/PackageTypeDescriberImplTestCase.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.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 testResolvePackageType() throws Exception {
+ URL artifactURL = getClass().getResource("/deployables/sample-calculator.jar");
+ assertEquals(ContentType.JAR, 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"));
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ packageTypeDescriber = new PackageTypeDescriberImpl();
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/resources/deployables/sample-calculator.jar b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/resources/deployables/sample-calculator.jar
new file mode 100644
index 0000000000..0ca3a1b781
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/resources/deployables/sample-calculator.jar
Binary files differ
diff --git a/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/resources/repository/sample-calculator.jar b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/resources/repository/sample-calculator.jar
new file mode 100644
index 0000000000..9c46c679d2
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/resources/repository/sample-calculator.jar
Binary files differ
diff --git a/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/resources/test.composite b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/resources/test.composite
new file mode 100644
index 0000000000..1e09549194
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/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/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/resources/test.ext b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/resources/test.ext
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.90/modules/contribution-impl/src/test/resources/test.ext