summaryrefslogtreecommitdiffstats
path: root/branches/sca-java-integration/sca/kernel/core
diff options
context:
space:
mode:
authordims <dims@13f79535-47bb-0310-9956-ffa450edef68>2008-06-17 00:23:01 +0000
committerdims <dims@13f79535-47bb-0310-9956-ffa450edef68>2008-06-17 00:23:01 +0000
commitbdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a (patch)
tree38a92061c0793434c4be189f1d70c3458b6bc41d /branches/sca-java-integration/sca/kernel/core
Move Tuscany from Incubator to top level.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'branches/sca-java-integration/sca/kernel/core')
-rw-r--r--branches/sca-java-integration/sca/kernel/core/.checkstyle6
-rw-r--r--branches/sca-java-integration/sca/kernel/core/.pmd2
-rw-r--r--branches/sca-java-integration/sca/kernel/core/.ruleset190
-rw-r--r--branches/sca-java-integration/sca/kernel/core/LICENSE.txt202
-rw-r--r--branches/sca-java-integration/sca/kernel/core/NOTICE.txt14
-rw-r--r--branches/sca-java-integration/sca/kernel/core/pom.xml96
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/AbstractLocalTargetInvoker.java77
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingBuilder.java56
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingDefinition.java45
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingLoader.java70
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvoker.java74
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalReferenceBinding.java61
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalServiceBinding.java55
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalTargetInvoker.java73
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/bootstrap/Bootstrapper.java88
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/bootstrap/DefaultBootstrapper.java262
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/bootstrap/DefaultRuntime.java83
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/bootstrap/DefaultSCARuntime.java92
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/BuilderRegistryImpl.java293
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/ConnectorImpl.java627
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/IllegalCallbackException.java54
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/IncompatibleInterfacesException.java93
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/InvalidTargetTypeException.java41
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/NoCompatibleBindingsException.java36
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/NoConversationalContractException.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/NoRegisteredBuilderException.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/TargetServiceNotFoundException.java42
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/WireConnectException.java58
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/WirePostProcessorRegistryImpl.java57
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/WiringExceptionFormatter.java72
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/ComponentContextImpl.java85
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/ScopeIdentifier.java35
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/WorkContextImpl.java211
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/AbstractEvent.java39
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/AbstractRequestEvent.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/CompositeEvent.java33
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/CompositeStart.java47
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/CompositeStop.java46
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/ConversationEnd.java31
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/ConversationStart.java31
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/ConversationalEvent.java39
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpRequestEnded.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpRequestStart.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionEnd.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionEvent.java45
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionStart.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/RequestEnd.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/RequestEvent.java28
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/RequestStart.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/AbstractScopeContainer.java158
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeContainer.java189
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactory.java50
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainer.java217
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeObjectFactory.java58
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeContainer.java135
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeObjectFactory.java54
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapper.java41
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperImpl.java63
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeContainer.java126
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeObjectFactory.java47
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/ScopeRegistryImpl.java63
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeContainer.java75
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactory.java54
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingInteceptor.java250
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingJavaInterfaceProcessor.java126
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingRegistryImpl.java121
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessor.java157
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataTypeLoader.java67
-rwxr-xr-xbranches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DirectedGraph.java357
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/Exception2ExceptionTransformer.java126
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/Group2GroupTransformer.java97
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/GroupDataBinding.java97
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/Input2InputTransformer.java201
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/MediatorImpl.java185
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/Output2OutputTransformer.java186
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/PassByValueInterceptor.java131
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/PassByValueWirePostProcessor.java188
-rwxr-xr-xbranches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/PipedTransformer.java66
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/SimpleDataBinding.java61
-rwxr-xr-xbranches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/TransformationContextImpl.java83
-rwxr-xr-xbranches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/TransformerRegistryImpl.java101
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/DOMNode2JavaBeanTransformer.java78
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/Java2XMLMapperException.java69
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2DOMNodeTransformer.java70
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2XMLStreamReader.java56
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2XMLTransformer.java226
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBeansDataBinding.java107
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/XML2JavaBeanTransformer.java300
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/XML2JavaMapperException.java76
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/BeanUtil.java196
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMDataBinding.java52
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMWrapperHandler.java78
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMXMLStreamReader.java129
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DelegatingNamespaceContext.java310
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2Node.java65
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2SAX.java63
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2Node.java67
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2SAX.java62
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/NameValueArrayStreamReader.java403
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/NameValuePairStreamReader.java347
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/NamedProperty.java59
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/NilElementStreamReader.java279
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2OutputStream.java66
-rwxr-xr-xbranches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2String.java59
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2Writer.java65
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2XMLStreamReader.java59
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2Node.java65
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2SAX.java58
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOM.java244
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOMPipe.java67
-rwxr-xr-xbranches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Source2ResultTransformer.java60
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAX2SAXAdapter.java256
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAXDataBinding.java52
-rwxr-xr-xbranches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAXHelper.java85
-rwxr-xr-xbranches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StreamDataPipe.java57
-rwxr-xr-xbranches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2Node.java60
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2SAX.java59
-rwxr-xr-xbranches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2XMLStreamReader.java55
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/WrappingXMLStreamReader.java230
-rwxr-xr-xbranches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Writer2ReaderDataPipe.java56
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLDocumentStreamReader.java432
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLFragmentStreamReader.java53
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLFragmentStreamReaderImpl.java857
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLGroupDataBinding.java58
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2Node.java62
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2SAX.java73
-rwxr-xr-xbranches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2String.java55
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamSerializer.java266
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamable.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStringDataBinding.java51
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/AbstractDeploymentContext.java61
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/ChildDeploymentContext.java60
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/DeployerImpl.java176
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/RootDeploymentContext.java65
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/federation/FederatedDeployer.java109
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/idl/java/IllegalCallbackException.java34
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/idl/java/InterfaceJavaLoader.java117
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/idl/java/JavaInterfaceProcessorRegistryImpl.java169
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/IntrospectionRegistryImpl.java135
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/PojoAtomicComponent.java282
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/PojoConfiguration.java232
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/AbstractCompositeBuilder.java61
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/AbstractCompositeComponent.java151
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/AbstractCompositeContext.java124
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ComponentTimeoutException.java33
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeBuilder.java50
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImpl.java114
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeComponentTypeLoader.java67
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeLoader.java426
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/Dependency.java39
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ImplementationCompositeLoader.java126
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ManagedRequestContext.java58
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ReferenceImpl.java90
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ServiceImpl.java98
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/SystemCompositeBuilder.java67
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/SystemSingletonAtomicComponent.java164
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponent.java100
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilder.java208
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaComponentTypeLoader.java141
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaImplementation.java62
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaImplementationLoader.java65
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaTargetInvoker.java144
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/AllowsPassByReferenceProcessor.java63
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/AmbiguousConstructorException.java41
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessor.java112
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ContextProcessor.java140
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ConversationProcessor.java142
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DestroyProcessor.java62
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateConstructorException.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateDestructorException.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateInitException.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateReferenceException.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateResourceException.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/EagerInitProcessor.java59
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/HeuristicPojoProcessor.java550
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalCallbackReferenceException.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalContextException.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalDestructorException.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalInitException.java36
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalReferenceException.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalResourceException.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalServiceDefinitionException.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceImpl.java469
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InitProcessor.java62
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidAutowireException.java34
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidConstructorException.java39
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidConversationalImplementation.java45
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidPropertyException.java34
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidReferenceException.java41
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidResourceException.java33
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidServiceType.java34
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/MonitorProcessor.java57
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/NoConstructorException.java36
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/PropertyProcessor.java79
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ReferenceProcessor.java184
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ResourceProcessor.java117
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ScopeProcessor.java64
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ServiceProcessor.java156
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ServiceTypeNotFoundException.java34
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/UnknownContextTypeException.java32
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/builder/SystemComponentBuilder.java184
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentImpl.java55
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemComponentTypeLoader.java101
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemCompositeComponentTypeLoader.java70
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemImplementationLoader.java75
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/model/SystemCompositeImplementation.java57
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/model/SystemImplementation.java51
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ArrayMultiplicityObjectFactory.java54
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/CallbackWireObjectFactory.java47
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/CompositeContextObjectFactory.java48
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ContextInjector.java32
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ConversationIDObjectFactory.java36
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/EventInvoker.java34
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/FieldInjector.java57
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/InjectionRuntimeException.java55
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/Injector.java35
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/InvalidAccessorException.java34
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/InvalidResourceTypeException.java33
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/JNDIListObjectFactory.java58
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/JNDIObjectFactory.java50
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ListMultiplicityObjectFactory.java50
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/MethodEventInvoker.java55
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/MethodInjector.java55
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/NoAccessorException.java39
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/NoMultiplicityTypeException.java29
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ObjectCallbackException.java48
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/PojoObjectFactory.java123
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/RequestContextObjectFactory.java26
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ResourceNotFoundException.java34
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ResourceObjectFactory.java146
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/SingletonListObjectFactory.java42
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/SingletonObjectFactory.java39
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/launcher/CompositeContextImpl.java60
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/launcher/LaunchException.java49
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/launcher/LauncherImpl.java250
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/launcher/LauncherRuntimeInfo.java96
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ComponentLoader.java524
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ComponentTypeElementLoader.java90
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/DefaultPropertyValueLoaderException.java32
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/DependencyLoader.java88
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/IncludeLoader.java111
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/JNDIPropertyFactory.java71
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/LoaderExceptionFormatter.java50
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/LoaderRegistryImpl.java185
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ManyPropertyValueLoaderException.java32
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/MissingTypePropertyLoaderException.java32
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/PolicySetLoader.java196
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/PropertyLoader.java170
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/PropertyLoaderException.java69
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ReferenceLoader.java196
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ServiceLoader.java106
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/StringParserPropertyFactory.java205
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/WireLoader.java112
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/marshaller/ComponentDefinitionMarshaller.java80
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/DefaultExceptionFormatter.java54
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/InvalidLevelException.java64
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/JavaLoggingMonitorFactory.java321
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/MonitorFactoryUtil.java78
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/NullMonitorFactory.java58
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/policy/IntentRegistryImpl.java167
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/policy/PolicyBuilderRegistryImpl.java79
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/policy/PolicyEngineImpl.java297
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/policy/PolicyHelper.java65
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/property/PropertyHelper.java235
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/property/PropertyObjectFactoryImpl.java147
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/property/SimpleMultivaluedPropertyObjectFactory.java74
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/property/SimplePropertyObjectFactory.java64
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/AbstractRuntime.java283
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/mini/SimpleRuntime.java32
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/mini/SimpleRuntimeImpl.java140
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/mini/SimpleRuntimeInfo.java48
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/mini/SimpleRuntimeInfoImpl.java184
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/artifact/LocalMavenRepository.java100
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ArtifactResolverRegistryImpl.java70
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/AssemblyServiceImpl.java156
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContentTypeDescriberImpl.java111
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionDirectoryWatcher.java70
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionLoader.java126
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionProcessorRegistryImpl.java96
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionRepositoryImpl.java275
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionServiceImpl.java232
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/DomainUpdateException.java47
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/InvalidContributionMetadataException.java52
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/InvalidDocumentException.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/XMLChangeSetHandler.java132
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/CompositeContributionProcessor.java102
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/FolderContributionProcessor.java139
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidComponentDefinitionlException.java41
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidFolderContributionURIException.java41
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidPojoComponentDefinitionlException.java36
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/JarContributionProcessor.java146
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/JavaContributionProcessor.java107
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/MetadataContributionProcessor.java90
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/resolver/ComponentDefinitionArtifactResolver.java69
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/extension/AbstractExtensionDeployer.java122
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/host/DelegatingResourceHostRegistry.java142
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/store/memory/MemoryStore.java198
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jca/JcaWorkScheduler.java206
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkScheduler.java217
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/DefaultWorkEvent.java73
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/DefaultWorkItem.java166
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/ThreadPoolWorkManager.java220
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/test/SCATestCaseRunner.java213
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/ClassLoaderHelper.java93
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/FileHelper.java704
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/IOHelper.java184
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/JavaIntrospectionHelper.java439
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/ReferenceLoaderHelper.java167
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/BridgingInterceptor.java29
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/CallbackInterfaceInterceptor.java60
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/InboundInvocationChainImpl.java41
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/InboundWireImpl.java166
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/IncompatibleServiceContractExceptionFormatter.java95
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/InvocationChainImpl.java107
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/InvokerInterceptor.java59
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/LoopBackWire.java33
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/NoMethodForOperationException.java42
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/NonBlockingBridgingInterceptor.java177
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/OptimizedWireObjectFactory.java47
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/OutboundInvocationChainImpl.java53
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/OutboundWireImpl.java176
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/SynchronousBridgingInterceptor.java55
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/WireObjectFactory.java84
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/WireServiceExtension.java323
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/WireUtils.java146
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandler.java137
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKInboundInvocationHandler.java173
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKOutboundInvocationHandler.java249
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKWireService.java114
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/resources/META-INF/tuscany/default-system.composite163
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/composite.scdl45
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/databinding.scdl183
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/deployment.scdl70
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/formatters.scdl43
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/implementation.scdl78
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/interfaceJava.scdl35
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/javaImplementation.scdl39
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/loader.scdl52
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/systemImplementation.scdl46
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/AbstractLocalTargetInvokerTestCase.java72
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalBindingBuilderTestCase.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalBindingLoaderTestCase.java70
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerInvocationExceptionTestCase.java86
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerTestCase.java82
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerThrowableTestCase.java98
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalTargetInvokerTestCase.java127
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/bootstrap/BootstrapperTestCase.java42
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/AbstractConnectorImplTestCase.java306
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/AtomicConnectorTestCase.java125
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/BuilderRegistryNoBindingsTestCase.java80
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/BuilderRegistryTestCase.java219
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/ConnectorImplTestCase.java322
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/ConnectorPostProcessTestCase.java104
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/IllegalCallbackExceptionTestCase.java43
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/InboundtoOutboundConnectTestCase.java168
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/IncompatibleInterfacesExceptionTestCase.java41
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/InvalidTargetTypeExceptionTestCase.java41
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/LocalReferenceWiringTestCase.java236
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/NonBlockingForwardNonBlockingCallbackConnectionTestCase.java172
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/NonBlockingForwardSyncCallbackConnectionTestCase.java171
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/OutboundToInboundConnectTestCase.java184
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/ReferenceConnectorTestCase.java169
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/ServiceConnectorTestCase.java172
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/SynchronousForwardCallbackConnectionTestCase.java256
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/TargetServiceNotFoundExceptionTestCase.java41
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/WirePostProcessorRegistryImplTestCase.java63
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/WiringExceptionFormatterTestCase.java88
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/WorkContextImplTestCase.java65
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/event/EventTestCase.java72
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/AbstractScopeContainerTestCase.java126
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicCompositeScopeTestCase.java127
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicConversationalScopeTestCase.java129
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicHttpSessionScopeTestCase.java145
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicRequestScopeTestCase.java128
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicStatelessScopeTestCase.java120
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeInitDestroyErrorTestCase.java78
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeInstanceLifecycleTestCase.java186
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactoryTestCase.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeRestartTestCase.java99
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerDestroyOnExpirationTestCase.java121
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerMaxAgeTestCase.java76
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerMaxIdleTimeTestCase.java79
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerPersistenceTestCase.java181
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeInstanceLifecycleTestCase.java70
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeRestartTestCase.java112
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/DependencyLifecycleTestCase.java170
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeInitDestroyErrorTestCase.java69
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeInstanceLifecycleTestCase.java136
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeRestartTestCase.java105
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/InstanceWrapperTestCase.java66
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/MockFactory.java137
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeInitDestroyErrorTestCase.java63
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeInstanceLifecycleTestCase.java129
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeRestartTestCase.java99
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ScopeRegistryTestCase.java80
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/StatelessScopeContainerTestCase.java48
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactoryTestCase.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/WorkContextTestCase.java212
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingInterceptorTestCase.java132
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingJavaInterfaceProcessorTestCase.java80
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingLoaderTestCase.java79
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingRegistryImplTestCase.java98
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingTestCase.java45
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessorOptimizationTestCase.java111
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessorTestCase.java231
-rwxr-xr-xbranches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DirectedGraphTestCase.java89
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/IDLTransformerTestCase.java217
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/MediatorImplTestCase.java118
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/PassByValueInterceptorTestCase.java75
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/PassByValueWirePostProcessorTestCase.java266
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/TransformerRegistryImplTestCase.java106
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/javabeans/DOMNode2JavaBeanTransformerTestCase.java187
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2DOMNodeTransformerTestCase.java127
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/DOM2StAXTestCase.java89
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/DataPipeTestCase.java89
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/JavaBean2XMLStreamReaderTestCase.java133
-rwxr-xr-xbranches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/Node2StringTestCase.java35
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/PushTransformationTestCase.java81
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/StAXHelperTestCase.java47
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/TraxTransformerTestCase.java99
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/deployer/BootstrapDeployerTestCase.java168
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/idl/java/ConversationalIntrospectionTestCase.java82
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/idl/java/JavaInterfaceProcessorRegistryImplTestCase.java100
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/IntrospectionRegistryTestCase.java124
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/PojoAtomicComponentTestCase.java159
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/TestUtils.java74
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/AutowireResolutionTestCase.java87
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/AutowireTestCase.java230
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeBuilderTestCase.java215
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImplBasicTestCase.java119
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImplSystemWireTestCase.java170
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImplTestCase.java179
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentResolutionTestCase.java84
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeLifecycleTestCase.java120
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeLoaderWireResolutionTestCase.java232
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositePropagationTestCase.java95
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/DuplicateRegistrationTestCase.java105
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/ImplementationCompositeLoaderTestCase.java194
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/JavaObjectRegistrationTestCase.java88
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/ManagedRequestContextTestCase.java42
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/ReferenceImplTestCase.java61
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/ServiceImplTestCase.java61
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/SystemComponentBuilderTestCase.java180
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/SystemSingletonAtomicComponentTestCase.java61
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponentMetadataInjectionTestCase.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponentNegativeMetadataTestCase.java49
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaBuilderPropertyTestCase.java137
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderConversationIDTestCase.java80
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderMetadataTestCase.java112
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderReferenceTestCase.java149
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderResourceTestCase.java81
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentTypeLoaderTestCase.java78
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaReferenceWireTestCase.java153
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerBasicInvocationTestCase.java188
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerMediationTestCase.java61
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerNonBlockingInvocationTestCase.java229
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerSequenceTestCase.java117
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerStatelessDestroyTestCase.java54
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerTestCase.java53
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/MultiplicityTestCase.java34
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/ResourceInjectionTestCase.java111
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/integration/CallbackInvocationTestCase.java395
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/integration/OutboundWireToJavaTestCase.java233
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/AllowsPassByReferenceProcessorTestCase.java59
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorAutowireTestCase.java154
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessorExtensibilityTestCase.java82
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessorTestCase.java185
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorPropertyTestCase.java168
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorReferenceTestCase.java172
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorResourceTestCase.java166
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ContextProcessorTestCase.java197
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConversationProcessorTestCase.java151
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConvertTimeMillisTestCase.java110
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/DestroyProcessorTestCase.java100
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/EagerInitProcessorTestCase.java54
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicAndPropertyTestCase.java70
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicConstructorTestCase.java330
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicPojoProcessorTestCase.java395
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeutisticExtensibleConstructorTestCase.java129
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceTestCase.java117
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceUniqueTestCase.java67
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/InitProcessorTestCase.java98
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/MonitorProcessorTestCase.java180
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/PropertyProcessorTestCase.java204
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ReferenceProcessorTestCase.java225
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ResourceProcessorTestCase.java99
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ScopeProcessorTestCase.java128
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ServiceCallbackTestCase.java166
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ServiceProcessorTestCase.java136
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/builder/SystemComponentBuilderResourceTestCase.java75
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentTestCase.java124
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentWireInvocationTestCase.java60
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/loader/SystemComponentTypeLoaderTestCase.java82
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/loader/SystemImplementationLoaderTestCase.java106
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/CallbackWireObjectFactoryTestCase.java47
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/FieldInjectorTestCase.java48
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/JNDIObjectFactoryTestCase.java61
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/MethodEventInvokerTestCase.java72
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/MethodInjectorTestCase.java79
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/PojoObjectFactoryTestCase.java64
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/RequestContextObjectFactoryTestCase.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/ResourceObjectFactoryTestCase.java152
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/SingletonObjectFactoryTestCase.java33
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/conversation/AbstractConversationTestCase.java62
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationIdleExpireTestCase.java140
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationMaxAgeExpireTestCase.java141
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationStartStopEndTestCase.java141
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/implementation/IntrospectionRegistryIntegrationTestCase.java131
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/implementation/system/builder/SystemBuilderPropertyTestCase.java89
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/mock/MockFactory.java278
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/scope/ScopeReferenceTestCase.java781
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/wire/DifferentInterfaceWireTestCase.java137
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/wire/ReferenceInjectionTestCase.java72
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/wire/oneway/OneWayWireToJavaInvocationTestCase.java130
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderNoBindingTestCase.java91
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderPropertyTestCase.java90
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderReferenceTestCase.java87
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderTestCase.java201
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderValidationTestCase.java170
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentReferenceOverridingTestCase.java178
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentTypeElementLoaderTestCase.java90
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/DependencyLoaderTestCase.java124
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/IncludeLoaderTestCase.java169
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/JNDIPropertyFactoryTestCase.java66
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/LoaderExceptionFormatterTestCase.java47
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/MultivaluePropertyLoadingTestCase.java204
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/PolicySetLoaderTestCase.java71
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/PropertyLoaderTestCase.java180
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/PropertyParsingTestCase.java78
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ReferenceLoaderTestCase.java143
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ServiceLoaderTestCase.java166
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/StAXLoaderRegistryImplTestCase.java131
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/StringParserPropertyFactoryTestCase.java133
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/WireLoaderTestCase.java159
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/binding/MockServiceBinding.java82
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/AsyncTarget.java31
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/BadContextPojo.java28
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/BadNamePojo.java26
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/BasicInterface.java30
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/BasicInterfaceImpl.java66
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeComponent.java31
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeComponentImpl.java40
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeDestroyOnlyComponent.java36
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeInitDestroyComponent.java39
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeInitOnlyComponent.java42
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeComponent.java29
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeComponentImpl.java29
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeDestroyOnlyComponent.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeInitDestroyComponent.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeInitOnlyComponent.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderException.java40
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedDependentPojo.java29
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedDependentPojoImpl.java36
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedEagerInitPojo.java60
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedInitPojo.java28
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedInitPojoImpl.java61
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OtherTarget.java31
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OtherTargetImpl.java39
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeComponent.java30
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeDestroyOnlyComponent.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeInitDestroyComponent.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeInitOnlyComponent.java39
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeComponent.java30
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeComponentImpl.java30
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeInitDestroyComponent.java36
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeInitOnlyComponent.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SimpleTarget.java30
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SimpleTargetImpl.java41
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/Source.java37
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SourceImpl.java63
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/StatelessComponent.java30
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/StatelessComponentImpl.java27
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/Target.java32
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/TargetImpl.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/wire/MockStaticInvoker.java97
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/wire/MockSyncInterceptor.java55
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/wire/MockTargetInvoker.java33
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/monitor/DefaultExceptionFormatterTestCase.java63
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/monitor/JavaLoggingTestCase.java153
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/policy/IntentRegistryImplTestCase.java152
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/policy/PolicyEngineImplTestCase.java140
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/property/PropertyHelperTestCase.java107
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/property/SimplePropertyObjectFactoryTestCase.java113
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/artifact/LocalMavenRepositoryTestCase.java82
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/AssemblyServiceImplTestCase.java107
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/ContentTypeDescriberImplTestCase.java52
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionLoaderTestCase.java82
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionRepositoryTestCase.java76
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionServiceImplTestCase.java72
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/CompositeContributionProcessorTestCase.java84
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/FolderContributionProcessorTestCase.java56
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/JarContributionProcessorTestCase.java53
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/JavaContributionProcessorTestCase.java79
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/host/DelegatingResourceHostRegistryTestCase.java147
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/store/memory/MemoryStoreTestCase.java164
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkSchedulerTest.java81
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkSchedulerTestCase.java100
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/workmanager/ThreadPoolWorkManagerTestCase.java132
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/util/Bean1.java45
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/util/Bean2.java47
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/util/JavaIntrospectionHelperTestCase.java180
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/util/SuperBean.java48
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/BasicReferenceInvocationHandlerTestCase.java69
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/CallbackInterfaceInterceptorTestCase.java60
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/ContractCompatibilityTestCase.java401
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/InboundInvocationErrorTestCase.java166
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/IncompatibleServiceContractExceptionFormatterTestCase.java82
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/InvocationChainImplTestCase.java94
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationErrorTestCase.java95
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationTestCase.java95
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/NonBlockingBridgingInterceptorTestCase.java75
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/OptimizedWireObjectFactoryTestCase.java44
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/OutboundInvocationErrorTestCase.java133
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/OutboundInvocationHandlerTestCase.java132
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/OutboundWireTestCase.java38
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/SynchronousBridgingInterceptorTestCase.java44
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/WireObjectFactoryTestCase.java138
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/WireOptimizationTestCase.java154
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/WireServiceExtensionTestCase.java333
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/WireUtilsTestCase.java94
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandlerSerializationTestCase.java54
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandlerTestCase.java54
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInboundInvocationHandlerSerializationTestCase.java110
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInboundInvocationHandlerTestCase.java162
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKOutboundInvocationHandlerProxyTestCase.java80
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKOutboundInvocationHandlerSerializationTestCase.java132
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKOutboundInvocationHandlerTestCase.java176
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKProxyTestCase.java61
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/resources/deployables/sample-calculator.jarbin0 -> 26901 bytes
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/databinding/impl/ipo.xsd136
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/databinding/impl/order.wsdl76
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/databinding/xml/foo.xml22
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/deployer/boot1-include.scdl33
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/deployer/boot1.scdl35
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/deployer/boot2.scdl136
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/loader/TestPolicy.scdl51
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/loader/test-include.scdl22
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/policy/PolicySet.scdl66
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/property/ipo.xml33
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/services/deployment/test.ext0
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/services/deployment/test.scdl22
-rw-r--r--branches/sca-java-integration/sca/kernel/core/src/test/resources/repository/sample-calculator.jarbin0 -> 26901 bytes
642 files changed, 69452 insertions, 0 deletions
diff --git a/branches/sca-java-integration/sca/kernel/core/.checkstyle b/branches/sca-java-integration/sca/kernel/core/.checkstyle
new file mode 100644
index 0000000000..142759d295
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/.checkstyle
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<fileset-config file-format-version="1.2.0" simple-config="true">
+ <fileset name="all" enabled="true" check-config-name="Tuscany Checks" local="false">
+ <file-match-pattern match-pattern="." include-pattern="true"/>
+ </fileset>
+</fileset-config>
diff --git a/branches/sca-java-integration/sca/kernel/core/.pmd b/branches/sca-java-integration/sca/kernel/core/.pmd
new file mode 100644
index 0000000000..9606e17e2d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/.pmd
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<pmd><useProjectRuleSet>true</useProjectRuleSet><rules/><includeDerivedFiles>false</includeDerivedFiles></pmd> \ No newline at end of file
diff --git a/branches/sca-java-integration/sca/kernel/core/.ruleset b/branches/sca-java-integration/sca/kernel/core/.ruleset
new file mode 100644
index 0000000000..ba9b5ce886
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/.ruleset
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<ruleset name="pmd-eclipse">
+ <description>PMD Plugin preferences rule set</description>
+
+
+ <rule ref="rulesets/basic.xml/BooleanInstantiation"/>
+ <rule ref="rulesets/basic.xml/CollapsibleIfStatements"/>
+ <rule ref="rulesets/basic.xml/DoubleCheckedLocking"/>
+<!--<rule ref="rulesets/basic.xml/EmptyCatchBlock"/>-->
+<!--<rule ref="rulesets/basic.xml/EmptyFinallyBlock"/>-->
+<!--<rule ref="rulesets/basic.xml/EmptyIfStmt"/>-->
+ <rule ref="rulesets/basic.xml/EmptyStatementNotInLoop"/>
+<!--<rule ref="rulesets/basic.xml/EmptyStaticInitializer"/>-->
+<!--<rule ref="rulesets/basic.xml/EmptySwitchStatements"/>-->
+<!--<rule ref="rulesets/basic.xml/EmptySynchronizedBlock"/>-->
+<!--<rule ref="rulesets/basic.xml/EmptyTryBlock"/>-->
+<!--<rule ref="rulesets/basic.xml/EmptyWhileStmt"/>-->
+ <rule ref="rulesets/basic.xml/ForLoopShouldBeWhileLoop"/>
+ <rule ref="rulesets/basic.xml/JumbledIncrementer"/>
+<!--<rule ref="rulesets/basic.xml/OverrideBothEqualsAndHashcode"/>-->
+ <rule ref="rulesets/basic.xml/ReturnFromFinallyBlock"/>
+ <rule ref="rulesets/basic.xml/UnconditionalIfStatement"/>
+ <rule ref="rulesets/basic.xml/UnnecessaryConversionTemporary"/>
+ <rule ref="rulesets/basic.xml/UnnecessaryFinalModifier"/>
+ <rule ref="rulesets/basic.xml/UnnecessaryReturn"/>
+<!--<rule ref="rulesets/basic.xml/UselessOverridingMethod"/>-->
+
+<!--<rule ref="rulesets/braces.xml/ForLoopsMustUseBraces"/>-->
+<!--<rule ref="rulesets/braces.xml/IfElseStmtsMustUseBraces"/>-->
+<!--<rule ref="rulesets/braces.xml/IfStmtsMustUseBraces"/>-->
+<!--<rule ref="rulesets/braces.xml/WhileLoopsMustUseBraces"/>-->
+
+<!--<rule ref="rulesets/clone.xml/CloneMethodMustImplementCloneable"/>-->
+<!--<rule ref="rulesets/clone.xml/CloneThrowsCloneNotSupportedException"/>-->
+<!--<rule ref="rulesets/clone.xml/ProperCloneImplementation"/>-->
+
+<!--<rule ref="rulesets/codesize.xml/CyclomaticComplexity"/>-->
+<!--<rule ref="rulesets/codesize.xml/ExcessiveClassLength"/>-->
+<!--<rule ref="rulesets/codesize.xml/ExcessiveMethodLength"/>-->
+<!--<rule ref="rulesets/codesize.xml/ExcessiveParameterList"/>-->
+<!--<rule ref="rulesets/codesize.xml/ExcessivePublicCount"/>-->
+<!--<rule ref="rulesets/codesize.xml/TooManyFields"/>-->
+
+<rule ref="rulesets/controversial.xml/AssignmentInOperand"/>
+<!--<rule ref="rulesets/controversial.xml/AtLeastOneConstructor"/>-->
+<!--<rule ref="rulesets/controversial.xml/CallSuperInConstructor"/>-->
+<!--<rule ref="rulesets/controversial.xml/DontImportSun"/>-->
+<!--<rule ref="rulesets/controversial.xml/NullAssignment"/>-->
+<!--<rule ref="rulesets/controversial.xml/OnlyOneReturn"/>-->
+<!--<rule ref="rulesets/controversial.xml/SingularField"/>-->
+<!--<rule ref="rulesets/controversial.xml/SuspiciousOctalEscape"/>-->
+<!--<rule ref="rulesets/controversial.xml/UnnecessaryConstructor"/>-->
+<rule ref="rulesets/controversial.xml/UnnecessaryParentheses"/>
+<!--<rule ref="rulesets/controversial.xml/UnusedModifier"/>-->
+
+<!--<rule ref="rulesets/coupling.xml/CouplingBetweenObjects"/>-->
+<!--<rule ref="rulesets/coupling.xml/ExcessiveImports"/>-->
+<!--<rule ref="rulesets/coupling.xml/LooseCoupling"/>-->
+
+<!--<rule ref="rulesets/design.xml/AbstractClassWithoutAbstractMethod"/>-->
+<!--<rule ref="rulesets/design.xml/AccessorClassGeneration"/>-->
+<!--<rule ref="rulesets/design.xml/AssignmentToNonFinalStatic"/>-->
+<!--<rule ref="rulesets/design.xml/AvoidDeeplyNestedIfStmts"/>-->
+<!--<rule ref="rulesets/design.xml/AvoidInstanceofChecksInCatchClause"/>-->
+<rule ref="rulesets/design.xml/AvoidProtectedFieldInFinalClass"/>
+<!--<rule ref="rulesets/design.xml/AvoidReassigningParameters"/>-->
+<!--<rule ref="rulesets/design.xml/AvoidSynchronizedAtMethodLevel"/>-->
+<!--<rule ref="rulesets/design.xml/BadComparison"/>-->
+<!--<rule ref="rulesets/design.xml/CloseConnection"/>-->
+<!--<rule ref="rulesets/design.xml/CompareObjectsWithEquals"/>-->
+<!--<rule ref="rulesets/design.xml/ConfusingTernary"/>-->
+<rule ref="rulesets/design.xml/ConstructorCallsOverridableMethod"/>
+<!--<rule ref="rulesets/design.xml/DefaultLabelNotLastInSwitchStmt"/>-->
+<!--<rule ref="rulesets/design.xml/FinalFieldCouldBeStatic"/>-->
+<rule ref="rulesets/design.xml/IdempotentOperations"/>
+<!--<rule ref="rulesets/design.xml/ImmutableField"/>-->
+<!--<rule ref="rulesets/design.xml/InstantiationToGetClass"/>-->
+<!--<rule ref="rulesets/design.xml/MissingBreakInSwitch"/>-->
+<!--<rule ref="rulesets/design.xml/MissingStaticMethodInNonInstantiatableClass"/>-->
+<!--<rule ref="rulesets/design.xml/NonCaseLabelInSwitchStatement"/>-->
+<!--<rule ref="rulesets/design.xml/NonStaticInitializer"/>-->
+<rule ref="rulesets/design.xml/OptimizableToArrayCall"/>
+<rule ref="rulesets/design.xml/PositionLiteralsFirstInComparisons"/>
+<rule ref="rulesets/design.xml/SimplifyBooleanExpressions"/>
+<rule ref="rulesets/design.xml/SimplifyBooleanReturns"/>
+<rule ref="rulesets/design.xml/SimplifyConditional"/>
+<!--<rule ref="rulesets/design.xml/SwitchDensity"/>-->
+<!--<rule ref="rulesets/design.xml/SwitchStmtsShouldHaveDefault"/>-->
+<!--<rule ref="rulesets/design.xml/UnnecessaryLocalBeforeReturn"/>-->
+<!--<rule ref="rulesets/design.xml/UseLocaleWithCaseConversions"/>-->
+<!--<rule ref="rulesets/design.xml/UseNotifyAllInsteadOfNotify"/>-->
+<!--<rule ref="rulesets/design.xml/UseSingleton"/>-->
+
+<!--<rule ref="rulesets/finalizers.xml/EmptyFinalizer"/>-->
+<!--<rule ref="rulesets/finalizers.xml/FinalizeOnlyCallsSuperFinalize"/>-->
+<!--<rule ref="rulesets/finalizers.xml/FinalizeOverloaded"/>-->
+<!--<rule ref="rulesets/finalizers.xml/FinalizeDoesNotCallSuperFinalize"/>-->
+<!--<rule ref="rulesets/finalizers.xml/FinalizeShouldBeProtected"/>-->
+<!--<rule ref="rulesets/finalizers.xml/AvoidCallingFinalize"/>-->
+
+<!--<rule ref="rulesets/imports.xml/DuplicateImports"/>-->
+<!--<rule ref="rulesets/imports.xml/DontImportJavaLang"/>-->
+<!--<rule ref="rulesets/imports.xml/UnusedImports"/>-->
+<!--<rule ref="rulesets/imports.xml/ImportFromSamePackage"/>-->
+
+<!--<rule ref="rulesets/javabeans.xml/BeanMembersShouldSerialize"/>-->
+<!--<rule ref="rulesets/javabeans.xml/MissingSerialVersionUID"/>-->
+
+<!--<rule ref="rulesets/junit.xml/JUnitStaticSuite"/>-->
+<!--<rule ref="rulesets/junit.xml/JUnitSpelling"/>-->
+<!--<rule ref="rulesets/junit.xml/JUnitAssertionsShouldIncludeMessage"/>-->
+<!--<rule ref="rulesets/junit.xml/JUnitTestsShouldIncludeAssert"/>-->
+<!--<rule ref="rulesets/junit.xml/TestClassWithoutTestCases"/>-->
+<!--<rule ref="rulesets/junit.xml/UnnecessaryBooleanAssertion"/>-->
+<!--<rule ref="rulesets/junit.xml/UseAssertEqualsInsteadOfAssertTrue"/>-->
+<!--<rule ref="rulesets/junit.xml/UseAssertSameInsteadOfAssertTrue"/>-->
+
+ <!--<rule ref="rulesets/logging-java.xml/AvoidPrintStackTrace"/>-->
+ <!--<rule ref="rulesets/logging-java.xml/LoggerIsNotStaticFinal"/>-->
+ <!--<rule ref="rulesets/logging-java.xml/MoreThanOneLogger"/>-->
+ <!--<rule ref="rulesets/logging-java.xml/LoggerIsNotStaticFinal"/>-->
+ <!--<rule ref="rulesets/logging-java.xml/LogBlockWithoutIf"/>-->
+ <!--<rule ref="rulesets/logging-java.xml/SystemPrintln"/>-->
+ <!--<rule ref="rulesets/logging-jakarta-commons.xml/UseCorrectExceptionLogging"/>-->
+ <!--<rule ref="rulesets/logging-jakarta-commons.xml/ProperLogger"/>-->
+
+ <!--<rule ref="rulesets/naming.xml/ShortVariable"/>-->
+ <!--<rule ref="rulesets/naming.xml/LongVariable"/>-->
+ <!--<rule ref="rulesets/naming.xml/ShortMethodName"/>-->
+ <!--<rule ref="rulesets/naming.xml/VariableNamingConventions"/>-->
+ <!--<rule ref="rulesets/naming.xml/MethodNamingConventions"/>-->
+ <!--<rule ref="rulesets/naming.xml/ClassNamingConventions"/>-->
+ <!--<rule ref="rulesets/naming.xml/AbstractNaming"/>-->
+ <!--<rule ref="rulesets/naming.xml/AvoidDollarSigns"/>-->
+ <!--<rule ref="rulesets/naming.xml/MethodWithSameNameAsEnclosingClass"/>-->
+ <!--<rule ref="rulesets/naming.xml/SuspiciousHashcodeMethodName"/>-->
+ <!--<rule ref="rulesets/naming.xml/SuspiciousConstantFieldName"/>-->
+ <!--<rule ref="rulesets/naming.xml/AvoidFieldNameMatchingTypeName"/>-->
+ <!--<rule ref="rulesets/naming.xml/AvoidFieldNameMatchingMethodName"/>-->
+ <!--<rule ref="rulesets/naming.xml/AvoidNonConstructorMethodsWithClassName"/>-->
+ <!--<rule ref="rulesets/naming.xml/NoPackage"/>-->
+ <!--<rule ref="rulesets/naming.xml/PackageCase"/>-->
+
+ <!--<rule ref="rulesets/optimizations.xml/LocalVariableCouldBeFinal"/>-->
+ <!--<rule ref="rulesets/optimizations.xml/MethodArgumentCouldBeFinal"/>-->
+ <!--<rule ref="rulesets/optimizations.xml/AvoidInstantiatingObjectsInLoops"/>-->
+ <!--<rule ref="rulesets/optimizations.xml/UseArrayListInsteadOfVector"/>-->
+ <!--<rule ref="rulesets/optimizations.xml/SimplifyStartsWith"/>-->
+ <!--<rule ref="rulesets/optimizations.xml/UseStringBufferForStringAppends"/>-->
+
+ <!--<rule ref="rulesets/strictexception.xml/AvoidCatchingThrowable"/>-->
+ <!--<rule ref="rulesets/strictexception.xml/SignatureDeclareThrowsException"/>-->
+ <!--<rule ref="rulesets/strictexception.xml/ExceptionAsFlowControl"/>-->
+ <!--<rule ref="rulesets/strictexception.xml/AvoidCatchingNPE"/>-->
+ <!--<rule ref="rulesets/strictexception.xml/AvoidThrowingRawExceptionTypes"/>-->
+ <!--<rule ref="rulesets/strictexception.xml/AvoidThrowingNullPointerException"/>-->
+
+ <!--<rule ref="rulesets/strings.xml/AvoidDuplicateLiterals"/>-->
+ <!--<rule ref="rulesets/strings.xml/StringInstantiation"/>-->
+ <!--<rule ref="rulesets/strings.xml/StringToString"/>-->
+ <!--<rule ref="rulesets/strings.xml/AvoidConcatenatingNonLiteralsInStringBuffer"/>-->
+ <!--<rule ref="rulesets/strings.xml/UnnecessaryCaseChange"/>-->
+
+ <!--<rule ref="rulesets/sunsecure.xml/MethodReturnsInternalArray"/>-->
+ <!--<rule ref="rulesets/sunsecure.xml/ArrayIsStoredDirectly"/>-->
+
+ <rule ref="rulesets/unusedcode.xml/UnusedLocalVariable"/>
+ <rule ref="rulesets/unusedcode.xml/UnusedPrivateField"/>
+ <rule ref="rulesets/unusedcode.xml/UnusedPrivateMethod"/>
+ <!--<rule ref="rulesets/unusedcode.xml/UnusedFormalParameter"/>-->
+
+</ruleset>
diff --git a/branches/sca-java-integration/sca/kernel/core/LICENSE.txt b/branches/sca-java-integration/sca/kernel/core/LICENSE.txt
new file mode 100644
index 0000000000..0084319535
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/LICENSE.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, serviceDefinition marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/branches/sca-java-integration/sca/kernel/core/NOTICE.txt b/branches/sca-java-integration/sca/kernel/core/NOTICE.txt
new file mode 100644
index 0000000000..d83ebbe236
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/NOTICE.txt
@@ -0,0 +1,14 @@
+${pom.name}
+Copyright (c) 2005 - 2006 The Apache Software Foundation
+
+Apache Tuscany is an effort undergoing incubation at The Apache Software
+Foundation (ASF), sponsored by the Apache Web Services PMC. Incubation is
+required of all newly accepted projects until a further review indicates that
+the infrastructure, communications, and decision making process have stabilized
+in a manner consistent with other successful ASF projects. While incubation
+status is not necessarily a reflection of the completeness or stability of the
+code, it does indicate that the project has yet to be fully endorsed by the ASF.
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/branches/sca-java-integration/sca/kernel/core/pom.xml b/branches/sca-java-integration/sca/kernel/core/pom.xml
new file mode 100644
index 0000000000..7d902e083c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/pom.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<project>
+ <parent>
+ <groupId>org.apache.tuscany.sca.kernel</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1-integration-incubating-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>tuscany-core</artifactId>
+ <packaging>jar</packaging>
+ <name>Apache Tuscany SCA Core</name>
+ <description>Core Tuscany runtime.</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tuscany.sca.kernel</groupId>
+ <artifactId>tuscany-spi</artifactId>
+ <version>${pom.version}</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca.kernel</groupId>
+ <artifactId>tuscany-host-api</artifactId>
+ <version>${sca.version}</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany</groupId>
+ <artifactId>commonj-api_r1.1</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.woodstox</groupId>
+ <artifactId>wstx-asl</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-j2ee-connector_1.5_spec</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymockclassextension</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ <resource>
+ <directory>${notice.dir}</directory>
+ <targetPath>META-INF</targetPath>
+ <filtering>true</filtering>
+ <includes>
+ <include>LICENSE.txt</include>
+ <include>NOTICE.txt</include>
+ </includes>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/AbstractLocalTargetInvoker.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/AbstractLocalTargetInvoker.java
new file mode 100644
index 0000000000..7727759a88
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/AbstractLocalTargetInvoker.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.binding.local;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+/**
+ * Base class for dispatching to a composite reference using the local binding
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractLocalTargetInvoker implements TargetInvoker {
+ protected boolean cacheable;
+
+ public boolean isCacheable() {
+ return cacheable;
+ }
+
+ public void setCacheable(boolean cacheable) {
+ this.cacheable = cacheable;
+ }
+
+ public boolean isOptimizable() {
+ return isCacheable(); // we only need to check if the scopes are correct
+ }
+
+ public Object invokeTarget(final Object payload, short sequence) throws InvocationTargetException {
+ throw new InvocationTargetException(new UnsupportedOperationException());
+ }
+
+ protected Message invoke(OutboundInvocationChain chain, TargetInvoker invoker, Message msg) throws Throwable {
+ Interceptor headInterceptor = chain.getHeadInterceptor();
+ if (headInterceptor == null) {
+ try {
+ // short-circuit the dispatch and invoke the target directly
+ if (invoker == null) {
+ String name = chain.getOperation().getName();
+ throw new AssertionError("No target invoker [" + name + "]");
+ }
+ return invoker.invoke(msg);
+ } catch (InvocationRuntimeException e) {
+ // the cause was thrown by the target so throw it
+ throw e.getCause();
+ }
+ } else {
+ msg.setTargetInvoker(invoker);
+ return headInterceptor.invoke(msg);
+ }
+ }
+
+ @Override
+ public AbstractLocalTargetInvoker clone() throws CloneNotSupportedException {
+ return (AbstractLocalTargetInvoker) super.clone();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingBuilder.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingBuilder.java
new file mode 100644
index 0000000000..c62523889d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingBuilder.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.binding.local;
+
+import org.apache.tuscany.spi.builder.BuilderException;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.BindingBuilderExtension;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+/**
+ * Creates runtime artifacts for the local binding
+ *
+ * @version $Rev$ $Date$
+ */
+public class LocalBindingBuilder extends BindingBuilderExtension<LocalBindingDefinition> {
+
+ protected Class<LocalBindingDefinition> getBindingType() {
+ return LocalBindingDefinition.class;
+ }
+
+ public ServiceBinding build(CompositeComponent parent,
+ ServiceDefinition serviceDefinition,
+ LocalBindingDefinition bindingDefinition,
+ DeploymentContext deploymentContext)
+ throws BuilderException {
+ return new LocalServiceBinding(serviceDefinition.getName(), parent);
+ }
+
+
+ public ReferenceBinding build(CompositeComponent parent,
+ AbstractReferenceDefinition referenceDefinition,
+ LocalBindingDefinition bindingDefinition,
+ DeploymentContext deploymentContext) throws BuilderException {
+ return new LocalReferenceBinding(referenceDefinition.getName(), parent);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingDefinition.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingDefinition.java
new file mode 100644
index 0000000000..4df3e413dc
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingDefinition.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.binding.local;
+
+import java.net.URI;
+
+import org.apache.tuscany.spi.model.BindingDefinition;
+
+
+/**
+ * Represents the local by-reference binding
+ *
+ * @version $Rev$ $Date$
+ */
+public class LocalBindingDefinition extends BindingDefinition implements Cloneable {
+
+ public LocalBindingDefinition() {
+ }
+
+ public LocalBindingDefinition(URI targetUri) {
+ super(targetUri);
+ }
+
+ public Object clone() {
+ LocalBindingDefinition clone = new LocalBindingDefinition();
+ clone.setTargetUri(URI.create(getTargetUri().toString()));
+ return clone;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingLoader.java
new file mode 100644
index 0000000000..777beeb00e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalBindingLoader.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.binding.local;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.wire.Wire;
+
+/**
+ * Loader responsible for handling the local binding
+ *
+ * @version $Rev$ $Date$
+ */
+public class LocalBindingLoader extends LoaderExtension<LocalBindingDefinition> {
+
+ /**
+ * Constructor specifies the registry to register with.
+ *
+ * @param registry the LoaderRegistry this loader should register with
+ */
+ public LocalBindingLoader(@Autowire LoaderRegistry registry) {
+ super(registry);
+ }
+
+ public QName getXMLType() {
+ return Wire.LOCAL_BINDING;
+ }
+
+ public LocalBindingDefinition load(CompositeComponent parent,
+ ModelObject object,
+ XMLStreamReader reader,
+ DeploymentContext deploymentContext) throws XMLStreamException, LoaderException {
+ String uri = reader.getAttributeValue(null, "uri");
+ if (uri != null) {
+ try {
+ return new LocalBindingDefinition(new URI(uri));
+ } catch (URISyntaxException e) {
+ throw new LoaderException(e);
+ }
+ }
+ return new LocalBindingDefinition();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvoker.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvoker.java
new file mode 100644
index 0000000000..03f42ca99c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvoker.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.core.binding.local;
+
+import java.util.Map;
+
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+/**
+ * Dispatches a callback invocation to the callback instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class LocalCallbackTargetInvoker extends AbstractLocalTargetInvoker {
+ private Operation operation;
+ private InboundWire inboundWire;
+
+ public LocalCallbackTargetInvoker(Operation operation, InboundWire inboundWire) {
+ assert operation != null : "Operation method cannot be null";
+ this.operation = operation;
+ this.inboundWire = inboundWire;
+ }
+
+ public Message invoke(Message msg) throws InvocationRuntimeException {
+ try {
+ return invoke(operation, msg);
+ } catch (Throwable e) {
+ Message faultMsg = new MessageImpl();
+ faultMsg.setBodyWithFault(e);
+ return faultMsg;
+ }
+ }
+
+ private Message invoke(Operation operation, Message msg) throws Throwable {
+ Object targetAddress = msg.popFromAddress();
+ if (targetAddress == null) {
+ throw new AssertionError("Popped a null from address from message");
+ }
+ //TODO optimize as this is slow in local invocations
+ Map<Operation<?>, OutboundInvocationChain> sourceCallbackInvocationChains =
+ inboundWire.getSourceCallbackInvocationChains(targetAddress);
+ OutboundInvocationChain chain = sourceCallbackInvocationChains.get(operation);
+ TargetInvoker invoker = chain.getTargetInvoker();
+ return invoke(chain, invoker, msg);
+ }
+
+ @Override
+ public LocalCallbackTargetInvoker clone() throws CloneNotSupportedException {
+ return (LocalCallbackTargetInvoker) super.clone();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalReferenceBinding.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalReferenceBinding.java
new file mode 100644
index 0000000000..9117fe903e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalReferenceBinding.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.binding.local;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.CoreRuntimeException;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.TargetInvokerCreationException;
+import org.apache.tuscany.spi.extension.ReferenceBindingExtension;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.apache.tuscany.spi.wire.Wire;
+
+/**
+ * The runtime representaion of the local reference binding
+ *
+ * @version $Rev$ $Date$
+ */
+public class LocalReferenceBinding extends ReferenceBindingExtension {
+
+ public LocalReferenceBinding(String name, CompositeComponent parent) throws CoreRuntimeException {
+ super(name, parent);
+ }
+
+ public QName getBindingType() {
+ return Wire.LOCAL_BINDING;
+ }
+
+ public TargetInvoker createTargetInvoker(ServiceContract contract, Operation operation)
+ throws TargetInvokerCreationException {
+ if (operation.isCallback()) {
+ return new LocalCallbackTargetInvoker(operation, inboundWire);
+ } else {
+ return new LocalTargetInvoker(operation, outboundWire);
+ }
+ }
+
+ public TargetInvoker createCallbackTargetInvoker(ServiceContract contract, Operation operation)
+ throws TargetInvokerCreationException {
+ return new LocalCallbackTargetInvoker(operation, inboundWire);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalServiceBinding.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalServiceBinding.java
new file mode 100644
index 0000000000..6205172d7b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalServiceBinding.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.binding.local;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.CoreRuntimeException;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.TargetInvokerCreationException;
+import org.apache.tuscany.spi.extension.ServiceBindingExtension;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.apache.tuscany.spi.wire.Wire;
+
+/**
+ * The runtime representaion of the local service binding
+ *
+ * @version $Rev$ $Date$
+ */
+public class LocalServiceBinding extends ServiceBindingExtension {
+
+ public LocalServiceBinding(String name, CompositeComponent parent) throws CoreRuntimeException {
+ super(name, parent);
+ }
+
+ public QName getBindingType() {
+ return Wire.LOCAL_BINDING;
+ }
+
+ public TargetInvoker createTargetInvoker(ServiceContract contract, Operation operation)
+ throws TargetInvokerCreationException {
+ if (operation.isCallback()) {
+ return new LocalCallbackTargetInvoker(operation, getInboundWire());
+ } else {
+ return new LocalTargetInvoker(operation, outboundWire);
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalTargetInvoker.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalTargetInvoker.java
new file mode 100644
index 0000000000..5b564c93b8
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/binding/local/LocalTargetInvoker.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.binding.local;
+
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+/**
+ * Dispatches an invocation through a composite service or reference using the local binding
+ *
+ * @version $Rev$ $Date$
+ */
+public class LocalTargetInvoker extends AbstractLocalTargetInvoker {
+ private OutboundInvocationChain chain;
+ private Object fromAddress;
+ private boolean contractHasCallback;
+
+ public LocalTargetInvoker(Operation operation, OutboundWire outboundWire) {
+ assert operation != null;
+ chain = outboundWire.getInvocationChains().get(operation);
+ assert chain != null;
+ fromAddress = (outboundWire.getContainer() == null) ? null : outboundWire.getContainer().getName();
+ contractHasCallback = outboundWire.getServiceContract().getCallbackClass() != null;
+ }
+
+ @Override
+ public LocalTargetInvoker clone() throws CloneNotSupportedException {
+ return (LocalTargetInvoker) super.clone();
+ }
+
+ public Message invoke(Message msg) throws InvocationRuntimeException {
+ try {
+ TargetInvoker invoker = chain.getTargetInvoker();
+ assert invoker != null;
+ // Pushing the from address only needs to happen in the outbound (forward) direction for callbacks
+ if (contractHasCallback) {
+ msg.pushFromAddress(fromAddress);
+ }
+
+ return invoke(chain, invoker, msg);
+ } catch (Throwable e) {
+ Message faultMsg = new MessageImpl();
+ faultMsg.setBodyWithFault(e);
+ return faultMsg;
+ }
+ }
+
+
+ public boolean isOptimizable() {
+ return true;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/bootstrap/Bootstrapper.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/bootstrap/Bootstrapper.java
new file mode 100644
index 0000000000..0f6b4a2c92
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/bootstrap/Bootstrapper.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.bootstrap;
+
+import org.apache.tuscany.host.MonitorFactory;
+import org.apache.tuscany.spi.bootstrap.RuntimeComponent;
+import org.apache.tuscany.spi.builder.Connector;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.deployer.Deployer;
+import org.apache.tuscany.spi.implementation.java.Introspector;
+import org.apache.tuscany.spi.loader.Loader;
+import org.apache.tuscany.spi.loader.PropertyObjectFactory;
+
+/**
+ * Interface that abstracts the process used to create a running Tuscany system. Implementation of this may provide
+ * different mechanisms for creating the primoridal system components used to boot the core to the level where it can
+ * support end-user applications.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface Bootstrapper {
+ /**
+ * Return the MonitorFactory being used by the implementation to provide monitor interfaces for the primordial
+ * components.
+ *
+ * @return the MonitorFactory being used by the bootstrapper
+ */
+ MonitorFactory getMonitorFactory();
+
+ /**
+ * Create the RuntimeComponent that forms the fundamental root of the component assembly. This component has two
+ * children: a {@link org.apache.tuscany.spi.component.CompositeComponent} that is the root for all system
+ * components, and a {@link org.apache.tuscany.spi.component.CompositeComponent} that is the root for all
+ * application components.
+ *
+ * @return a new RuntimeComponent; basically a new Tuscany instance
+ */
+ RuntimeComponent createRuntime();
+
+ /**
+ * Create a Deployer that can be used to deploy the system definition. This will most likely only support a small
+ * subset of the available programming model.
+ *
+ * @return a new primordial Deployer
+ */
+ Deployer createDeployer();
+
+ /**
+ * Create a Loader for parsing a system definition represented as a XML SCDL file.
+ *
+ * @param propertyFactory the StAXPropertyFactory to be used to parse property values
+ * @param introspector the introspector to be used to extract component type information from a Java class
+ * @return a new prmordial Loader
+ */
+ Loader createLoader(PropertyObjectFactory propertyFactory, Introspector introspector);
+
+ /**
+ * Create a ScopeRegistry that supports the Scopes supported for primordial components
+ *
+ * @param workContext the WorkContext the Scopes should use
+ * @return a new primordial ScopeRegistry
+ */
+ ScopeRegistry createScopeRegistry(WorkContext workContext);
+
+ /**
+ * Create a Connector that can wire together primordial components.
+ *
+ * @return a new primordial Connector
+ */
+ Connector createConnector();
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/bootstrap/DefaultBootstrapper.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/bootstrap/DefaultBootstrapper.java
new file mode 100644
index 0000000000..762568eb01
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/bootstrap/DefaultBootstrapper.java
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.bootstrap;
+
+import javax.xml.stream.XMLInputFactory;
+
+import org.apache.tuscany.spi.bootstrap.ComponentNames;
+import org.apache.tuscany.spi.bootstrap.RuntimeComponent;
+import org.apache.tuscany.spi.builder.Builder;
+import org.apache.tuscany.spi.builder.Connector;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.deployer.Deployer;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService;
+import org.apache.tuscany.spi.implementation.java.Introspector;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.PropertyObjectFactory;
+import org.apache.tuscany.spi.services.management.TuscanyManagementService;
+
+import org.apache.tuscany.core.binding.local.LocalBindingBuilder;
+import org.apache.tuscany.core.binding.local.LocalBindingDefinition;
+import org.apache.tuscany.core.binding.local.LocalBindingLoader;
+import org.apache.tuscany.core.builder.BuilderRegistryImpl;
+import org.apache.tuscany.core.builder.ConnectorImpl;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.component.scope.CompositeScopeObjectFactory;
+import org.apache.tuscany.core.component.scope.ScopeRegistryImpl;
+import org.apache.tuscany.core.deployer.DeployerImpl;
+import org.apache.tuscany.core.idl.java.InterfaceJavaLoader;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.implementation.IntrospectionRegistryImpl;
+import org.apache.tuscany.core.implementation.composite.CompositeComponentImpl;
+import org.apache.tuscany.core.implementation.composite.CompositeLoader;
+import org.apache.tuscany.core.implementation.processor.ConstructorProcessor;
+import org.apache.tuscany.core.implementation.processor.DestroyProcessor;
+import org.apache.tuscany.core.implementation.processor.EagerInitProcessor;
+import org.apache.tuscany.core.implementation.processor.HeuristicPojoProcessor;
+import org.apache.tuscany.core.implementation.processor.ImplementationProcessorServiceImpl;
+import org.apache.tuscany.core.implementation.processor.InitProcessor;
+import org.apache.tuscany.core.implementation.processor.MonitorProcessor;
+import org.apache.tuscany.core.implementation.processor.PropertyProcessor;
+import org.apache.tuscany.core.implementation.processor.ReferenceProcessor;
+import org.apache.tuscany.core.implementation.processor.ResourceProcessor;
+import org.apache.tuscany.core.implementation.processor.ScopeProcessor;
+import org.apache.tuscany.core.implementation.processor.ServiceProcessor;
+import org.apache.tuscany.core.implementation.system.builder.SystemComponentBuilder;
+import org.apache.tuscany.core.implementation.composite.SystemCompositeBuilder;
+import org.apache.tuscany.core.implementation.system.loader.SystemComponentTypeLoader;
+import org.apache.tuscany.core.implementation.system.loader.SystemCompositeComponentTypeLoader;
+import org.apache.tuscany.core.implementation.system.loader.SystemImplementationLoader;
+import org.apache.tuscany.core.implementation.system.model.SystemCompositeImplementation;
+import org.apache.tuscany.core.implementation.system.model.SystemImplementation;
+import org.apache.tuscany.core.loader.ComponentLoader;
+import org.apache.tuscany.core.loader.ComponentTypeElementLoader;
+import org.apache.tuscany.core.loader.IncludeLoader;
+import org.apache.tuscany.core.loader.LoaderRegistryImpl;
+import org.apache.tuscany.core.loader.PropertyLoader;
+import org.apache.tuscany.core.loader.ReferenceLoader;
+import org.apache.tuscany.core.loader.ServiceLoader;
+import org.apache.tuscany.core.property.PropertyObjectFactoryImpl;
+import org.apache.tuscany.core.wire.jdk.JDKWireService;
+import org.apache.tuscany.host.MonitorFactory;
+
+/**
+ * A default implementation of a Bootstrapper. Please see the documentation on the individual methods for how the
+ * primordial components are created.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefaultBootstrapper implements Bootstrapper {
+ private final MonitorFactory monitorFactory;
+ private final XMLInputFactory xmlFactory;
+ private final TuscanyManagementService managementService;
+
+ /**
+ * Create a default bootstrapper.
+ *
+ * @param monitorFactory the MonitorFactory to be used to create monitors for the primordial components
+ * @param xmlFactory the XMLInputFactory to be used by the components to load XML artifacts
+ * @param managementService management service used by the runtime.
+ */
+ public DefaultBootstrapper(MonitorFactory monitorFactory,
+ XMLInputFactory xmlFactory,
+ TuscanyManagementService managementService) {
+ this.monitorFactory = monitorFactory;
+ this.xmlFactory = xmlFactory;
+ this.managementService = managementService;
+ }
+
+ /**
+ * Returns the MonitorFactory being used by this bootstrapper.
+ *
+ * @return the MonitorFactory being used by this bootstrapper
+ */
+ public MonitorFactory getMonitorFactory() {
+ return monitorFactory;
+ }
+
+ /**
+ * Create the RuntimeComponent that will form the root of the component tree. Returns an new instance of a {@link
+ * DefaultRuntime} with the system and application root components initialized with default composite components.
+ *
+ * @return a newly created root for the component tree
+ */
+ public RuntimeComponent createRuntime() {
+ DefaultRuntime runtime = new DefaultRuntime();
+ CompositeComponent systemComponent =
+ new CompositeComponentImpl(ComponentNames.TUSCANY_SYSTEM_ROOT, runtime, null, true);
+ runtime.setSystemComponent(systemComponent);
+ CompositeComponent rootComponent =
+ new CompositeComponentImpl(ComponentNames.TUSCANY_APPLICATION_ROOT, runtime, null, null);
+ runtime.setRootComponent(rootComponent);
+ return runtime;
+ }
+
+ /**
+ * Create primordial deployer that can be used to load the system definition.
+ *
+ * @return the primordial deployer
+ */
+ public Deployer createDeployer() {
+ ScopeRegistry scopeRegistry = createScopeRegistry(new WorkContextImpl());
+ Builder builder = createBuilder(scopeRegistry);
+ JavaInterfaceProcessorRegistry interfaceIntrospector = new JavaInterfaceProcessorRegistryImpl();
+ Introspector introspector = createIntrospector(interfaceIntrospector);
+ LoaderRegistry loader = createLoader(new PropertyObjectFactoryImpl(), introspector);
+ DeployerImpl deployer = new DeployerImpl(xmlFactory, loader, builder);
+ deployer.setMonitor(getMonitorFactory().getMonitor(ScopeContainerMonitor.class));
+ return deployer;
+ }
+
+ /**
+ * Create a basic ScopeRegistry containing the ScopeContainers that are available to components in the system
+ * definition. The implementation returned only support COMPOSITE scope.
+ *
+ * @param workContext the WorkContext the scopes should use
+ * @return a new ScopeRegistry
+ */
+ public ScopeRegistry createScopeRegistry(WorkContext workContext) {
+ ScopeRegistry scopeRegistry = new ScopeRegistryImpl();
+ new CompositeScopeObjectFactory(scopeRegistry, monitorFactory.getMonitor(ScopeContainerMonitor.class));
+ return scopeRegistry;
+ }
+
+ /**
+ * Create a Loader that can be used to parse an XML file containing the SCDL for the system definition. The
+ * following Implementation types are supported: <ul> <li>SystemImplementation</li>
+ * <li>SystemCompositeImplementation</li> </ul> and the following SCDL elements are supported: <ul>
+ * <li>composite</li> <li>component</li> <li>componentType</li> <li>interface.java</li> <li>property</li>
+ * <li>reference</li> <li>service</li> <li>implementation.system</li> </ul> Note the Java component type and the
+ * WSDL interface type are not supported.
+ *
+ * @param propertyFactory the StAXPropertyFactory to be used for parsing Property values
+ * @param introspector the Introspector to be used to inspect component implementations
+ * @return a new StAX XML loader
+ */
+ public LoaderRegistry createLoader(PropertyObjectFactory propertyFactory, Introspector introspector) {
+ LoaderRegistryImpl loaderRegistry =
+ new LoaderRegistryImpl(monitorFactory.getMonitor(LoaderRegistryImpl.Monitor.class));
+
+ // register component type loaders
+ loaderRegistry.registerLoader(SystemImplementation.class, new SystemComponentTypeLoader(introspector));
+ loaderRegistry.registerLoader(SystemCompositeImplementation.class,
+ new SystemCompositeComponentTypeLoader(loaderRegistry));
+
+ // register element loaders
+ registerLoader(loaderRegistry, new ComponentLoader(loaderRegistry, propertyFactory));
+ registerLoader(loaderRegistry, new ComponentTypeElementLoader(loaderRegistry));
+ registerLoader(loaderRegistry, new CompositeLoader(loaderRegistry, null));
+ registerLoader(loaderRegistry, new IncludeLoader(loaderRegistry));
+ JavaInterfaceProcessorRegistryImpl processorRegistry = new JavaInterfaceProcessorRegistryImpl();
+ registerLoader(loaderRegistry, new InterfaceJavaLoader(loaderRegistry, processorRegistry));
+ registerLoader(loaderRegistry, new PropertyLoader(loaderRegistry));
+ registerLoader(loaderRegistry, new ReferenceLoader(loaderRegistry));
+ registerLoader(loaderRegistry, new ServiceLoader(loaderRegistry));
+ registerLoader(loaderRegistry, new SystemImplementationLoader(loaderRegistry));
+ registerLoader(loaderRegistry, new LocalBindingLoader(loaderRegistry));
+ return loaderRegistry;
+ }
+
+ /**
+ * Create new Introspector for extracting a ComponentType definition from a Java class.
+ *
+ * @return a new Introspector
+ */
+ public Introspector createIntrospector(JavaInterfaceProcessorRegistry registry) {
+ ImplementationProcessorService service = new ImplementationProcessorServiceImpl(registry);
+ IntrospectionRegistryImpl.Monitor monitor = monitorFactory.getMonitor(IntrospectionRegistryImpl.Monitor.class);
+ IntrospectionRegistryImpl introspectionRegistry = new IntrospectionRegistryImpl(monitor);
+ introspectionRegistry.registerProcessor(new ConstructorProcessor(service));
+ introspectionRegistry.registerProcessor(new DestroyProcessor());
+ introspectionRegistry.registerProcessor(new InitProcessor());
+ introspectionRegistry.registerProcessor(new EagerInitProcessor());
+ introspectionRegistry.registerProcessor(new ScopeProcessor());
+ introspectionRegistry.registerProcessor(new PropertyProcessor(service));
+ introspectionRegistry.registerProcessor(new ReferenceProcessor(registry));
+ introspectionRegistry.registerProcessor(new ResourceProcessor());
+ introspectionRegistry.registerProcessor(new ServiceProcessor(service));
+ introspectionRegistry.registerProcessor(new HeuristicPojoProcessor(service));
+ introspectionRegistry.registerProcessor(new MonitorProcessor(monitorFactory, service));
+ return introspectionRegistry;
+ }
+
+ /**
+ * Create a new Connector that can be used to wire primordial components together.
+ *
+ * @return a new Connector
+ */
+ public Connector createConnector() {
+ return new ConnectorImpl();
+ }
+
+ /**
+ * Helper method for registering a loader with the registry. The Loader is registered once for the QName returned by
+ * its {@link LoaderExtension#getXMLType()} method.
+ *
+ * @param registry the LoaderRegistry to register with
+ * @param loader the Loader to register
+ */
+ protected void registerLoader(LoaderRegistry registry, LoaderExtension<?> loader) {
+ registry.registerLoader(loader.getXMLType(), loader);
+ }
+
+ /**
+ * Create a Builder that can be used to build the components in the system definition. The default implementation
+ * only supports implementations from the system programming model.
+ *
+ * @param scopeRegistry the ScopeRegistry defining the component scopes that will be supported
+ * @return a new Builder
+ */
+ private Builder createBuilder(ScopeRegistry scopeRegistry) {
+ BuilderRegistryImpl builderRegistry =
+ new BuilderRegistryImpl(scopeRegistry, new JDKWireService());
+ SystemCompositeBuilder builder =
+ new SystemCompositeBuilder(builderRegistry, createConnector(), managementService);
+ builderRegistry.register(SystemCompositeImplementation.class, builder);
+ builderRegistry.register(SystemImplementation.class, new SystemComponentBuilder());
+ builderRegistry.register(LocalBindingDefinition.class, new LocalBindingBuilder());
+ return builderRegistry;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/bootstrap/DefaultRuntime.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/bootstrap/DefaultRuntime.java
new file mode 100644
index 0000000000..978d10fc37
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/bootstrap/DefaultRuntime.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.bootstrap;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.w3c.dom.Document;
+
+import org.apache.tuscany.spi.bootstrap.ComponentNames;
+import org.apache.tuscany.spi.bootstrap.RuntimeComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.deployer.Deployer;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import org.apache.tuscany.core.implementation.composite.CompositeComponentImpl;
+
+/**
+ * The default implementation of the Tuscany runtime component
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefaultRuntime extends CompositeComponentImpl implements RuntimeComponent {
+ private CompositeComponent rootComponent;
+ private CompositeComponent systemComponent;
+
+ /**
+ * Initialize a default runtime with an empty set of Property values.
+ */
+ public DefaultRuntime() {
+ this(new HashMap<String, Document>());
+ }
+
+ /**
+ * Initialize a runtime with the a set of properties
+ *
+ * @param runtimeProperties Property values for the runtime itself
+ */
+ public DefaultRuntime(Map<String, Document> runtimeProperties) {
+ super(ComponentNames.TUSCANY_RUNTIME, null, null, runtimeProperties);
+ }
+
+ protected void setRootComponent(CompositeComponent rootComponent) {
+ this.rootComponent = rootComponent;
+ }
+
+ protected void setSystemComponent(CompositeComponent systemComponent) {
+ this.systemComponent = systemComponent;
+ }
+
+ public CompositeComponent getRootComponent() {
+ return rootComponent;
+ }
+
+ public CompositeComponent getSystemComponent() {
+ return systemComponent;
+ }
+
+ public Deployer getDeployer() throws TargetResolutionException {
+ InboundWire wire = systemComponent.resolveExternalAutowire(Deployer.class);
+ if (wire != null) {
+ return (Deployer) wire.getTargetService();
+ }
+ return null;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/bootstrap/DefaultSCARuntime.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/bootstrap/DefaultSCARuntime.java
new file mode 100644
index 0000000000..15172c60c0
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/bootstrap/DefaultSCARuntime.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.bootstrap;
+
+import java.net.URI;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.tuscany.api.SCARuntime;
+import org.apache.tuscany.api.TuscanyException;
+import org.apache.tuscany.core.component.ComponentContextImpl;
+import org.apache.tuscany.core.launcher.CompositeContextImpl;
+import org.apache.tuscany.core.runtime.mini.SimpleRuntime;
+import org.apache.tuscany.core.runtime.mini.SimpleRuntimeImpl;
+import org.apache.tuscany.core.runtime.mini.SimpleRuntimeInfo;
+import org.apache.tuscany.core.runtime.mini.SimpleRuntimeInfoImpl;
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.osoa.sca.ComponentContext;
+import org.osoa.sca.CurrentCompositeContext;
+import org.osoa.sca.ServiceUnavailableException;
+
+/**
+ * Default implementation of SCARuntime.
+ *
+ * @version $Rev$ $Date$
+ */
+@SuppressWarnings("deprecation")
+public class DefaultSCARuntime extends SCARuntime {
+ protected CompositeComponent application;
+ protected CompositeContextImpl context;
+
+ protected SimpleRuntime runtime;
+
+ protected void startup(URL system, URL[] exts, URL applicationSCDL, String compositePath) throws Exception {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ List<URL> extensions = exts == null ? null : Arrays.asList(exts);
+ URI contributionURI = URI.create("/default");
+ SimpleRuntimeInfo runtimeInfo =
+ new SimpleRuntimeInfoImpl(cl, system, extensions, contributionURI, applicationSCDL, compositePath);
+ runtime = new SimpleRuntimeImpl(runtimeInfo);
+
+ try {
+ application = runtime.start();
+ } catch (TuscanyException e) {
+ throw e;
+ }
+
+ }
+
+ protected void shutdown() throws Exception {
+ runtime.destroy();
+ }
+
+ @Override
+ protected ComponentContext getContext(String componentName) {
+ CompositeComponent composite = ((CompositeContextImpl)context).getComposite();
+ Component component = (Component)composite.getChild(componentName);
+ return new ComponentContextImpl(CurrentCompositeContext.getContext(), component);
+ }
+
+ public CompositeComponent getCompsiteComponent() {
+ return application;
+ }
+
+ @Override
+ public Object getSystemService(String serviceName) {
+ try {
+ return runtime.getSystemService(Object.class, serviceName);
+ } catch (TargetResolutionException e) {
+ throw new ServiceUnavailableException(e);
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/BuilderRegistryImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/BuilderRegistryImpl.java
new file mode 100644
index 0000000000..2bb0524201
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/BuilderRegistryImpl.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.core.binding.local.LocalBindingDefinition;
+import org.apache.tuscany.core.implementation.composite.ReferenceImpl;
+import org.apache.tuscany.core.implementation.composite.ServiceImpl;
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.builder.BindingBuilder;
+import org.apache.tuscany.spi.builder.BuilderException;
+import org.apache.tuscany.spi.builder.BuilderRegistry;
+import org.apache.tuscany.spi.builder.ComponentBuilder;
+import org.apache.tuscany.spi.builder.GenericBuilder;
+import org.apache.tuscany.spi.builder.MissingWireTargetException;
+import org.apache.tuscany.spi.builder.ScopeNotFoundException;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.Reference;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.component.Service;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.model.BindingDefinition;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.ComponentType;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.Implementation;
+import org.apache.tuscany.spi.model.InteractionScope;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.apache.tuscany.spi.wire.WireService;
+import org.osoa.sca.annotations.EagerInit;
+
+/**
+ * The default builder registry in the runtime
+ *
+ * @version $Rev$ $Date$
+ */
+@EagerInit
+public class BuilderRegistryImpl implements BuilderRegistry {
+ protected WireService wireService;
+ protected ScopeRegistry scopeRegistry;
+
+ private final Map<Class<? extends Implementation<?>>, ComponentBuilder<? extends Implementation<?>>> componentBuilders =
+ new HashMap<Class<? extends Implementation<?>>, ComponentBuilder<? extends Implementation<?>>>();
+ private final Map<Class<? extends BindingDefinition>, BindingBuilder<? extends BindingDefinition>> bindingBuilders =
+ new HashMap<Class<? extends BindingDefinition>, BindingBuilder<? extends BindingDefinition>>();
+ private final Map<Class<? extends ModelObject>, GenericBuilder<? extends SCAObject, ? extends ModelObject>> genericBuilders =
+ new HashMap<Class<? extends ModelObject>, GenericBuilder<? extends SCAObject, ? extends ModelObject>>();
+
+ public BuilderRegistryImpl(@Autowire
+ ScopeRegistry scopeRegistry, @Autowire
+ WireService wireService) {
+ this.scopeRegistry = scopeRegistry;
+ this.wireService = wireService;
+ }
+
+ public <I extends Implementation<?>> void register(Class<I> implClass, ComponentBuilder<I> builder) {
+ componentBuilders.put(implClass, builder);
+ }
+
+ public <I extends Implementation<?>> void unregisterComponentBuilder(Class<I> implClass) {
+ componentBuilders.remove(implClass);
+ }
+
+ public <B extends BindingDefinition> void register(Class<B> implClass, BindingBuilder<B> builder) {
+ bindingBuilders.put(implClass, builder);
+ }
+
+ @SuppressWarnings("unchecked")
+ public <I extends Implementation<?>> Component build(CompositeComponent parent,
+ ComponentDefinition<I> componentDefinition,
+ DeploymentContext context) throws BuilderException {
+
+ Class<?> implClass = componentDefinition.getImplementation().getClass();
+ // noinspection SuspiciousMethodCalls
+ ComponentBuilder<I> componentBuilder = (ComponentBuilder<I>)componentBuilders.get(implClass);
+ try {
+ if (componentBuilder == null) {
+ String name = implClass.getName();
+ throw new NoRegisteredBuilderException("No builder registered for implementation", name);
+ }
+
+ Component component = componentBuilder.build(parent, componentDefinition, context);
+ if (component != null) {
+ component.setDefaultPropertyValues(componentDefinition.getPropertyValues());
+ Scope scope = componentDefinition.getImplementation().getComponentType().getImplementationScope();
+ if (scope == Scope.SYSTEM || scope == Scope.COMPOSITE) {
+ component.setScopeContainer(context.getCompositeScope());
+ } else {
+ // Check for conversational contract if conversational scope
+ if (scope == Scope.CONVERSATION) {
+ boolean hasConversationalContract = false;
+ ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, ?> componentType =
+ componentDefinition.getImplementation().getComponentType();
+ Map<String, ServiceDefinition> services = componentType.getServices();
+ for (ServiceDefinition serviceDef : services.values()) {
+ InteractionScope intScope = serviceDef.getServiceContract().getInteractionScope();
+ if (intScope == InteractionScope.CONVERSATIONAL) {
+ hasConversationalContract = true;
+ break;
+ }
+ }
+ if (!hasConversationalContract) {
+ Map<String, ComponentTypeReferenceDefinition> references = componentType.getReferences();
+ for (AbstractReferenceDefinition refDef : references.values()) {
+ // TODO check for a conversational callback
+ // contract
+ // refDef.getServiceContract() ...
+ }
+ }
+ if (!hasConversationalContract) {
+ String name = implClass.getName();
+ throw new NoConversationalContractException("No conversational contract for conversational implementation",
+ name);
+ }
+ }
+ // Now it's ok to set the scope container
+ ScopeContainer scopeContainer = scopeRegistry.getScopeContainer(scope);
+ if (scopeContainer == null) {
+ throw new ScopeNotFoundException(scope.toString());
+ }
+ component.setScopeContainer(scopeContainer);
+ }
+ }
+ ComponentType<?, ?, ?> componentType = componentDefinition.getImplementation().getComponentType();
+ assert componentType != null : "Component type must be set";
+ // create wires for the component
+ if (wireService != null && component instanceof AtomicComponent) {
+ wireService.createWires((AtomicComponent)component, componentDefinition);
+ }
+ // FIXME: Can we merge all the extensions at the component level?
+ buildExtensions(component, componentType, context);
+ buildExtensions(component, componentDefinition.getImplementation(), context);
+ buildExtensions(component, componentDefinition, context);
+ return component;
+ } catch (BuilderException e) {
+ e.addContextName(componentDefinition.getName());
+ throw e;
+ }
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public Service build(CompositeComponent parent,
+ ServiceDefinition serviceDefinition,
+ DeploymentContext deploymentContext) throws BuilderException {
+ String name = serviceDefinition.getName();
+ ServiceContract<?> serviceContract = serviceDefinition.getServiceContract();
+ if (serviceDefinition.getBindings().isEmpty()) {
+ // if no bindings are configured, default to the local binding.
+ // this should be changed to allow runtime selection
+ if (serviceDefinition.getBindings().isEmpty()) {
+ // TODO JFM implement capability for the runtime to choose a
+ // binding
+ serviceDefinition.addBinding(new LocalBindingDefinition());
+ }
+ }
+ boolean system = parent.isSystem();
+ URI targetUri = serviceDefinition.getTarget();
+ Service service = new ServiceImpl(name, parent, serviceContract, targetUri, system);
+ for (BindingDefinition definition : serviceDefinition.getBindings()) {
+ Class<?> bindingClass = definition.getClass();
+ // noinspection SuspiciousMethodCalls
+ BindingBuilder bindingBuilder = bindingBuilders.get(bindingClass);
+ if (bindingBuilder == null) {
+ throw new NoRegisteredBuilderException("No builder registered for type", bindingClass.getName());
+ }
+ ServiceBinding binding = bindingBuilder.build(parent, serviceDefinition, definition, deploymentContext);
+ if (wireService != null) {
+ URI uri = serviceDefinition.getTarget();
+ if (uri == null) {
+ throw new MissingWireTargetException("Service uri not specified");
+ }
+ String path = uri.getPath();
+ ServiceContract<?> contract = serviceDefinition.getServiceContract();
+ wireService.createWires(binding, contract, path);
+ }
+ buildExtensions(binding, definition, deploymentContext);
+ service.addServiceBinding(binding);
+ }
+ buildExtensions(service, serviceDefinition, deploymentContext);
+ return service;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Reference build(CompositeComponent parent,
+ AbstractReferenceDefinition referenceDefinition,
+ DeploymentContext context)
+ throws BuilderException {
+ String name = referenceDefinition.getName();
+ ServiceContract<?> contract = referenceDefinition.getServiceContract();
+ if (referenceDefinition.getBindings().isEmpty()) {
+ // if no bindings are configured, default to the local binding.
+ // this should be changed to allow runtime selection
+ if (referenceDefinition.getBindings().isEmpty()) {
+ // TODO JFM implement capability for the runtime to choose a
+ // binding
+ referenceDefinition.addBinding(new LocalBindingDefinition());
+ }
+ }
+
+ Reference reference = new ReferenceImpl(name, parent, contract);
+ for (BindingDefinition bindingDefinition : referenceDefinition.getBindings()) {
+ Class<?> bindingClass = bindingDefinition.getClass();
+ // noinspection SuspiciousMethodCalls
+ BindingBuilder bindingBuilder = bindingBuilders.get(bindingClass);
+ ReferenceBinding binding = bindingBuilder.build(parent, referenceDefinition, bindingDefinition, context);
+ // create wires for the component
+ if (wireService != null) {
+ URI targetUri = bindingDefinition.getTargetUri();
+ // it is possible for a binding to not have a URI
+ QualifiedName targetName = null;
+ if (targetUri != null) {
+ targetName = new QualifiedName(targetUri.getPath());
+ }
+ wireService.createWires(binding, contract, targetName);
+
+ }
+ buildExtensions(binding, bindingDefinition, context);
+ reference.addReferenceBinding(binding);
+
+ }
+ buildExtensions(reference, referenceDefinition, context);
+ return reference;
+ }
+
+ @SuppressWarnings("unchecked")
+ public SCAObject build(SCAObject parent, ModelObject modelObject, DeploymentContext context)
+ throws BuilderException {
+ if (modelObject != null) {
+ GenericBuilder builder = genericBuilders.get(modelObject.getClass());
+ if (builder != null) {
+ return builder.build(parent, modelObject, context);
+ }
+ }
+ return null;
+ }
+
+ // We need to include all the extensions from the include
+ private void buildExtensions(SCAObject parent, ModelObject model, DeploymentContext deploymentContext)
+ throws BuilderException {
+ for (Object o : model.getExtensions().values()) {
+ if (o instanceof ModelObject) {
+ SCAObject scaObject = build(parent, (ModelObject)o, deploymentContext);
+ if (scaObject != null) {
+ parent.getExtensions().put(scaObject.getName(), scaObject);
+ }
+ }
+ }
+ }
+
+ public <S extends SCAObject, M extends ModelObject> void register(Class<M> modelClass,
+ GenericBuilder<S, M> builder) {
+ genericBuilders.put(modelClass, builder);
+ }
+
+ public <B extends BindingDefinition> void unregisterBindingBuilder(Class<B> implClass) {
+ bindingBuilders.remove(implClass);
+ }
+
+ public <M extends ModelObject> void unregisterGenericBuilder(Class<M> modelClass) {
+ genericBuilders.remove(modelClass);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/ConnectorImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/ConnectorImpl.java
new file mode 100644
index 0000000000..728b0b8fc9
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/ConnectorImpl.java
@@ -0,0 +1,627 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import java.util.List;
+import java.util.Map;
+
+import org.osoa.sca.annotations.Constructor;
+
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.builder.Connector;
+import org.apache.tuscany.spi.builder.MissingWireTargetException;
+import org.apache.tuscany.spi.builder.WiringException;
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.Reference;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.Service;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.component.TargetInvokerCreationException;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.services.work.WorkScheduler;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.IncompatibleServiceContractException;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.apache.tuscany.spi.wire.WirePostProcessorRegistry;
+import org.apache.tuscany.spi.wire.WireService;
+
+import org.apache.tuscany.core.wire.LoopBackWire;
+import org.apache.tuscany.core.wire.NonBlockingBridgingInterceptor;
+import org.apache.tuscany.core.wire.SynchronousBridgingInterceptor;
+import org.apache.tuscany.core.wire.WireUtils;
+
+/**
+ * The default connector implmentation
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class ConnectorImpl implements Connector {
+ private WirePostProcessorRegistry postProcessorRegistry;
+ private WireService wireService;
+ private WorkContext workContext;
+ private WorkScheduler scheduler;
+
+ public ConnectorImpl() {
+ }
+
+ @Constructor
+ public ConnectorImpl(@Autowire WireService wireService,
+ @Autowire WirePostProcessorRegistry processorRegistry,
+ @Autowire WorkScheduler scheduler,
+ @Autowire WorkContext workContext) {
+ this.postProcessorRegistry = processorRegistry;
+ this.wireService = wireService;
+ this.scheduler = scheduler;
+ this.workContext = workContext;
+ }
+
+ public void connect(SCAObject source) throws WiringException {
+ if (source instanceof Component) {
+ handleComponent((Component) source);
+ } else if (source instanceof Reference) {
+ handleReference((Reference) source);
+ } else if (source instanceof Service) {
+ handleService((Service) source);
+ } else {
+ throw new AssertionError("Invalid source type");
+ }
+ }
+
+ public void connect(InboundWire sourceWire, OutboundWire targetWire, boolean optimizable)
+ throws WiringException {
+ Map<Operation<?>, OutboundInvocationChain> targetChains = targetWire.getInvocationChains();
+ if (sourceWire.getContainer() != null && sourceWire.getContainer().isSystem()) {
+ sourceWire.setTargetWire(targetWire);
+ // system services do not need to have their chains processed, return
+ return;
+ }
+ for (InboundInvocationChain inboundChain : sourceWire.getInvocationChains().values()) {
+ // match invocation chains
+ OutboundInvocationChain outboundChain = targetChains.get(inboundChain.getOperation());
+ if (outboundChain == null) {
+ throw new IncompatibleInterfacesException(sourceWire, targetWire);
+ }
+ connect(inboundChain, outboundChain);
+ }
+ if (postProcessorRegistry != null) {
+ // run wire post-processors
+ postProcessorRegistry.process(sourceWire, targetWire);
+ }
+ if (optimizable && WireUtils.isOptimizable(sourceWire) && WireUtils.isOptimizable(targetWire)) {
+ sourceWire.setOptimizable(true);
+ sourceWire.setTargetWire(targetWire);
+ }
+ }
+
+ /**
+ * Connects the source outbound wire to a corresponding target inbound wire
+ *
+ * @param sourceWire the source wire to connect
+ * @param targetWire the target wire to connect to
+ * @param optimizable true if the wire connection can be optimized
+ * @throws WiringException
+ */
+ public void connect(OutboundWire sourceWire, InboundWire targetWire, boolean optimizable)
+ throws WiringException {
+ SCAObject source = sourceWire.getContainer();
+ assert source != null;
+ SCAObject target = targetWire.getContainer();
+ assert target != null;
+ Map<Operation<?>, InboundInvocationChain> targetChains = targetWire.getInvocationChains();
+ if (sourceWire.getContainer() != null && sourceWire.getContainer().isSystem()) {
+ sourceWire.setTargetWire(targetWire);
+ // system services do not need to have their chains processed, return
+ return;
+ }
+
+ // FIXME: [rfeng] The targetWire is provided by the system
+ if (targetWire.getContainer() != null && targetWire.getContainer().isSystem()) {
+ sourceWire.setOptimizable(true);
+ sourceWire.setTargetWire(targetWire);
+ // system services do not need to have their chains processed, return
+ return;
+ }
+
+ // match outbound to inbound chains
+ for (OutboundInvocationChain outboundChain : sourceWire.getInvocationChains().values()) {
+ Operation<?> operation = outboundChain.getOperation();
+
+ // TODO: TUSCANY-1111, can't use targetChains.get with different IDLs so use simple name matching
+ // InboundInvocationChain inboundChain = targetChains.get(operation);
+ InboundInvocationChain inboundChain = null; // = targetChains.get(operation);
+ for (InboundInvocationChain ic: targetChains.values()) {
+ if (ic.getOperation().equals(operation)) {
+ inboundChain = ic;
+ break;
+ }
+ }
+ if (inboundChain == null) {
+ throw new IncompatibleInterfacesException(sourceWire, targetWire);
+ }
+ Operation<?> inboundOperation = inboundChain.getOperation();
+ boolean isOneWayOperation = operation.isNonBlocking();
+ TargetInvoker invoker;
+ if (target instanceof Component) {
+ Component component = (Component) target;
+ QualifiedName wireTargetName = sourceWire.getTargetName();
+ String portName = null;
+ if (wireTargetName != null) {
+ portName = wireTargetName.getPortName();
+ }
+ try {
+ invoker = component.createTargetInvoker(portName, inboundOperation, targetWire);
+ } catch (TargetInvokerCreationException e) {
+ throw new WireConnectException("Error connecting source and target", sourceWire, targetWire, e);
+ }
+ } else if (target instanceof ReferenceBinding) {
+ ReferenceBinding referenceBinding = (ReferenceBinding) target;
+ try {
+ invoker = referenceBinding.createTargetInvoker(targetWire.getServiceContract(), inboundOperation);
+ } catch (TargetInvokerCreationException e) {
+ String targetName = targetWire.getContainer().getName();
+ throw new WireConnectException("Error processing inbound wire", null, null, targetName, null, e);
+ }
+ } else if (target instanceof ServiceBinding) {
+ ServiceBinding binding = (ServiceBinding) target;
+ try {
+ invoker = binding.createTargetInvoker(targetWire.getServiceContract(), inboundChain.getOperation());
+ } catch (TargetInvokerCreationException e) {
+ String targetName = targetWire.getContainer().getName();
+ throw new WireConnectException("Error processing inbound wire", null, null, targetName, null, e);
+ }
+ } else {
+ throw new AssertionError();
+ }
+
+ if (source instanceof ServiceBinding) {
+ // services are a special case: invoker must go on the inbound and outbound chains
+ if (target instanceof Component && isOneWayOperation) {
+ // if the target is a component and the operation is non-blocking
+ connect(outboundChain, inboundChain, invoker, true);
+ } else {
+ connect(outboundChain, inboundChain, invoker, false);
+ }
+ ServiceBinding binding = (ServiceBinding) source;
+ InboundInvocationChain chain = binding.getInboundWire().getInvocationChains().get(operation);
+ chain.setTargetInvoker(invoker);
+ } else {
+ if (target instanceof Component && isOneWayOperation) {
+ // if the target is a component and the operation is non-blocking
+ connect(outboundChain, inboundChain, invoker, true);
+ } else {
+ connect(outboundChain, inboundChain, invoker, false);
+ }
+ }
+ }
+
+ // create source callback chains and connect them if target callback chains exist
+ Map<Operation<?>, OutboundInvocationChain> sourceCallbackChains =
+ targetWire.getSourceCallbackInvocationChains(source.getName());
+ for (InboundInvocationChain inboundChain : sourceWire.getTargetCallbackInvocationChains().values()) {
+ Operation<?> operation = inboundChain.getOperation();
+ if (sourceCallbackChains != null && sourceCallbackChains.get(operation) != null) {
+ String opName = operation.getName();
+ throw new IllegalCallbackException("Source callback chain should not exist for operation",
+ opName,
+ sourceWire,
+ targetWire);
+ }
+
+ ServiceContract<?> targetContract = targetWire.getServiceContract();
+ assert targetContract != null;
+ String opName = operation.getName();
+ assert opName != null;
+ Operation targetOp = targetContract.getCallbackOperations().get(opName);
+ OutboundInvocationChain outboundChain = wireService.createOutboundChain(targetOp);
+ targetWire.addSourceCallbackInvocationChain(source.getName(), targetOp, outboundChain);
+ if (source instanceof Component) {
+ Component component = (Component) source;
+ TargetInvoker invoker;
+ try {
+ invoker = component.createTargetInvoker(targetOp.getName(), operation, null);
+ } catch (TargetInvokerCreationException e) {
+ throw new WireConnectException("Error connecting source and target", sourceWire, targetWire, e);
+ }
+ boolean isOneWayOperation = targetOp.isNonBlocking();
+ if (target instanceof Component && isOneWayOperation) {
+ // if the target is a component and the operation is non-blocking
+ connect(outboundChain, inboundChain, invoker, true);
+ } else {
+ connect(outboundChain, inboundChain, invoker, false);
+ }
+ } else if (source instanceof ReferenceBinding) {
+ ReferenceBinding binding = (ReferenceBinding) source;
+ ServiceContract sourceContract = sourceWire.getServiceContract();
+ TargetInvoker invoker;
+ try {
+ invoker = binding.createTargetInvoker(sourceContract, operation);
+ } catch (TargetInvokerCreationException e) {
+ throw new WireConnectException("Error connecting source and target", sourceWire, targetWire, e);
+ }
+ connect(outboundChain, inboundChain, invoker, false);
+ } else if (source instanceof ServiceBinding) {
+ ServiceBinding binding = (ServiceBinding) source;
+ ServiceContract sourceContract = sourceWire.getServiceContract();
+ TargetInvoker invoker;
+ try {
+ invoker = binding.createTargetInvoker(sourceContract, operation);
+ } catch (TargetInvokerCreationException e) {
+ String targetName = sourceWire.getContainer().getName();
+ throw new WireConnectException("Error processing callback wire", null, null, targetName, null, e);
+ }
+ connect(outboundChain, inboundChain, invoker, false);
+ } else {
+ throw new AssertionError();
+ }
+ }
+ if (postProcessorRegistry != null) {
+ // run wire post-processors
+ postProcessorRegistry.process(sourceWire, targetWire);
+ }
+ // perform optimization, if possible
+ if (optimizable && WireUtils.isOptimizable(sourceWire) && WireUtils.isOptimizable(targetWire)) {
+ sourceWire.setOptimizable(true);
+ sourceWire.setTargetWire(targetWire);
+ }
+ }
+
+ /**
+ * Connects a source to target chain
+ *
+ * @param sourceChain the source chain
+ * @param targetChain the target chain
+ * @param invoker the invoker to place on the source chain for dispatching invocations
+ * @param nonBlocking true if the operation is non-blocking
+ */
+ protected void connect(OutboundInvocationChain sourceChain,
+ InboundInvocationChain targetChain,
+ TargetInvoker invoker,
+ boolean nonBlocking) throws WireConnectException {
+ Interceptor head = targetChain.getHeadInterceptor();
+ if (head == null) {
+ throw new WireConnectException("Inbound chain must contain at least one interceptor");
+ }
+ if (nonBlocking) {
+ sourceChain.setTargetInterceptor(new NonBlockingBridgingInterceptor(scheduler, workContext, head));
+ } else {
+ sourceChain.setTargetInterceptor(new SynchronousBridgingInterceptor(head));
+ }
+ sourceChain.prepare();
+ sourceChain.setTargetInvoker(invoker);
+ }
+
+
+ /**
+ * Connects an inbound source chain to an outbound target chain
+ *
+ * @param sourceChain the source chain to connect
+ * @param targetChain the target chain to connect
+ */
+ protected void connect(InboundInvocationChain sourceChain, OutboundInvocationChain targetChain)
+ throws WireConnectException {
+ Interceptor head = targetChain.getHeadInterceptor();
+ if (head == null) {
+ throw new WireConnectException("Outbound chain must contain at least one interceptor");
+ }
+ // invocations from inbound to outbound chains are always synchronous as they occur in services and references
+ sourceChain.addInterceptor(new SynchronousBridgingInterceptor(head));
+ }
+
+ /**
+ * Connects an outbound wire to its target in a composite.
+ *
+ * @param sourceWire the source wire to connect
+ * @throws WiringException
+ */
+ protected void connect(SCAObject source, OutboundWire sourceWire, SCAObject target) throws WiringException {
+ assert sourceWire.getTargetName() != null;
+ QualifiedName targetName = sourceWire.getTargetName();
+ if (target instanceof Component) {
+ connect(source, sourceWire, (Component) target);
+ } else if (target instanceof Reference) {
+ connect(source, sourceWire, (Reference) target);
+ } else if (target instanceof Service) {
+ connect(source, sourceWire, (Service) target);
+ } else if (target == null) {
+ String sourceName = sourceWire.getContainer().getName();
+ String sourceReference = sourceWire.getReferenceName();
+ throw new TargetServiceNotFoundException("Target service not found",
+ sourceName,
+ sourceReference,
+ targetName.getPartName(),
+ targetName.getPortName());
+ } else {
+ String sourceName = sourceWire.getContainer().getName();
+ String sourceRef = sourceWire.getReferenceName();
+ String partName = targetName.getPartName();
+ String portName = targetName.getPortName();
+ throw new InvalidTargetTypeException("Invalid target type", sourceName, sourceRef, partName, portName);
+ }
+ }
+
+ protected void connect(SCAObject source, OutboundWire sourceWire, Reference target) throws WiringException {
+ assert sourceWire.getTargetName() != null;
+ QualifiedName targetName = sourceWire.getTargetName();
+ InboundWire targetWire = null;
+ for (ReferenceBinding binding : target.getReferenceBindings()) {
+ InboundWire candidate = binding.getInboundWire();
+ if (sourceWire.getBindingType().equals(candidate.getBindingType())) {
+ targetWire = candidate;
+ break;
+ }
+ }
+ if (targetWire == null) {
+ if (target.getReferenceBindings().size() > 0 && source instanceof Component) {
+ // TODO create a pluggable algorithm for selecting the binding type
+ targetWire = target.getReferenceBindings().get(0).getInboundWire();
+ }
+ if (targetWire == null) {
+ throw new NoCompatibleBindingsException(source.getName(),
+ targetName.getPartName(),
+ targetName.getPortName());
+ }
+ }
+ checkIfWireable(sourceWire, targetWire);
+ boolean optimizable = isOptimizable(source.getScope(), target.getScope());
+ connect(sourceWire, targetWire, optimizable);
+ }
+
+ protected void connect(SCAObject source, OutboundWire sourceWire, Service target) throws WiringException {
+ assert sourceWire.getTargetName() != null;
+ QualifiedName targetName = sourceWire.getTargetName();
+ InboundWire targetWire = null;
+ for (ServiceBinding binding : target.getServiceBindings()) {
+ InboundWire candidate = binding.getInboundWire();
+ if (sourceWire.getBindingType().equals(candidate.getBindingType())) {
+ targetWire = candidate;
+ break;
+ }
+ }
+ if (targetWire == null) {
+ throw new NoCompatibleBindingsException(source.getName(),
+ targetName.getPartName(),
+ targetName.getPortName());
+ }
+ checkIfWireable(sourceWire, targetWire);
+ boolean optimizable = isOptimizable(source.getScope(), target.getScope());
+ connect(sourceWire, targetWire, optimizable);
+ }
+
+ protected void connect(SCAObject source, OutboundWire sourceWire, Component target)
+ throws WiringException {
+ assert sourceWire.getTargetName() != null;
+ QualifiedName targetName = sourceWire.getTargetName();
+ InboundWire targetWire;
+ // FIXME JFM should we move getInboundSystemWire up to Component?
+ if (target instanceof CompositeComponent && source.isSystem()) {
+ targetWire = ((CompositeComponent) target).getInboundSystemWire(targetName.getPortName());
+ } else {
+ targetWire = target.getInboundWire(targetName.getPortName());
+ }
+ if (targetWire == null) {
+ String sourceName = sourceWire.getContainer().getName();
+ String sourceReference = sourceWire.getReferenceName();
+ throw new TargetServiceNotFoundException("Target service does not exist or is not configured with a "
+ + "local binding",
+ sourceName,
+ sourceReference,
+ targetName.getPartName(),
+ targetName.getPortName());
+ }
+ checkIfWireable(sourceWire, targetWire);
+ boolean optimizable = isOptimizable(source.getScope(), target.getScope());
+ connect(sourceWire, targetWire, optimizable);
+ }
+
+ protected void autowire(OutboundWire outboundWire, CompositeComponent parent)
+ throws WiringException {
+ // JFM FIXME test coverage for this method
+ InboundWire targetWire;
+ try {
+ Class interfaze = outboundWire.getServiceContract().getInterfaceClass();
+ if (CompositeComponent.class.equals(interfaze)) {
+ JavaServiceContract contract = new JavaServiceContract(CompositeComponent.class);
+ targetWire = new LoopBackWire();
+ targetWire.setServiceContract(contract);
+ targetWire.setContainer(parent);
+ outboundWire.setTargetWire(targetWire);
+ return;
+ }
+ if (outboundWire.getContainer().isSystem()) {
+ targetWire = parent.resolveSystemAutowire(interfaze);
+ } else {
+ targetWire = parent.resolveAutowire(interfaze);
+ }
+ } catch (TargetResolutionException e) {
+ String sourceReference = outboundWire.getReferenceName();
+ String sourceName = outboundWire.getContainer().getName();
+ throw new WireConnectException("Error resolving autowire target",
+ sourceName,
+ sourceReference,
+ null,
+ null,
+ e);
+ }
+ if (targetWire == null) {
+ // autowire may return null if it is optional. The client must decide if an error should be thrown
+ return;
+ }
+ Scope sourceScope = outboundWire.getContainer().getScope();
+ Scope targetScope = targetWire.getContainer().getScope();
+ boolean optimizable = isOptimizable(sourceScope, targetScope);
+ connect(outboundWire, targetWire, optimizable);
+ }
+
+ protected void checkIfWireable(OutboundWire sourceWire, InboundWire targetWire)
+ throws IncompatibleInterfacesException {
+ if (wireService == null) {
+ Class<?> sourceInterface = sourceWire.getServiceContract().getInterfaceClass();
+ Class<?> targetInterface = targetWire.getServiceContract().getInterfaceClass();
+ if (!sourceInterface.isAssignableFrom(targetInterface)) {
+ throw new IncompatibleInterfacesException(sourceWire, targetWire);
+ }
+ } else {
+ try {
+ ServiceContract sourceContract = sourceWire.getServiceContract();
+ ServiceContract targetContract = targetWire.getServiceContract();
+ wireService.checkCompatibility(sourceContract, targetContract, false);
+ } catch (IncompatibleServiceContractException e) {
+ throw new IncompatibleInterfacesException(sourceWire, targetWire, e);
+ }
+ }
+ }
+
+ protected boolean isOptimizable(Scope pReferrer, Scope pReferee) {
+ if (pReferrer == Scope.UNDEFINED
+ || pReferee == Scope.UNDEFINED
+ || pReferrer == Scope.CONVERSATION
+ || pReferee == Scope.CONVERSATION) {
+ return false;
+ }
+ if (pReferee == pReferrer) {
+ return true;
+ } else if (pReferrer == Scope.STATELESS) {
+ return true;
+ } else if (pReferee == Scope.STATELESS) {
+ return false;
+ } else if (pReferrer == Scope.REQUEST && pReferee == Scope.SESSION) {
+ return true;
+ } else if (pReferrer == Scope.REQUEST && pReferee == Scope.COMPOSITE) {
+ return true;
+ } else if (pReferrer == Scope.REQUEST && pReferee == Scope.SYSTEM) {
+ return true;
+ } else if (pReferrer == Scope.SESSION && pReferee == Scope.COMPOSITE) {
+ return true;
+ } else if (pReferrer == Scope.SESSION && pReferee == Scope.SYSTEM) {
+ return true;
+ } else //noinspection SimplifiableIfStatement
+ if (pReferrer == Scope.SYSTEM && pReferee == Scope.COMPOSITE) {
+ // case where a service context points to a composite scoped component
+ return true;
+ } else {
+ return pReferrer == Scope.COMPOSITE && pReferee == Scope.SYSTEM;
+ }
+ }
+
+ /**
+ * Connects wires from a service to a target
+ *
+ * @param service the service
+ * @throws WiringException if an exception connecting the service wires is encountered
+ */
+ private void handleService(Service service) throws WiringException {
+ CompositeComponent parent = service.getParent();
+ assert parent != null;
+ for (ServiceBinding binding : service.getServiceBindings()) {
+ InboundWire inboundWire = binding.getInboundWire();
+ OutboundWire outboundWire = binding.getOutboundWire();
+ // For a composite reference only, since its outbound wire comes from its parent composite,
+ // the corresponding target would not lie in its parent but rather in its parent's parent
+ SCAObject target;
+ if (service.isSystem()) {
+ target = parent.getSystemChild(outboundWire.getTargetName().getPartName());
+ } else {
+ target = parent.getChild(outboundWire.getTargetName().getPartName());
+ }
+ // connect the outbound service wire to the target
+ connect(binding, outboundWire, target);
+ // NB: this connect must be done after the outbound service chain is connected to its target above
+ connect(inboundWire, outboundWire, true);
+ }
+ }
+
+ private void handleReference(Reference reference) throws WiringException {
+ CompositeComponent parent = reference.getParent();
+ assert parent != null;
+ for (ReferenceBinding binding : reference.getReferenceBindings()) {
+ InboundWire inboundWire = binding.getInboundWire();
+ Map<Operation<?>, InboundInvocationChain> inboundChains = inboundWire.getInvocationChains();
+ for (InboundInvocationChain chain : inboundChains.values()) {
+ // add target invoker on inbound side
+ ServiceContract contract = inboundWire.getServiceContract();
+ Operation operation = chain.getOperation();
+ TargetInvoker invoker;
+ try {
+ invoker = binding.createTargetInvoker(contract, operation);
+ } catch (TargetInvokerCreationException e) {
+ String targetName = inboundWire.getContainer().getName();
+ throw new WireConnectException("Error processing inbound wire",
+ null,
+ null,
+ targetName,
+ null,
+ e);
+ }
+ chain.setTargetInvoker(invoker);
+ chain.prepare();
+ }
+ OutboundWire outboundWire = binding.getOutboundWire();
+ // connect the reference's inbound and outbound wires
+ connect(inboundWire, outboundWire, true);
+ }
+ }
+
+ private void handleComponent(Component component) throws WiringException {
+ CompositeComponent parent = component.getParent();
+ assert parent != null;
+ // connect outbound wires for component references to their targets
+ for (List<OutboundWire> referenceWires : component.getOutboundWires().values()) {
+ for (OutboundWire outboundWire : referenceWires) {
+ try {
+ if (component.isSystem()) {
+ if (outboundWire.isAutowire()) {
+ autowire(outboundWire, parent);
+
+ } else {
+ SCAObject target = parent.getSystemChild(outboundWire.getTargetName().getPartName());
+ connect(component, outboundWire, target);
+ }
+ } else {
+ if (outboundWire.isAutowire()) {
+ autowire(outboundWire, parent);
+ } else {
+ if (outboundWire.getTargetName() == null) {
+ String referenceName = outboundWire.getReferenceName();
+ throw new MissingWireTargetException("Target name was null", referenceName);
+ }
+ SCAObject target = parent.getChild(outboundWire.getTargetName().getPartName());
+ connect(component, outboundWire, target);
+ }
+ }
+ } catch (WiringException e) {
+ e.addContextName(component.getName());
+ e.addContextName(parent.getName());
+ throw e;
+ }
+ }
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/IllegalCallbackException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/IllegalCallbackException.java
new file mode 100644
index 0000000000..5ca843e198
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/IllegalCallbackException.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import org.apache.tuscany.spi.builder.WiringException;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+/**
+ * Denotes an illegal callback
+ *
+ * @version $Rev$ $Date$
+ */
+public class IllegalCallbackException extends WiringException {
+
+ public IllegalCallbackException(String message,
+ String identifier,
+ String sourceName,
+ String referenceName,
+ String targetName,
+ String serviceName) {
+ super(message, identifier);
+ setSourceName(sourceName);
+ setReferenceName(referenceName);
+ setTargetName(targetName);
+ setTargetServiceName(serviceName);
+ }
+
+
+ public IllegalCallbackException(String message, String identifier, OutboundWire source, InboundWire target) {
+ super(message, identifier);
+ setSourceName(source.getContainer().getName());
+ setReferenceName(source.getReferenceName());
+ setTargetName(target.getContainer().getName());
+ setTargetServiceName(target.getServiceName());
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/IncompatibleInterfacesException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/IncompatibleInterfacesException.java
new file mode 100644
index 0000000000..4b94983c34
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/IncompatibleInterfacesException.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import org.apache.tuscany.spi.builder.WiringException;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+/**
+ * Denotes an attempt to wire incompatible interfaces
+ *
+ * @version $Rev$ $Date$
+ */
+public class IncompatibleInterfacesException extends WiringException {
+
+
+ public IncompatibleInterfacesException(String message,
+ String sourceName,
+ String referenceName,
+ String targetName,
+ String targetServiceName) {
+ super(message);
+ setSourceName(sourceName);
+ setReferenceName(referenceName);
+ setTargetName(targetName);
+ setTargetServiceName(targetServiceName);
+ }
+
+ public IncompatibleInterfacesException(String message, String sourceName,
+ String referenceName,
+ String targetName,
+ String serviceName,
+ Throwable cause) {
+ super(message, cause);
+ setSourceName(sourceName);
+ setReferenceName(referenceName);
+ setTargetName(targetName);
+ setTargetServiceName(serviceName);
+ }
+
+ public IncompatibleInterfacesException(InboundWire source, OutboundWire target) {
+ super("Incompatible source and target interfaces");
+ setTargetServiceName(source.getServiceName());
+ if (source.getContainer() != null) {
+ setSourceName(source.getContainer().getName());
+ }
+ setReferenceName(target.getReferenceName());
+ if (target.getContainer() != null) {
+ setTargetName(target.getContainer().getName());
+ }
+ }
+
+ public IncompatibleInterfacesException(OutboundWire source, InboundWire target) {
+ super("Incompatible source and target interfaces");
+ setTargetServiceName(target.getServiceName());
+ if (source.getContainer() != null) {
+ setSourceName(source.getContainer().getName());
+ }
+ setReferenceName(source.getReferenceName());
+ if (target.getContainer() != null) {
+ setTargetName(target.getContainer().getName());
+ }
+ }
+
+ public IncompatibleInterfacesException(OutboundWire source, InboundWire target, Throwable throwable) {
+ super("Incompatible source and target interfaces", throwable);
+ setTargetServiceName(target.getServiceName());
+ if (source.getContainer() != null) {
+ setSourceName(source.getContainer().getName());
+ }
+ setReferenceName(source.getReferenceName());
+ if (target.getContainer() != null) {
+ setTargetName(target.getContainer().getName());
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/InvalidTargetTypeException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/InvalidTargetTypeException.java
new file mode 100644
index 0000000000..e96fb764a0
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/InvalidTargetTypeException.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import org.apache.tuscany.spi.builder.WiringException;
+
+/**
+ * Denotes an invalid target service for a wire
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidTargetTypeException extends WiringException {
+
+ public InvalidTargetTypeException(String message,
+ String sourceName,
+ String referenceName,
+ String targetName,
+ String serviceName) {
+ super(message);
+ setSourceName(sourceName);
+ setReferenceName(referenceName);
+ setTargetName(targetName);
+ setTargetServiceName(serviceName);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/NoCompatibleBindingsException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/NoCompatibleBindingsException.java
new file mode 100644
index 0000000000..620fbf6694
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/NoCompatibleBindingsException.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import org.apache.tuscany.spi.builder.WiringException;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class NoCompatibleBindingsException extends WiringException {
+ public NoCompatibleBindingsException(String sourceName,
+ String targetName,
+ String serviceName) {
+ super("No compatible bindings for source and target");
+ setSourceName(sourceName);
+ setTargetName(targetName);
+ setTargetServiceName(serviceName);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/NoConversationalContractException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/NoConversationalContractException.java
new file mode 100644
index 0000000000..71eb9ebd26
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/NoConversationalContractException.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import org.apache.tuscany.spi.builder.BuilderException;
+
+/**
+ * Raised when a component has conversational scope but no conversational contract
+ *
+ * @version $Rev: 487877 $ $Date: 2006-12-16 15:32:16 -0500 (Sat, 16 Dec 2006) $
+ */
+public class NoConversationalContractException extends BuilderException {
+
+ public NoConversationalContractException(String message, String identifier) {
+ super(message, identifier);
+ }
+
+ public NoConversationalContractException(String message) {
+ super(message);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/NoRegisteredBuilderException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/NoRegisteredBuilderException.java
new file mode 100644
index 0000000000..340a20f239
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/NoRegisteredBuilderException.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import org.apache.tuscany.spi.builder.BuilderException;
+
+/**
+ * Raised when a builder cannot be found for a SCDL entry type
+ *
+ * @version $Rev$ $Date$
+ */
+public class NoRegisteredBuilderException extends BuilderException {
+
+ public NoRegisteredBuilderException(String message, String identifier) {
+ super(message, identifier);
+ }
+
+ public NoRegisteredBuilderException(String message) {
+ super(message);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/TargetServiceNotFoundException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/TargetServiceNotFoundException.java
new file mode 100644
index 0000000000..873bf619b0
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/TargetServiceNotFoundException.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import org.apache.tuscany.spi.builder.WiringException;
+
+/**
+ * Indicates the target service of a reference was not found
+ *
+ * @version $Rev$ $Date$
+ */
+public class TargetServiceNotFoundException extends WiringException {
+
+ public TargetServiceNotFoundException(String message,
+ String sourceName,
+ String referenceName,
+ String targetName,
+ String serviceName) {
+ super(message);
+ setSourceName(sourceName);
+ setReferenceName(referenceName);
+ setTargetName(targetName);
+ setTargetServiceName(serviceName);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/WireConnectException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/WireConnectException.java
new file mode 100644
index 0000000000..89105d27b4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/WireConnectException.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import org.apache.tuscany.spi.builder.WiringException;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+/**
+ * Denotes a general error connecting two wires
+ *
+ * @version $Rev$ $Date$
+ */
+public class WireConnectException extends WiringException {
+
+ public WireConnectException(String message) {
+ super(message);
+ }
+
+ public WireConnectException(String message,
+ String sourceName,
+ String referenceName,
+ String targetName,
+ String serviceName,
+ Throwable throwable) {
+ super(message, throwable);
+ setSourceName(sourceName);
+ setReferenceName(referenceName);
+ setTargetName(targetName);
+ setTargetServiceName(serviceName);
+ }
+
+
+ public WireConnectException(String message, OutboundWire source, InboundWire target, Throwable throwable) {
+ super(message, throwable);
+ setSourceName(source.getContainer().getName());
+ setReferenceName(source.getReferenceName());
+ setTargetName(target.getContainer().getName());
+ setTargetServiceName(target.getServiceName());
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/WirePostProcessorRegistryImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/WirePostProcessorRegistryImpl.java
new file mode 100644
index 0000000000..3bc617066a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/WirePostProcessorRegistryImpl.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.wire.WirePostProcessor;
+import org.apache.tuscany.spi.wire.WirePostProcessorRegistry;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+/**
+ * The default implementation of a <code>WirePostProcessor</code>
+ *
+ * @version $Rev$ $Date$
+ */
+public class WirePostProcessorRegistryImpl implements WirePostProcessorRegistry {
+
+ private final List<WirePostProcessor> processors = new ArrayList<WirePostProcessor>();
+
+ public void process(OutboundWire source, InboundWire target) {
+ for (WirePostProcessor processor : processors) {
+ processor.process(source, target);
+ }
+ }
+
+ public void process(InboundWire source, OutboundWire target) {
+ for (WirePostProcessor processor : processors) {
+ processor.process(source, target);
+ }
+ }
+
+ public void register(WirePostProcessor processor) {
+ processors.add(processor);
+ }
+
+ public void unregister(WirePostProcessor processor) {
+ processors.remove(processor);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/WiringExceptionFormatter.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/WiringExceptionFormatter.java
new file mode 100644
index 0000000000..16cf27048a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/builder/WiringExceptionFormatter.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import java.io.PrintWriter;
+
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.EagerInit;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.builder.WiringException;
+
+import org.apache.tuscany.host.monitor.ExceptionFormatter;
+import org.apache.tuscany.host.monitor.FormatterRegistry;
+
+/**
+ * Formats {@link WiringException}s
+ *
+ * @version $Rev$ $Date$
+ */
+@EagerInit
+public class WiringExceptionFormatter implements ExceptionFormatter {
+ private FormatterRegistry factory;
+
+ public WiringExceptionFormatter(@Autowire FormatterRegistry factory) {
+ this.factory = factory;
+ factory.register(this);
+ }
+
+ public boolean canFormat(Class<?> type) {
+ return WiringException.class.isAssignableFrom(type);
+ }
+
+ @Destroy
+ public void destroy() {
+ factory.unregister(this);
+ }
+
+ public PrintWriter write(PrintWriter writer, Throwable exception) {
+ assert exception instanceof WiringException;
+ WiringException e = (WiringException) exception;
+ e.appendBaseMessage(writer);
+ if (e.getSourceName() != null && e.getReferenceName() != null) {
+ writer.write("\nSource : " + e.getSourceName() + "/" + e.getReferenceName());
+ } else if (e.getSourceName() != null) {
+ writer.write("\nSource : " + e.getSourceName());
+ }
+ if (e.getTargetName() != null && e.getTargetServiceName() != null) {
+ writer.write("\nTarget : " + e.getTargetName() + "/" + e.getTargetServiceName());
+ } else if (e.getTargetName() != null) {
+ writer.write("\nTarget : " + e.getTargetName());
+ }
+ e.appendContextStack(writer).append("\n");
+ return writer;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/ComponentContextImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/ComponentContextImpl.java
new file mode 100644
index 0000000000..6cc06d7646
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/ComponentContextImpl.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component;
+
+import java.net.URI;
+
+import org.osoa.sca.CallableReference;
+import org.osoa.sca.ComponentContext;
+import org.osoa.sca.CompositeContext;
+import org.osoa.sca.RequestContext;
+import org.osoa.sca.ServiceReference;
+import org.osoa.sca.ServiceRuntimeException;
+
+import org.apache.tuscany.api.TuscanyRuntimeException;
+import org.apache.tuscany.spi.component.Component;
+
+/**
+ *
+ * @version $Rev$ $Date$
+ */
+public class ComponentContextImpl implements ComponentContext {
+ private final CompositeContext context;
+ private final Component component;
+
+ public ComponentContextImpl(CompositeContext context, Component component) {
+ this.component = component;
+ this.context = context;
+ }
+
+ public String getURI() {
+ try {
+ return component.getName();
+ } catch (TuscanyRuntimeException e) {
+ throw new ServiceRuntimeException(e.getMessage(), e);
+ }
+ }
+
+ public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException {
+ throw new UnsupportedOperationException();
+ }
+
+ public <B> B getService(Class<B> businessInterface, String referenceName) {
+ try {
+ return context.locateService(businessInterface, component.getName() + "/" + referenceName);
+ } catch (TuscanyRuntimeException e) {
+ throw new ServiceRuntimeException(e.getMessage(), e);
+ }
+ }
+
+ public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, String referenceName) {
+ throw new UnsupportedOperationException();
+ }
+
+ public <B> B getProperty(Class<B> type, String propertyName) {
+ throw new UnsupportedOperationException();
+ }
+
+ public <B> ServiceReference<B> createSelfReference(Class<B> businessInterface) {
+ return null;
+ }
+
+ public <B> ServiceReference<B> createSelfReference(Class<B> businessInterface, String serviceName) {
+ return null;
+ }
+
+ public RequestContext getRequestContext() {
+ return context.getRequestContext();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/ScopeIdentifier.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/ScopeIdentifier.java
new file mode 100644
index 0000000000..35125b85ef
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/ScopeIdentifier.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component;
+
+/**
+ * Implementations enable lazy retrieval of a scope id associated with a request, i.e. an id (and presumably a context)
+ * do not have to be generated if the scope is never accessed. Identifiers are associated with the current request
+ * thread and keyed on scope type.
+ *
+ * @version $Rev$ $Date$
+ * @see org.apache.tuscany.spi.component.WorkContext
+ */
+public interface ScopeIdentifier {
+
+ /**
+ * Returns the scope id for the request.
+ */
+ Object getIdentifier();
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/WorkContextImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/WorkContextImpl.java
new file mode 100644
index 0000000000..8d2afc35d9
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/WorkContextImpl.java
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component;
+
+import java.util.ArrayList;
+import java.util.IdentityHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.WorkContext;
+
+/**
+ * An implementation of an {@link org.apache.tuscany.spi.component.WorkContext} that handles event-to-thread
+ * associations using an <code>InheritableThreadLocal</code>
+ *
+ * @version $Rev$ $Date$
+ */
+public class WorkContextImpl implements WorkContext {
+ private static final Object REMOTE_CONTEXT = new Object();
+ private static final Object CORRELATION_ID = new Object();
+ private static final Object CALLBACK_ROUTING_CHAIN = new Object();
+ private static final Object CURRENT_ATOMIC = new Object();
+ private static final Object CURRENT_SERVICE_NAMES = new Object();
+
+ // [rfeng] We cannot use InheritableThreadLocal for message ids here since it's shared by parent and children
+ private ThreadLocal<Map<Object, Object>> workContext = new ThreadLocal<Map<Object, Object>>();
+
+ // [rfeng] Session id requires InheritableThreadLocal
+ private ThreadLocal<Map<Object, Object>> inheritableContext = new InheritableThreadLocal<Map<Object, Object>>();
+
+ public WorkContextImpl() {
+ super();
+ }
+
+ public Object getCurrentCorrelationId() {
+ Map<Object, Object> map = workContext.get();
+ if (map == null) {
+ return null;
+ }
+ return map.get(CORRELATION_ID);
+ }
+
+ public void setCurrentCorrelationId(Object correlationId) {
+ Map<Object, Object> map = getWorkContextMap();
+ map.put(CORRELATION_ID, correlationId);
+ }
+
+ public AtomicComponent getCurrentAtomicComponent() {
+ Map<Object, Object> map = workContext.get();
+ if (map == null) {
+ return null;
+ }
+ return (AtomicComponent) map.get(CURRENT_ATOMIC);
+ }
+
+ public void setCurrentAtomicComponent(AtomicComponent component) {
+ Map<Object, Object> map = getWorkContextMap();
+ map.put(CURRENT_ATOMIC, component);
+ }
+
+ @SuppressWarnings("unchecked")
+ public LinkedList<Object> getCurrentCallbackRoutingChain() {
+ Map<Object, Object> map = workContext.get();
+ if (map == null) {
+ return null;
+ }
+ return (LinkedList<Object>) map.get(CALLBACK_ROUTING_CHAIN);
+ }
+
+ public void setCurrentCallbackRoutingChain(LinkedList<Object> callbackRoutingChain) {
+ Map<Object, Object> map = getWorkContextMap();
+ map.put(CALLBACK_ROUTING_CHAIN, callbackRoutingChain);
+ }
+
+ public CompositeComponent getRemoteComponent() {
+ Map<Object, Object> map = workContext.get();
+ if (map == null) {
+ return null;
+ }
+ return (CompositeComponent) map.get(REMOTE_CONTEXT);
+ }
+
+
+ public void setRemoteComponent(CompositeComponent component) {
+ Map<Object, Object> map = getWorkContextMap();
+ map.put(REMOTE_CONTEXT, component);
+ }
+
+ public Object getIdentifier(Object type) {
+ Map<Object, Object> map = inheritableContext.get();
+ if (map == null) {
+ return null;
+ }
+ Object currentId = map.get(type);
+ if (currentId instanceof ScopeIdentifier) {
+ currentId = ((ScopeIdentifier) currentId).getIdentifier();
+ // once we have accessed the id, replace the lazy wrapper
+ map.put(type, currentId);
+ }
+ return currentId;
+ }
+
+ public void setIdentifier(Object type, Object identifier) {
+ Map<Object, Object> map = inheritableContext.get();
+ if (map == null) {
+ map = new IdentityHashMap<Object, Object>();
+ inheritableContext.set(map);
+ }
+ map.put(type, identifier);
+ }
+
+ public void clearIdentifier(Object type) {
+ if (type == null) {
+ return;
+ }
+ Map map = inheritableContext.get();
+ if (map != null) {
+ map.remove(type);
+ }
+ }
+
+ public void clearIdentifiers() {
+ inheritableContext.remove();
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public String popServiceName() {
+ Map<Object, Object> map = inheritableContext.get();
+ if (map == null) {
+ return null;
+ }
+ List<String> stack = (List) map.get(CURRENT_SERVICE_NAMES);
+ if (stack == null || stack.size() < 1) {
+ return null;
+ }
+ String name = stack.remove(stack.size() - 1);
+ if (stack.size() == 0) {
+ // cleanup to avoid leaks
+ map.remove(CURRENT_SERVICE_NAMES);
+ }
+ return name;
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public String getCurrentServiceName() {
+ Map<Object, Object> map = inheritableContext.get();
+ if (map == null) {
+ return null;
+ }
+ List<String> stack = (List) map.get(CURRENT_SERVICE_NAMES);
+ if (stack == null || stack.size() < 1) {
+ return null;
+ }
+ return stack.get(stack.size() - 1);
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public void pushServiceName(String name) {
+ Map<Object, Object> map = inheritableContext.get();
+ List<String> names;
+ if (map == null) {
+ map = new IdentityHashMap<Object, Object>();
+ inheritableContext.set(map);
+ names = new ArrayList<String>();
+ map.put(CURRENT_SERVICE_NAMES, names);
+ } else {
+ names = (List<String>) map.get(CURRENT_SERVICE_NAMES);
+ if (names == null) {
+ names = new ArrayList<String>();
+ map.put(CURRENT_SERVICE_NAMES, names);
+ }
+ }
+ names.add(name);
+ }
+
+ public void clearServiceNames() {
+ Map<Object, Object> map = inheritableContext.get();
+ if (map == null) {
+ return;
+ }
+ map.remove(CURRENT_SERVICE_NAMES);
+ }
+
+ private Map<Object, Object> getWorkContextMap() {
+ Map<Object, Object> map = workContext.get();
+ if (map == null) {
+ map = new IdentityHashMap<Object, Object>();
+ workContext.set(map);
+ }
+ return map;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/AbstractEvent.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/AbstractEvent.java
new file mode 100644
index 0000000000..6d026ca08c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/AbstractEvent.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+import org.apache.tuscany.spi.event.Event;
+
+/**
+ * A basic implementation of a runtime event
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public abstract class AbstractEvent implements Event {
+ protected Object source;
+
+ public AbstractEvent(Object source) {
+ assert source != null : "Source id was null";
+ this.source = source;
+ }
+
+ public Object getSource() {
+ return source;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/AbstractRequestEvent.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/AbstractRequestEvent.java
new file mode 100644
index 0000000000..762b917600
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/AbstractRequestEvent.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+/**
+ * Base implementation of a request event
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public abstract class AbstractRequestEvent extends AbstractEvent implements RequestEvent {
+
+ /**
+ * Creates a new event
+ *
+ * @param source the source of the event
+ */
+ public AbstractRequestEvent(Object source) {
+ super(source);
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/CompositeEvent.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/CompositeEvent.java
new file mode 100644
index 0000000000..ce058404da
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/CompositeEvent.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.event.Event;
+
+/**
+ * Implemented by runtime events associated with a composite, e.g. lifecycle events
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public interface CompositeEvent extends Event {
+
+ CompositeComponent getComposite();
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/CompositeStart.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/CompositeStart.java
new file mode 100644
index 0000000000..fba36feaf6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/CompositeStart.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+
+/**
+ * Propagated when a composite starts
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class CompositeStart extends AbstractEvent implements CompositeEvent {
+
+ private CompositeComponent component;
+
+ /**
+ * Creates a composite stop event
+ *
+ * @param source the source of the event
+ * @param component the composite component associated the composite being stopped
+ */
+ public CompositeStart(Object source, CompositeComponent component) {
+ super(source);
+ this.component = component;
+ }
+
+ public CompositeComponent getComposite() {
+ return component;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/CompositeStop.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/CompositeStop.java
new file mode 100644
index 0000000000..6b3e37f619
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/CompositeStop.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+
+/**
+ * Propagated when a composite stops
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class CompositeStop extends AbstractEvent implements CompositeEvent {
+
+ private CompositeComponent component;
+
+ /**
+ * Creates a composite stop event
+ *
+ * @param source the source of the event
+ * @param component the composite component associated the composite being stopped
+ */
+ public CompositeStop(Object source, CompositeComponent component) {
+ super(source);
+ this.component = component;
+ }
+
+ public CompositeComponent getComposite() {
+ return component;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/ConversationEnd.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/ConversationEnd.java
new file mode 100644
index 0000000000..4a51d970c3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/ConversationEnd.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+/**
+ * Propagated when a conversation session is expired
+ *
+ * @version $$Rev: 430937 $$ $$Date: 2006-08-11 21:17:56 -0400 (Fri, 11 Aug 2006) $$
+ */
+public class ConversationEnd extends ConversationalEvent {
+
+ public ConversationEnd(Object source, Object id) {
+ super(source, id);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/ConversationStart.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/ConversationStart.java
new file mode 100644
index 0000000000..5725369bf6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/ConversationStart.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+/**
+ * Propagated when a conversation session has started
+ *
+ * @version $$Rev: 430937 $$ $$Date: 2006-08-11 21:17:56 -0400 (Fri, 11 Aug 2006) $$
+ */
+public class ConversationStart extends ConversationalEvent {
+
+ public ConversationStart(Object source, Object id) {
+ super(source, id);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/ConversationalEvent.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/ConversationalEvent.java
new file mode 100644
index 0000000000..a75086e745
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/ConversationalEvent.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+/**
+ * A base implementation of conversational session events in the runtime
+ *
+ * @version $$Rev: 430937 $$ $$Date: 2006-08-11 21:17:56 -0400 (Fri, 11 Aug 2006) $$
+ */
+public class ConversationalEvent extends AbstractEvent {
+
+ private Object id;
+
+ public ConversationalEvent(Object source, Object id) {
+ super(source);
+ assert id != null : "Conversation id was null";
+ this.id = id;
+ }
+
+ public Object getId() {
+ return id;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpRequestEnded.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpRequestEnded.java
new file mode 100644
index 0000000000..01bd769031
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpRequestEnded.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+/**
+ * Propagated when an HTTP-based request has ended.
+ *
+ * @version $$Rev: 430937 $$ $$Date: 2006-08-11 21:17:56 -0400 (Fri, 11 Aug 2006) $$
+ */
+public class HttpRequestEnded extends HttpSessionEvent {
+
+ /**
+ * Creates a new event
+ *
+ * @param source the source of the event
+ * @param id the id of the HTTP session being ended
+ */
+ public HttpRequestEnded(Object source, Object id) {
+ super(source, id);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpRequestStart.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpRequestStart.java
new file mode 100644
index 0000000000..9d0ff80dd7
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpRequestStart.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+/**
+ * Propagated when an HTTP-based request has started
+ *
+ * @version $$Rev: 430937 $$ $$Date: 2006-08-11 21:17:56 -0400 (Fri, 11 Aug 2006) $$
+ */
+public class HttpRequestStart extends HttpSessionEvent {
+
+ /**
+ * Creates a new event
+ *
+ * @param source the source of the event
+ * @param id the id of the HTTP session being ended
+ */
+ public HttpRequestStart(Object source, Object id) {
+ super(source, id);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionEnd.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionEnd.java
new file mode 100644
index 0000000000..7f2bebe94a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionEnd.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+/**
+ * Propagated when an HTTP-based session is expired
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class HttpSessionEnd extends HttpSessionEvent {
+
+ /**
+ * Creates a new event
+ *
+ * @param source the source of the event
+ * @param id the id of the HTTP session being ended
+ */
+ public HttpSessionEnd(Object source, Object id) {
+ super(source, id);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionEvent.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionEvent.java
new file mode 100644
index 0000000000..ed245d0930
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionEvent.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+/**
+ * A base implementation of HTTP-based session events in the runtime
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public abstract class HttpSessionEvent extends AbstractEvent {
+
+ private Object id;
+
+ public HttpSessionEvent(Object source, Object id) {
+ super(source);
+ assert id != null : "Session id was null";
+ this.id = id;
+ }
+
+
+ public Object getSource() {
+ return source;
+ }
+
+ public Object getId() {
+ return id;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionStart.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionStart.java
new file mode 100644
index 0000000000..7f9c0fadea
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/HttpSessionStart.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+/**
+ * Propagated when an HTTP-based session has started
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class HttpSessionStart extends HttpSessionEvent {
+
+ /**
+ * Creates a new event
+ *
+ * @param source the source of the event
+ * @param id the id of the HTTP session being ended
+ */
+ public HttpSessionStart(Object source, Object id) {
+ super(source, id);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/RequestEnd.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/RequestEnd.java
new file mode 100644
index 0000000000..25856e86f8
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/RequestEnd.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+/**
+ * Propagated when a request completes or is ended
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class RequestEnd extends AbstractRequestEvent {
+
+ /**
+ * Creates a new event
+ *
+ * @param source the source of the event
+ */
+ public RequestEnd(Object source) {
+ super(source);
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/RequestEvent.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/RequestEvent.java
new file mode 100644
index 0000000000..9a6d767236
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/RequestEvent.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+/**
+ * Implemented by runtime events associated request
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public interface RequestEvent {
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/RequestStart.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/RequestStart.java
new file mode 100644
index 0000000000..466f52551a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/event/RequestStart.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+/**
+ * Propagated when a request is started in the runtime
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class RequestStart extends AbstractRequestEvent {
+
+ /**
+ * Creates a new event
+ *
+ * @param source the source of the event
+ */
+ public RequestStart(Object source) {
+ super(source);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/AbstractScopeContainer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/AbstractScopeContainer.java
new file mode 100644
index 0000000000..cde61eaa5a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/AbstractScopeContainer.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.tuscany.spi.AbstractLifecycle;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.PersistenceException;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.TargetNotFoundException;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.event.EventFilter;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+import org.apache.tuscany.spi.event.TrueFilter;
+
+/**
+ * Implements functionality common to scope contexts.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractScopeContainer extends AbstractLifecycle implements ScopeContainer {
+ private static final EventFilter TRUE_FILTER = new TrueFilter();
+
+ protected WorkContext workContext;
+ protected ScopeContainerMonitor monitor;
+ private Map<EventFilter, List<RuntimeEventListener>> listeners;
+
+ public AbstractScopeContainer(WorkContext workContext, ScopeContainerMonitor monitor) {
+ this.workContext = workContext;
+ this.monitor = monitor;
+ }
+
+ public void addListener(RuntimeEventListener listener) {
+ addListener(TRUE_FILTER, listener);
+ }
+
+ public void removeListener(RuntimeEventListener listener) {
+ assert listener != null;
+ synchronized (getListeners()) {
+ for (List<RuntimeEventListener> currentList : getListeners().values()) {
+ for (RuntimeEventListener current : currentList) {
+ if (current == listener) {
+ currentList.remove(current);
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ public void addListener(EventFilter filter, RuntimeEventListener listener) {
+ assert listener != null;
+ synchronized (getListeners()) {
+ List<RuntimeEventListener> list = getListeners().get(filter);
+ if (list == null) {
+ list = new CopyOnWriteArrayList<RuntimeEventListener>();
+ listeners.put(filter, list);
+ }
+ list.add(listener);
+ }
+ }
+
+ public void publish(Event event) {
+ assert event != null;
+ for (Map.Entry<EventFilter, List<RuntimeEventListener>> entry : getListeners().entrySet()) {
+ if (entry.getKey().match(event)) {
+ for (RuntimeEventListener listener : entry.getValue()) {
+ listener.onEvent(event);
+ }
+ }
+ }
+ }
+
+ public Object getInstance(AtomicComponent component) throws TargetResolutionException {
+ InstanceWrapper ctx = getInstanceWrapper(component, true);
+ if (ctx != null) {
+ if (!ctx.isStarted()) {
+ ctx.start();
+ }
+ return ctx.getInstance();
+ }
+ return null;
+ }
+
+ public Object getAssociatedInstance(AtomicComponent component) throws TargetResolutionException {
+ InstanceWrapper ctx = getInstanceWrapper(component, false);
+ if (ctx != null) {
+ if (!ctx.isStarted()) {
+ ctx.start();
+ }
+ return ctx.getInstance();
+ }
+ throw new TargetNotFoundException(component.getName());
+ }
+
+ public void persistNew(AtomicComponent component, String id, Object instance, long expiration)
+ throws PersistenceException {
+ throw new UnsupportedOperationException("Scope does not support persistence");
+
+ }
+
+ public void persist(AtomicComponent component, String id, Object instance, long expiration)
+ throws PersistenceException {
+ throw new UnsupportedOperationException("Scope does not support persistence");
+ }
+
+ public void remove(AtomicComponent component) throws PersistenceException {
+ throw new UnsupportedOperationException("Scope does not support persistence");
+ }
+
+ protected Map<EventFilter, List<RuntimeEventListener>> getListeners() {
+ if (listeners == null) {
+ listeners = new ConcurrentHashMap<EventFilter, List<RuntimeEventListener>>();
+ }
+ return listeners;
+ }
+
+ protected void checkInit() {
+ if (getLifecycleState() != RUNNING) {
+ throw new IllegalStateException("Scope container not running [" + getLifecycleState() + "]");
+ }
+ }
+
+ protected WorkContext getWorkContext() {
+ return workContext;
+ }
+
+ public String toString() {
+ return "In state [" + super.toString() + ']';
+ }
+
+ protected abstract InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create)
+ throws TargetResolutionException;
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeContainer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeContainer.java
new file mode 100644
index 0000000000..21ff792282
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeContainer.java
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.component.TargetInitializationException;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.model.Scope;
+
+import org.apache.tuscany.core.component.event.CompositeStart;
+import org.apache.tuscany.core.component.event.CompositeStop;
+
+/**
+ * A scope context which manages atomic component instances keyed by composite
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompositeScopeContainer extends AbstractScopeContainer {
+ private static final InstanceWrapper EMPTY = new EmptyWrapper();
+ private static final ComponentInitComparator COMPARATOR = new ComponentInitComparator();
+
+ private final Map<AtomicComponent, InstanceWrapper> instanceWrappers;
+ // the queue of instanceWrappers to destroy, in the order that their instances were created
+ private final List<InstanceWrapper> destroyQueue;
+
+ public CompositeScopeContainer(ScopeContainerMonitor monitor) {
+ super(null, monitor);
+ instanceWrappers = new ConcurrentHashMap<AtomicComponent, InstanceWrapper>();
+ destroyQueue = new ArrayList<InstanceWrapper>();
+ }
+
+ public Scope getScope() {
+ return Scope.COMPOSITE;
+ }
+
+ public void onEvent(Event event) {
+ checkInit();
+ if (event instanceof CompositeStart) {
+ try {
+ eagerInitComponents();
+ } catch (ObjectCreationException e) {
+ monitor.eagerInitializationError(e);
+ } catch (TargetResolutionException e) {
+ monitor.eagerInitializationError(e);
+ }
+ lifecycleState = RUNNING;
+ } else if (event instanceof CompositeStop) {
+ shutdownContexts();
+ }
+ }
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
+ }
+ lifecycleState = RUNNING;
+ }
+
+ public synchronized void stop() {
+ checkInit();
+ instanceWrappers.clear();
+ synchronized (destroyQueue) {
+ destroyQueue.clear();
+ }
+ lifecycleState = STOPPED;
+ }
+
+ /**
+ * Notifies instanceWrappers of a shutdown in reverse order to which they were started
+ */
+ private void shutdownContexts() {
+ if (destroyQueue.size() == 0) {
+ return;
+ }
+ synchronized (destroyQueue) {
+ // shutdown destroyable instances in reverse instantiation order
+ ListIterator<InstanceWrapper> iter = destroyQueue.listIterator(destroyQueue.size());
+ while (iter.hasPrevious()) {
+ try {
+ iter.previous().stop();
+ } catch (TargetDestructionException e) {
+ monitor.destructionError(e);
+ }
+ }
+ destroyQueue.clear();
+ }
+ }
+
+ public void register(AtomicComponent component) {
+ checkInit();
+ instanceWrappers.put(component, EMPTY);
+ }
+
+ protected InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create)
+ throws TargetResolutionException {
+ checkInit();
+ InstanceWrapper ctx = instanceWrappers.get(component);
+ assert ctx != null;
+ if (ctx == EMPTY && !create) {
+ return null;
+ }
+ if (ctx == EMPTY) {
+ ctx = new InstanceWrapperImpl(component, component.createInstance());
+ ctx.start();
+ instanceWrappers.put(component, ctx);
+ synchronized (destroyQueue) {
+ destroyQueue.add(ctx);
+ }
+ }
+ return ctx;
+ }
+
+ private void eagerInitComponents() throws ObjectCreationException, TargetResolutionException {
+ List<AtomicComponent> componentList = new ArrayList<AtomicComponent>(instanceWrappers.keySet());
+ Collections.sort(componentList, COMPARATOR);
+ // start each group
+ for (AtomicComponent component : componentList) {
+ if (component.getInitLevel() <= 0) {
+ // Don't eagerly init
+ continue;
+ }
+ // the instance could have been created from a depth-first traversal
+ InstanceWrapper ctx = instanceWrappers.get(component);
+ if (ctx == EMPTY) {
+ try {
+ ctx = new InstanceWrapperImpl(component, component.createInstance());
+ } catch (ObjectCreationException e) {
+ e.addContextName(component.getName());
+ throw e;
+ }
+ ctx.start();
+ instanceWrappers.put(component, ctx);
+ destroyQueue.add(ctx);
+ }
+ }
+ }
+
+ private static class ComponentInitComparator implements Comparator<AtomicComponent> {
+ public int compare(AtomicComponent o1, AtomicComponent o2) {
+ return o1.getInitLevel() - o2.getInitLevel();
+ }
+ }
+
+ private static class EmptyWrapper implements InstanceWrapper {
+ public Object getInstance() {
+ return null;
+ }
+
+ public boolean isStarted() {
+ return true;
+ }
+
+ public void start() throws TargetInitializationException {
+
+ }
+
+ public void stop() throws TargetDestructionException {
+
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactory.java
new file mode 100644
index 0000000000..a761f05d4b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.osoa.sca.annotations.EagerInit;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.model.Scope;
+
+import org.apache.tuscany.api.annotation.Monitor;
+
+/**
+ * Creates a new composite scope context
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+@EagerInit
+public class CompositeScopeObjectFactory implements ObjectFactory<CompositeScopeContainer> {
+ private ScopeContainerMonitor monitor;
+
+ public CompositeScopeObjectFactory(@Autowire ScopeRegistry registry,
+ @Monitor ScopeContainerMonitor monitor) {
+ registry.registerFactory(Scope.COMPOSITE, this);
+ this.monitor = monitor;
+ }
+
+ public CompositeScopeContainer getInstance() throws ObjectCreationException {
+ return new CompositeScopeContainer(monitor);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainer.java
new file mode 100644
index 0000000000..1a77f3ecb3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainer.java
@@ -0,0 +1,217 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.PersistenceException;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.component.TargetNotFoundException;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.services.store.Store;
+import org.apache.tuscany.spi.services.store.StoreExpirationEvent;
+import org.apache.tuscany.spi.services.store.StoreReadException;
+import org.apache.tuscany.spi.services.store.StoreWriteException;
+
+/**
+ * A scope context which manages atomic component instances keyed on a conversation session
+ *
+ * @version $Rev: 452655 $ $Date: 2006-10-03 18:09:02 -0400 (Tue, 03 Oct 2006) $
+ */
+public class ConversationalScopeContainer extends AbstractScopeContainer implements ScopeContainer {
+ private Store nonDurableStore;
+ private Map<AtomicComponent, AtomicComponent> components;
+
+ public ConversationalScopeContainer(Store store, WorkContext workContext, final ScopeContainerMonitor monitor) {
+ super(workContext, monitor);
+ this.nonDurableStore = store;
+ if (store != null) {
+ store.addListener(new ExpirationListener(monitor));
+ }
+ components = new ConcurrentHashMap<AtomicComponent, AtomicComponent>();
+ }
+
+ public Scope getScope() {
+ return Scope.CONVERSATION;
+ }
+
+ public void onEvent(Event event) {
+ checkInit();
+ }
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
+ }
+ lifecycleState = RUNNING;
+ }
+
+ public synchronized void stop() {
+ lifecycleState = STOPPED;
+ }
+
+ public void register(AtomicComponent component) {
+ components.put(component, component);
+ component.addListener(this);
+ }
+
+ @Override
+ public Object getInstance(AtomicComponent component) throws TargetResolutionException {
+ String conversationId = getConversationId();
+ try {
+ workContext.setCurrentAtomicComponent(component);
+ Object instance = nonDurableStore.readRecord(component, conversationId);
+ if (instance != null) {
+ if (component.getMaxIdleTime() > 0) {
+ // update expiration
+ long expire = System.currentTimeMillis() + component.getMaxIdleTime();
+ nonDurableStore.updateRecord(component, conversationId, instance, expire);
+ }
+ } else {
+ instance = component.createInstance();
+ long expire = calculateExpiration(component);
+ nonDurableStore.insertRecord(component, conversationId, instance, expire);
+ component.init(instance);
+ }
+ return instance;
+ } catch (StoreReadException e) {
+ throw new TargetResolutionException("Error retrieving target instance", e);
+ } catch (StoreWriteException e) {
+ throw new TargetResolutionException("Error persisting target instance", e);
+ } finally {
+ workContext.setCurrentAtomicComponent(null);
+ }
+ }
+
+ public Object getAssociatedInstance(AtomicComponent component) throws TargetResolutionException {
+ String conversationId = getConversationId();
+ try {
+ workContext.setCurrentAtomicComponent(component);
+ Object instance = nonDurableStore.readRecord(component, conversationId);
+ if (instance != null) {
+ if (component.getMaxIdleTime() > 0) {
+ // update expiration
+ long expire = System.currentTimeMillis() + component.getMaxIdleTime();
+ nonDurableStore.updateRecord(component, conversationId, instance, expire);
+ }
+ return instance;
+ } else {
+ throw new TargetNotFoundException(component.getName());
+ }
+ } catch (StoreReadException e) {
+ throw new TargetResolutionException("Error retrieving target instance", e);
+ } catch (StoreWriteException e) {
+ throw new TargetResolutionException("Error persisting target instance", e);
+ } finally {
+ workContext.setCurrentAtomicComponent(null);
+ }
+ }
+
+ public void persistNew(AtomicComponent component, String id, Object instance, long expiration)
+ throws PersistenceException {
+ try {
+ nonDurableStore.insertRecord(component, id, instance, expiration);
+ } catch (StoreWriteException e) {
+ throw new PersistenceException(e);
+ }
+ }
+
+ public void persist(AtomicComponent component, String id, Object instance, long expiration)
+ throws PersistenceException {
+ try {
+ nonDurableStore.updateRecord(component, id, instance, expiration);
+ } catch (StoreWriteException e) {
+ throw new PersistenceException(e);
+ }
+ }
+
+ public void remove(AtomicComponent component) throws PersistenceException {
+ String conversationId = getConversationId();
+ try {
+ workContext.setCurrentAtomicComponent(component);
+ Object instance = nonDurableStore.readRecord(component, conversationId);
+ if (instance != null) {
+ nonDurableStore.removeRecord(component, conversationId);
+ }
+ } catch (StoreReadException e) {
+ throw new PersistenceException(e);
+ } catch (StoreWriteException e) {
+ throw new PersistenceException(e);
+ }
+ }
+
+ protected InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the conversation id associated with the current invocation context
+ */
+ private String getConversationId() {
+ String conversationId = (String) workContext.getIdentifier(Scope.CONVERSATION);
+ assert conversationId != null;
+ return conversationId;
+ }
+
+ private long calculateExpiration(AtomicComponent component) {
+ if (component.getMaxAge() > 0) {
+ long now = System.currentTimeMillis();
+ return now + component.getMaxAge();
+ } else if (component.getMaxIdleTime() > 0) {
+ long now = System.currentTimeMillis();
+ return now + component.getMaxIdleTime();
+ } else {
+ return Store.DEFAULT_EXPIRATION_OFFSET;
+ }
+ }
+
+ /**
+ * Receives expiration events from the store and notifies the corresponding atomic component
+ */
+ private static class ExpirationListener implements RuntimeEventListener {
+ private final ScopeContainerMonitor monitor;
+
+ public ExpirationListener(ScopeContainerMonitor monitor) {
+ this.monitor = monitor;
+ }
+
+ public void onEvent(Event event) {
+ if (event instanceof StoreExpirationEvent) {
+ StoreExpirationEvent expiration = (StoreExpirationEvent) event;
+ SCAObject object = expiration.getOwner();
+ assert object instanceof AtomicComponent;
+ AtomicComponent owner = (AtomicComponent) object;
+ try {
+ owner.destroy(expiration.getInstance());
+ } catch (TargetDestructionException e) {
+ monitor.destructionError(e);
+ }
+ }
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeObjectFactory.java
new file mode 100644
index 0000000000..32dfaed8d9
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/ConversationalScopeObjectFactory.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.osoa.sca.annotations.EagerInit;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.services.store.Store;
+
+import org.apache.tuscany.api.annotation.Monitor;
+
+/**
+ * Creates a new Session Scope context
+ *
+ * @version $$Rev: 450456 $$ $$Date: 2006-09-27 10:28:36 -0400 (Wed, 27 Sep 2006) $$
+ */
+@EagerInit
+public class ConversationalScopeObjectFactory implements ObjectFactory<ConversationalScopeContainer> {
+ private WorkContext context;
+ private Store store;
+ private ScopeContainerMonitor monitor;
+
+ public ConversationalScopeObjectFactory(@Autowire ScopeRegistry registry,
+ @Autowire WorkContext context,
+ @Autowire Store store,
+ @Monitor ScopeContainerMonitor monitor) {
+ registry.registerFactory(Scope.CONVERSATION, this);
+ this.context = context;
+ this.store = store;
+ this.monitor = monitor;
+ }
+
+ public ConversationalScopeContainer getInstance() throws ObjectCreationException {
+ return new ConversationalScopeContainer(store, context, monitor);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeContainer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeContainer.java
new file mode 100644
index 0000000000..83c79b2367
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeContainer.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.model.Scope;
+
+import org.apache.tuscany.core.component.event.HttpSessionEnd;
+
+/**
+ * A scope context which manages atomic component instances keyed on HTTP session
+ *
+ * @version $Rev$ $Date$
+ */
+public class HttpSessionScopeContainer extends AbstractScopeContainer {
+ private final Map<AtomicComponent, Map<Object, InstanceWrapper>> contexts;
+ private final Map<Object, List<InstanceWrapper>> destroyQueues;
+
+ public HttpSessionScopeContainer(WorkContext workContext, ScopeContainerMonitor monitor) {
+ super(workContext, monitor);
+ contexts = new ConcurrentHashMap<AtomicComponent, Map<Object, InstanceWrapper>>();
+ destroyQueues = new ConcurrentHashMap<Object, List<InstanceWrapper>>();
+ }
+
+ public Scope getScope() {
+ return Scope.SESSION;
+ }
+
+ public void onEvent(Event event) {
+ checkInit();
+ if (event instanceof HttpSessionEnd) {
+ Object key = ((HttpSessionEnd) event).getId();
+ shutdownInstances(key);
+ workContext.clearIdentifier(key);
+ }
+ }
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
+ }
+ lifecycleState = RUNNING;
+ }
+
+ public synchronized void stop() {
+ contexts.clear();
+ synchronized (destroyQueues) {
+ destroyQueues.clear();
+ }
+ lifecycleState = STOPPED;
+ }
+
+ public void register(AtomicComponent component) {
+ contexts.put(component, new ConcurrentHashMap<Object, InstanceWrapper>());
+ component.addListener(this);
+ }
+
+ protected InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create)
+ throws TargetResolutionException {
+ Object key = workContext.getIdentifier(Scope.SESSION);
+ assert key != null : "HTTP session key not bound in work context";
+ return getInstance(component, key, create);
+ }
+
+ private InstanceWrapper getInstance(AtomicComponent component, Object key, boolean create)
+ throws TargetResolutionException {
+ Map<Object, InstanceWrapper> wrappers = contexts.get(component);
+ InstanceWrapper ctx = wrappers.get(key);
+ if (ctx == null && !create) {
+ return null;
+ }
+ if (ctx == null) {
+ ctx = new InstanceWrapperImpl(component, component.createInstance());
+ ctx.start();
+ wrappers.put(key, ctx);
+ List<InstanceWrapper> destroyQueue = destroyQueues.get(key);
+ if (destroyQueue == null) {
+ destroyQueue = new ArrayList<InstanceWrapper>();
+ destroyQueues.put(key, destroyQueue);
+ }
+ synchronized (destroyQueue) {
+ destroyQueue.add(ctx);
+ }
+ }
+ return ctx;
+
+ }
+
+ private void shutdownInstances(Object key) {
+ List<InstanceWrapper> destroyQueue = destroyQueues.remove(key);
+ if (destroyQueue != null) {
+ for (Map<Object, InstanceWrapper> map : contexts.values()) {
+ map.remove(key);
+ }
+ ListIterator<InstanceWrapper> iter = destroyQueue.listIterator(destroyQueue.size());
+ synchronized (destroyQueue) {
+ while (iter.hasPrevious()) {
+ try {
+ iter.previous().stop();
+ } catch (TargetDestructionException e) {
+ monitor.destructionError(e);
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeObjectFactory.java
new file mode 100644
index 0000000000..14713f9144
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/HttpSessionScopeObjectFactory.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.osoa.sca.annotations.EagerInit;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+
+import org.apache.tuscany.api.annotation.Monitor;
+
+/**
+ * Creates a new HTTP session scope context
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+@EagerInit
+public class HttpSessionScopeObjectFactory implements ObjectFactory<HttpSessionScopeContainer> {
+ private WorkContext context;
+ private ScopeContainerMonitor monitor;
+
+ public HttpSessionScopeObjectFactory(@Autowire ScopeRegistry registry,
+ @Autowire WorkContext context,
+ @Monitor ScopeContainerMonitor monitor) {
+ registry.registerFactory(Scope.SESSION, this);
+ this.context = context;
+ this.monitor = monitor;
+ }
+
+ public HttpSessionScopeContainer getInstance() throws ObjectCreationException {
+ return new HttpSessionScopeContainer(context, monitor);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapper.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapper.java
new file mode 100644
index 0000000000..50f4a31128
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapper.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.component.TargetInitializationException;
+
+/**
+ * Provides lifecycle management for an implementation instance associated with an {@link
+ * org.apache.tuscany.spi.component.AtomicComponent} for use by the atomic component's associated {@link
+ * org.apache.tuscany.spi.component.ScopeContainer}
+ *
+ * @version $Rev$ $Date$
+ */
+public interface InstanceWrapper {
+
+ Object getInstance();
+
+ boolean isStarted();
+
+ void start() throws TargetInitializationException;
+
+ void stop() throws TargetDestructionException;
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperImpl.java
new file mode 100644
index 0000000000..c4648d1e7b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/InstanceWrapperImpl.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.component.TargetInitializationException;
+
+/**
+ * Default implementation of an <code>InstanceWrapper</code>
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class InstanceWrapperImpl implements InstanceWrapper {
+ private Object instance;
+ private AtomicComponent component;
+ private boolean started;
+
+ public InstanceWrapperImpl(AtomicComponent component, Object instance) {
+ assert component != null;
+ assert instance != null;
+ this.component = component;
+ this.instance = instance;
+ }
+
+ public boolean isStarted() {
+ return started;
+ }
+
+ public Object getInstance() {
+ if (!started) {
+ throw new IllegalStateException("Instance not started");
+ }
+ return instance;
+ }
+
+ public void start() throws TargetInitializationException {
+ component.init(instance);
+ started = true;
+ }
+
+ public void stop() throws TargetDestructionException {
+ component.destroy(instance);
+ started = false;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeContainer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeContainer.java
new file mode 100644
index 0000000000..22beaae740
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeContainer.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.model.Scope;
+
+import org.apache.tuscany.core.component.event.RequestEnd;
+
+/**
+ * A scope context which manages atomic component instances keyed on the current request context
+ *
+ * @version $Rev$ $Date$
+ */
+public class RequestScopeContainer extends AbstractScopeContainer {
+ private final Map<AtomicComponent, Map<Thread, InstanceWrapper>> contexts;
+ private final Map<Thread, List<InstanceWrapper>> destroyQueues;
+
+ public RequestScopeContainer(WorkContext workContext, ScopeContainerMonitor monitor) {
+ super(workContext, monitor);
+ contexts = new ConcurrentHashMap<AtomicComponent, Map<Thread, InstanceWrapper>>();
+ destroyQueues = new ConcurrentHashMap<Thread, List<InstanceWrapper>>();
+ }
+
+ public Scope getScope() {
+ return Scope.REQUEST;
+ }
+
+ public void onEvent(Event event) {
+ checkInit();
+ if (event instanceof RequestEnd) {
+ shutdownInstances(Thread.currentThread());
+ }
+ }
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
+ }
+ lifecycleState = RUNNING;
+ }
+
+ public synchronized void stop() {
+ contexts.clear();
+ synchronized (destroyQueues) {
+ destroyQueues.clear();
+ }
+ lifecycleState = STOPPED;
+ }
+
+ public void register(AtomicComponent component) {
+ contexts.put(component, new ConcurrentHashMap<Thread, InstanceWrapper>());
+ }
+
+ protected InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create)
+ throws TargetResolutionException {
+ Map<Thread, InstanceWrapper> instanceContextMap = contexts.get(component);
+ assert instanceContextMap != null : "Atomic component not registered";
+ InstanceWrapper ctx = instanceContextMap.get(Thread.currentThread());
+ if (ctx == null && !create) {
+ return null;
+ }
+ if (ctx == null) {
+ ctx = new InstanceWrapperImpl(component, component.createInstance());
+ ctx.start();
+ instanceContextMap.put(Thread.currentThread(), ctx);
+ List<InstanceWrapper> destroyQueue = destroyQueues.get(Thread.currentThread());
+ if (destroyQueue == null) {
+ destroyQueue = new ArrayList<InstanceWrapper>();
+ destroyQueues.put(Thread.currentThread(), destroyQueue);
+ }
+ synchronized (destroyQueue) {
+ destroyQueue.add(ctx);
+ }
+ }
+ return ctx;
+ }
+
+ private void shutdownInstances(Thread key) {
+ List<InstanceWrapper> destroyQueue = destroyQueues.remove(key);
+ if (destroyQueue != null && destroyQueue.size() > 0) {
+ Thread thread = Thread.currentThread();
+ for (Map<Thread, InstanceWrapper> map : contexts.values()) {
+ map.remove(thread);
+ }
+ ListIterator<InstanceWrapper> iter = destroyQueue.listIterator(destroyQueue.size());
+ synchronized (destroyQueue) {
+ while (iter.hasPrevious()) {
+ try {
+ iter.previous().stop();
+ } catch (TargetDestructionException e) {
+ monitor.destructionError(e);
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeObjectFactory.java
new file mode 100644
index 0000000000..0377bcd548
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/RequestScopeObjectFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.WorkContext;
+
+import org.apache.tuscany.api.annotation.Monitor;
+
+/**
+ * Creates a new request scope context
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class RequestScopeObjectFactory implements ObjectFactory<RequestScopeContainer> {
+ private WorkContext context;
+ private ScopeContainerMonitor monitor;
+
+
+ public RequestScopeObjectFactory(@Autowire WorkContext context, @Monitor ScopeContainerMonitor monitor) {
+ this.context = context;
+ this.monitor = monitor;
+ }
+
+ public RequestScopeContainer getInstance() throws ObjectCreationException {
+ return new RequestScopeContainer(context, monitor);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/ScopeRegistryImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/ScopeRegistryImpl.java
new file mode 100644
index 0000000000..da338dd0ef
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/ScopeRegistryImpl.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.model.Scope;
+
+/**
+ * The default implementation of a scope registry
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScopeRegistryImpl implements ScopeRegistry {
+ private final Map<Scope, ScopeContainer> scopeCache =
+ new ConcurrentHashMap<Scope, ScopeContainer>();
+ private final Map<Scope, ObjectFactory<? extends ScopeContainer>> factoryCache =
+ new ConcurrentHashMap<Scope, ObjectFactory<? extends ScopeContainer>>();
+
+ public ScopeContainer getScopeContainer(Scope scope) {
+ assert Scope.COMPOSITE != scope;
+ ScopeContainer container = scopeCache.get(scope);
+ if (container == null) {
+ ObjectFactory<? extends ScopeContainer> factory = factoryCache.get(scope);
+ if (factory != null) {
+ container = factory.getInstance();
+ container.start();
+ scopeCache.put(scope, container);
+ }
+ }
+ return container;
+ }
+
+ public <T extends ScopeContainer> void registerFactory(Scope scope, ObjectFactory<T> factory) {
+ factoryCache.put(scope, factory);
+ }
+
+ public void deregisterFactory(Scope scope) {
+ factoryCache.remove(scope);
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeContainer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeContainer.java
new file mode 100644
index 0000000000..cbd47b6cdd
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeContainer.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.model.Scope;
+
+/**
+ * A scope context which manages stateless atomic component instances in a non-pooled fashion
+ *
+ * @version $Rev$ $Date$
+ */
+public class StatelessScopeContainer extends AbstractScopeContainer {
+
+ public StatelessScopeContainer(WorkContext workContext, ScopeContainerMonitor monitor) {
+ super(workContext, monitor);
+ }
+
+ public Scope getScope() {
+ return Scope.STATELESS;
+ }
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED or STOPPED state [" + lifecycleState + "]");
+ }
+ lifecycleState = RUNNING;
+ }
+
+ public synchronized void stop() {
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Scope in wrong state [" + lifecycleState + "]");
+ }
+ lifecycleState = STOPPED;
+ }
+
+ public void onEvent(Event event) {
+ }
+
+ public void register(AtomicComponent component) {
+ checkInit();
+ }
+
+ protected InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create)
+ throws TargetResolutionException {
+ // there never is a previously associated instance, return null
+ if (!create) {
+ return null;
+ }
+ InstanceWrapper ctx = new InstanceWrapperImpl(component, component.createInstance());
+ ctx.start();
+ return ctx;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactory.java
new file mode 100644
index 0000000000..8e05510723
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactory.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.osoa.sca.annotations.EagerInit;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+
+import org.apache.tuscany.api.annotation.Monitor;
+
+/**
+ * Creates a new stateless scope context
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+@EagerInit
+public class StatelessScopeObjectFactory implements ObjectFactory<StatelessScopeContainer> {
+ private WorkContext context;
+ private ScopeContainerMonitor monitor;
+
+ public StatelessScopeObjectFactory(@Autowire ScopeRegistry registry,
+ @Autowire WorkContext context,
+ @Monitor ScopeContainerMonitor monitor) {
+ registry.registerFactory(Scope.STATELESS, this);
+ this.context = context;
+ this.monitor = monitor;
+ }
+
+ public StatelessScopeContainer getInstance() throws ObjectCreationException {
+ return new StatelessScopeContainer(context, monitor);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingInteceptor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingInteceptor.java
new file mode 100644
index 0000000000..aedd715fed
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingInteceptor.java
@@ -0,0 +1,250 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.databinding.DataBinding;
+import org.apache.tuscany.spi.databinding.ExceptionHandler;
+import org.apache.tuscany.spi.databinding.Mediator;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.idl.ServiceFaultException;
+import org.apache.tuscany.spi.model.DataType;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.Wire;
+
+/**
+ * An interceptor to transform data accross databindings on the wire
+ *
+ * @version $Rev$ $Date$
+ */
+public class DataBindingInteceptor implements Interceptor {
+ private Interceptor next;
+
+ private CompositeComponent compositeComponent;
+
+ private Operation<?> sourceOperation;
+
+ private Operation<?> targetOperation;
+
+ private Mediator mediator;
+
+ public DataBindingInteceptor(Wire sourceWire, Operation<?> sourceOperation, Operation<?> targetOperation) {
+ super();
+ // this.sourceWire = sourceWire;
+ this.sourceOperation = sourceOperation;
+ // this.targetWire = targetWire;
+ this.targetOperation = targetOperation;
+ this.compositeComponent = sourceWire.getContainer().getParent();
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.wire.Interceptor#getNext()
+ */
+ public Interceptor getNext() {
+ return next;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.wire.Interceptor#invoke(org.apache.tuscany.spi.wire.Message)
+ */
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.tuscany.spi.wire.Interceptor#invoke(org.apache.tuscany.spi.wire.Message)
+ */
+ public Message invoke(Message msg) {
+ Object input = transform(msg.getBody(), sourceOperation.getInputType(), targetOperation.getInputType());
+ msg.setBody(input);
+ Message resultMsg = next.invoke(msg);
+ Object result = resultMsg.getBody();
+ if (sourceOperation.isNonBlocking()) {
+ // Not to reset the message body
+ return resultMsg;
+ }
+
+ // FIXME: Should we fix the Operation model so that getOutputType
+ // returns DataType<DataType<T>>?
+ DataType<DataType> targetType =
+ new DataType<DataType>(DataBinding.IDL_OUTPUT, Object.class, targetOperation.getOutputType());
+
+ targetType.setOperation(targetOperation.getOutputType().getOperation());
+ DataType<DataType> sourceType =
+ new DataType<DataType>(DataBinding.IDL_OUTPUT, Object.class, sourceOperation.getOutputType());
+ sourceType.setOperation(sourceOperation.getOutputType().getOperation());
+
+ if (resultMsg.isFault()) {
+
+ // FIXME: We need to figure out what fault type it is and then
+ // transform it
+ // back the source fault type
+ // throw new InvocationRuntimeException((Throwable) result);
+
+ if ((result instanceof Exception) && !(result instanceof RuntimeException)) {
+ // FIXME: How to match fault data to a fault type for the
+ // operation?
+
+ // If the result is from an InvocationTargetException look at
+ // the actual cause.
+ if (result instanceof InvocationTargetException) {
+ result = ((InvocationTargetException)result).getCause();
+ }
+ DataType targetDataType = null;
+ for (DataType exType : targetOperation.getFaultTypes()) {
+ if (((Class)exType.getPhysical()).isInstance(result)) {
+ if (result instanceof ServiceFaultException) {
+ if (((ServiceFaultException)result).isMatchingType(exType.getLogical())) {
+ targetDataType = exType;
+ break;
+ }
+
+ } else {
+ targetDataType = exType;
+ break;
+ }
+ }
+ }
+
+ if (targetDataType == null) {
+ // Not a business exception
+ return resultMsg;
+ }
+
+ DataType targetFaultType = getFaultType(targetDataType);
+ if (targetFaultType == null) {
+ throw new TransformationException("Target fault type cannot be resolved");
+ }
+
+ // FIXME: How to match a source fault type to a target fault
+ // type?
+ DataType sourceDataType = null;
+ DataType sourceFaultType = null;
+ for (DataType exType : sourceOperation.getFaultTypes()) {
+ DataType faultType = getFaultType(exType);
+ // Match by the QName (XSD element) of the fault type
+ if (faultType != null && targetFaultType.getLogical().equals(faultType.getLogical())) {
+ sourceDataType = exType;
+ sourceFaultType = faultType;
+ break;
+ }
+ }
+
+ if (sourceFaultType == null) {
+ throw new TransformationException("No matching source fault type is found");
+ }
+
+ Object newResult =
+ transformException(result, targetDataType, sourceDataType, targetFaultType, sourceFaultType);
+ if (newResult != result) {
+ resultMsg.setBodyWithFault(newResult);
+ }
+ }
+
+ } else {
+ assert !(result instanceof Throwable) : "Expected messages that are not throwable " + result;
+
+ Object newResult = transform(result, targetType, sourceType);
+ if (newResult != result) {
+ resultMsg.setBody(newResult);
+ }
+ }
+
+ return resultMsg;
+ }
+
+ private Object transform(Object source, DataType sourceType, DataType targetType) {
+ if (sourceType == targetType || (sourceType != null && sourceType.equals(targetType))) {
+ return source;
+ }
+ Map<Class<?>, Object> metadata = new HashMap<Class<?>, Object>();
+ metadata.put(CompositeComponent.class, compositeComponent);
+ return mediator.mediate(source, sourceType, targetType, metadata);
+ }
+
+ private DataType getFaultType(DataType exceptionType) {
+ // FIXME: We cannot assume the exception will have a databinding set
+ DataBinding targetDataBinding =
+ mediator.getDataBindingRegistry().getDataBinding(exceptionType.getDataBinding());
+ if (targetDataBinding == null) {
+ return null;
+ }
+ ExceptionHandler targetHandler = targetDataBinding.getExceptionHandler();
+ if (targetHandler == null) {
+ return null;
+ }
+ return targetHandler.getFaultType(exceptionType);
+ }
+
+ /**
+ * @param source The source exception
+ * @param sourceExType The data type for the source exception
+ * @param targetExType The data type for the target exception
+ * @param sourceType The fault type for the source
+ * @param targetType The fault type for the target
+ * @return
+ */
+ private Object transformException(Object source,
+ DataType sourceExType,
+ DataType targetExType,
+ DataType sourceType,
+ DataType targetType) {
+ if (sourceType == targetType || (sourceType != null && sourceType.equals(targetType))) {
+ return source;
+ }
+ Map<Class<?>, Object> metadata = new HashMap<Class<?>, Object>();
+ metadata.put(CompositeComponent.class, compositeComponent);
+
+ DataType<DataType<?>> eSourceDataType =
+ new DataType<DataType<?>>("idl:fault", sourceExType.getPhysical(), sourceType);
+ DataType<DataType<?>> eTargetDataType =
+ new DataType<DataType<?>>("idl:fault", targetExType.getPhysical(), targetType);
+
+ return mediator.mediate(source, eSourceDataType, eTargetDataType, metadata);
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.wire.Interceptor#isOptimizable()
+ */
+ public boolean isOptimizable() {
+ return false;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.wire.Interceptor#setNext(org.apache.tuscany.spi.wire.Interceptor)
+ */
+ public void setNext(Interceptor next) {
+ this.next = next;
+ }
+
+ /**
+ * @param mediator the mediator to set
+ */
+ public void setMediator(Mediator mediator) {
+ this.mediator = mediator;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingJavaInterfaceProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingJavaInterfaceProcessor.java
new file mode 100644
index 0000000000..6e176cf0a6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingJavaInterfaceProcessor.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.datatype.Duration;
+import javax.xml.datatype.XMLGregorianCalendar;
+
+import org.apache.tuscany.api.annotation.DataType;
+import org.apache.tuscany.api.annotation.IDLMapping;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.databinding.DataBindingRegistry;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorExtension;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.Operation;
+
+/**
+ * The databinding annotation processor for java interfaces
+ *
+ * @version $Rev$ $Date$
+ */
+public class DataBindingJavaInterfaceProcessor extends JavaInterfaceProcessorExtension {
+ private static final Class[] SIMPLE_JAVA_TYPES =
+ {Byte.class, Character.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Date.class,
+ Calendar.class, GregorianCalendar.class, Duration.class, XMLGregorianCalendar.class, BigInteger.class,
+ BigDecimal.class};
+
+ private static final Set<Class> SIMPLE_TYPE_SET = new HashSet<Class>(Arrays.asList(SIMPLE_JAVA_TYPES));
+
+ private DataBindingRegistry dataBindingRegistry;
+
+ public DataBindingJavaInterfaceProcessor(@Autowire
+ DataBindingRegistry dataBindingRegistry) {
+ super();
+ this.dataBindingRegistry = dataBindingRegistry;
+ }
+
+ public void visitInterface(Class<?> clazz, Class<?> callbackClass, JavaServiceContract contract)
+ throws InvalidServiceContractException {
+ if (!contract.isRemotable()) {
+ return;
+ }
+ Map<String, Operation<Type>> operations = contract.getOperations();
+ processInterface(clazz, contract, operations);
+ if (callbackClass != null) {
+ Map<String, Operation<Type>> callbackOperations = contract.getCallbackOperations();
+ processInterface(callbackClass, contract, callbackOperations);
+ }
+ }
+
+ private void processInterface(Class<?> clazz, JavaServiceContract contract,
+ Map<String, Operation<Type>> operations) {
+ IDLMapping interfaceMapping = clazz.getAnnotation(IDLMapping.class);
+ DataType interfaceDataType = clazz.getAnnotation(DataType.class);
+ if (interfaceDataType != null) {
+ contract.setDataBinding(interfaceDataType.name());
+ }
+ for (Method method : clazz.getMethods()) {
+ Operation<?> operation = operations.get(method.getName());
+ DataType operationDataType = method.getAnnotation(DataType.class);
+ if (operationDataType == null) {
+ operationDataType = interfaceDataType;
+ }
+
+ if (operationDataType != null) {
+ operation.setDataBinding(operationDataType.name());
+ // FIXME: [rfeng] Keep data context as metadata?
+ }
+ IDLMapping operationMapping = clazz.getAnnotation(IDLMapping.class);
+ if (operationMapping == null) {
+ operationMapping = interfaceMapping;
+ }
+
+ if (operationMapping != null) {
+ operation.setDataBinding(operationMapping.dataBinding());
+ operation.setWrapperStyle(operationMapping.wrapperStyle());
+ }
+ // String dataBinding = operation.getDataBinding();
+
+ Annotation[] annotations = null;
+ if (operationDataType != null) {
+ annotations = new Annotation[] {operationDataType};
+ }
+ // FIXME: We need a better way to identify simple java types
+ for (org.apache.tuscany.spi.model.DataType<?> d : operation.getInputType().getLogical()) {
+ dataBindingRegistry.introspectType(d, annotations);
+ }
+ if (operation.getOutputType() != null) {
+ dataBindingRegistry.introspectType(operation.getOutputType(), annotations);
+ }
+ for (org.apache.tuscany.spi.model.DataType<?> d : operation.getFaultTypes()) {
+ dataBindingRegistry.introspectType(d, annotations);
+ }
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingRegistryImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingRegistryImpl.java
new file mode 100644
index 0000000000..8c7f7e28ad
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingRegistryImpl.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import java.lang.annotation.Annotation;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tuscany.core.databinding.javabeans.JavaBeansDataBinding;
+import org.apache.tuscany.spi.databinding.DataBinding;
+import org.apache.tuscany.spi.databinding.DataBindingRegistry;
+import org.apache.tuscany.spi.model.DataType;
+import org.osoa.sca.annotations.EagerInit;
+
+/**
+ * The default implementation of a data binding registry
+ *
+ * @version $Rev$ $Date$
+ */
+@EagerInit
+public class DataBindingRegistryImpl implements DataBindingRegistry {
+ private final Map<String, DataBinding> bindings = new HashMap<String, DataBinding>();
+
+ public DataBinding getDataBinding(String id) {
+ if (id == null) {
+ return null;
+ }
+ return bindings.get(id.toLowerCase());
+ }
+
+ public void register(DataBinding dataBinding) {
+ bindings.put(dataBinding.getName().toLowerCase(), dataBinding);
+ String[] aliases = dataBinding.getAliases();
+ if (aliases != null) {
+ for (String alias : aliases) {
+ bindings.put(alias.toLowerCase(), dataBinding);
+ }
+ }
+ }
+
+ public DataBinding unregister(String id) {
+ if (id == null) {
+ return null;
+ }
+ DataBinding dataBinding = bindings.remove(id.toLowerCase());
+ if (dataBinding != null) {
+ String[] aliases = dataBinding.getAliases();
+ if (aliases != null) {
+ for (String alias : aliases) {
+ bindings.remove(alias.toLowerCase());
+ }
+ }
+ }
+ return dataBinding;
+ }
+
+ private Set<DataBinding> getDataBindings() {
+ return new HashSet<DataBinding>(bindings.values());
+ }
+
+ public boolean introspectType(DataType dataType, Annotation[] annotations) {
+ for (DataBinding binding : getDataBindings()) {
+ // don't introspect for JavaBeansDatabinding as all javatypes will
+ // anyways match to its basetype
+ // which is java.lang.Object. Default to this only if no databinding
+ // results
+ if (!binding.getName().equals(JavaBeansDataBinding.NAME)) {
+ if (binding.introspect(dataType, annotations)) {
+ return true;
+ }
+ }
+ }
+ // FIXME: Should we honor the databinding from operation/interface
+ // level?
+ Object physical = dataType.getPhysical();
+ if (physical instanceof Class) {
+ if (physical == Object.class || Throwable.class.isAssignableFrom((Class)physical)) {
+ return false;
+ }
+ }
+ dataType.setDataBinding(JavaBeansDataBinding.NAME);
+ return false;
+ }
+
+ public DataType introspectType(Object value) {
+ DataType dataType = null;
+ for (DataBinding binding : getDataBindings()) {
+ // don't introspect for JavaBeansDatabinding as all javatypes will
+ // anyways match to its basetype
+ // which is java.lang.Object. Default to this only if no databinding
+ // results
+ if (!binding.getName().equals(JavaBeansDataBinding.NAME)) {
+ dataType = binding.introspect(value);
+ }
+ if (dataType != null) {
+ return dataType;
+ }
+ }
+ return new DataType<Class>(JavaBeansDataBinding.NAME, value.getClass(), value.getClass());
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessor.java
new file mode 100644
index 0000000000..e687a161eb
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessor.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.databinding.Mediator;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.WirePostProcessorExtension;
+import org.osoa.sca.annotations.Constructor;
+
+/**
+ * This processor is responsible to add an interceptor to invocation chain if the source and target operations have
+ * different databinding requirements
+ *
+ * @version $Rev$ $Date$
+ */
+public class DataBindingWirePostProcessor extends WirePostProcessorExtension {
+ private Mediator mediator;
+
+ @Constructor({"mediator"})
+ public DataBindingWirePostProcessor(@Autowire Mediator mediator) {
+ super();
+ this.mediator = mediator;
+ }
+
+ public void process(OutboundWire source, InboundWire target) {
+ Map<Operation<?>, OutboundInvocationChain> chains = source.getInvocationChains();
+ for (Map.Entry<Operation<?>, OutboundInvocationChain> entry : chains.entrySet()) {
+ Operation<?> sourceOperation = entry.getKey();
+ Operation<?> targetOperation =
+ getTargetOperation(target.getInvocationChains().keySet(), sourceOperation.getName());
+ String sourceDataBinding = sourceOperation.getDataBinding();
+ String targetDataBinding = targetOperation.getDataBinding();
+ if (sourceDataBinding == null && targetDataBinding == null) {
+ continue;
+ }
+ if (sourceDataBinding == null || targetDataBinding == null
+ || !sourceDataBinding.equals(targetDataBinding)) {
+ // Add the interceptor to the source side because multiple
+ // references can be wired
+ // to the same service
+ DataBindingInteceptor interceptor =
+ new DataBindingInteceptor(source, sourceOperation, targetOperation);
+ interceptor.setMediator(mediator);
+ entry.getValue().addInterceptor(0, interceptor);
+ }
+ }
+
+ // Check if there's a callback
+ Map callbackOperations = source.getServiceContract().getCallbackOperations();
+ if (callbackOperations == null || callbackOperations.isEmpty()) {
+ return;
+ }
+ Object targetAddress = source.getContainer().getName();
+ Map<Operation<?>, OutboundInvocationChain> callbackChains =
+ target.getSourceCallbackInvocationChains(targetAddress);
+ if (callbackChains == null) {
+ // callback chains could be null
+ return;
+ }
+ for (Map.Entry<Operation<?>, OutboundInvocationChain> entry : callbackChains.entrySet()) {
+ Operation<?> sourceOperation = entry.getKey();
+ Operation<?> targetOperation =
+ getTargetOperation(source.getTargetCallbackInvocationChains().keySet(), sourceOperation
+ .getName());
+ String sourceDataBinding = sourceOperation.getDataBinding();
+ String targetDataBinding = targetOperation.getDataBinding();
+ if (sourceDataBinding == null && targetDataBinding == null) {
+ continue;
+ }
+ if (sourceDataBinding == null || targetDataBinding == null
+ || !sourceDataBinding.equals(targetDataBinding)) {
+ // Add the interceptor to the source side because multiple
+ // references can be wired
+ // to the same service
+ DataBindingInteceptor interceptor =
+ new DataBindingInteceptor(source, sourceOperation, targetOperation);
+ interceptor.setMediator(mediator);
+ entry.getValue().addInterceptor(0, interceptor);
+ }
+ }
+ }
+
+ public void process(InboundWire source, OutboundWire target) {
+ SCAObject container = source.getContainer();
+ // Either Service or Reference
+ boolean isReference = container instanceof ReferenceBinding;
+
+ Map<Operation<?>, InboundInvocationChain> chains = source.getInvocationChains();
+ for (Map.Entry<Operation<?>, InboundInvocationChain> entry : chains.entrySet()) {
+ Operation<?> sourceOperation = entry.getKey();
+ Operation<?> targetOperation =
+ getTargetOperation(target.getInvocationChains().keySet(), sourceOperation.getName());
+ String sourceDataBinding = sourceOperation.getDataBinding();
+ String targetDataBinding = targetOperation.getDataBinding();
+ if (sourceDataBinding == null && targetDataBinding == null) {
+ continue;
+ }
+ if (sourceDataBinding == null || targetDataBinding == null
+ || !sourceDataBinding.equals(targetDataBinding)) {
+ // Add the interceptor to the source side
+ DataBindingInteceptor interceptor =
+ new DataBindingInteceptor(source, sourceOperation, targetOperation);
+ interceptor.setMediator(mediator);
+ if (isReference) {
+ // FIXME: We need a better way to position the interceptors
+ target.getInvocationChains().get(targetOperation).addInterceptor(0, interceptor);
+ Interceptor tail = entry.getValue().getTailInterceptor();
+ if (tail != null) {
+ // HACK to relink the bridging interceptor
+ tail.setNext(interceptor);
+ }
+ } else {
+ entry.getValue().addInterceptor(0, interceptor);
+ }
+
+ }
+ }
+ }
+
+ private Operation getTargetOperation(Set<Operation<?>> operations, String operationName) {
+ for (Operation<?> op : operations) {
+ if (op.getName().equals(operationName)) {
+ return op;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataTypeLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataTypeLoader.java
new file mode 100644
index 0000000000..10731f8c53
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DataTypeLoader.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.impl;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.InvalidValueException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.LoaderUtil;
+import org.apache.tuscany.spi.model.DataType;
+import org.apache.tuscany.spi.model.ModelObject;
+
+import org.osoa.sca.annotations.Constructor;
+
+/**
+ * The StAX loader for data type
+ */
+public class DataTypeLoader extends LoaderExtension<DataType> {
+ public static final QName DATA_BINDING =
+ new QName("http://tuscany.apache.org/xmlns/sca/databinding/1.0", "databinding");
+
+ @Constructor({"registry"})
+ public DataTypeLoader(@Autowire LoaderRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public QName getXMLType() {
+ return DATA_BINDING;
+ }
+
+ public DataType load(CompositeComponent parent,
+ ModelObject object, XMLStreamReader reader,
+ DeploymentContext deploymentContext) throws XMLStreamException, LoaderException {
+ assert DATA_BINDING.equals(reader.getName());
+ String name = reader.getAttributeValue(null, "name");
+ LoaderUtil.skipToEndElement(reader);
+ if (name == null) {
+ throw new InvalidValueException("The 'name' attrbiute is required");
+ }
+ DataType dataType = new DataType<Class>(name, Object.class, Object.class);
+ return dataType;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DirectedGraph.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DirectedGraph.java
new file mode 100755
index 0000000000..02adf5860c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/DirectedGraph.java
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.impl;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Directed, weighted graph
+ *
+ * @param <V> The type of vertex object
+ * @param <E> The type of edge object
+ */
+public class DirectedGraph<V, E> {
+ private final Map<V, Vertex> vertices = new HashMap<V, Vertex>();
+
+ /**
+ * Key for the shortest path cache
+ */
+ private final class VertexPair {
+ private Vertex source;
+
+ private Vertex target;
+
+ /**
+ * @param source
+ * @param target
+ */
+ private VertexPair(Vertex source, Vertex target) {
+ super();
+ this.source = source;
+ this.target = target;
+ }
+
+ public boolean equals(Object object) {
+ if (!VertexPair.class.isInstance(object)) {
+ return false;
+ }
+ VertexPair pair = (VertexPair)object;
+ return source == pair.source && target == pair.target;
+ }
+
+ public int hashCode() {
+ int x = source == null ? 0 : source.hashCode();
+ int y = target == null ? 0 : target.hashCode();
+ return x ^ y;
+ }
+
+ }
+
+ private final Map<VertexPair, Path> paths = new HashMap<VertexPair, Path>();
+
+ /**
+ * Vertex of a graph
+ */
+ public final class Vertex {
+ private V value;
+
+ // TODO: Do we want to support multiple edges for a vertex pair? If so,
+ // we should use a List instead of Map
+ private Map<Vertex, Edge> outEdges = new HashMap<Vertex, Edge>();
+
+ private Vertex(V value) {
+ this.value = value;
+ }
+
+ public String toString() {
+ return "(" + value + ")";
+ }
+
+ public V getValue() {
+ return value;
+ }
+
+ public Map<Vertex, Edge> getOutEdges() {
+ return outEdges;
+ }
+
+ }
+
+ /**
+ * An Edge connects two vertices in one direction
+ */
+ public final class Edge {
+ private Vertex sourceVertex;
+
+ private Vertex targetVertex;
+
+ private E value;
+
+ private int weight;
+
+ public Edge(Vertex source, Vertex target, E value, int weight) {
+ this.sourceVertex = source;
+ this.targetVertex = target;
+ this.value = value;
+ this.weight = weight;
+ }
+
+ public String toString() {
+ return sourceVertex + "->" + targetVertex + "[" + value + "," + weight + "]";
+ }
+
+ public E getValue() {
+ return value;
+ }
+
+ public void setValue(E value) {
+ this.value = value;
+ }
+
+ public Vertex getTargetVertex() {
+ return targetVertex;
+ }
+
+ public void setTargetVertex(Vertex vertex) {
+ this.targetVertex = vertex;
+ }
+
+ public int getWeight() {
+ return weight;
+ }
+
+ public void setWeight(int weight) {
+ this.weight = weight;
+ }
+
+ public Vertex getSourceVertex() {
+ return sourceVertex;
+ }
+
+ public void setSourceVertex(Vertex sourceVertex) {
+ this.sourceVertex = sourceVertex;
+ }
+ }
+
+ private final class Node implements Comparable<Node> {
+
+ private long distance = Integer.MAX_VALUE;
+
+ private Node previous; // NOPMD by rfeng on 9/26/06 9:17 PM
+
+ private Vertex vertex; // NOPMD by rfeng on 9/26/06 9:17 PM
+
+ private Node(Vertex vertex) {
+ this.vertex = vertex;
+ }
+
+ public int compareTo(Node o) {
+ return (distance > o.distance) ? 1 : ((distance == o.distance) ? 0 : -1);
+ }
+ }
+
+ public void addEdge(V source, V target, E edgeValue, int weight) {
+ Vertex s = getVertex(source);
+ if (s == null) {
+ s = new Vertex(source);
+ vertices.put(source, s);
+ }
+ Vertex t = getVertex(target);
+ if (t == null) {
+ t = new Vertex(target);
+ vertices.put(target, t);
+ }
+ Edge edge = new Edge(s, t, edgeValue, weight);
+ s.outEdges.put(t, edge);
+ }
+
+ public Vertex getVertex(V source) {
+ Vertex s = vertices.get(source);
+ return s;
+ }
+
+ public boolean removeEdge(V source, V target) {
+ Vertex s = getVertex(source);
+ if (s == null) {
+ return false;
+ }
+
+ Vertex t = getVertex(target);
+ if (t == null) {
+ return false;
+ }
+
+ return s.outEdges.remove(t) != null;
+
+ }
+
+ public Edge getEdge(Vertex source, Vertex target) {
+ return source.outEdges.get(target);
+ }
+
+ public Edge getEdge(V source, V target) {
+ return getEdge(getVertex(source), getVertex(target));
+ }
+
+ /**
+ * Get the shortes path from the source vertex to the target vertex using
+ * Dijkstra's algorithm. If there's no path, null will be returned. If the
+ * source is the same as the target, it returns a path with empty edges with
+ * weight 0.
+ *
+ * @param sourceValue The value identifies the source
+ * @param targetValue The value identifies the target
+ * @return The shortest path
+ */
+ public Path getShortestPath(V sourceValue, V targetValue) {
+ Vertex source = getVertex(sourceValue);
+ if (source == null) {
+ return null;
+ }
+ Vertex target = getVertex(targetValue);
+ if (target == null) {
+ return null;
+ }
+
+ VertexPair pair = new VertexPair(source, target);
+ if (paths.containsKey(pair)) {
+ return paths.get(pair);
+ }
+
+ // HACK: To support same vertex
+ if (source == target) {
+ Path path = new Path();
+ Edge edge = getEdge(source, target);
+ if (edge != null) {
+ path.addEdge(edge);
+ }
+ paths.put(pair, path);
+ return path;
+ }
+
+ Map<Vertex, Node> nodes = new HashMap<Vertex, Node>();
+ for (Vertex v : vertices.values()) {
+ Node node = new Node(v);
+ if (v == source) {
+ node.distance = 0;
+ }
+ nodes.put(v, node);
+ }
+
+ Set<Node> otherNodes = new HashSet<Node>(nodes.values());
+ Set<Node> nodesOnPath = new HashSet<Node>();
+ while (!otherNodes.isEmpty()) {
+ Node nextNode = extractMin(otherNodes);
+ if (nextNode.vertex == target) {
+ Path path = getPath(nextNode);
+ paths.put(pair, path); // Cache it
+ return path;
+ }
+ nodesOnPath.add(nextNode);
+ for (Edge edge : nextNode.vertex.outEdges.values()) {
+ Node adjacentNode = nodes.get(edge.targetVertex);
+ if (nextNode.distance + edge.weight < adjacentNode.distance) {
+ adjacentNode.distance = nextNode.distance + edge.weight;
+ adjacentNode.previous = nextNode;
+ }
+ }
+ }
+ paths.put(pair, null); // Cache it
+ return null;
+ }
+
+ /**
+ * Searches for the vertex u in the vertex set Q that has the least d[u]
+ * value. That vertex is removed from the set Q and returned to the user.
+ *
+ * @param nodes
+ * @return
+ */
+ private Node extractMin(Set<Node> nodes) {
+ Node node = Collections.min(nodes);
+ nodes.remove(node);
+ return node;
+ }
+
+ /**
+ * The path between two vertices
+ */
+ public final class Path {
+ private List<Edge> edges = new LinkedList<Edge>();
+
+ private int weight;
+
+ public int getWeight() {
+ return weight;
+ }
+
+ public List<Edge> getEdges() {
+ return edges;
+ }
+
+ public void addEdge(Edge edge) {
+ edges.add(0, edge);
+ weight += edge.weight;
+ }
+
+ public String toString() {
+ return edges + ", " + weight;
+ }
+ }
+
+ private Path getPath(Node t) {
+ if (t.distance == Integer.MAX_VALUE) {
+ return null;
+ }
+ Path path = new Path();
+ Node u = t;
+ while (u.previous != null) {
+ Edge edge = getEdge(u.previous.vertex, u.vertex);
+ path.addEdge(edge);
+ u = u.previous;
+ }
+ return path;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ for (Vertex v : vertices.values()) {
+ sb.append(v.outEdges.values()).append("\n");
+ }
+ return sb.toString();
+ }
+
+ public Map<V, Vertex> getVertices() {
+ return vertices;
+ }
+
+ public void addGraph(DirectedGraph<V, E> otherGraph) {
+ for (Vertex v : otherGraph.vertices.values()) {
+ for (Edge e : v.outEdges.values()) {
+ addEdge(e.sourceVertex.value, e.targetVertex.value, e.value, e.weight);
+ }
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/Exception2ExceptionTransformer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/Exception2ExceptionTransformer.java
new file mode 100644
index 0000000000..d1ef0cbd1a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/Exception2ExceptionTransformer.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.databinding.DataBinding;
+import org.apache.tuscany.spi.databinding.ExceptionHandler;
+import org.apache.tuscany.spi.databinding.Mediator;
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.apache.tuscany.spi.model.DataType;
+import org.osoa.sca.annotations.Service;
+
+/**
+ * This is a special transformer to transform the exception from one IDL to the
+ * other one
+ */
+@Service(Transformer.class)
+public class Exception2ExceptionTransformer extends TransformerExtension<Object[], Object[]> implements
+ PullTransformer<Exception, Exception> {
+
+ protected Mediator mediator;
+
+ public Exception2ExceptionTransformer() {
+ super();
+ }
+
+ @Override
+ public String getSourceDataBinding() {
+ return DataBinding.IDL_FAULT;
+ }
+
+ @Override
+ public String getTargetDataBinding() {
+ return DataBinding.IDL_FAULT;
+ }
+
+ /**
+ * @param mediator the mediator to set
+ */
+ @Autowire
+ public void setMediator(Mediator mediator) {
+ this.mediator = mediator;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.extension.TransformerExtension#getSourceType()
+ */
+ @Override
+ protected Class getSourceType() {
+ return Exception.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.extension.TransformerExtension#getTargetType()
+ */
+ @Override
+ protected Class getTargetType() {
+ return Exception.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.Transformer#getWeight()
+ */
+ public int getWeight() {
+ return 10000;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Exception transform(Exception source, TransformationContext context) {
+ DataType<DataType> sourceType = context.getSourceDataType();
+
+ DataType<DataType> targetType = context.getTargetDataType();
+
+ ExceptionHandler exceptionHandler = getExceptionHandler(sourceType);
+ if (exceptionHandler == null) {
+ return source;
+ }
+
+ Object sourceFaultInfo = exceptionHandler.getFaultInfo(source);
+ Object targetFaultInfo =
+ mediator.mediate(sourceFaultInfo, sourceType.getLogical(), targetType.getLogical(), context.getMetadata());
+
+ ExceptionHandler targetHandler = getExceptionHandler(targetType);
+
+ if (targetHandler != null) {
+ Exception targetException =
+ targetHandler.createException(targetType, source.getMessage(), targetFaultInfo, source.getCause());
+ return targetException;
+ }
+
+ // FIXME
+ return source;
+
+ }
+
+ private ExceptionHandler getExceptionHandler(DataType<DataType> targetType) {
+ DataType targetFaultType = (DataType)targetType.getLogical();
+ DataBinding targetDataBinding =
+ mediator.getDataBindingRegistry().getDataBinding(targetFaultType.getDataBinding());
+ if (targetDataBinding == null) {
+ return null;
+ }
+ ExceptionHandler targetHandler = targetDataBinding.getExceptionHandler();
+ return targetHandler;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/Group2GroupTransformer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/Group2GroupTransformer.java
new file mode 100644
index 0000000000..c774336f4c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/Group2GroupTransformer.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.databinding.Mediator;
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.apache.tuscany.spi.model.DataType;
+import org.osoa.sca.annotations.Service;
+
+/**
+ * This is a special transformer to transform the output from one IDL to the
+ * other one
+ */
+@Service(Transformer.class)
+public class Group2GroupTransformer extends TransformerExtension<Object, Object> implements
+ PullTransformer<Object, Object> {
+
+ protected Mediator mediator;
+
+ /**
+ * @param wrapperHandler
+ */
+ public Group2GroupTransformer() {
+ super();
+ }
+
+ /**
+ * @param mediator the mediator to set
+ */
+ @Autowire
+ public void setMediator(Mediator mediator) {
+ this.mediator = mediator;
+ }
+
+ @Override
+ public String getSourceDataBinding() {
+ return GroupDataBinding.NAME;
+ }
+
+ @Override
+ public String getTargetDataBinding() {
+ return GroupDataBinding.NAME;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.extension.TransformerExtension#getSourceType()
+ */
+ @Override
+ protected Class getSourceType() {
+ return Object.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.extension.TransformerExtension#getTargetType()
+ */
+ @Override
+ protected Class getTargetType() {
+ return Object.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.Transformer#getWeight()
+ */
+ public int getWeight() {
+ return 10;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object transform(Object source, TransformationContext context) {
+ DataType<DataType> sourceType = context.getSourceDataType();
+ DataType<DataType> targetType = context.getTargetDataType();
+
+ return mediator.mediate(source, sourceType.getLogical(), targetType.getLogical(), context.getMetadata());
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/GroupDataBinding.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/GroupDataBinding.java
new file mode 100644
index 0000000000..6f56fbc2d5
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/GroupDataBinding.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+import org.apache.tuscany.spi.databinding.extension.DataBindingExtension;
+import org.apache.tuscany.spi.model.DataType;
+
+/**
+ * The base class for a special databinding which represents a group of other databindings
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class GroupDataBinding extends DataBindingExtension {
+ public static final String NAME = "databinding:group";
+
+ /**
+ * Marker type is a java class or interface representing the data format.
+ */
+ protected Class[] markerTypes;
+
+ public GroupDataBinding(Class[] types) {
+ super(NAME, null, GroupDataBinding.class);
+ this.markerTypes = types;
+ }
+
+ @SuppressWarnings("unchecked")
+ public boolean introspect(DataType type, Annotation[] annotations) {
+ if (markerTypes == null) {
+ return false;
+ }
+ Type physical = type.getPhysical();
+ if (physical instanceof ParameterizedType) {
+ physical = ((ParameterizedType)physical).getRawType();
+ }
+ if (!(physical instanceof Class)) {
+ return false;
+ }
+ Class cls = (Class)physical;
+ for (Class<?> c : markerTypes) {
+ if (isTypeOf(c, cls)) {
+ type.setDataBinding(getDataBinding(c));
+ type.setLogical(getLogical(cls, annotations));
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test if the given type is a subtype of the base type
+ * @param markerType
+ * @param type
+ * @return
+ */
+ protected boolean isTypeOf(Class<?> markerType, Class<?> type) {
+ return markerType.isAssignableFrom(type);
+ }
+
+ /**
+ * Derive the databinding name from a base class
+ * @param baseType
+ * @return
+ */
+ protected String getDataBinding(Class<?> baseType) {
+ return baseType.getName();
+ }
+
+ /**
+ * Get the logical type
+ * @param type The java type
+ * @param annotations
+ * @return
+ */
+ protected abstract Object getLogical(Class<?> type, Annotation[] annotations);
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/Input2InputTransformer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/Input2InputTransformer.java
new file mode 100644
index 0000000000..3f3f49f0b8
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/Input2InputTransformer.java
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.databinding.DataBinding;
+import org.apache.tuscany.spi.databinding.Mediator;
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.WrapperHandler;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.apache.tuscany.spi.idl.ElementInfo;
+import org.apache.tuscany.spi.idl.XMLType;
+import org.apache.tuscany.spi.model.DataType;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.WrapperInfo;
+import org.osoa.sca.annotations.Service;
+
+/**
+ * This is a special transformer to transform the input from one IDL to the
+ * other one
+ */
+@Service(Transformer.class)
+public class Input2InputTransformer extends TransformerExtension<Object[], Object[]> implements
+ PullTransformer<Object[], Object[]> {
+
+ protected Mediator mediator;
+
+ public Input2InputTransformer() {
+ super();
+ }
+
+ @Override
+ public String getSourceDataBinding() {
+ return DataBinding.IDL_INPUT;
+ }
+
+ @Override
+ public String getTargetDataBinding() {
+ return DataBinding.IDL_INPUT;
+ }
+
+ /**
+ * @param mediator the mediator to set
+ */
+ @Autowire
+ public void setMediator(Mediator mediator) {
+ this.mediator = mediator;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.extension.TransformerExtension#getSourceType()
+ */
+ @Override
+ protected Class getSourceType() {
+ return Object[].class;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.extension.TransformerExtension#getTargetType()
+ */
+ @Override
+ protected Class getTargetType() {
+ return Object[].class;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.Transformer#getWeight()
+ */
+ public int getWeight() {
+ return 10000;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object[] transform(Object[] source, TransformationContext context) {
+ DataType<List<DataType<?>>> sourceType = context.getSourceDataType();
+ Operation<?> sourceOp = (Operation<?>)sourceType.getOperation();
+ boolean sourceWrapped = sourceOp != null && sourceOp.isWrapperStyle();
+
+ WrapperHandler sourceWrapperHandler = null;
+ if (sourceWrapped) {
+ sourceWrapperHandler = getWapperHandler(sourceType.getOperation().getDataBinding(), true);
+ }
+
+ DataType<List<DataType<XMLType>>> targetType = context.getTargetDataType();
+ Operation<?> targetOp = (Operation<?>)targetType.getOperation();
+ boolean targetWrapped = targetOp != null && targetOp.isWrapperStyle();
+ WrapperHandler targetWrapperHandler = null;
+ if (targetWrapped) {
+ targetWrapperHandler = getWapperHandler(targetType.getOperation().getDataBinding(), true);
+ }
+
+ if ((!sourceWrapped) && targetWrapped) {
+ // Unwrapped --> Wrapped
+ WrapperInfo wrapper = targetOp.getWrapper();
+ ElementInfo wrapperElement = wrapper.getInputWrapperElement();
+
+ // If the source can be wrapped, wrapped it first
+ if (sourceWrapperHandler != null) {
+ Object sourceWrapper = sourceWrapperHandler.create(wrapperElement, context);
+ for (int i = 0; i < source.length; i++) {
+ ElementInfo argElement = wrapper.getInputChildElements().get(i);
+ sourceWrapperHandler.setChild(sourceWrapper, i, argElement, source[0]);
+ }
+ }
+ Object targetWrapper = targetWrapperHandler.create(wrapperElement, context);
+ if (source == null) {
+ return new Object[] {targetWrapper};
+ }
+ List<DataType<XMLType>> argTypes = wrapper.getUnwrappedInputType().getLogical();
+
+ for (int i = 0; i < source.length; i++) {
+ ElementInfo argElement = wrapper.getInputChildElements().get(i);
+ DataType<XMLType> argType = argTypes.get(i);
+ Object child = source[i];
+ child =
+ mediator.mediate(source[i], sourceType.getLogical().get(i), argType, context
+ .getMetadata());
+ targetWrapperHandler.setChild(targetWrapper, i, argElement, child);
+ }
+ return new Object[] {targetWrapper};
+ } else if (sourceWrapped && (!targetWrapped)) {
+ // Wrapped to Unwrapped
+ Object sourceWrapper = source[0];
+ // List<ElementInfo> childElements = sourceOp.getWrapper().getInputChildElements();
+ Object[] target = null;
+
+ targetWrapperHandler = getWapperHandler(targetType.getOperation().getDataBinding(), false);
+ if (targetWrapperHandler != null) {
+ ElementInfo wrapperElement = sourceOp.getWrapper().getInputWrapperElement();
+ // Object targetWrapper =
+ // targetWrapperHandler.create(wrapperElement, context);
+ DataType<XMLType> targetWrapperType =
+ new DataType<XMLType>(targetType.getOperation().getDataBinding(), Object.class,
+ new XMLType(wrapperElement));
+ Object targetWrapper =
+ mediator.mediate(sourceWrapper,
+ sourceType.getLogical().get(0),
+ targetWrapperType,
+ context.getMetadata());
+ target = targetWrapperHandler.getChildren(targetWrapper).toArray();
+ } else {
+ Object[] sourceChildren = sourceWrapperHandler.getChildren(sourceWrapper).toArray();
+ target = new Object[sourceChildren.length];
+ for (int i = 0; i < sourceChildren.length; i++) {
+ DataType<XMLType> childType =
+ sourceOp.getWrapper().getUnwrappedInputType().getLogical().get(i);
+ target[i] =
+ mediator.mediate(sourceChildren[i], childType, targetType.getLogical().get(i), context
+ .getMetadata());
+ }
+ }
+ return target;
+ } else {
+ // Assuming wrapper to wrapper conversion can be handled here as
+ // well
+ Object[] newArgs = new Object[source.length];
+ for (int i = 0; i < source.length; i++) {
+ Object child =
+ mediator.mediate(source[i], sourceType.getLogical().get(i), targetType.getLogical()
+ .get(i), context.getMetadata());
+ newArgs[i] = child;
+ }
+ return newArgs;
+ }
+ }
+
+ private WrapperHandler getWapperHandler(String dataBindingId, boolean required) {
+ DataBinding dataBinding = mediator.getDataBindingRegistry().getDataBinding(dataBindingId);
+ WrapperHandler wrapperHandler = dataBinding == null ? null : dataBinding.getWrapperHandler();
+ if (wrapperHandler == null && required) {
+ throw new TransformationException(
+ "No wrapper handler is provided for databinding: " + dataBindingId);
+ }
+ return wrapperHandler;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/MediatorImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/MediatorImpl.java
new file mode 100644
index 0000000000..2b6d871472
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/MediatorImpl.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.impl;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.databinding.DataBindingRegistry;
+import org.apache.tuscany.spi.databinding.DataPipe;
+import org.apache.tuscany.spi.databinding.Mediator;
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.TransformerRegistry;
+import org.apache.tuscany.spi.model.DataType;
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * Default Mediator implementation
+ */
+@Scope("COMPOSITE")
+public class MediatorImpl implements Mediator {
+
+ private DataBindingRegistry dataBindingRegistry;
+
+ private TransformerRegistry transformerRegistry;
+
+ @Autowire
+ public void setTransformerRegistry(TransformerRegistry transformerRegistry) {
+ this.transformerRegistry = transformerRegistry;
+ }
+
+ /**
+ * @param dataBindingRegistry the dataBindingRegistry to set
+ */
+ @Autowire
+ public void setDataBindingRegistry(DataBindingRegistry dataBindingRegistry) {
+ this.dataBindingRegistry = dataBindingRegistry;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.Mediator#mediate(java.lang.Object,
+ * org.apache.tuscany.spi.model.DataType,
+ * org.apache.tuscany.spi.model.DataType, Map)
+ */
+ @SuppressWarnings("unchecked")
+ public Object mediate(Object source,
+ DataType sourceDataType,
+ DataType targetDataType,
+ Map<Class<?>, Object> metadata) {
+ if (sourceDataType == null) {
+ sourceDataType = dataBindingRegistry.introspectType(source);
+ }
+ if (sourceDataType == null) {
+ return source;
+ } else if (sourceDataType.equals(targetDataType)) {
+ return source;
+ }
+
+ List<Transformer> path = getTransformerChain(sourceDataType, targetDataType);
+
+ Object result = source;
+ int size = path.size();
+ int i = 0;
+ while (i < size) {
+ Transformer transformer = path.get(i);
+ TransformationContext context =
+ createTransformationContext(sourceDataType, targetDataType, size, i, transformer, metadata);
+ // the source and target type
+ if (transformer instanceof PullTransformer) {
+ // For intermediate node, set data type to null
+ result = ((PullTransformer)transformer).transform(result, context);
+ } else if (transformer instanceof PushTransformer) {
+ DataPipe dataPipe = (i < size - 1) ? (DataPipe)path.get(++i) : null;
+ ((PushTransformer)transformer).transform(result, dataPipe.getSink(), context);
+ result = dataPipe.getResult();
+ }
+ i++;
+ }
+
+ return result;
+ }
+
+ private TransformationContext createTransformationContext(DataType sourceDataType,
+ DataType targetDataType,
+ int size,
+ int index,
+ Transformer transformer,
+ Map<Class<?>, Object> metadata) {
+ DataType sourceType =
+ (index == 0) ? sourceDataType : new DataType<Object>(transformer.getSourceDataBinding(),
+ Object.class, null);
+ DataType targetType =
+ (index == size - 1) ? targetDataType : new DataType<Object>(transformer.getTargetDataBinding(),
+ Object.class, null);
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ TransformationContext context =
+ new TransformationContextImpl(sourceType, targetType, classLoader, metadata);
+ return context;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void mediate(Object source,
+ Object target,
+ DataType sourceDataType,
+ DataType targetDataType,
+ Map<Class<?>, Object> metadata) {
+ if (source == null) {
+ // Shortcut for null value
+ return;
+ }
+ if (sourceDataType == null) {
+ sourceDataType = dataBindingRegistry.introspectType(source);
+ }
+ if (sourceDataType == null) {
+ return;
+ } else if (sourceDataType.equals(targetDataType)) {
+ return;
+ }
+
+ List<Transformer> path = getTransformerChain(sourceDataType, targetDataType);
+ Object result = source;
+ int size = path.size();
+ for (int i = 0; i < size; i++) {
+ Transformer transformer = path.get(i);
+ TransformationContext context =
+ createTransformationContext(sourceDataType, targetDataType, size, i, transformer, metadata);
+
+ if (transformer instanceof PullTransformer) {
+ result = ((PullTransformer)transformer).transform(result, context);
+ } else if (transformer instanceof PushTransformer) {
+ DataPipe dataPipe = (i < size - 1) ? (DataPipe)path.get(++i) : null;
+ Object sink = dataPipe != null ? dataPipe.getSink() : target;
+ ((PushTransformer)transformer).transform(result, sink, context);
+ result = (dataPipe != null) ? dataPipe.getResult() : null;
+ }
+ }
+ }
+
+ private List<Transformer> getTransformerChain(DataType sourceDataType, DataType targetDataType) {
+ String sourceId = sourceDataType.getDataBinding();
+ String targetId = targetDataType.getDataBinding();
+ List<Transformer> path = transformerRegistry.getTransformerChain(sourceId, targetId);
+ if (path == null) {
+ TransformationException ex = new TransformationException("No path found for the transformation");
+ ex.addContextName("Source: " + sourceId);
+ ex.addContextName("Target: " + targetId);
+ throw ex;
+ }
+ return path;
+ }
+
+ /**
+ * @return the dataBindingRegistry
+ */
+ public DataBindingRegistry getDataBindingRegistry() {
+ return dataBindingRegistry;
+ }
+
+ /**
+ * @return the transformerRegistry
+ */
+ public TransformerRegistry getTransformerRegistry() {
+ return transformerRegistry;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/Output2OutputTransformer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/Output2OutputTransformer.java
new file mode 100644
index 0000000000..ef5798511a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/Output2OutputTransformer.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import java.util.List;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.databinding.DataBinding;
+import org.apache.tuscany.spi.databinding.Mediator;
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.WrapperHandler;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.apache.tuscany.spi.idl.ElementInfo;
+import org.apache.tuscany.spi.idl.XMLType;
+import org.apache.tuscany.spi.model.DataType;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.WrapperInfo;
+import org.osoa.sca.annotations.Service;
+
+/**
+ * This is a special transformer to transform the output from one IDL to the
+ * other one
+ */
+@Service(Transformer.class)
+public class Output2OutputTransformer extends TransformerExtension<Object, Object> implements
+ PullTransformer<Object, Object> {
+
+ protected Mediator mediator;
+
+ /**
+ * @param wrapperHandler
+ */
+ public Output2OutputTransformer() {
+ super();
+ }
+
+ /**
+ * @param mediator the mediator to set
+ */
+ @Autowire
+ public void setMediator(Mediator mediator) {
+ this.mediator = mediator;
+ }
+
+ @Override
+ public String getSourceDataBinding() {
+ return DataBinding.IDL_OUTPUT;
+ }
+
+ @Override
+ public String getTargetDataBinding() {
+ return DataBinding.IDL_OUTPUT;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.extension.TransformerExtension#getSourceType()
+ */
+ @Override
+ protected Class getSourceType() {
+ return Object.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.extension.TransformerExtension#getTargetType()
+ */
+ @Override
+ protected Class getTargetType() {
+ return Object.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.Transformer#getWeight()
+ */
+ public int getWeight() {
+ return 10;
+ }
+
+ private WrapperHandler getWapperHandler(Operation<?> operation) {
+ String dataBindingId;
+ dataBindingId = operation.getDataBinding();
+ DataBinding dataBinding = mediator.getDataBindingRegistry().getDataBinding(dataBindingId);
+ WrapperHandler wrapperHandler = dataBinding == null ? null : dataBinding.getWrapperHandler();
+ if (wrapperHandler == null) {
+ throw new TransformationException(
+ "No wrapper handler is provided for databinding: " + dataBindingId);
+ }
+ return wrapperHandler;
+ }
+
+ private WrapperHandler getWapperHandler(String dataBindingId) {
+ DataBinding dataBinding = mediator.getDataBindingRegistry().getDataBinding(dataBindingId);
+ return dataBinding == null ? null : dataBinding.getWrapperHandler();
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object transform(Object response, TransformationContext context) {
+ try {
+ DataType<DataType> sourceType = context.getSourceDataType();
+ Operation<?> sourceOp = (Operation<?>)sourceType.getOperation();
+ boolean sourceWrapped = sourceOp != null && sourceOp.isWrapperStyle();
+ WrapperHandler sourceWrapperHandler = null;
+ if (sourceWrapped) {
+ sourceWrapperHandler = getWapperHandler(sourceOp);
+ }
+
+ DataType<DataType> targetType = context.getTargetDataType();
+ Operation<?> targetOp = (Operation<?>)targetType.getOperation();
+ boolean targetWrapped = targetOp != null && targetOp.isWrapperStyle();
+ WrapperHandler targetWrapperHandler = null;
+ if (targetWrapped) {
+ targetWrapperHandler = getWapperHandler(targetOp);
+ }
+
+ if ((!sourceWrapped) && targetWrapped) {
+ // Unwrapped --> Wrapped
+ WrapperInfo wrapper = targetOp.getWrapper();
+ Object targetWrapper =
+ targetWrapperHandler.create(wrapper.getOutputWrapperElement(), context);
+
+ List<ElementInfo> childElements = wrapper.getOutputChildElements();
+ if (childElements.isEmpty()) {
+ // void output
+ return targetWrapper;
+ }
+ ElementInfo argElement = childElements.get(0);
+ DataType<XMLType> argType = wrapper.getUnwrappedOutputType();
+ Object child = response;
+ child = mediator.mediate(response, sourceType.getLogical(), argType, context.getMetadata());
+ targetWrapperHandler.setChild(targetWrapper, 0, argElement, child);
+ return targetWrapper;
+ } else if (sourceWrapped && (!targetWrapped)) {
+ // Wrapped to Unwrapped
+ Object sourceWrapper = response;
+ List<ElementInfo> childElements = sourceOp.getWrapper().getOutputChildElements();
+ if (childElements.isEmpty()) {
+ // The void output
+ return null;
+ }
+ targetWrapperHandler = getWapperHandler(targetType.getLogical().getDataBinding());
+ if (targetWrapperHandler != null) {
+ ElementInfo wrapperElement = sourceOp.getWrapper().getInputWrapperElement();
+ // Object targetWrapper =
+ // targetWrapperHandler.create(wrapperElement, context);
+ DataType<XMLType> targetWrapperType =
+ new DataType<XMLType>(targetType.getLogical().getDataBinding(), Object.class,
+ new XMLType(wrapperElement));
+ Object targetWrapper =
+ mediator.mediate(sourceWrapper, sourceType.getLogical(), targetWrapperType, context
+ .getMetadata());
+ return targetWrapperHandler.getChildren(targetWrapper).get(0);
+ } else {
+ Object child = sourceWrapperHandler.getChildren(sourceWrapper).get(0);
+ DataType<?> childType = sourceOp.getWrapper().getUnwrappedOutputType();
+ return mediator.mediate(child, childType, targetType.getLogical(), context.getMetadata());
+ }
+ } else {
+ // FIXME: Do we want to handle wrapped to wrapped?
+ return mediator.mediate(response, sourceType.getLogical(), targetType.getLogical(), context
+ .getMetadata());
+ }
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/PassByValueInterceptor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/PassByValueInterceptor.java
new file mode 100644
index 0000000000..c891ff7a61
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/PassByValueInterceptor.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.databinding.DataBinding;
+import org.apache.tuscany.spi.databinding.DataBindingRegistry;
+import org.apache.tuscany.spi.model.DataType;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+
+/**
+ * An interceptor to enforce pass-by-value semantics for remotable interfaces
+ *
+ * @version $Rev$ $Date$
+ */
+public class PassByValueInterceptor implements Interceptor {
+ private DataBindingRegistry registry;
+ private DataBinding[] parameterDatabindings;
+ private DataBinding resultDataBinding;
+
+ private Interceptor next;
+
+ public PassByValueInterceptor(DataBindingRegistry registry) {
+ this.registry = registry;
+ }
+
+ public Interceptor getNext() {
+ return next;
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+
+ public void setNext(Interceptor next) {
+ this.next = next;
+ }
+
+ public Message invoke(Message msg) {
+ Object obj = msg.getBody();
+ msg.setBody(copy((Object[])obj));
+ Message result = getNext().invoke(msg);
+
+ if (!result.isFault()) {
+ result.setBody(copy(result.getBody(), getResultDataBinding()));
+ }
+ return result;
+ }
+
+ public Object[] copy(Object[] args) {
+ if (args == null) {
+ return null;
+ }
+ Object[] copiedArgs = new Object[args.length];
+ Map<Object, Object> map = new IdentityHashMap<Object, Object>();
+ for (int i = 0; i < args.length; i++) {
+ if (args[i] == null) {
+ copiedArgs[i] = null;
+ } else {
+ Object copiedArg = map.get(args[i]);
+ if (copiedArg != null) {
+ copiedArgs[i] = copiedArg;
+ } else {
+ DataBinding dataBinding =
+ (getParameterDatabindings() != null) ? getParameterDatabindings()[i] : null;
+ copiedArg = copy(args[i], dataBinding);
+ map.put(args[i], copiedArg);
+ copiedArgs[i] = copiedArg;
+ }
+ }
+ }
+ return copiedArgs;
+ }
+
+ public Object copy(Object arg, DataBinding argDataBinding) {
+ if (arg == null) {
+ return null;
+ }
+ Object copiedArg;
+ if (argDataBinding != null) {
+ copiedArg = argDataBinding.copy(arg);
+ } else {
+ copiedArg = arg;
+ DataType<?> dataType = registry.introspectType(arg);
+ if (dataType != null) {
+ DataBinding binding = registry.getDataBinding(dataType.getDataBinding());
+ if (binding != null) {
+ copiedArg = binding.copy(arg);
+ }
+ }
+ // FIXME: What to do if it's not recognized?
+ }
+ return copiedArg;
+ }
+
+ public DataBinding[] getParameterDatabindings() {
+ return parameterDatabindings;
+ }
+
+ public void setParameterDatabindings(DataBinding[] dataBindings) {
+ this.parameterDatabindings = dataBindings;
+ }
+
+ public DataBinding getResultDataBinding() {
+ return resultDataBinding;
+ }
+
+ public void setResultDataBinding(DataBinding retDataBinding) {
+ this.resultDataBinding = retDataBinding;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/PassByValueWirePostProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/PassByValueWirePostProcessor.java
new file mode 100644
index 0000000000..a95b0ef073
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/PassByValueWirePostProcessor.java
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.databinding.DataBinding;
+import org.apache.tuscany.spi.databinding.DataBindingRegistry;
+import org.apache.tuscany.spi.extension.AtomicComponentExtension;
+import org.apache.tuscany.spi.model.DataType;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.WirePostProcessorExtension;
+
+/**
+ * This processor is responsible for enforcing the pass-by-value semantics
+ * required of Remotable interfaces. This is done by adding a pass-by-value
+ * interceptor to the inbound invocation chain of a target if the target
+ * interface is Remotable.
+ *
+ * @version $Rev$ $Date$
+ */
+public class PassByValueWirePostProcessor extends WirePostProcessorExtension {
+
+ private DataBindingRegistry dataBindingRegistry;
+
+ public PassByValueWirePostProcessor() {
+ super();
+ }
+
+ /**
+ * @param dataBindingRegistry the dataBindingRegistry to set
+ */
+ @Autowire
+ public void setDataBindingRegistry(DataBindingRegistry dataBindingRegistry) {
+ this.dataBindingRegistry = dataBindingRegistry;
+ }
+
+ public void process(OutboundWire source, InboundWire target) {
+ PassByValueInterceptor interceptor;
+ Operation<?> targetOperation;
+ Operation<?> sourceOperation;
+ DataBinding[] argsDataBindings;
+ DataBinding resultDataBinding;
+
+ boolean implAllowsPBR = false;
+ boolean methodAllowsPBR = false;
+
+ // if the source is a service binding or the target is a reference
+ // binding do no
+ // add interceptor since the bindings will ensure passbyvalue semantics
+ if (!(source.getContainer() instanceof ServiceBinding || target.getContainer() instanceof ReferenceBinding)) {
+
+ if (target.getContainer() instanceof AtomicComponentExtension) {
+ implAllowsPBR = ((AtomicComponentExtension)target.getContainer()).isAllowsPassByReference();
+ }
+
+ Map<Operation<?>, InboundInvocationChain> chains = target.getInvocationChains();
+ for (Map.Entry<Operation<?>, InboundInvocationChain> entry : chains.entrySet()) {
+ targetOperation = entry.getKey();
+ methodAllowsPBR = false;
+
+ if (target.getContainer() instanceof AtomicComponentExtension) {
+ methodAllowsPBR =
+ ((AtomicComponentExtension)target.getContainer()).getPassByReferenceMethods()
+ .contains(targetOperation.getName());
+ }
+
+ if (target.getServiceContract().isRemotable() && (!implAllowsPBR && !methodAllowsPBR)) {
+ sourceOperation =
+ getSourceOperation(source.getInvocationChains().keySet(), targetOperation.getName());
+
+ if (null != sourceOperation) {
+ argsDataBindings = getParameterDataBindings(sourceOperation);
+ resultDataBinding = getResultDataBinding(sourceOperation);
+ interceptor = new PassByValueInterceptor(dataBindingRegistry);
+ interceptor.setParameterDatabindings(argsDataBindings);
+ interceptor.setResultDataBinding(resultDataBinding);
+ source.getInvocationChains().get(sourceOperation).addInterceptor(0, interceptor);
+ /*
+ * tailInterceptor =
+ * source.getInvocationChains().get(sourceOperation).getTailInterceptor();
+ * if (tailInterceptor != null) {
+ * tailInterceptor.setNext(passByValueInterceptor); }
+ */
+ }
+ }
+ }
+
+ // Check if there's a callback
+ Map callbackOperations = source.getServiceContract().getCallbackOperations();
+ implAllowsPBR = false;
+
+ if (callbackOperations != null && !callbackOperations.isEmpty()) {
+ if (source.getContainer() instanceof AtomicComponentExtension) {
+ implAllowsPBR = ((AtomicComponentExtension)source.getContainer()).isAllowsPassByReference();
+ }
+
+ Object targetAddress = source.getContainer().getName();
+ Map<Operation<?>, InboundInvocationChain> callbackChains = source.getTargetCallbackInvocationChains();
+ for (Map.Entry<Operation<?>, InboundInvocationChain> entry : callbackChains.entrySet()) {
+ targetOperation = entry.getKey();
+ methodAllowsPBR = false;
+
+ if (source.getContainer() instanceof AtomicComponentExtension) {
+ methodAllowsPBR =
+ ((AtomicComponentExtension)source.getContainer()).getPassByReferenceMethods()
+ .contains(targetOperation.getName());
+ }
+
+ if (source.getServiceContract().isRemotable() && (!implAllowsPBR && !methodAllowsPBR)) {
+ sourceOperation =
+ getSourceOperation(target.getSourceCallbackInvocationChains(targetAddress).keySet(),
+ targetOperation.getName());
+
+ argsDataBindings = getParameterDataBindings(targetOperation);
+ resultDataBinding = getResultDataBinding(targetOperation);
+
+ interceptor = new PassByValueInterceptor(dataBindingRegistry);
+ interceptor.setParameterDatabindings(argsDataBindings);
+ interceptor.setResultDataBinding(resultDataBinding);
+
+ entry.getValue().addInterceptor(0, interceptor);
+ /*
+ * tailInterceptor =
+ * target.getSourceCallbackInvocationChains(targetAddress).get(sourceOperation)
+ * .getTailInterceptor(); if (tailInterceptor != null) {
+ * tailInterceptor.setNext(passByValueInterceptor); }
+ */
+ }
+ }
+ }
+ }
+ }
+
+ public void process(InboundWire source, OutboundWire target) {
+ // to be done if required..
+ }
+
+ private Operation getSourceOperation(Set<Operation<?>> operations, String operationName) {
+ for (Operation<?> op : operations) {
+ if (op.getName().equals(operationName)) {
+ return op;
+ }
+ }
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ private DataBinding[] getParameterDataBindings(Operation operation) {
+ List<DataType<?>> argumentTypes = (List<DataType<?>>)operation.getInputType().getLogical();
+ DataBinding[] argDataBindings = new DataBinding[argumentTypes.size()];
+ int count = 0;
+ for (DataType argType : argumentTypes) {
+ argDataBindings[count++] = dataBindingRegistry.getDataBinding(argType.getDataBinding());
+ }
+ return argDataBindings;
+ }
+
+ private DataBinding getResultDataBinding(Operation operation) {
+ DataType<?> resultType = (DataType<?>)operation.getOutputType();
+ return dataBindingRegistry.getDataBinding(resultType.getDataBinding());
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/PipedTransformer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/PipedTransformer.java
new file mode 100755
index 0000000000..388ea710a7
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/PipedTransformer.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.impl;
+
+import org.apache.tuscany.spi.databinding.DataPipe;
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+
+/**
+ * A utility class to connect PushTransformer and DataPipe to create a
+ * PullTransformer
+ *
+ * @param <S> Source type
+ * @param <I> Intermidate type
+ * @param <R> Result type
+ */
+public class PipedTransformer<S, I, R> implements PullTransformer<S, R> {
+ private PushTransformer<S, I> pusher;
+
+ private DataPipe<I, R> pipe;
+
+ /**
+ * @param pumper
+ * @param pipe
+ */
+ public PipedTransformer(PushTransformer<S, I> pumper, DataPipe<I, R> pipe) {
+ super();
+ this.pusher = pumper;
+ this.pipe = pipe;
+ }
+
+ public R transform(S source, TransformationContext context) {
+ pusher.transform(source, pipe.getSink(), context);
+ return pipe.getResult();
+ }
+
+ public String getSourceDataBinding() {
+ return pusher.getSourceDataBinding();
+ }
+
+ public String getTargetDataBinding() {
+ return pipe.getTargetDataBinding();
+ }
+
+ public int getWeight() {
+ return pusher.getWeight() + pipe.getWeight();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/SimpleDataBinding.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/SimpleDataBinding.java
new file mode 100644
index 0000000000..b1550c9f0a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/SimpleDataBinding.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import org.osoa.sca.annotations.Property;
+
+import org.apache.tuscany.spi.databinding.extension.DataBindingExtension;
+import org.apache.tuscany.spi.loader.MissingResourceException;
+
+/**
+ * Simple databinding represented by a base java type. A SCDL property className is used to customize this component.
+ * <p/>
+ * The following illustrates how a simple data binding can be registered as a SCA component.
+ * <p/>
+ * <pre>
+ * &lt;component name="databinding.MyDataBinding"&gt;<br>
+ * &nbsp;&nbsp;&lt;system:implementation.java
+ * class="org.apache.tuscany.databinding.impl.SimpleDataBinding"/&gt;<br>
+ * &nbsp;&nbsp;&lt;property name="className"&gt;my.Type&lt;/property&gt;<br>
+ * &lt/component&gt;
+ * </pre>
+ *
+ * @version $Rv$ $Date$
+ */
+public class SimpleDataBinding extends DataBindingExtension {
+
+ public SimpleDataBinding(@Property(name = "className")String className) throws MissingResourceException {
+ super(resolve(className));
+ }
+
+ private static Class<?> resolve(String className) throws MissingResourceException {
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ try {
+ return Class.forName(className, false, classLoader);
+ } catch (ClassNotFoundException e) {
+ classLoader = SimpleDataBinding.class.getClassLoader();
+ try {
+ return Class.forName(className, false, classLoader);
+ } catch (ClassNotFoundException e1) {
+ throw new MissingResourceException(className, e1);
+ }
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/TransformationContextImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/TransformationContextImpl.java
new file mode 100755
index 0000000000..47f340097b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/TransformationContextImpl.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.impl;
+
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.model.DataType;
+
+public class TransformationContextImpl implements TransformationContext {
+ private DataType sourceDataType;
+
+ private DataType targetDataType;
+
+ private final Map<Class<?>, Object> metadata = new HashMap<Class<?>, Object>();
+
+ private WeakReference<ClassLoader> classLoaderRef;
+
+ public TransformationContextImpl() {
+ super();
+ setClassLoader(Thread.currentThread().getContextClassLoader());
+ }
+
+ public TransformationContextImpl(DataType sourceDataType,
+ DataType targetDataType,
+ ClassLoader classLoader,
+ Map<Class<?>, Object> metadata) {
+ super();
+ this.sourceDataType = sourceDataType;
+ this.targetDataType = targetDataType;
+ setClassLoader(classLoader);
+ if (metadata != null) {
+ this.metadata.putAll(metadata);
+ }
+ }
+
+ public DataType getSourceDataType() {
+ return sourceDataType;
+ }
+
+ public DataType getTargetDataType() {
+ return targetDataType;
+ }
+
+ public void setSourceDataType(DataType sourceDataType) {
+ this.sourceDataType = sourceDataType;
+ }
+
+ public void setTargetDataType(DataType targetDataType) {
+ this.targetDataType = targetDataType;
+ }
+
+ public final void setClassLoader(ClassLoader classLoader) {
+ this.classLoaderRef = new WeakReference<ClassLoader>(classLoader);
+ }
+
+ public ClassLoader getClassLoader() {
+ return classLoaderRef.get();
+ }
+
+ public Map<Class<?>, Object> getMetadata() {
+ return metadata;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/TransformerRegistryImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/TransformerRegistryImpl.java
new file mode 100755
index 0000000000..6f5c6d0e73
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/impl/TransformerRegistryImpl.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.osoa.sca.annotations.EagerInit;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.databinding.DataBinding;
+import org.apache.tuscany.spi.databinding.DataBindingRegistry;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.TransformerRegistry;
+
+/**
+ * @version $Rev$ $Date$
+ */
+@EagerInit
+public class TransformerRegistryImpl implements TransformerRegistry {
+ private DataBindingRegistry dataBindingRegistry;
+
+ private final DirectedGraph<Object, Transformer> graph = new DirectedGraph<Object, Transformer>();
+
+ public void registerTransformer(String sourceType, String resultType, int weight, Transformer transformer) {
+ graph.addEdge(sourceType, resultType, transformer, weight);
+ }
+
+ public void registerTransformer(Transformer transformer) {
+ graph.addEdge(transformer.getSourceDataBinding(),
+ transformer.getTargetDataBinding(),
+ transformer,
+ transformer.getWeight());
+ }
+
+ public boolean unregisterTransformer(String sourceType, String resultType) {
+ return graph.removeEdge(sourceType, resultType);
+ }
+
+ public Transformer getTransformer(String sourceType, String resultType) {
+ DirectedGraph<Object, Transformer>.Edge edge = graph.getEdge(sourceType, resultType);
+ return (edge == null) ? null : edge.getValue();
+ }
+
+ public List<Transformer> getTransformerChain(String sourceType, String resultType) {
+ String source = normalize(sourceType);
+ String result = normalize(resultType);
+ List<Transformer> transformers = new ArrayList<Transformer>();
+ DirectedGraph<Object, Transformer>.Path path = graph.getShortestPath(source, result);
+ if (path == null) {
+ return null;
+ }
+ for (DirectedGraph<Object, Transformer>.Edge edge : path.getEdges()) {
+ transformers.add(edge.getValue());
+ }
+ return transformers;
+ }
+
+ public String toString() {
+ return graph.toString();
+ }
+
+ /**
+ * @param dataBindingRegistry the dataBindingRegistry to set
+ */
+ @Autowire
+ public void setDataBindingRegistry(DataBindingRegistry dataBindingRegistry) {
+ this.dataBindingRegistry = dataBindingRegistry;
+ }
+
+ /**
+ * Normalize the id to a name of a data binding as databindings may have aliases
+ * @param id
+ * @return
+ */
+ private String normalize(String id) {
+ if (dataBindingRegistry != null) {
+ DataBinding dataBinding = dataBindingRegistry.getDataBinding(id);
+ return dataBinding == null ? id : dataBinding.getName();
+ } else {
+ return id;
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/DOMNode2JavaBeanTransformer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/DOMNode2JavaBeanTransformer.java
new file mode 100644
index 0000000000..80f9fa04da
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/DOMNode2JavaBeanTransformer.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.javabeans;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Transformer to convert data from DOM Node to JavaBean
+ */
+@Service(Transformer.class)
+public class DOMNode2JavaBeanTransformer extends XML2JavaBeanTransformer<Node> {
+
+ @Override
+ public Node getRootElement(Node element) throws XML2JavaMapperException {
+ if (element instanceof Document) {
+ return ((Document)element).getDocumentElement();
+ } else {
+ return element;
+ }
+
+ }
+
+ @Override
+ public List<Node> getChildElements(Node parent) throws XML2JavaMapperException {
+ NodeList nodeList = parent.getChildNodes();
+ List<Node> nodeArrayList = new ArrayList<Node>(nodeList.getLength());
+ for (int count = 0; count < nodeList.getLength(); ++count) {
+ nodeArrayList.add(nodeList.item(count));
+ }
+
+ return nodeArrayList;
+ }
+
+ @Override
+ public String getElementName(Node element) throws XML2JavaMapperException {
+ return element.getLocalName();
+ }
+
+ @Override
+ public String getText(Node element) throws XML2JavaMapperException {
+ if (element instanceof Document) {
+ element = ((Document)element).getDocumentElement();
+ }
+ return element.getTextContent();
+ }
+
+ @Override
+ public boolean isTextElement(Node element) throws XML2JavaMapperException {
+ return element.getNodeType() == Node.TEXT_NODE;
+ }
+
+ public Class getSourceType() {
+ return Node.class;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/Java2XMLMapperException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/Java2XMLMapperException.java
new file mode 100644
index 0000000000..3f88a4ee89
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/Java2XMLMapperException.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.javabeans;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.api.TuscanyRuntimeException;
+
+/**
+ * This exception is used to encapsulate and rethrow exceptions that arise out
+ * of converting JavaBean objects to XML
+ */
+public class Java2XMLMapperException extends TuscanyRuntimeException {
+ private static final long serialVersionUID = 6811924384399578686L;
+
+ private QName xmlElementName;
+ private String javaFieldName;
+ private Class javaType;
+
+ public Java2XMLMapperException(String message) {
+ super(message);
+ }
+
+ public Java2XMLMapperException(Throwable cause) {
+ super(cause);
+ }
+
+ public String getJavaFieldName() {
+ return javaFieldName;
+ }
+
+ public void setJavaFieldName(String javaFieldName) {
+ this.javaFieldName = javaFieldName;
+ }
+
+ public Class getJavaType() {
+ return javaType;
+ }
+
+ public void setJavaType(Class javaType) {
+ this.javaType = javaType;
+ }
+
+ public QName getXmlElementName() {
+ return xmlElementName;
+ }
+
+ public void setXmlElementName(QName xmlElementName) {
+ this.xmlElementName = xmlElementName;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2DOMNodeTransformer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2DOMNodeTransformer.java
new file mode 100644
index 0000000000..5925e87b69
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2DOMNodeTransformer.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.javabeans;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.DOMHelper;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * Transformer to convert data from a JavaBean object to DOM Node
+ */
+@Service(Transformer.class)
+public class JavaBean2DOMNodeTransformer extends JavaBean2XMLTransformer<Node> {
+
+ public static final String COLON = ":";
+ private Document factory;
+
+ public JavaBean2DOMNodeTransformer() {
+ super();
+ try {
+ factory = DOMHelper.newDocument();
+ } catch (ParserConfigurationException e) {
+ throw new Java2XMLMapperException(e);
+ }
+ }
+
+ @Override
+ public void appendChild(Node parentElement, Node childElement) throws Java2XMLMapperException {
+ parentElement.appendChild(childElement);
+ }
+
+ @Override
+ public Node createElement(QName qName) throws Java2XMLMapperException {
+ String qualifedName =
+ (qName.getPrefix() == null || qName.getPrefix().length() <= 0) ? qName.getLocalPart()
+ : qName.getPrefix() + COLON + qName.getLocalPart();
+ return factory.createElementNS(qName.getNamespaceURI(), qualifedName);
+ }
+
+ @Override
+ public Node createText(String textData) throws Java2XMLMapperException {
+ return factory.createTextNode(textData);
+ }
+
+ public Class getTargetType() {
+ return Node.class;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2XMLStreamReader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2XMLStreamReader.java
new file mode 100644
index 0000000000..770c8e7254
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2XMLStreamReader.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.javabeans;
+
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.core.databinding.xml.BeanUtil;
+import org.apache.tuscany.core.databinding.xml.XMLDocumentStreamReader;
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+
+@Service(Transformer.class)
+public class JavaBean2XMLStreamReader extends TransformerExtension<Object, XMLStreamReader> implements
+ PullTransformer<Object, XMLStreamReader> {
+
+ public XMLStreamReader transform(Object source, TransformationContext context) {
+ try {
+ return new XMLDocumentStreamReader(BeanUtil.getXMLStreamReader(source));
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return Object.class;
+ }
+
+ public Class getTargetType() {
+ return XMLStreamReader.class;
+ }
+
+ public int getWeight() {
+ return 50;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2XMLTransformer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2XMLTransformer.java
new file mode 100644
index 0000000000..c0199eee95
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2XMLTransformer.java
@@ -0,0 +1,226 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.javabeans;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+
+/**
+ * Transformer to convert data from a JavaBean object to xml
+ */
+@Service(Transformer.class)
+public abstract class JavaBean2XMLTransformer<T> extends TransformerExtension<Object, T> implements
+ PullTransformer<Object, T> {
+
+ public static final String GET = "get";
+ public static final String PREFIX = "n";
+ public static final String PERIOD = ".";
+ public static final String FWD_SLASH = "/";
+ public static final String HTTP = "http://";
+ private static int prefixCount = 1;
+
+ protected SimpleTypeMapperExtension mapper;
+
+ public JavaBean2XMLTransformer() {
+ this.mapper = new SimpleTypeMapperExtension();
+ }
+
+ public T transform(Object source, TransformationContext context) {
+ QName rootElementName = (QName)context.getTargetDataType().getMetadata("RootElementName");
+ if (rootElementName == null) {
+ rootElementName = new QName(resolveRootElementName(source.getClass()));
+ }
+ T root = createElement(rootElementName);
+ appendChildElements(root,
+ resolveElementName(source.getClass()),
+ source.getClass(),
+ source,
+ context);
+ return root;
+ }
+
+ private void appendChildElements(T parent,
+ QName elementName,
+ Class javaType,
+ Object javaObject,
+ TransformationContext context) {
+ T element = null;
+ if (javaObject != null) {
+ if (javaType.isPrimitive() || isSimpleJavaType(javaObject)) {
+ appendChild(parent, createText(mapper.toXMLLiteral(null, javaObject, context)));
+ } else if (javaType.isArray()) {
+ boolean arrayDone = false;
+ Object arrayObject = null;
+ for (int count = 0; !arrayDone; ++count) {
+ try {
+ arrayObject = Array.get(javaObject, count);
+ element = createElement(elementName);
+ appendChild(parent, element);
+ appendChildElements(element,
+ elementName,
+ javaType.getComponentType(),
+ arrayObject,
+ context);
+ } catch (ArrayIndexOutOfBoundsException e1) {
+ arrayDone = true;
+ }
+ }
+ } else {
+ Field[] javaFields = javaType.getFields();
+ for (Field aField : javaFields) {
+ try {
+ QName fieldElementName = new QName(aField.getName());
+ if (!aField.getType().isArray()) {
+ element = createElement(fieldElementName);
+ appendChild(parent, element);
+ appendChildElements(element,
+ fieldElementName,
+ aField.getType(),
+ aField.get(javaObject),
+ context);
+ } else {
+ appendChildElements(parent,
+ fieldElementName,
+ aField.getType(),
+ aField.get(javaObject),
+ context);
+ }
+ } catch (IllegalAccessException e) {
+ Java2XMLMapperException java2xmlEx = new Java2XMLMapperException(e);
+ java2xmlEx.setJavaFieldName(aField.getName());
+ java2xmlEx.setJavaType(javaType);
+ throw java2xmlEx;
+ }
+ }
+
+ Method[] methods = javaType.getDeclaredMethods();
+ String fieldName = null;
+ for (Method aMethod : methods) {
+ try {
+ if (Modifier.isPublic(aMethod.getModifiers()) && aMethod.getName().startsWith(GET)
+ && aMethod.getParameterTypes().length == 0) {
+ fieldName = resolveFieldFromMethod(aMethod.getName());
+ try {
+ javaType.getField(fieldName);
+ } catch (NoSuchFieldException e) {
+ QName fieldElementName = new QName(fieldName);
+ if (aMethod.getReturnType().isArray()) {
+ appendChildElements(parent, fieldElementName, aMethod.getReturnType(), aMethod
+ .invoke(javaObject, new Object[0]), context);
+ } else {
+ element = createElement(fieldElementName);
+ appendChild(parent, element);
+ appendChildElements(element, fieldElementName, aMethod.getReturnType(), aMethod
+ .invoke(javaObject, new Object[0]), context);
+ }
+ }
+ }
+ } catch (IllegalAccessException e) {
+ Java2XMLMapperException java2xmlEx = new Java2XMLMapperException(e);
+ java2xmlEx.setJavaFieldName(fieldName);
+ java2xmlEx.setJavaType(javaType);
+ throw java2xmlEx;
+ } catch (InvocationTargetException e) {
+ Java2XMLMapperException java2xmlEx = new Java2XMLMapperException(e);
+ java2xmlEx.setJavaFieldName(fieldName);
+ java2xmlEx.setJavaType(javaType);
+ throw java2xmlEx;
+ }
+ }
+ }
+ }
+ }
+
+ public Class getSourceType() {
+ return Object.class;
+ }
+
+ private boolean isSimpleJavaType(Object javaObject) {
+ if (javaObject instanceof String) {
+ return true;
+ }
+ if (javaObject instanceof Byte || javaObject instanceof Character
+ || javaObject instanceof Short
+ || javaObject instanceof Integer
+ || javaObject instanceof Long
+ || javaObject instanceof Float
+ || javaObject instanceof Double) {
+ return true;
+ }
+ if (javaObject instanceof GregorianCalendar || javaObject instanceof Date
+ || javaObject instanceof XMLGregorianCalendar
+ || javaObject instanceof byte[]
+ || javaObject instanceof QName) {
+ return true;
+ }
+ return false;
+ }
+
+ private String resolveRootElementName(Class javaType) {
+ if (javaType.isArray()) {
+ return javaType.getComponentType().getSimpleName() + "_collection";
+ } else {
+ return javaType.getSimpleName() + "_instance";
+ }
+ }
+
+
+ private QName resolveElementName(Class javaType) {
+ if (javaType.isArray()) {
+ return new QName(javaType.getComponentType().getSimpleName());
+ } else {
+ return new QName(javaType.getSimpleName());
+ }
+ }
+
+ private String resolveFieldFromMethod(String methodName) {
+ StringBuffer fieldName = new StringBuffer();
+ fieldName.append(Character.toLowerCase(methodName.charAt(GET.length())));
+ fieldName.append(methodName.substring(GET.length() + 1));
+ return fieldName.toString();
+ }
+
+ public String getNexPrefix() {
+ return PREFIX + prefixCount++;
+ }
+
+ @Override
+ public int getWeight() {
+ return JavaBeansDataBinding.HEAVY_WEIGHT;
+ }
+
+ public abstract T createElement(QName qName) throws Java2XMLMapperException;
+ public abstract T createText(String textData) throws Java2XMLMapperException;
+ public abstract void appendChild(T parentElement, T childElement) throws Java2XMLMapperException;
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBeansDataBinding.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBeansDataBinding.java
new file mode 100644
index 0000000000..58c3728202
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/JavaBeansDataBinding.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.javabeans;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.OutputStream;
+import java.io.Serializable;
+
+import org.apache.tuscany.spi.databinding.DataBinding;
+import org.apache.tuscany.spi.databinding.extension.DataBindingExtension;
+import org.osoa.sca.annotations.Service;
+
+/**
+ * DataBinding for JavaBeans
+ */
+@Service(DataBinding.class)
+public class JavaBeansDataBinding extends DataBindingExtension {
+ /**
+ * Defining a weight to a very high number so that the transformer won't be picked
+ * up by other paths unless it's the only available path
+ */
+ public static final int HEAVY_WEIGHT = 10000;
+ public static final String NAME = Object.class.getName();
+
+ public JavaBeansDataBinding() {
+ super(NAME, Object.class);
+ }
+
+ public Object copy(Object arg) {
+ if (arg == null) {
+ return null;
+ }
+ final Class clazz = arg.getClass();
+ if (String.class == clazz || clazz.isPrimitive()
+ || Number.class.isAssignableFrom(clazz)
+ || Boolean.class.isAssignableFrom(clazz)
+ || Character.class.isAssignableFrom(clazz)
+ || Byte.class.isAssignableFrom(clazz)) {
+ // Immutable classes
+ return arg;
+ }
+ try {
+ if (arg instanceof Serializable) {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = getObjectOutputStream(bos);
+ oos.writeObject(arg);
+ oos.close();
+ bos.close();
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ ObjectInputStream ois = getObjectInputStream(bis, clazz.getClassLoader());
+ Object objectCopy = ois.readObject();
+ ois.close();
+ bis.close();
+ return objectCopy;
+ } else {
+ // return arg;
+ throw new IllegalArgumentException("Pass-by-value is not supported for the given object");
+ }
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Pass-by-value is not supported for the given object", e);
+ }
+ }
+
+ protected ObjectOutputStream getObjectOutputStream(OutputStream os) throws IOException {
+ return new ObjectOutputStream(os);
+ }
+
+ protected ObjectInputStream getObjectInputStream(InputStream is, final ClassLoader cl) throws IOException {
+ ObjectInputStream ois = new ObjectInputStream(is) {
+ @Override
+ protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
+ try {
+ return Class.forName(desc.getName(), false, cl);
+ } catch (ClassNotFoundException e) {
+ return super.resolveClass(desc);
+ }
+ }
+
+ };
+ return ois;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/XML2JavaBeanTransformer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/XML2JavaBeanTransformer.java
new file mode 100644
index 0000000000..2013502851
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/XML2JavaBeanTransformer.java
@@ -0,0 +1,300 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.javabeans;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.apache.tuscany.spi.idl.ElementInfo;
+import org.apache.tuscany.spi.idl.TypeInfo;
+import org.apache.tuscany.spi.idl.XMLType;
+import org.osoa.sca.annotations.Service;
+
+/**
+ * Transformer to convert data from XML to JavaBean
+ */
+@Service(Transformer.class)
+public abstract class XML2JavaBeanTransformer<T> extends TransformerExtension<T, Object> implements
+ PullTransformer<T, Object> {
+
+ public static final String SET = "set";
+
+ protected SimpleTypeMapperExtension mapper;
+
+ public XML2JavaBeanTransformer() {
+ this.mapper = new SimpleTypeMapperExtension();
+ }
+
+ @Override
+ public int getWeight() {
+ return JavaBeansDataBinding.HEAVY_WEIGHT;
+ }
+
+ public Object transform(T source, TransformationContext context) {
+ XMLType xmlType = (XMLType) context.getSourceDataType().getLogical();
+ return toJavaObject(xmlType.getTypeName(), getRootElement(source), context);
+ }
+
+ public Object toJavaObject(QName xmlType, T xmlElement, TransformationContext context) {
+ if (SimpleTypeMapperExtension.isSimpleXSDType(xmlType)) {
+ return mapper.toJavaObject(xmlType, getText(xmlElement), context);
+ } else {
+ Class<?> javaType = (Class<?>)context.getTargetDataType().getPhysical();
+ return createJavaObject(xmlElement, javaType, context);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private <L> L createJavaObject(T element, Class<L> javaType, TransformationContext context)
+ throws XML2JavaMapperException {
+ List<T> childElements = getChildElements(element);
+ if (childElements.size() == 1 && isTextElement(childElements.get(0))) {
+ return (L) mapper.toJavaObject(mapper.getXMLType(javaType).getQName(),
+ getText(childElements.get(0)),
+ context);
+ } else {
+ String fieldName = null;
+ try {
+ L javaInstance = javaType.newInstance();
+ Map<Field, List<Object>> arrayFields = new Hashtable<Field, List<Object>>();
+ Map<Method, List<Object>> arraySetters = new Hashtable<Method, List<Object>>();
+ for (int count = 0; count < childElements.size(); ++count) {
+ if (!isTextElement(childElements.get(count))) {
+ fieldName = getElementName(childElements.get(count));
+ try {
+ Field javaField = javaType.getField(fieldName);
+ setFieldValue(javaInstance,
+ javaField,
+ childElements.get(count),
+ arrayFields,
+ context);
+
+ } catch (NoSuchFieldException e1) {
+ setFieldValueUsingSetter(javaType,
+ javaInstance,
+ fieldName,
+ childElements.get(count),
+ arraySetters,
+ context);
+ }
+ }
+ }
+
+ setArrayValues(javaInstance, arrayFields, arraySetters);
+ return javaInstance;
+ } catch (Exception e2) {
+ XML2JavaMapperException xml2JavaEx = new XML2JavaMapperException(e2);
+ xml2JavaEx.setJavaType(javaType);
+ xml2JavaEx.setJavaFieldName(fieldName);
+ throw xml2JavaEx;
+ }
+ }
+ }
+
+ private void setFieldValue(Object javaInstance,
+ Field javaField,
+ T fieldValue,
+ Map<Field, List<Object>> arrayFields,
+ TransformationContext context) throws IllegalAccessException {
+ Class<?> javaFieldType = (Class<?>) javaField.getType();
+
+ if (javaFieldType.isArray()) {
+ Class<?> componentType = javaFieldType.getComponentType();
+ List<Object> fldValueArray = arrayFields.get(javaField);
+ if (fldValueArray == null) {
+ fldValueArray = new ArrayList<Object>();
+ arrayFields.put(javaField, fldValueArray);
+ }
+ fldValueArray.add(createJavaObject(fieldValue, componentType, context));
+ } else {
+ javaField.setAccessible(true);
+ javaField.set(javaInstance, createJavaObject(fieldValue, javaFieldType, context));
+ }
+ }
+
+ private void setFieldValueUsingSetter(Class javaType,
+ Object javaInstance,
+ String fieldName,
+ T fieldValue,
+ Map<Method, List<Object>> arraySetters,
+ TransformationContext context) throws IllegalAccessException,
+ InvocationTargetException {
+ char firstChar = Character.toUpperCase(fieldName.charAt(0));
+ StringBuilder methodName = new StringBuilder(SET + fieldName);
+ methodName.setCharAt(SET.length(), firstChar);
+ boolean methodNotFound = true;
+
+ for (int methodCount = 0; methodNotFound && methodCount < javaType.getMethods().length; ++methodCount) {
+ Method aMethod = javaType.getMethods()[methodCount];
+ if (aMethod.getName().equals(methodName.toString())
+ && aMethod.getParameterTypes().length == 1) {
+ Class<?> paramType = aMethod.getParameterTypes()[0];
+
+ if (paramType.isArray()) {
+ Class<?> componentType = paramType.getComponentType();
+ List<Object> setterValueArray = arraySetters.get(aMethod);
+ if (setterValueArray == null) {
+ setterValueArray = new ArrayList<Object>();
+ arraySetters.put(aMethod, setterValueArray);
+ }
+ setterValueArray.add(createJavaObject(fieldValue, componentType, context));
+ } else {
+ aMethod.invoke(javaInstance, new Object[] {createJavaObject(fieldValue,
+ paramType,
+ context)});
+ }
+ methodNotFound = false;
+ }
+ }
+
+ if (methodNotFound) {
+ XML2JavaMapperException xml2JavaEx =
+ new XML2JavaMapperException("No field or setter method to configure xml data");
+ xml2JavaEx.setJavaFieldName(fieldName);
+ xml2JavaEx.setJavaType(javaType);
+ throw xml2JavaEx;
+ }
+ }
+
+ private void setArrayValues(Object javaInstance,
+ Map<Field, List<Object>> arrayFields,
+ Map<Method, List<Object>> arraySetters) throws IllegalAccessException,
+ InvocationTargetException {
+ if (arrayFields.size() > 0) {
+ for (Field javaField : arrayFields.keySet()) {
+ javaField.setAccessible(true);
+
+ if (javaField.getType().getComponentType().isPrimitive()) {
+ javaField.set(javaInstance, createPrimitiveArray(javaField.getType()
+ .getComponentType(),
+ arrayFields.get(javaField)));
+ } else {
+ javaField.set(javaInstance,
+ createNonPrimitiveArray(javaField.getType().getComponentType(),
+ arrayFields.get(javaField)));
+ }
+ }
+ }
+
+ if (arraySetters.size() > 0) {
+ for (Method aMethod : arraySetters.keySet()) {
+ Class paramType = aMethod.getParameterTypes()[0];
+ if (paramType.getComponentType().isPrimitive()) {
+ aMethod.invoke(javaInstance,
+ new Object[] {createPrimitiveArray(paramType.getComponentType(),
+ arraySetters.get(aMethod))});
+ } else {
+ aMethod.invoke(javaInstance,
+ new Object[] {createNonPrimitiveArray(paramType.getComponentType(),
+ arraySetters.get(aMethod))});
+ }
+ }
+ }
+ }
+
+ private Object createNonPrimitiveArray(Class fieldType, List values) {
+ Object objectArray = Array.newInstance(fieldType, values.size());
+ for (int count = 0; count < values.size(); ++count) {
+ Array.set(objectArray, count, values.get(count));
+ }
+ return objectArray;
+ }
+
+ private Object createPrimitiveArray(Class fieldType, List values) {
+ if (fieldType.isPrimitive()) {
+ if (fieldType.getName().equals("int")) {
+ int[] primitiveValues = new int[values.size()];
+ for (int count = 0; count < values.size(); ++count) {
+ primitiveValues[count] = ((Integer) values.get(count)).intValue();
+ }
+ return primitiveValues;
+ } else if (fieldType.getName().equals("float")) {
+ float[] primitiveValues = new float[values.size()];
+ for (int count = 0; count < values.size(); ++count) {
+ primitiveValues[count] = ((Float) values.get(count)).floatValue();
+ }
+ return primitiveValues;
+ } else if (fieldType.getName().equals("boolean")) {
+ boolean[] primitiveValues = new boolean[values.size()];
+ for (int count = 0; count < values.size(); ++count) {
+ primitiveValues[count] = ((Boolean) values.get(count)).booleanValue();
+ }
+ return primitiveValues;
+ } else if (fieldType.getName().equals("char")) {
+ char[] primitiveValues = new char[values.size()];
+ for (int count = 0; count < values.size(); ++count) {
+ primitiveValues[count] = ((Character) values.get(count)).charValue();
+ }
+ return primitiveValues;
+ } else if (fieldType.getName().equals("byte")) {
+ byte[] primitiveValues = new byte[values.size()];
+ for (int count = 0; count < values.size(); ++count) {
+ primitiveValues[count] = ((Byte) values.get(count)).byteValue();
+ }
+ return primitiveValues;
+ } else if (fieldType.getName().equals("short")) {
+ short[] primitiveValues = new short[values.size()];
+ for (int count = 0; count < values.size(); ++count) {
+ primitiveValues[count] = ((Short) values.get(count)).shortValue();
+ }
+ return primitiveValues;
+ } else if (fieldType.getName().equals("long")) {
+ long[] primitiveValues = new long[values.size()];
+ for (int count = 0; count < values.size(); ++count) {
+ primitiveValues[count] = ((Long) values.get(count)).longValue();
+ }
+ return primitiveValues;
+ } else if (fieldType.getName().equals("double")) {
+ double[] primitiveValues = new double[values.size()];
+ for (int count = 0; count < values.size(); ++count) {
+ primitiveValues[count] = ((Double) values.get(count)).doubleValue();
+ }
+ return primitiveValues;
+ }
+ }
+ return values;
+ }
+
+ public abstract String getText(T source) throws XML2JavaMapperException;
+
+ public abstract List<T> getChildElements(T parent) throws XML2JavaMapperException;
+
+ public abstract String getElementName(T element) throws XML2JavaMapperException;
+
+ public abstract boolean isTextElement(T element) throws XML2JavaMapperException;
+
+ public abstract T getRootElement(T element) throws XML2JavaMapperException;
+
+ public Class getTargetType() {
+ return Object.class;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/XML2JavaMapperException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/XML2JavaMapperException.java
new file mode 100644
index 0000000000..dfdd54084b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/javabeans/XML2JavaMapperException.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.javabeans;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.api.TuscanyRuntimeException;
+
+/**
+ * This exception is used to encapsulate and rethrow exceptions that arise out
+ * of converting XML Data to Java Objects.
+ */
+public class XML2JavaMapperException extends TuscanyRuntimeException {
+ private static final long serialVersionUID = 6596530102591630642L;
+
+ private QName xmlElementName;
+ private String javaFieldName;
+ private Class javaType;
+
+ public XML2JavaMapperException(String message) {
+ super(message);
+ }
+
+ public XML2JavaMapperException(Throwable cause) {
+ super(cause);
+ }
+
+ public QName getXmlElementName() {
+ return xmlElementName;
+ }
+
+ public void setXmlElementName(QName xmlElementName) {
+ this.xmlElementName = xmlElementName;
+ }
+
+ public String getJavaFieldName() {
+ return javaFieldName;
+ }
+
+ public void setJavaFieldName(String javaFieldName) {
+ this.javaFieldName = javaFieldName;
+ }
+
+ public Class getJavaType() {
+ return javaType;
+ }
+
+ public void setJavaType(Class javaType) {
+ this.javaType = javaType;
+ }
+
+ @Override
+ public String getMessage() {
+ return super.getMessage() + " <" + getJavaFieldName() + "> " + " in <" + getJavaType() + ">";
+ }
+
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/BeanUtil.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/BeanUtil.java
new file mode 100644
index 0000000000..34e3e07843
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/BeanUtil.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension;
+import org.apache.tuscany.spi.idl.TypeInfo;
+
+public final class BeanUtil {
+ private static final Object[] NULL = (Object[])null;
+ private static int nsCount = 1;
+
+ private static final SimpleTypeMapperExtension MAPPER = new SimpleTypeMapperExtension();
+
+ private BeanUtil() {
+ }
+
+ private static boolean isSimpleType(Class javaType) {
+ return MAPPER.getXMLType(javaType) != null;
+ }
+
+ private static String getStringValue(Object o) {
+ if (o == null) {
+ return null;
+ }
+ TypeInfo info = MAPPER.getXMLType(o.getClass());
+ if (info != null) {
+ return MAPPER.toXMLLiteral(info.getQName(), o, null);
+ } else {
+ return String.valueOf(o);
+ }
+ }
+
+ /**
+ * To Serilize Bean object this method is used, this will create an object
+ * array using given bean object
+ *
+ * @param beanObject
+ * @param beanName
+ */
+ public static XMLStreamReader getXMLStreamReader(Object beanObject, QName beanName) {
+ try {
+ ClassLoader cl = beanObject.getClass().getClassLoader();
+ if (cl == null) {
+ cl = ClassLoader.getSystemClassLoader();
+ }
+ String beanNS = beanName.getNamespaceURI();
+ String beanPrefix = beanName.getPrefix();
+ BeanInfo beanInfo = Introspector.getBeanInfo(beanObject.getClass());
+ PropertyDescriptor[] propDescs = beanInfo.getPropertyDescriptors();
+ Map<String, PropertyDescriptor> propertMap = new HashMap<String, PropertyDescriptor>();
+ for (int i = 0; i < propDescs.length; i++) {
+ PropertyDescriptor propDesc = propDescs[i];
+ propertMap.put(propDesc.getName(), propDesc);
+ }
+ List<String> properties = new ArrayList<String>(propertMap.keySet());
+ Collections.sort(properties);
+ List<NamedProperty> props = new ArrayList<NamedProperty>();
+ for (int i = 0; i < properties.size(); i++) {
+ String property = properties.get(i);
+ PropertyDescriptor propDesc = (PropertyDescriptor)propertMap.get(property);
+ if (propDesc == null) {
+ // JAM does bad thing so I need to add this
+ continue;
+ }
+ Class ptype = propDesc.getPropertyType();
+ if ("class".equals(property)) {
+ continue;
+ }
+ if (isSimpleType(ptype)) {
+ Object value = propDesc.getReadMethod().invoke(beanObject, NULL);
+ NamedProperty prop =
+ new NamedProperty(new QName(beanNS, property, beanPrefix), getStringValue(value));
+ props.add(prop);
+ } else if (ptype.isArray()) {
+ if (isSimpleType(ptype.getComponentType())) {
+ Object value = propDesc.getReadMethod().invoke(beanObject, NULL);
+ if (value != null) {
+ int i1 = Array.getLength(value);
+ for (int j = 0; j < i1; j++) {
+ Object o = Array.get(value, j);
+ NamedProperty prop =
+ new NamedProperty(new QName(beanNS, property, beanPrefix), getStringValue(o));
+ props.add(prop);
+ }
+ } else {
+ NamedProperty prop = new NamedProperty(new QName(beanNS, property, beanPrefix), value);
+ props.add(prop);
+ }
+
+ } else {
+ Object value[] = (Object[])propDesc.getReadMethod().invoke(beanObject, NULL);
+ if (value != null) {
+ for (int j = 0; j < value.length; j++) {
+ Object o = value[j];
+ NamedProperty prop =
+ new NamedProperty(new QName(beanNS, property, beanPrefix), getStringValue(o));
+ props.add(prop);
+ }
+ } else {
+ NamedProperty prop = new NamedProperty(new QName(beanNS, property, beanPrefix), value);
+ props.add(prop);
+ }
+ }
+ } else if (Collection.class.isAssignableFrom(ptype)) {
+ Object value = propDesc.getReadMethod().invoke(beanObject, NULL);
+ Collection objList = (Collection)value;
+ if (objList != null && objList.size() > 0) {
+ // this was given error , when the array.size = 0
+ // and if the array contain simple type , then the
+ // ADBPullParser asked
+ // PullParser from That simpel type
+ for (Iterator j = objList.iterator(); j.hasNext();) {
+ Object o = j.next();
+ if (isSimpleType(o.getClass())) {
+ NamedProperty prop =
+ new NamedProperty(new QName(beanNS, property, beanPrefix), getStringValue(o));
+ props.add(prop);
+ } else {
+ NamedProperty prop = new NamedProperty(new QName(beanNS, property, beanPrefix), o);
+ props.add(prop);
+ }
+ }
+
+ } else {
+ NamedProperty prop = new NamedProperty(new QName(beanNS, property, beanPrefix), value);
+ props.add(prop);
+ }
+ } else {
+ Object value = propDesc.getReadMethod().invoke(beanObject, NULL);
+ NamedProperty prop = new NamedProperty(new QName(beanNS, property, beanPrefix), value);
+ props.add(prop);
+ }
+ }
+ NamedProperty[] elements = new NamedProperty[props.size()];
+ props.toArray(elements);
+ return new XMLFragmentStreamReaderImpl(beanName, elements, null);
+ } catch (Exception e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ /**
+ * to get the pull parser for a given bean object , generate the wrpper
+ * element using class name
+ *
+ * @param beanObject
+ */
+ public static XMLStreamReader getXMLStreamReader(Object beanObject) {
+ String className = beanObject.getClass().getName();
+ if (className.indexOf(".") > 0) {
+ className = className.substring(className.lastIndexOf('.') + 1, className.length());
+ }
+ return getXMLStreamReader(beanObject, new QName(className));
+ }
+
+ /**
+ * increments the namespace counter and returns a new prefix
+ *
+ * @return unique prefix
+ */
+ public static String getUniquePrefix() {
+ return "s" + nsCount++;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMDataBinding.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMDataBinding.java
new file mode 100644
index 0000000000..a3f13663bc
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMDataBinding.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+
+import org.w3c.dom.Node;
+
+import org.apache.tuscany.spi.databinding.WrapperHandler;
+import org.apache.tuscany.spi.databinding.extension.DataBindingExtension;
+
+/**
+ * DOM DataBinding
+ *
+ * @version $Rev$ $Date$
+ */
+public class DOMDataBinding extends DataBindingExtension {
+ public static final String NAME = Node.class.getName();
+ public static final String[] ALIASES = new String[] {"dom"};
+
+ public DOMDataBinding() {
+ super(NAME, ALIASES, Node.class);
+ }
+
+ @Override
+ public WrapperHandler getWrapperHandler() {
+ return new DOMWrapperHandler();
+ }
+
+ public Object copy(Object source) {
+ if (Node.class.isAssignableFrom(source.getClass())) {
+ Node nodeSource = (Node) source;
+ return nodeSource.cloneNode(true);
+ }
+ return super.copy(source);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMWrapperHandler.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMWrapperHandler.java
new file mode 100644
index 0000000000..6aac20e98f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMWrapperHandler.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.xml;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.WrapperHandler;
+import org.apache.tuscany.spi.databinding.extension.DOMHelper;
+import org.apache.tuscany.spi.idl.ElementInfo;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class DOMWrapperHandler implements WrapperHandler<Node> {
+
+ private Document document;
+
+ public DOMWrapperHandler() {
+ super();
+ try {
+ this.document = DOMHelper.newDocument();
+ } catch (ParserConfigurationException e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Node create(ElementInfo element, TransformationContext context) {
+ QName name = element.getQName();
+ return DOMHelper.createElement(document, name);
+ }
+
+ public void setChild(Node wrapper, int i, ElementInfo childElement, Object value) {
+ Node node = (Node) value;
+ if (node.getNodeType() == Node.DOCUMENT_NODE) {
+ node = ((Document) node).getDocumentElement();
+ }
+ wrapper.appendChild(wrapper.getOwnerDocument().importNode(node, true));
+ }
+
+ public List getChildren(Node wrapper) {
+ assert wrapper != null;
+ if (wrapper.getNodeType() == Node.DOCUMENT_NODE) {
+ wrapper = ((Document) wrapper).getDocumentElement();
+ }
+ List<Node> elements = new ArrayList<Node>();
+ NodeList nodes = wrapper.getChildNodes();
+ for (int j = 0; j < nodes.getLength(); j++) {
+ Node node = nodes.item(j);
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ elements.add(node);
+ }
+ }
+ return elements;
+ }
+} \ No newline at end of file
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMXMLStreamReader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMXMLStreamReader.java
new file mode 100644
index 0000000000..39adcf332d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMXMLStreamReader.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import static javax.xml.XMLConstants.DEFAULT_NS_PREFIX;
+import static javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.CharacterData;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class DOMXMLStreamReader extends XMLFragmentStreamReaderImpl {
+ private Element rootElement;
+
+ public DOMXMLStreamReader(Node node) {
+ super(null);
+ switch (node.getNodeType()) {
+ case Node.DOCUMENT_NODE:
+ this.rootElement = ((Document)node).getDocumentElement();
+ break;
+ case Node.ELEMENT_NODE:
+ this.rootElement = (Element)node;
+ break;
+ default:
+ throw new IllegalArgumentException("Illegal Node");
+ }
+ String ns = rootElement.getNamespaceURI();
+ String prefix = rootElement.getPrefix();
+ String name = rootElement.getLocalName();
+ elementQName = new QName(ns == null ? "" : ns, name, prefix == null ? "" : prefix);
+ }
+
+ @Override
+ protected final NamedProperty[] getAttributes() {
+ if (attributes == null) {
+ List<NamedProperty> attributeList = new ArrayList<NamedProperty>();
+ NamedNodeMap nodeMap = rootElement.getAttributes();
+ for (int i = 0; i < nodeMap.getLength(); i++) {
+ Attr attr = (Attr)nodeMap.item(i);
+ String ns = attr.getNamespaceURI();
+ String prefix = attr.getPrefix();
+ if (!XMLNS_ATTRIBUTE_NS_URI.equals(ns)) {
+ QName attrName = new QName(ns == null ? "" : ns, attr.getLocalName(), prefix != null ? prefix : "");
+ NamedProperty pair = new NamedProperty(attrName, attr.getValue());
+ attributeList.add(pair);
+ }
+ }
+ attributes = new NamedProperty[attributeList.size()];
+ attributeList.toArray(attributes);
+ }
+ return attributes;
+ }
+
+ @Override
+ protected QName[] getNamespaces() {
+ List<QName> nsList = new ArrayList<QName>();
+ NamedNodeMap nodeMap = rootElement.getAttributes();
+ for (int i = 0; i < nodeMap.getLength(); i++) {
+ Attr attr = (Attr)nodeMap.item(i);
+ String ns = attr.getNamespaceURI();
+ if (XMLNS_ATTRIBUTE_NS_URI.equals(ns)) {
+ String prefix = attr.getPrefix();
+ if (prefix == null) {
+ // xmlns="http://ns"
+ nsList.add(new QName(attr.getValue(), "", DEFAULT_NS_PREFIX));
+ } else {
+ // xmlns:ns="http://ns"
+ nsList.add(new QName(attr.getValue(), "", attr.getLocalName()));
+ }
+ }
+ }
+ QName[] nss = new QName[nsList.size()];
+ nsList.toArray(nss);
+ return nss;
+ }
+
+ @Override
+ protected NamedProperty[] getElements() {
+ if (elements == null) {
+ List<NamedProperty> elementList = new ArrayList<NamedProperty>();
+ NodeList nodeList = rootElement.getChildNodes();
+ for (int i = 0; i < nodeList.getLength(); i++) {
+ Node node = nodeList.item(i);
+ switch (node.getNodeType()) {
+ case Node.TEXT_NODE:
+ case Node.CDATA_SECTION_NODE:
+ NamedProperty pair = new NamedProperty(ELEMENT_TEXT, ((CharacterData)node).getData());
+ elementList.add(pair);
+ break;
+
+ case Node.ELEMENT_NODE:
+ Element element = (Element)node;
+ QName elementName = new QName(element.getNamespaceURI(), element.getLocalName());
+ pair = new NamedProperty(elementName, new DOMXMLStreamReader(element));
+ elementList.add(pair);
+ break;
+ }
+ }
+ elements = new NamedProperty[elementList.size()];
+ elementList.toArray(elements);
+ }
+ return elements;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DelegatingNamespaceContext.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DelegatingNamespaceContext.java
new file mode 100644
index 0000000000..1edc52c089
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DelegatingNamespaceContext.java
@@ -0,0 +1,310 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import java.util.ArrayList;
+import java.util.EmptyStackException;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.namespace.NamespaceContext;
+
+public class DelegatingNamespaceContext implements NamespaceContext {
+ private static int count;
+
+ private class WrappingIterator implements Iterator {
+
+ private Iterator containedIterator;
+
+ public WrappingIterator(Iterator containedIterator) {
+ this.containedIterator = containedIterator;
+ }
+
+ public Iterator getContainedIterator() {
+ return containedIterator;
+ }
+
+ public boolean hasNext() {
+ return containedIterator.hasNext();
+ }
+
+ public Object next() {
+ return containedIterator.next();
+ }
+
+ /**
+ * As per the contract on the API of Namespace context the returned iterator should be immutable
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setContainedIterator(Iterator containedIterator) {
+ this.containedIterator = containedIterator;
+ }
+ }
+
+ private NamespaceContext parentNsContext;
+
+ private FastStack<String> prefixStack = new FastStack<String>();
+
+ // Keep two arraylists for the prefixes and namespaces. They should be in
+ // sync
+ // since the index of the entry will be used to relate them
+ // use the minimum initial capacity to let things handle memory better
+
+ private FastStack<String> uriStack = new FastStack<String>();
+
+ /**
+ * Generates a unique namespace prefix that is not in the scope of the NamespaceContext
+ *
+ * @return string
+ */
+ public String generateUniquePrefix() {
+ String prefix = "p" + count++;
+ // null should be returned if the prefix is not bound!
+ while (getNamespaceURI(prefix) != null) {
+ prefix = "p" + count++;
+ }
+
+ return prefix;
+ }
+
+ public String getNamespaceURI(String prefix) {
+ // do the corrections as per the javadoc
+ int index = prefixStack.search(prefix);
+ if (index != -1) {
+ return (String)uriStack.get(index);
+ }
+ if (parentNsContext != null) {
+ return parentNsContext.getPrefix(prefix);
+ }
+ return null;
+ }
+
+ public NamespaceContext getParentNsContext() {
+ return parentNsContext;
+ }
+
+ public String getPrefix(String uri) {
+ // do the corrections as per the javadoc
+ int index = uriStack.search(uri);
+ if (index != -1) {
+ return (String)prefixStack.get(index);
+ }
+
+ if (parentNsContext != null) {
+ return parentNsContext.getPrefix(uri);
+ }
+ return null;
+ }
+
+ public Iterator getPrefixes(String uri) {
+ // create an arraylist that contains the relevant prefixes
+ String[] uris = (String[])uriStack.toArray(new String[uriStack.size()]);
+ List<String> tempList = new ArrayList<String>();
+ for (int i = uris.length - 1; i >= 0; i--) {
+ if (uris[i].equals(uri)) {
+ tempList.add(prefixStack.get(i));
+ // we assume that array conversion preserves the order
+ }
+ }
+ // by now all the relevant prefixes are collected
+ // make a new iterator and provide a wrapper iterator to
+ // obey the contract on the API
+ return new WrappingIterator(tempList.iterator());
+ }
+
+ /**
+ * Pop a namespace
+ */
+ public void popNamespace() {
+ prefixStack.pop();
+ uriStack.pop();
+ }
+
+ /**
+ * Register a namespace in this context
+ *
+ * @param prefix
+ * @param uri
+ */
+ public void pushNamespace(String prefix, String uri) {
+ prefixStack.push(prefix);
+ uriStack.push(uri);
+
+ }
+
+ public void setParentNsContext(NamespaceContext parentNsContext) {
+ this.parentNsContext = parentNsContext;
+ }
+
+ /**
+ * An implementation of the {@link java.util.Stack} API that is based on an <code>ArrayList</code> instead of a
+ * <code>Vector</code>, so it is not synchronized to protect against multi-threaded access. The implementation is
+ * therefore operates faster in environments where you do not need to worry about multiple thread contention.
+ * <p>
+ * The removal order of an <code>ArrayStack</code> is based on insertion order: The most recently added element is
+ * removed first. The iteration order is <i>not</i> the same as the removal order. The iterator returns elements
+ * from the bottom up, whereas the {@link #remove()} method removes them from the top down.
+ * <p>
+ * Unlike <code>Stack</code>, <code>ArrayStack</code> accepts null entries.
+ */
+ public static class FastStack<T> extends ArrayList<T> {
+
+ /** Ensure serialization compatibility */
+ private static final long serialVersionUID = 2130079159931574599L;
+
+ /**
+ * Constructs a new empty <code>ArrayStack</code>. The initial size is controlled by <code>ArrayList</code>
+ * and is currently 10.
+ */
+ public FastStack() {
+ super();
+ }
+
+ /**
+ * Constructs a new empty <code>ArrayStack</code> with an initial size.
+ *
+ * @param initialSize the initial size to use
+ * @throws IllegalArgumentException if the specified initial size is negative
+ */
+ public FastStack(int initialSize) {
+ super(initialSize);
+ }
+
+ /**
+ * Return <code>true</code> if this stack is currently empty.
+ * <p>
+ * This method exists for compatibility with <code>java.util.Stack</code>. New users of this class should use
+ * <code>isEmpty</code> instead.
+ *
+ * @return true if the stack is currently empty
+ */
+ public boolean empty() {
+ return isEmpty();
+ }
+
+ /**
+ * Returns the top item off of this stack without removing it.
+ *
+ * @return the top item on the stack
+ * @throws EmptyStackException if the stack is empty
+ */
+ public T peek() throws EmptyStackException {
+ int n = size();
+ if (n <= 0) {
+ throw new EmptyStackException();
+ } else {
+ return get(n - 1);
+ }
+ }
+
+ /**
+ * Returns the n'th item down (zero-relative) from the top of this stack without removing it.
+ *
+ * @param n the number of items down to go
+ * @return the n'th item on the stack, zero relative
+ * @throws EmptyStackException if there are not enough items on the stack to satisfy this request
+ */
+ public T peek(int n) throws EmptyStackException {
+ int m = (size() - n) - 1;
+ if (m < 0) {
+ throw new EmptyStackException();
+ } else {
+ return get(m);
+ }
+ }
+
+ /**
+ * Pops the top item off of this stack and return it.
+ *
+ * @return the top item on the stack
+ * @throws EmptyStackException if the stack is empty
+ */
+ public T pop() throws EmptyStackException {
+ int n = size();
+ if (n <= 0) {
+ throw new EmptyStackException();
+ } else {
+ return remove(n - 1);
+ }
+ }
+
+ /**
+ * Pushes a new item onto the top of this stack. The pushed item is also returned. This is equivalent to calling
+ * <code>add</code>.
+ *
+ * @param item the item to be added
+ * @return the item just pushed
+ */
+ public Object push(T item) {
+ add(item);
+ return item;
+ }
+
+ /**
+ * Returns the top-most index for the object in the stack
+ *
+ * @param object the object to be searched for
+ * @return top-most index, or -1 if not found
+ */
+ public int search(T object) {
+ int i = size() - 1; // Current index
+ while (i >= 0) {
+ T current = get(i);
+ if ((object == null && current == null) || (object != null && object.equals(current))) {
+ return i;
+ }
+ i--;
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the element on the top of the stack.
+ *
+ * @return the element on the top of the stack
+ * @throws EmptyStackException if the stack is empty
+ */
+ public T get() {
+ int size = size();
+ if (size == 0) {
+ throw new EmptyStackException();
+ }
+ return get(size - 1);
+ }
+
+ /**
+ * Removes the element on the top of the stack.
+ *
+ * @return the removed element
+ * @throws EmptyStackException if the stack is empty
+ */
+ public T remove() {
+ int size = size();
+ if (size == 0) {
+ throw new EmptyStackException();
+ }
+ return remove(size - 1);
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2Node.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2Node.java
new file mode 100644
index 0000000000..e9757fa13c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2Node.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+
+/**
+ * Push DOM InputSource to Node
+ */
+@Service(Transformer.class)
+public class InputSource2Node extends TransformerExtension<InputSource, Node> implements
+ PullTransformer<InputSource, Node> {
+ private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer();
+
+ public Node transform(InputSource source, TransformationContext context) {
+ try {
+ Source streamSource = new StreamSource(source.getCharacterStream());
+ DOMResult result = new DOMResult();
+ TRANSFORMER.transform(streamSource, result, context);
+ return result.getNode();
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return InputSource.class;
+ }
+
+ public Class getTargetType() {
+ return Node.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2SAX.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2SAX.java
new file mode 100644
index 0000000000..be78a07ede
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2SAX.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * Push InputSource to SAX
+ */
+@Service(Transformer.class)
+public class InputSource2SAX extends TransformerExtension<InputSource, ContentHandler> implements
+ PushTransformer<InputSource, ContentHandler> {
+
+ public void transform(InputSource source, ContentHandler target, TransformationContext context) {
+ try {
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+ reader.setFeature("http://xml.org/sax/features/namespaces", true);
+ reader.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
+ reader.setContentHandler(target);
+ reader.parse(source);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return InputSource.class;
+ }
+
+ public Class getTargetType() {
+ return ContentHandler.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2Node.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2Node.java
new file mode 100644
index 0000000000..e103c82b33
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2Node.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import java.io.InputStream;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.sax.SAXSource;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+
+/**
+ * Push DOM InputSource to Node
+ */
+@Service(Transformer.class)
+public class InputStream2Node extends TransformerExtension<InputStream, Node> implements
+ PullTransformer<InputStream, Node> {
+ private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer();
+
+ public Node transform(InputStream source, TransformationContext context) {
+ try {
+ Source streamSource = new SAXSource(new InputSource(source));
+ DOMResult result = new DOMResult();
+ TRANSFORMER.transform(streamSource, result, context);
+ return result.getNode();
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return InputStream.class;
+ }
+
+ public Class getTargetType() {
+ return Node.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2SAX.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2SAX.java
new file mode 100644
index 0000000000..d74863ea95
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2SAX.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import java.io.InputStream;
+
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * Push InputStream to SAX
+ */
+@Service(Transformer.class)
+public class InputStream2SAX extends TransformerExtension<InputStream, ContentHandler> implements
+ PushTransformer<InputStream, ContentHandler> {
+ public void transform(InputStream source, ContentHandler target, TransformationContext context) {
+ try {
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+ reader.setContentHandler(target);
+ reader.parse(new InputSource(source));
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return InputStream.class;
+ }
+
+ public Class getTargetType() {
+ return ContentHandler.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/NameValueArrayStreamReader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/NameValueArrayStreamReader.java
new file mode 100644
index 0000000000..d10af29b35
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/NameValueArrayStreamReader.java
@@ -0,0 +1,403 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+
+public class NameValueArrayStreamReader implements XMLFragmentStreamReader {
+
+ private static final int START_ELEMENT_STATE = 0;
+ private static final int TEXT_STATE = 1;
+ private static final int END_ELEMENT_STATE = 2;
+ private static final int FINAL_END_ELEMENT_STATE = 3;
+ private static final int START_ELEMENT_STATE_WITH_NULL = 4;
+
+ private DelegatingNamespaceContext namespaceContext = new DelegatingNamespaceContext();
+ // the index of the array
+ private int arrayIndex;
+
+ private QName name;
+ private String[] values;
+
+ // start element is the default state
+ private int state = START_ELEMENT_STATE;
+
+ public NameValueArrayStreamReader(QName name, String[] values) {
+ this.name = name;
+ this.values = values;
+ }
+
+ public void setParentNamespaceContext(NamespaceContext nsContext) {
+ this.namespaceContext.setParentNsContext(nsContext);
+ }
+
+ public void init() {
+ // todo what if the Qname namespace has not been declared
+ }
+
+ public Object getProperty(String string) throws IllegalArgumentException {
+ return null;
+ }
+
+ /**
+ * @throws XMLStreamException
+ */
+ public int next() throws XMLStreamException {
+ switch (state) {
+ case START_ELEMENT_STATE:
+ if (values.length > 0) {
+ state = TEXT_STATE;
+ return CHARACTERS;
+ } else {
+ state = FINAL_END_ELEMENT_STATE;
+ return END_ELEMENT;
+ }
+
+ case START_ELEMENT_STATE_WITH_NULL:
+ if (arrayIndex == (values.length - 1)) {
+ state = FINAL_END_ELEMENT_STATE;
+ } else {
+ state = END_ELEMENT_STATE;
+ }
+ return END_ELEMENT;
+ case FINAL_END_ELEMENT_STATE:
+ // oops, not supposed to happen!
+ throw new XMLStreamException("end already reached!");
+ case END_ELEMENT_STATE:
+ // we've to have more values since this is not the
+ // last value
+ // increment the counter
+ arrayIndex++;
+ if (values[arrayIndex] == null) {
+ state = START_ELEMENT_STATE_WITH_NULL;
+ } else {
+ state = START_ELEMENT_STATE;
+ }
+ return START_ELEMENT;
+ case TEXT_STATE:
+ if (arrayIndex == (values.length - 1)) {
+ state = FINAL_END_ELEMENT_STATE;
+ return END_ELEMENT;
+ } else {
+ state = END_ELEMENT_STATE;
+ return END_ELEMENT;
+ }
+
+ default:
+ throw new XMLStreamException("unknown event type!");
+ }
+ }
+
+ public void require(int i, String string, String string1) throws XMLStreamException {
+ // nothing done here
+ }
+
+ public String getElementText() throws XMLStreamException {
+ return null; // not implemented
+ }
+
+ public int nextTag() throws XMLStreamException {
+ return 0; // not implemented
+ }
+
+ public String getAttributeValue(String string, String string1) {
+ if (state == TEXT_STATE) {
+ // todo something
+ return null;
+ } else {
+ return null;
+ }
+
+ }
+
+ public int getAttributeCount() {
+ if (state == START_ELEMENT_STATE_WITH_NULL) {
+ return 1;
+ }
+ if (state == START_ELEMENT_STATE) {
+ return 0;
+ } else {
+ throw new IllegalStateException();
+ }
+
+ }
+
+ public QName getAttributeName(int i) {
+ if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) {
+ return NIL_QNAME;
+ }
+ if (state == START_ELEMENT_STATE) {
+ return null;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeNamespace(int i) {
+ if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) {
+ return NIL_QNAME.getNamespaceURI();
+ }
+ if (state == START_ELEMENT_STATE) {
+ return null;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeLocalName(int i) {
+ if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) {
+ return NIL_QNAME.getLocalPart();
+ }
+ if (state == START_ELEMENT_STATE) {
+ return null;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributePrefix(int i) {
+ if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) {
+ return NIL_QNAME.getPrefix();
+ }
+ if (state == START_ELEMENT_STATE) {
+ return null;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeType(int i) {
+ return null; // not implemented
+ }
+
+ public String getAttributeValue(int i) {
+ if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) {
+ return NIL_VALUE_TRUE;
+ }
+ if (state == START_ELEMENT_STATE) {
+ return null;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public boolean isAttributeSpecified(int i) {
+ return false; // not supported
+ }
+
+ public int getNamespaceCount() {
+ if (state == START_ELEMENT_STATE_WITH_NULL && isXsiNamespacePresent()) {
+ return 1;
+ } else {
+ return 0;
+ }
+
+ }
+
+ public String getNamespacePrefix(int i) {
+ if (state == START_ELEMENT_STATE_WITH_NULL && isXsiNamespacePresent() && i == 0) {
+ return NIL_QNAME.getPrefix();
+ } else {
+ return null;
+ }
+ }
+
+ public String getNamespaceURI(int i) {
+ if (state == START_ELEMENT_STATE_WITH_NULL && isXsiNamespacePresent() && i == 0) {
+ return NIL_QNAME.getNamespaceURI();
+ } else {
+ return null;
+ }
+ }
+
+ public NamespaceContext getNamespaceContext() {
+ return this.namespaceContext;
+ }
+
+ public boolean isDone() {
+ return state == FINAL_END_ELEMENT_STATE;
+ }
+
+ public int getEventType() {
+ switch (state) {
+ case START_ELEMENT_STATE:
+ return START_ELEMENT;
+ case END_ELEMENT_STATE:
+ return END_ELEMENT;
+ case TEXT_STATE:
+ return CHARACTERS;
+ case FINAL_END_ELEMENT_STATE:
+ return END_ELEMENT;
+ default:
+ throw new UnsupportedOperationException();
+ // we've no idea what this is!!!!!
+ }
+
+ }
+
+ public String getText() {
+ if (state == TEXT_STATE) {
+ return values[arrayIndex];
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public char[] getTextCharacters() {
+ if (state == TEXT_STATE) {
+ return values[arrayIndex].toCharArray();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException {
+ // not implemented
+ throw new UnsupportedOperationException();
+ }
+
+ public int getTextStart() {
+ if (state == TEXT_STATE) {
+ return 0;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextLength() {
+ if (state == TEXT_STATE) {
+ return values[arrayIndex].length();
+ } else {
+ throw new IllegalStateException();
+ }
+
+ }
+
+ public String getEncoding() {
+ return null;
+ }
+
+ public boolean hasText() {
+ return state == TEXT_STATE;
+ }
+
+ public Location getLocation() {
+ return null; // not supported
+ }
+
+ public QName getName() {
+ if (state != TEXT_STATE) {
+ return name;
+ } else {
+ return null;
+ }
+ }
+
+ public String getLocalName() {
+ if (state != TEXT_STATE) {
+ return name.getLocalPart();
+ } else {
+ return null;
+ }
+ }
+
+ public boolean hasName() {
+ return state != TEXT_STATE;
+
+ }
+
+ public String getNamespaceURI() {
+ if (state != TEXT_STATE) {
+ return name.getNamespaceURI();
+ } else {
+ return null;
+ }
+
+ }
+
+ public String getPrefix() {
+ if (state != TEXT_STATE) {
+ return name.getPrefix();
+ } else {
+ return null;
+ }
+ }
+
+ public String getVersion() {
+ return null; // todo 1.0 ?
+ }
+
+ public boolean isStandalone() {
+ return false;
+ }
+
+ public boolean standaloneSet() {
+ return false;
+ }
+
+ public String getCharacterEncodingScheme() {
+ return null;
+ }
+
+ public String getPITarget() {
+ return null;
+ }
+
+ public String getPIData() {
+ return null;
+ }
+
+ public boolean hasNext() throws XMLStreamException {
+ return state != FINAL_END_ELEMENT_STATE;
+ }
+
+ public void close() throws XMLStreamException {
+ // Do nothing - we've nothing to free here
+ }
+
+ public String getNamespaceURI(String prefix) {
+ return namespaceContext.getNamespaceURI(prefix);
+ }
+
+ public boolean isStartElement() {
+ return state == START_ELEMENT_STATE;
+ }
+
+ public boolean isEndElement() {
+ return state == END_ELEMENT_STATE;
+ }
+
+ public boolean isCharacters() {
+ return state == TEXT_STATE;
+ }
+
+ public boolean isWhiteSpace() {
+ return false; // no whitespaces here
+ }
+
+ /**
+ * Test whether the xsi namespace is present
+ */
+ private boolean isXsiNamespacePresent() {
+ return namespaceContext.getNamespaceURI(NIL_QNAME.getPrefix()) != null;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/NameValuePairStreamReader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/NameValuePairStreamReader.java
new file mode 100644
index 0000000000..d9261b8b4f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/NameValuePairStreamReader.java
@@ -0,0 +1,347 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+
+
+public class NameValuePairStreamReader implements XMLFragmentStreamReader {
+
+ private static final int START_ELEMENT_STATE = 0;
+ private static final int TEXT_STATE = 1;
+ private static final int END_ELEMENT_STATE = 2;
+
+ private DelegatingNamespaceContext namespaceContext = new DelegatingNamespaceContext();
+
+ private QName name;
+ private String value;
+
+ private int state = START_ELEMENT_STATE;
+ // initiate at the start element state
+
+ // keeps track whether the namespace is declared
+ // false by default
+ private boolean nsDeclared;
+
+ public NameValuePairStreamReader(QName name, String value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ public Object getProperty(String key) throws IllegalArgumentException {
+ return null;
+ }
+
+ public int next() throws XMLStreamException {
+ // no need to handle null here. it should have been handled
+ // already
+ switch (state) {
+ case START_ELEMENT_STATE:
+ state = TEXT_STATE;
+ return CHARACTERS;
+ case END_ELEMENT_STATE:
+ // oops, not supposed to happen!
+ throw new XMLStreamException("end already reached!");
+ case TEXT_STATE:
+ state = END_ELEMENT_STATE;
+ return END_ELEMENT;
+ default:
+ throw new XMLStreamException("unknown event type!");
+ }
+ }
+
+ public void require(int i, String string, String string1) throws XMLStreamException {
+ // not implemented
+ }
+
+ public String getElementText() throws XMLStreamException {
+ if (state == START_ELEMENT) {
+ // move to the end state and return the value
+ state = END_ELEMENT_STATE;
+ return value;
+ } else {
+ throw new XMLStreamException();
+ }
+
+ }
+
+ public int nextTag() throws XMLStreamException {
+ return 0; // todo
+ }
+
+ public boolean hasNext() throws XMLStreamException {
+ return state != END_ELEMENT_STATE;
+ }
+
+ public void close() throws XMLStreamException {
+ // Do nothing - we've nothing to free here
+ }
+
+ public String getNamespaceURI(String prefix) {
+ return namespaceContext.getNamespaceURI(prefix);
+ }
+
+ public boolean isStartElement() {
+ return state == START_ELEMENT_STATE;
+ }
+
+ public boolean isEndElement() {
+ return state == END_ELEMENT_STATE;
+ }
+
+ public boolean isCharacters() {
+ return state == TEXT_STATE;
+ }
+
+ public boolean isWhiteSpace() {
+ return false; // no whitespaces here
+ }
+
+ public String getAttributeValue(String string, String string1) {
+ return null;
+ }
+
+ public int getAttributeCount() {
+ return 0;
+ }
+
+ public QName getAttributeName(int i) {
+ return null;
+ }
+
+ public String getAttributeNamespace(int i) {
+ return null;
+ }
+
+ public String getAttributeLocalName(int i) {
+ return null;
+ }
+
+ public String getAttributePrefix(int i) {
+ return null;
+ }
+
+ public String getAttributeType(int i) {
+ return null;
+ }
+
+ public String getAttributeValue(int i) {
+ return null;
+ }
+
+ public boolean isAttributeSpecified(int i) {
+ return false; // no attribs here
+ }
+
+ public int getNamespaceCount() {
+ return nsDeclared ? 1 : 0;
+ }
+
+ public String getNamespacePrefix(int i) {
+ return (nsDeclared && i == 0) ? name.getPrefix() : null;
+ }
+
+ public String getNamespaceURI(int i) {
+ return (nsDeclared && i == 0) ? name.getNamespaceURI() : null;
+ }
+
+ public NamespaceContext getNamespaceContext() {
+ return this.namespaceContext;
+ }
+
+ public int getEventType() {
+ switch (state) {
+ case START_ELEMENT_STATE:
+ return START_ELEMENT;
+ case END_ELEMENT_STATE:
+ return END_ELEMENT;
+ case TEXT_STATE:
+ return CHARACTERS;
+ default:
+ throw new UnsupportedOperationException();
+ // we've no idea what this is!!!!!
+ }
+
+ }
+
+ public String getText() {
+ if (state == TEXT_STATE) {
+ return value;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public char[] getTextCharacters() {
+ if (state == TEXT_STATE) {
+ return value.toCharArray();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException {
+ // not implemented
+ throw new UnsupportedOperationException();
+ }
+
+ public int getTextStart() {
+ if (state == TEXT_STATE) {
+ return 0;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextLength() {
+ if (state == TEXT_STATE) {
+ return value.length();
+ } else {
+ throw new IllegalStateException();
+ }
+
+ }
+
+ public String getEncoding() {
+ return null;
+ }
+
+ public boolean hasText() {
+ return state == TEXT_STATE;
+ }
+
+ public Location getLocation() {
+ return new Location() {
+ public int getLineNumber() {
+ return 0;
+ }
+
+ public int getColumnNumber() {
+ return 0;
+ }
+
+ public int getCharacterOffset() {
+ return 0;
+ }
+
+ public String getPublicId() {
+ return null;
+ }
+
+ public String getSystemId() {
+ return null;
+ }
+ };
+ }
+
+ public QName getName() {
+ if (state != TEXT_STATE) {
+ return name;
+ } else {
+ return null;
+ }
+ }
+
+ public String getLocalName() {
+ if (state != TEXT_STATE) {
+ return name.getLocalPart();
+ } else {
+ return null;
+ }
+ }
+
+ public boolean hasName() {
+ return state != TEXT_STATE;
+
+ }
+
+ public String getNamespaceURI() {
+ if (state != TEXT_STATE) {
+ return name.getNamespaceURI();
+ } else {
+ return null;
+ }
+
+ }
+
+ public String getPrefix() {
+ if (state != TEXT_STATE) {
+ return name.getPrefix();
+ } else {
+ return null;
+ }
+ }
+
+ public String getVersion() {
+ return null; // todo 1.0 ?
+ }
+
+ public boolean isStandalone() {
+ return false;
+ }
+
+ public boolean standaloneSet() {
+ return false;
+ }
+
+ public String getCharacterEncodingScheme() {
+ return null;
+ }
+
+ public String getPITarget() {
+ return null;
+ }
+
+ public String getPIData() {
+ return null;
+ }
+
+ public boolean isDone() {
+ return state == END_ELEMENT_STATE;
+ }
+
+ public void setParentNamespaceContext(NamespaceContext nsContext) {
+ this.namespaceContext.setParentNsContext(nsContext);
+ }
+
+ public void init() {
+ // just add the current elements namespace and prefix to the this
+ // elements nscontext
+ addToNsMap(name.getPrefix(), name.getNamespaceURI());
+
+ }
+
+ /**
+ * @param prefix
+ * @param uri
+ */
+ private void addToNsMap(String prefix, String uri) {
+ // todo - need to fix this up to cater for cases where
+ // namespaces are having no prefixes
+ if (!uri.equals(namespaceContext.getNamespaceURI(prefix))) {
+ // this namespace is not there. Need to declare it
+ namespaceContext.pushNamespace(prefix, uri);
+ nsDeclared = true;
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/NamedProperty.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/NamedProperty.java
new file mode 100644
index 0000000000..0ce249e912
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/NamedProperty.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.xml;
+
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+/**
+ * A named property
+ *
+ * @version $Rev$ $Date$
+ */
+public class NamedProperty implements Map.Entry<QName, Object> {
+ private QName key;
+
+ private Object value;
+
+ public NamedProperty(QName key, Object value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public NamedProperty(String key, Object value) {
+ this.key = new QName(key);
+ this.value = value;
+ }
+
+ public QName getKey() {
+ return key;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ public Object setValue(Object value) {
+ Object v = this.value;
+ this.value = value;
+ return v;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/NilElementStreamReader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/NilElementStreamReader.java
new file mode 100644
index 0000000000..8a454c8342
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/NilElementStreamReader.java
@@ -0,0 +1,279 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+
+public class NilElementStreamReader implements XMLFragmentStreamReader {
+
+ private static final int END_ELEMENT_STATE = 2;
+
+ private static final int START_ELEMENT_STATE = 1;
+ private int currentState = START_ELEMENT;
+
+ private QName elementQName;
+
+ public NilElementStreamReader(QName elementQName) {
+ this.elementQName = elementQName;
+ }
+
+ public void setParentNamespaceContext(NamespaceContext nsContext) {
+ // NOOP
+ }
+
+ public void close() throws XMLStreamException {
+ // do nothing
+ }
+
+ public int getAttributeCount() {
+ return 1;
+ }
+
+ public String getAttributeLocalName(int i) {
+ return (i == 0) ? NIL_QNAME.getLocalPart() : null;
+ }
+
+ public QName getAttributeName(int i) {
+ return (i == 0) ? NIL_QNAME : null;
+ }
+
+ public String getAttributeNamespace(int i) {
+ return (i == 0) ? NIL_QNAME.getNamespaceURI() : null;
+ }
+
+ public String getAttributePrefix(int i) {
+ return (i == 0) ? NIL_QNAME.getPrefix() : null;
+ }
+
+ public String getAttributeType(int i) {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getAttributeValue(int i) {
+ return (i == 0) ? NIL_VALUE_TRUE : null;
+ }
+
+ public String getAttributeValue(String string, String string1) {
+ if (string == null && NIL_QNAME.getLocalPart().equals(string1)) {
+ return NIL_VALUE_TRUE;
+ }
+ return null;
+ }
+
+ public String getCharacterEncodingScheme() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getElementText() throws XMLStreamException {
+ return null;
+ }
+
+ public String getEncoding() {
+ return null;
+ }
+
+ public int getEventType() {
+ int returnEvent = START_DOCUMENT;
+ switch (currentState) {
+ case START_ELEMENT_STATE:
+ returnEvent = START_ELEMENT;
+ break;
+ case END_ELEMENT_STATE:
+ returnEvent = END_ELEMENT;
+ break;
+ }
+ return returnEvent;
+ }
+
+ public String getLocalName() {
+ return elementQName.getLocalPart();
+ }
+
+ public Location getLocation() {
+ return new Location() {
+ public int getCharacterOffset() {
+ return 0;
+ }
+
+ public int getColumnNumber() {
+ return 0;
+ }
+
+ public int getLineNumber() {
+ return 0;
+ }
+
+ public String getPublicId() {
+ return null;
+ }
+
+ public String getSystemId() {
+ return null;
+ }
+ };
+ }
+
+ public QName getName() {
+ return elementQName;
+ }
+
+ public NamespaceContext getNamespaceContext() {
+ throw new UnsupportedOperationException();
+ }
+
+ public int getNamespaceCount() {
+ return 0;
+ }
+
+ public String getNamespacePrefix(int i) {
+ return null;
+ }
+
+ public String getNamespaceURI() {
+ return elementQName.getNamespaceURI();
+ }
+
+ public String getNamespaceURI(int i) {
+ return null;
+ }
+
+ public String getNamespaceURI(String string) {
+ if (elementQName.getPrefix() != null && elementQName.getPrefix().equals(string)) {
+ return elementQName.getNamespaceURI();
+ } else {
+ return null;
+ }
+ }
+
+ public String getPIData() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getPITarget() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getPrefix() {
+ return elementQName.getPrefix();
+ }
+
+ public Object getProperty(String key) throws IllegalArgumentException {
+ // since optimization is a global property
+ // we've to implement it everywhere
+ return null;
+ }
+
+ public String getText() {
+ return null;
+ }
+
+ public char[] getTextCharacters() {
+ return new char[0];
+ }
+
+ public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException {
+ return 0;
+ }
+
+ public int getTextLength() {
+ return 0;
+ }
+
+ public int getTextStart() {
+ return 0;
+ }
+
+ public String getVersion() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean hasName() {
+ return true;
+ }
+
+ public boolean hasNext() throws XMLStreamException {
+ return currentState != END_ELEMENT_STATE;
+
+ }
+
+ public boolean hasText() {
+ return false;
+ }
+
+ public void init() {
+ // NOOP
+ }
+
+ public boolean isAttributeSpecified(int i) {
+ return i == 0;
+ }
+
+ public boolean isCharacters() {
+ return false;
+ }
+
+ public boolean isDone() {
+ return currentState == END_ELEMENT_STATE;
+ }
+
+ public boolean isEndElement() {
+ return currentState == END_ELEMENT_STATE;
+ }
+
+ public boolean isStandalone() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isStartElement() {
+ return currentState == START_ELEMENT_STATE;
+ }
+
+ public boolean isWhiteSpace() {
+ return false;
+ }
+
+ public int next() throws XMLStreamException {
+ int returnEvent = START_DOCUMENT;
+ switch (currentState) {
+ case START_ELEMENT_STATE:
+ currentState = END_ELEMENT_STATE;
+ returnEvent = END_ELEMENT;
+ break;
+ case END_ELEMENT_STATE:
+ throw new XMLStreamException("parser completed!");
+
+ }
+ return returnEvent;
+ }
+
+ public int nextTag() throws XMLStreamException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void require(int i, String string, String string1) throws XMLStreamException {
+ // nothing
+ }
+
+ public boolean standaloneSet() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2OutputStream.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2OutputStream.java
new file mode 100644
index 0000000000..34fbdf8c6f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2OutputStream.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import java.io.OutputStream;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+
+/**
+ * Push DOM Node to OutputStream
+ */
+@Service(Transformer.class)
+public class Node2OutputStream extends TransformerExtension<Node, OutputStream> implements
+ PushTransformer<Node, OutputStream> {
+ private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer();
+
+ public void transform(Node source, OutputStream writer, TransformationContext context) {
+ try {
+ Source domSource = new DOMSource(source);
+ Result result = new StreamResult(writer);
+ TRANSFORMER.transform(domSource, result, context);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return Node.class;
+ }
+
+ public Class getTargetType() {
+ return OutputStream.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2String.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2String.java
new file mode 100755
index 0000000000..92378e96a3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2String.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import java.io.StringWriter;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+
+/**
+ * Transform DOM Node to XML String
+ */
+@Service(org.apache.tuscany.spi.databinding.Transformer.class)
+public class Node2String extends TransformerExtension<Node, String> implements PullTransformer<Node, String> {
+ private static final Node2Writer TRANSFORMER = new Node2Writer();
+
+ public String transform(Node source, TransformationContext context) {
+ try {
+ StringWriter writer = new StringWriter();
+ TRANSFORMER.transform(source, writer, context);
+ return writer.toString();
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return Node.class;
+ }
+
+ public Class getTargetType() {
+ return String.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2Writer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2Writer.java
new file mode 100644
index 0000000000..96328fdd2f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2Writer.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import java.io.Writer;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+
+/**
+ * Push DOM Node to Writer
+ */
+@Service(Transformer.class)
+public class Node2Writer extends TransformerExtension<Node, Writer> implements PushTransformer<Node, Writer> {
+ private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer();
+
+ public void transform(Node source, Writer writer, TransformationContext context) {
+ try {
+ Source domSource = new DOMSource(source);
+ Result result = new StreamResult(writer);
+ TRANSFORMER.transform(domSource, result, context);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return Node.class;
+ }
+
+ public Class getTargetType() {
+ return Writer.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2XMLStreamReader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2XMLStreamReader.java
new file mode 100644
index 0000000000..0c75826ffa
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2XMLStreamReader.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+
+/**
+ * Transform DOM Node to XML XMLStreamReader
+ */
+@Service(Transformer.class)
+public class Node2XMLStreamReader extends TransformerExtension<Node, XMLStreamReader> implements
+ PullTransformer<Node, XMLStreamReader> {
+
+ public XMLStreamReader transform(Node source, TransformationContext context) {
+ try {
+ DOMXMLStreamReader reader = new DOMXMLStreamReader(source);
+ return new XMLDocumentStreamReader(reader);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return Node.class;
+ }
+
+ public Class getTargetType() {
+ return XMLStreamReader.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2Node.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2Node.java
new file mode 100644
index 0000000000..02de055c35
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2Node.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import java.io.Reader;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+
+/**
+ * Push DOM Reader to Node
+ */
+@Service(Transformer.class)
+public class Reader2Node extends TransformerExtension<Reader, Node> implements PullTransformer<Reader, Node> {
+ private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer();
+
+ public Node transform(Reader source, TransformationContext context) {
+ try {
+ Source streamSource = new StreamSource(source);
+ DOMResult result = new DOMResult();
+ TRANSFORMER.transform(streamSource, result, context);
+ return result.getNode();
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return Reader.class;
+ }
+
+ public Class getTargetType() {
+ return Node.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2SAX.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2SAX.java
new file mode 100644
index 0000000000..0a4504b3de
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2SAX.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import java.io.Reader;
+
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+
+/**
+ * Transform XML string to SAX
+ */
+@Service(Transformer.class)
+public class Reader2SAX extends TransformerExtension<Reader, ContentHandler> implements
+ PushTransformer<Reader, ContentHandler> {
+ public void transform(Reader source, ContentHandler target, TransformationContext context) {
+ try {
+ new InputSource2SAX().transform(new InputSource(source), target, context);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return Reader.class;
+ }
+
+ public Class getTargetType() {
+ return ContentHandler.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOM.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOM.java
new file mode 100644
index 0000000000..8f8f0f952e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOM.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tuscany.core.databinding.xml;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.tuscany.spi.databinding.extension.DOMHelper;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * SAX2DOM adapter
+ */
+public class SAX2DOM implements ContentHandler, LexicalHandler {
+ public static final String EMPTYSTRING = "";
+ public static final String XML_PREFIX = "xml";
+ public static final String XMLNS_PREFIX = "xmlns";
+ public static final String XMLNS_STRING = "xmlns:";
+ public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
+
+ private Node root;
+
+ private Document document;
+
+ private Node nextSibling;
+
+ private Stack<Node> nodeStk = new Stack<Node>();
+
+ private List<String> namespaceDecls;
+
+ private Node lastSibling;
+
+ public SAX2DOM() throws ParserConfigurationException {
+ this.document = DOMHelper.newDocument();
+ this.root = document;
+ }
+
+ public SAX2DOM(Node root, Node nextSibling) throws ParserConfigurationException {
+ this.root = root;
+ if (root instanceof Document) {
+ this.document = (Document)root;
+ } else if (root != null) {
+ this.document = root.getOwnerDocument();
+ } else {
+ this.document = DOMHelper.newDocument();
+ this.root = document;
+ }
+
+ this.nextSibling = nextSibling;
+ }
+
+ public SAX2DOM(Node root) throws ParserConfigurationException {
+ this(root, null);
+ }
+
+ public Node getDOM() {
+ return root;
+ }
+
+ public void characters(char[] ch, int start, int length) {
+ final Node last = (Node)nodeStk.peek();
+
+ // No text nodes can be children of root (DOM006 exception)
+ if (last != document) {
+ final String text = new String(ch, start, length);
+ if (lastSibling != null && lastSibling.getNodeType() == Node.TEXT_NODE) {
+ ((Text)lastSibling).appendData(text);
+ } else if (last == root && nextSibling != null) {
+ lastSibling = last.insertBefore(document.createTextNode(text), nextSibling);
+ } else {
+ lastSibling = last.appendChild(document.createTextNode(text));
+ }
+
+ }
+ }
+
+ public void startDocument() {
+ nodeStk.push(root);
+ }
+
+ public void endDocument() {
+ nodeStk.pop();
+ }
+
+ public void startElement(String namespace, String localName, String qName, Attributes attrs) {
+ final Element tmp = (Element)document.createElementNS(namespace, qName);
+
+ // Add namespace declarations first
+ if (namespaceDecls != null) {
+ final int nDecls = namespaceDecls.size();
+ for (int i = 0; i < nDecls; i++) {
+ final String prefix = (String)namespaceDecls.get(i++);
+
+ if (prefix == null || prefix.equals(EMPTYSTRING)) {
+ tmp.setAttributeNS(XMLNS_URI, XMLNS_PREFIX, (String)namespaceDecls.get(i));
+ } else {
+ tmp.setAttributeNS(XMLNS_URI, XMLNS_STRING + prefix, (String)namespaceDecls.get(i));
+ }
+ }
+ namespaceDecls.clear();
+ }
+
+ // Add attributes to element
+ final int nattrs = attrs.getLength();
+ for (int i = 0; i < nattrs; i++) {
+ if (attrs.getLocalName(i) == null) {
+ tmp.setAttribute(attrs.getQName(i), attrs.getValue(i));
+ } else {
+ tmp.setAttributeNS(attrs.getURI(i), attrs.getQName(i), attrs.getValue(i));
+ }
+ }
+
+ // Append this new node onto current stack node
+ Node last = (Node)nodeStk.peek();
+
+ // If the SAX2DOM is created with a non-null next sibling node,
+ // insert the result nodes before the next sibling under the root.
+ if (last == root && nextSibling != null) {
+ last.insertBefore(tmp, nextSibling);
+ } else {
+ last.appendChild(tmp);
+ }
+
+ // Push this node onto stack
+ nodeStk.push(tmp);
+ lastSibling = null;
+ }
+
+ public void endElement(String namespace, String localName, String qName) {
+ nodeStk.pop();
+ lastSibling = null;
+ }
+
+ public void startPrefixMapping(String prefix, String uri) {
+ if (namespaceDecls == null) {
+ namespaceDecls = new ArrayList<String>(2);
+ }
+ namespaceDecls.add(prefix);
+ namespaceDecls.add(uri);
+ }
+
+ public void endPrefixMapping(String prefix) {
+ // do nothing
+ }
+
+ /**
+ * This class is only used internally so this method should never be called.
+ */
+ public void ignorableWhitespace(char[] ch, int start, int length) {
+ }
+
+ /**
+ * adds processing instruction node to DOM.
+ */
+ public void processingInstruction(String target, String data) {
+ final Node last = (Node)nodeStk.peek();
+ ProcessingInstruction pi = document.createProcessingInstruction(target, data);
+ if (pi != null) {
+ if (last == root && nextSibling != null) {
+ last.insertBefore(pi, nextSibling);
+ } else {
+ last.appendChild(pi);
+ }
+
+ lastSibling = pi;
+ }
+ }
+
+ /**
+ * This class is only used internally so this method should never be called.
+ */
+ public void setDocumentLocator(Locator locator) {
+ }
+
+ /**
+ * This class is only used internally so this method should never be called.
+ */
+ public void skippedEntity(String name) {
+ }
+
+ /**
+ * Lexical Handler method to create comment node in DOM tree.
+ */
+ public void comment(char[] ch, int start, int length) {
+ final Node last = (Node)nodeStk.peek();
+ Comment comment = document.createComment(new String(ch, start, length));
+ if (comment != null) {
+ if (last == root && nextSibling != null) {
+ last.insertBefore(comment, nextSibling);
+ } else {
+ last.appendChild(comment);
+ }
+
+ lastSibling = comment;
+ }
+ }
+
+ // Lexical Handler methods- not implemented
+ public void startCDATA() {
+ }
+
+ public void endCDATA() {
+ }
+
+ public void startEntity(java.lang.String name) {
+ }
+
+ public void endDTD() {
+ }
+
+ public void endEntity(String name) {
+ }
+
+ public void startDTD(String name, String publicId, String systemId) throws SAXException {
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOMPipe.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOMPipe.java
new file mode 100644
index 0000000000..79118b4a2c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOMPipe.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.tuscany.spi.databinding.DataPipe;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+import org.xml.sax.ContentHandler;
+
+@Service(Transformer.class)
+public class SAX2DOMPipe extends TransformerExtension<ContentHandler, Node> implements
+ DataPipe<ContentHandler, Node> {
+ private SAX2DOM pipe;
+
+ /**
+ *
+ */
+ public SAX2DOMPipe() {
+ super();
+ try {
+ this.pipe = new SAX2DOM();
+ } catch (ParserConfigurationException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ public Node getResult() {
+ return pipe.getDOM();
+ }
+
+ public Class getTargetType() {
+ return Node.class;
+ }
+
+ public ContentHandler getSink() {
+ return pipe;
+ }
+
+ public Class getSourceType() {
+ return ContentHandler.class;
+ }
+
+ public int getWeight() {
+ return 30;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Source2ResultTransformer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Source2ResultTransformer.java
new file mode 100755
index 0000000000..7db14efb39
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Source2ResultTransformer.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerFactory;
+
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+
+/**
+ * Transform TrAX Source to Result
+ */
+@Service(org.apache.tuscany.spi.databinding.Transformer.class)
+public class Source2ResultTransformer extends TransformerExtension<Source, Result> implements
+ PushTransformer<Source, Result> {
+ private static final TransformerFactory FACTORY = TransformerFactory.newInstance();
+
+ public void transform(Source source, Result result, TransformationContext context) {
+ try {
+ javax.xml.transform.Transformer transformer = FACTORY.newTransformer();
+ transformer.transform(source, result);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return Source.class;
+ }
+
+ public Class getTargetType() {
+ return Result.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAX2SAXAdapter.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAX2SAXAdapter.java
new file mode 100644
index 0000000000..63fa53edb4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAX2SAXAdapter.java
@@ -0,0 +1,256 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * Adapter that converts from StAX to SAX event streams. Currently the following
+ * SAX events are not generated:
+ * <ul>
+ * <li>ignorableWhitespace</li>
+ * <li>skippedEntity</li>
+ * <ul>
+ * Also the following StAX events are not mapped:
+ * <ul>
+ * <li>CDATA</li>
+ * <li>COMMENT</li>
+ * <li>DTD</li>
+ * <li>ENTITY_DECLARATION</li>
+ * <li>ENTITY_REFERENCE</li>
+ * <li>NOTATION_DECLARATION</li>
+ * <li>SPACE</li>
+ * </ul>
+ * StAX ATTRIBUTE events are ignored but the equivalent attributes (derived from
+ * the START_ELEMENT event) are supplied in the SAX startElement event's
+ * Attributes parameter. If the adaptor is configured to pass namespace prefixes
+ * then namespace information will also be included in the Attributes; StAX
+ * NAMESPACE events are ignored. <p/> Another issue is namespace processing. If
+ * the reader is positioned at a sub-node, we cannot capture all the in-scope
+ * namespace bindings. Therefore we cannot re-create a proper SAX event stream
+ * from a StAX parser. <p/> For example <p/> &lt;a:root xmlns:a="foo"
+ * xmlns:b="bar"&gt;&lt;b:sub&gt;a:foo&lt;/b:sub&gt;&lt;/a:root&gt; <p/> And if
+ * you are handed a parser at &lt;b:sub&gt;, then your SAX events should look
+ * like: <p/> &lt;b:sub xmlns:a="foo" xmlns:b="bar"&gt;a:foo&lt;/b:sub&gt; <p/>
+ * not: <p/> &lt;b:sub&gt;a:foo&lt;/b:sub&gt; <p/> <p/> Proposal: we change the
+ * receiver of SAX events (SDOXMLResourceImpl) so that it uses NamespaceContext
+ * to resolve prefix (as opposed to record start/endPrefixMappings and use it
+ * for resolution.)
+ *
+ * @version $Rev$ $Date$
+ */
+public class StAX2SAXAdapter {
+ private final boolean namespacePrefixes;
+
+ /**
+ * Construct a new StAX to SAX adapter that will convert a StAX event stream
+ * into a SAX event stream.
+ *
+ * @param namespacePrefixes whether xmlns attributes should be included in
+ * startElement events;
+ */
+ public StAX2SAXAdapter(boolean namespacePrefixes) {
+ this.namespacePrefixes = namespacePrefixes;
+ }
+
+ /**
+ * Pull events from the StAX stream and dispatch to the SAX ContentHandler.
+ * The StAX stream would typically be located on a START_DOCUMENT or
+ * START_ELEMENT event and when this method returns it will be located on
+ * the associated END_DOCUMENT or END_ELEMENT event. Behaviour with other
+ * start events is undefined.
+ *
+ * @param reader StAX event source to read
+ * @param handler SAX ContentHandler for processing events
+ * @throws XMLStreamException if there was a problem reading the stream
+ * @throws SAXException passed through from the ContentHandler
+ */
+ public void parse(XMLStreamReader reader, ContentHandler handler) throws XMLStreamException, SAXException {
+ handler.setDocumentLocator(new LocatorAdaptor(reader.getLocation()));
+
+ // remembers the nest level of elements to know when we are done
+ int level = 0;
+ int event = reader.getEventType();
+ while (true) {
+ switch (event) {
+ case XMLStreamConstants.START_DOCUMENT:
+ level++;
+ handler.startDocument();
+ break;
+ case XMLStreamConstants.START_ELEMENT:
+ level++;
+ handleStartElement(reader, handler);
+ break;
+ case XMLStreamConstants.PROCESSING_INSTRUCTION:
+ handler.processingInstruction(reader.getPITarget(), reader.getPIData());
+ break;
+ case XMLStreamConstants.CHARACTERS:
+ handler.characters(reader.getTextCharacters(), reader.getTextStart(), reader
+ .getTextLength());
+ break;
+ case XMLStreamConstants.END_ELEMENT:
+ handleEndElement(reader, handler);
+ level--;
+ if (level == 0) {
+ return;
+ }
+ break;
+ case XMLStreamConstants.END_DOCUMENT:
+ handler.endDocument();
+ return;
+ /*
+ * uncomment to handle all events rather than just mapped
+ * ones // StAX events that are not mapped to SAX case
+ * XMLStreamConstants.COMMENT: case
+ * XMLStreamConstants.SPACE: case
+ * XMLStreamConstants.ENTITY_REFERENCE: case
+ * XMLStreamConstants.DTD: case XMLStreamConstants.CDATA:
+ * case XMLStreamConstants.NOTATION_DECLARATION: case
+ * XMLStreamConstants.ENTITY_DECLARATION: break; // StAX
+ * events handled in START_ELEMENT case
+ * XMLStreamConstants.ATTRIBUTE: case
+ * XMLStreamConstants.NAMESPACE: break; default: throw new
+ * AssertionError("Unknown StAX event: " + event);
+ */
+ }
+ event = reader.next();
+ }
+ }
+
+ private void handleStartElement(XMLStreamReader reader, ContentHandler handler) throws SAXException {
+ // send startPrefixMapping events immediately before startElement event
+ int nsCount = reader.getNamespaceCount();
+ for (int i = 0; i < nsCount; i++) {
+ String prefix = reader.getNamespacePrefix(i);
+ if (prefix == null) { // true for default namespace
+ prefix = "";
+ }
+ handler.startPrefixMapping(prefix, reader.getNamespaceURI(i));
+ }
+
+ // fire startElement
+ QName qname = reader.getName();
+ String prefix = qname.getPrefix();
+ String rawname;
+ if (prefix == null || prefix.length() == 0) {
+ rawname = qname.getLocalPart();
+ } else {
+ rawname = prefix + ':' + qname.getLocalPart();
+ }
+ Attributes attrs = getAttributes(reader);
+ handler.startElement(qname.getNamespaceURI(), qname.getLocalPart(), rawname, attrs);
+ }
+
+ private static void handleEndElement(XMLStreamReader reader, ContentHandler handler) throws SAXException {
+ // fire endElement
+ QName qname = reader.getName();
+ handler.endElement(qname.getNamespaceURI(), qname.getLocalPart(), qname.toString());
+
+ // send endPrefixMapping events immediately after endElement event
+ // we send them in the opposite order to that returned but this is not
+ // actually required by SAX
+ int nsCount = reader.getNamespaceCount();
+ for (int i = nsCount - 1; i >= 0; i--) {
+ String prefix = reader.getNamespacePrefix(i);
+ if (prefix == null) { // true for default namespace
+ prefix = "";
+ }
+ handler.endPrefixMapping(prefix);
+ }
+ }
+
+ /**
+ * Get the attributes associated with the current START_ELEMENT event.
+ *
+ * @return the StAX attributes converted to org.xml.sax.Attributes
+ */
+ private Attributes getAttributes(XMLStreamReader reader) {
+ assert reader.getEventType() == XMLStreamConstants.START_ELEMENT;
+
+ AttributesImpl attrs = new AttributesImpl();
+
+ // add namespace declarations if required
+ if (namespacePrefixes) {
+ for (int i = 0; i < reader.getNamespaceCount(); i++) {
+ String prefix = reader.getNamespacePrefix(i);
+ String uri = reader.getNamespaceURI(i);
+ attrs.addAttribute(null, prefix, "xmlns:" + prefix, "CDATA", uri);
+ }
+ }
+
+ // Regular attributes
+ for (int i = 0; i < reader.getAttributeCount(); i++) {
+ String uri = reader.getAttributeNamespace(i);
+ if (uri == null) {
+ uri = "";
+ }
+ String localName = reader.getAttributeLocalName(i);
+ String prefix = reader.getAttributePrefix(i);
+ String qname;
+ if (prefix == null || prefix.length() == 0) {
+ qname = localName;
+ } else {
+ qname = prefix + ':' + localName;
+ }
+ String type = reader.getAttributeType(i);
+ String value = reader.getAttributeValue(i);
+
+ attrs.addAttribute(uri, localName, qname, type, value);
+ }
+
+ return attrs;
+ }
+
+ /**
+ * Adaptor for mapping Locator information.
+ */
+ private static final class LocatorAdaptor implements Locator {
+ private final Location location;
+
+ private LocatorAdaptor(Location location) {
+ this.location = location;
+ }
+
+ public int getColumnNumber() {
+ return location == null ? 0 : location.getColumnNumber();
+ }
+
+ public int getLineNumber() {
+ return location == null ? 0 : location.getLineNumber();
+ }
+
+ public String getPublicId() {
+ return location == null ? "" : location.getPublicId();
+ }
+
+ public String getSystemId() {
+ return location == null ? "" : location.getSystemId();
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAXDataBinding.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAXDataBinding.java
new file mode 100644
index 0000000000..f21e4f3734
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAXDataBinding.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.xml;
+
+import java.lang.annotation.Annotation;
+
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.databinding.extension.DataBindingExtension;
+import org.apache.tuscany.spi.idl.XMLType;
+import org.apache.tuscany.spi.model.DataType;
+
+/**
+ * A DataBinding for the StAX
+ *
+ * @version $Rev$ $Date$
+ */
+public class StAXDataBinding extends DataBindingExtension {
+ public static final String NAME = XMLStreamReader.class.getName();
+ public static final String[] ALIASES = new String[] {"stax"};
+
+ public StAXDataBinding() {
+ super(NAME, ALIASES, XMLStreamReader.class);
+ }
+
+ public boolean introspect(DataType type, Annotation[] annotations) {
+ if (super.introspect(type, annotations)) {
+ type.setLogical(XMLType.UNKNOWN);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAXHelper.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAXHelper.java
new file mode 100755
index 0000000000..3ce9ca1144
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAXHelper.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Source;
+
+
+public final class StAXHelper {
+ private static final XMLInputFactory INPUT_FACTORY = XMLInputFactory.newInstance();
+ private static final XMLOutputFactory OUTPUT_FACTORY = XMLOutputFactory.newInstance();
+
+ private StAXHelper() {
+ }
+
+ public static XMLStreamReader createXMLStreamReader(InputStream inputStream) throws XMLStreamException {
+ return INPUT_FACTORY.createXMLStreamReader(inputStream);
+ }
+
+ public static XMLStreamReader createXMLStreamReader(Reader reader) throws XMLStreamException {
+ return INPUT_FACTORY.createXMLStreamReader(reader);
+ }
+
+ public static XMLStreamReader createXMLStreamReader(Source source) throws XMLStreamException {
+ return INPUT_FACTORY.createXMLStreamReader(source);
+ }
+
+ public static XMLStreamReader createXMLStreamReader(String string) throws XMLStreamException {
+ StringReader reader = new StringReader(string);
+ return createXMLStreamReader(reader);
+ }
+
+ public static String save(XMLStreamReader reader) throws XMLStreamException {
+ StringWriter writer = new StringWriter();
+ save(reader, writer);
+ return writer.toString();
+ }
+
+ public static void save(XMLStreamReader reader, OutputStream outputStream) throws XMLStreamException {
+ XMLStreamSerializer serializer = new XMLStreamSerializer();
+ XMLStreamWriter streamWriter = OUTPUT_FACTORY.createXMLStreamWriter(outputStream);
+ serializer.serialize(reader, streamWriter);
+ streamWriter.flush();
+ }
+
+ public static void save(XMLStreamReader reader, Writer writer) throws XMLStreamException {
+ XMLStreamSerializer serializer = new XMLStreamSerializer();
+ XMLStreamWriter streamWriter = OUTPUT_FACTORY.createXMLStreamWriter(writer);
+ serializer.serialize(reader, streamWriter);
+ streamWriter.flush();
+ }
+
+ public static void save(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException {
+ XMLStreamSerializer serializer = new XMLStreamSerializer();
+ serializer.serialize(reader, writer);
+ writer.flush();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StreamDataPipe.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StreamDataPipe.java
new file mode 100755
index 0000000000..d0b6ce07f2
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StreamDataPipe.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.tuscany.spi.databinding.DataPipe;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+
+@Service(Transformer.class)
+public class StreamDataPipe extends TransformerExtension<OutputStream, InputStream> implements
+ DataPipe<OutputStream, InputStream> {
+
+ private ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+ public InputStream getResult() {
+ return new ByteArrayInputStream(outputStream.toByteArray());
+ }
+
+ public Class getTargetType() {
+ return InputStream.class;
+ }
+
+ public int getWeight() {
+ return 50;
+ }
+
+ public OutputStream getSink() {
+ return outputStream;
+ }
+
+ public Class getSourceType() {
+ return OutputStream.class;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2Node.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2Node.java
new file mode 100755
index 0000000000..3f878a07b9
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2Node.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import java.io.StringReader;
+
+import javax.xml.parsers.DocumentBuilder;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.DOMHelper;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+
+@Service(Transformer.class)
+public class String2Node extends TransformerExtension<String, Node> implements PullTransformer<String, Node> {
+
+ public Node transform(String source, TransformationContext context) {
+ try {
+ DocumentBuilder builder = DOMHelper.newDocumentBuilder();
+ InputSource inputSource = new InputSource(new StringReader(source));
+ return builder.parse(inputSource);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return String.class;
+ }
+
+ public Class getTargetType() {
+ return Node.class;
+ }
+
+ public int getWeight() {
+ return 50;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2SAX.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2SAX.java
new file mode 100644
index 0000000000..50ea110b17
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2SAX.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import java.io.StringReader;
+
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+
+/**
+ * Transform XML string to SAX
+ */
+@Service(Transformer.class)
+public class String2SAX extends TransformerExtension<String, ContentHandler> implements
+ PushTransformer<String, ContentHandler> {
+
+ public void transform(String source, ContentHandler target, TransformationContext context) {
+ try {
+ new InputSource2SAX().transform(new InputSource(new StringReader(source)), target, context);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return String.class;
+ }
+
+ public Class getTargetType() {
+ return ContentHandler.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2XMLStreamReader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2XMLStreamReader.java
new file mode 100755
index 0000000000..9793cc3f7e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2XMLStreamReader.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+
+@Service(Transformer.class)
+public class String2XMLStreamReader extends TransformerExtension<String, XMLStreamReader> implements
+ PullTransformer<String, XMLStreamReader> {
+
+ public XMLStreamReader transform(String source, TransformationContext context) {
+ try {
+ return StAXHelper.createXMLStreamReader(source);
+ } catch (XMLStreamException e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return String.class;
+ }
+
+ public Class getTargetType() {
+ return XMLStreamReader.class;
+ }
+
+ public int getWeight() {
+ return 50;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/WrappingXMLStreamReader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/WrappingXMLStreamReader.java
new file mode 100644
index 0000000000..6fa6478bf0
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/WrappingXMLStreamReader.java
@@ -0,0 +1,230 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.namespace.QName;
+import javax.xml.namespace.NamespaceContext;
+
+public class WrappingXMLStreamReader implements XMLFragmentStreamReader {
+
+ private XMLStreamReader reader;
+
+ public WrappingXMLStreamReader(XMLStreamReader reader) {
+ this.reader = reader;
+ }
+
+ public boolean isDone() {
+ try {
+ return !hasNext();
+ } catch (XMLStreamException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Object getProperty(String string) throws IllegalArgumentException {
+ return reader.getProperty(string);
+ }
+
+ public int next() throws XMLStreamException {
+ return reader.next();
+ }
+
+ public void require(int i, String string, String string1) throws XMLStreamException {
+ // nothing to do
+ }
+
+ public String getElementText() throws XMLStreamException {
+ return reader.getElementText();
+ }
+
+ public int nextTag() throws XMLStreamException {
+ return reader.nextTag();
+ }
+
+ public boolean hasNext() throws XMLStreamException {
+ return reader.hasNext();
+ }
+
+ public void close() throws XMLStreamException {
+ reader.close();
+ }
+
+ public String getNamespaceURI(String string) {
+ return reader.getNamespaceURI(string);
+ }
+
+ public boolean isStartElement() {
+ return reader.isStartElement();
+ }
+
+ public boolean isEndElement() {
+ return reader.isEndElement();
+ }
+
+ public boolean isCharacters() {
+ return reader.isCharacters();
+ }
+
+ public boolean isWhiteSpace() {
+ return reader.isWhiteSpace();
+ }
+
+ public String getAttributeValue(String string, String string1) {
+ return reader.getAttributeValue(string, string1);
+ }
+
+ public int getAttributeCount() {
+ return reader.getAttributeCount();
+ }
+
+ public QName getAttributeName(int i) {
+ return reader.getAttributeName(i);
+ }
+
+ public String getAttributeNamespace(int i) {
+ return reader.getAttributeNamespace(i);
+ }
+
+ public String getAttributeLocalName(int i) {
+ return reader.getAttributeLocalName(i);
+ }
+
+ public String getAttributePrefix(int i) {
+ return reader.getAttributeLocalName(i);
+ }
+
+ public String getAttributeType(int i) {
+ return reader.getAttributeType(i);
+ }
+
+ public String getAttributeValue(int i) {
+ return reader.getAttributeValue(i);
+ }
+
+ public boolean isAttributeSpecified(int i) {
+ return reader.isAttributeSpecified(i);
+ }
+
+ public int getNamespaceCount() {
+ return reader.getNamespaceCount();
+ }
+
+ public String getNamespacePrefix(int i) {
+ return reader.getNamespacePrefix(i);
+ }
+
+ public String getNamespaceURI(int i) {
+ return reader.getNamespaceURI(i);
+ }
+
+ public NamespaceContext getNamespaceContext() {
+ return reader.getNamespaceContext();
+ }
+
+ public int getEventType() {
+ return reader.getEventType();
+ }
+
+ public String getText() {
+ return reader.getText();
+ }
+
+ public char[] getTextCharacters() {
+ return reader.getTextCharacters();
+ }
+
+ public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException {
+ return reader.getTextCharacters(i, chars, i1, i2);
+ }
+
+ public int getTextStart() {
+ return reader.getTextStart();
+ }
+
+ public int getTextLength() {
+ return reader.getTextLength();
+ }
+
+ public String getEncoding() {
+ return reader.getEncoding();
+ }
+
+ public boolean hasText() {
+ return reader.hasText();
+ }
+
+ public Location getLocation() {
+ return reader.getLocation();
+ }
+
+ public QName getName() {
+ return reader.getName();
+ }
+
+ public String getLocalName() {
+ return reader.getLocalName();
+ }
+
+ public boolean hasName() {
+ return reader.hasName();
+ }
+
+ public String getNamespaceURI() {
+ return reader.getNamespaceURI();
+ }
+
+ public String getPrefix() {
+ return reader.getPrefix();
+ }
+
+ public String getVersion() {
+ return reader.getVersion();
+ }
+
+ public boolean isStandalone() {
+ return reader.isStandalone();
+ }
+
+ public boolean standaloneSet() {
+ return reader.standaloneSet();
+ }
+
+ public String getCharacterEncodingScheme() {
+ return reader.getCharacterEncodingScheme();
+ }
+
+ public String getPITarget() {
+ return reader.getPITarget();
+ }
+
+ public String getPIData() {
+ return reader.getPIData();
+ }
+
+ public void setParentNamespaceContext(NamespaceContext nsContext) {
+ // nothing to do here
+ }
+
+ public void init() {
+ // Nothing to do here
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Writer2ReaderDataPipe.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Writer2ReaderDataPipe.java
new file mode 100755
index 0000000000..c66d0fd934
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Writer2ReaderDataPipe.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+
+import org.apache.tuscany.spi.databinding.DataPipe;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+
+@Service(Transformer.class)
+public class Writer2ReaderDataPipe extends TransformerExtension<Writer, Reader> implements DataPipe<Writer, Reader> {
+
+ private StringWriter writer = new StringWriter();
+
+ public Reader getResult() {
+ return new StringReader(writer.toString());
+ }
+
+ public Class getTargetType() {
+ return Reader.class;
+ }
+
+ public int getWeight() {
+ return 50;
+ }
+
+ public Writer getSink() {
+ return writer;
+ }
+
+ public Class getSourceType() {
+ return Writer.class;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLDocumentStreamReader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLDocumentStreamReader.java
new file mode 100644
index 0000000000..993516fa19
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLDocumentStreamReader.java
@@ -0,0 +1,432 @@
+package org.apache.tuscany.core.databinding.xml;
+
+import java.util.NoSuchElementException;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+/**
+ * This class is derived from Apache Axis2 class
+ * org.apache.axis2.util.StreamWrapper</a>. It's used wrap a XMLStreamReader to
+ * create a XMLStreamReader representing a document and it will produce
+ * START_DOCUMENT, END_DOCUMENT events.
+ */
+public class XMLDocumentStreamReader implements XMLStreamReader {
+ private static final int STATE_COMPLETE_AT_NEXT = 2; // The wrapper
+ // will produce
+ // END_DOCUMENT
+
+ private static final int STATE_COMPLETED = 3; // Done
+
+ private static final int STATE_INIT = 0; // The wrapper will produce
+ // START_DOCUMENT
+
+ private static final int STATE_SWITCHED = 1; // The real reader will
+ // produce events
+
+ private XMLStreamReader realReader;
+
+ private int state = STATE_INIT;
+
+ public XMLDocumentStreamReader(XMLStreamReader realReader) {
+ if (realReader == null) {
+ throw new UnsupportedOperationException("Reader cannot be null");
+ }
+
+ this.realReader = realReader;
+
+ if (realReader instanceof XMLFragmentStreamReader) {
+ ((XMLFragmentStreamReader)realReader).init();
+ }
+
+ // If the real reader is positioned at START_DOCUMENT, always use
+ // the real reader
+ if (realReader.getEventType() == START_DOCUMENT) {
+ state = STATE_SWITCHED;
+ }
+ }
+
+ public void close() throws XMLStreamException {
+ realReader.close();
+ }
+
+ public int getAttributeCount() {
+ if (isDelegating()) {
+ return realReader.getAttributeCount();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeLocalName(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributeLocalName(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public QName getAttributeName(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributeName(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeNamespace(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributeNamespace(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributePrefix(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributePrefix(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeType(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributeType(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeValue(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributeValue(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeValue(String s, String s1) {
+ if (isDelegating()) {
+ return realReader.getAttributeValue(s, s1);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getCharacterEncodingScheme() {
+ return realReader.getCharacterEncodingScheme();
+ }
+
+ public String getElementText() throws XMLStreamException {
+ if (isDelegating()) {
+ return realReader.getElementText();
+ } else {
+ throw new XMLStreamException();
+ }
+ }
+
+ public String getEncoding() {
+ return realReader.getEncoding();
+ }
+
+ public int getEventType() {
+ int event = -1;
+ switch (state) {
+ case STATE_SWITCHED:
+ case STATE_COMPLETE_AT_NEXT:
+ event = realReader.getEventType();
+ break;
+ case STATE_INIT:
+ event = START_DOCUMENT;
+ break;
+ case STATE_COMPLETED:
+ event = END_DOCUMENT;
+ break;
+ }
+ return event;
+ }
+
+ public String getLocalName() {
+ if (isDelegating()) {
+ return realReader.getLocalName();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public Location getLocation() {
+ if (isDelegating()) {
+ return realReader.getLocation();
+ } else {
+ return null;
+ }
+ }
+
+ public QName getName() {
+ if (isDelegating()) {
+ return realReader.getName();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public NamespaceContext getNamespaceContext() {
+ return realReader.getNamespaceContext();
+ }
+
+ public int getNamespaceCount() {
+ if (isDelegating()) {
+ return realReader.getNamespaceCount();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getNamespacePrefix(int i) {
+ if (isDelegating()) {
+ return realReader.getNamespacePrefix(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getNamespaceURI() {
+ if (isDelegating()) {
+ return realReader.getNamespaceURI();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getNamespaceURI(int i) {
+ if (isDelegating()) {
+ return realReader.getNamespaceURI(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getNamespaceURI(String s) {
+ if (isDelegating()) {
+ return realReader.getNamespaceURI(s);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getPIData() {
+ if (isDelegating()) {
+ return realReader.getPIData();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getPITarget() {
+ if (isDelegating()) {
+ return realReader.getPITarget();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getPrefix() {
+ if (isDelegating()) {
+ return realReader.getPrefix();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public Object getProperty(String s) throws IllegalArgumentException {
+ if (isDelegating()) {
+ return realReader.getProperty(s);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ public String getText() {
+ if (isDelegating()) {
+ return realReader.getText();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public char[] getTextCharacters() {
+ if (isDelegating()) {
+ return realReader.getTextCharacters();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException {
+ if (isDelegating()) {
+ return realReader.getTextCharacters(i, chars, i1, i2);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextLength() {
+ if (isDelegating()) {
+ return realReader.getTextLength();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextStart() {
+ if (isDelegating()) {
+ return realReader.getTextStart();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getVersion() {
+ if (isDelegating()) {
+ return realReader.getVersion();
+ } else {
+ return null;
+ }
+ }
+
+ public boolean hasName() {
+ if (isDelegating()) {
+ return realReader.hasName();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean hasNext() throws XMLStreamException {
+ if (state == STATE_COMPLETE_AT_NEXT) {
+ return true;
+ } else if (state == STATE_COMPLETED) {
+ return false;
+ } else if (state == STATE_SWITCHED) {
+ return realReader.hasNext();
+ } else {
+ return true;
+ }
+ }
+
+ public boolean hasText() {
+ if (isDelegating()) {
+ return realReader.hasText();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isAttributeSpecified(int i) {
+ if (isDelegating()) {
+ return realReader.isAttributeSpecified(i);
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isCharacters() {
+ if (isDelegating()) {
+ return realReader.isCharacters();
+ } else {
+ return false;
+ }
+ }
+
+ private boolean isDelegating() {
+ return state == STATE_SWITCHED || state == STATE_COMPLETE_AT_NEXT;
+ }
+
+ public boolean isEndElement() {
+ if (isDelegating()) {
+ return realReader.isEndElement();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isStandalone() {
+ if (isDelegating()) {
+ return realReader.isStandalone();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isStartElement() {
+ if (isDelegating()) {
+ return realReader.isStartElement();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isWhiteSpace() {
+ if (isDelegating()) {
+ return realReader.isWhiteSpace();
+ } else {
+ return false;
+ }
+ }
+
+ public int next() throws XMLStreamException {
+ int returnEvent;
+
+ switch (state) {
+ case STATE_SWITCHED:
+ returnEvent = realReader.next();
+ if (returnEvent == END_DOCUMENT) {
+ state = STATE_COMPLETED;
+ } else if (!realReader.hasNext()) {
+ state = STATE_COMPLETE_AT_NEXT;
+ }
+ break;
+ case STATE_INIT:
+ state = STATE_SWITCHED;
+ returnEvent = realReader.getEventType();
+ break;
+ case STATE_COMPLETE_AT_NEXT:
+ state = STATE_COMPLETED;
+ returnEvent = END_DOCUMENT;
+ break;
+ case STATE_COMPLETED:
+ // oops - no way we can go beyond this
+ throw new NoSuchElementException("End of stream has reached.");
+ default:
+ throw new UnsupportedOperationException();
+ }
+
+ return returnEvent;
+ }
+
+ public int nextTag() throws XMLStreamException {
+ if (isDelegating()) {
+ return realReader.nextTag();
+ } else {
+ throw new XMLStreamException();
+ }
+ }
+
+ public void require(int i, String s, String s1) throws XMLStreamException {
+ if (isDelegating()) {
+ realReader.require(i, s, s1);
+ }
+ }
+
+ public boolean standaloneSet() {
+ if (isDelegating()) {
+ return realReader.standaloneSet();
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLFragmentStreamReader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLFragmentStreamReader.java
new file mode 100644
index 0000000000..f54a43bb29
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLFragmentStreamReader.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamReader;
+
+public interface XMLFragmentStreamReader extends XMLStreamReader {
+ QName NIL_QNAME = new QName("http://www.w3.org/2001/XMLSchema-instance", "nil", "xsi");
+ String NIL_VALUE_TRUE = "true";
+
+ /**
+ * this will help to handle Text within the current element. user should
+ * pass the element text to the property list as this ELEMENT_TEXT as the
+ * key. This key deliberately has a space in it so that it is not a valid
+ * XML name
+ */
+ String ELEMENT_TEXT = "Element Text";
+
+ /**
+ * Extra method to query the state of the pullparser
+ */
+ boolean isDone();
+
+ /**
+ * add the parent namespace context to this parser
+ */
+ void setParentNamespaceContext(NamespaceContext nsContext);
+
+ /**
+ * Initiate the parser - this will do whatever the needed tasks to initiate
+ * the parser and must be called before attempting any specific parsing
+ * using this parser
+ */
+ void init();
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLFragmentStreamReaderImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLFragmentStreamReaderImpl.java
new file mode 100644
index 0000000000..fe67225f81
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLFragmentStreamReaderImpl.java
@@ -0,0 +1,857 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+/**
+ * This is the new implementation of the XMLFramentStreamReader. The approach
+ * here is simple When the pull parser needs to generate events for a particular
+ * name-value(s) pair it always handes over (delegates) the task to another pull
+ * parser which knows how to deal with it The common types of name value pairs
+ * we'll come across are
+ * <ul>
+ * <li> String name/QName name - String value
+ * <li> String name/QName name - String[] value
+ * <li> QName name/String name - XMLStreamReader value
+ * <li> QName name/String name - XMLStreamable value
+ * <li> QName name/String name - Java bean
+ * <li> QName name/String name - Datahandler
+ *
+ * </ul>
+ * <p/> As for the attributes, these are the possible combinations in the array
+ * <ul>
+ * <li> String name/QName name - String value
+ * </ul>
+ * Note that certain array methods have been deliberately removed to avoid
+ * complications. The generated code will take the trouble to lay the elements
+ * of the array in the correct order <p/> <p/> Hence there will be a parser impl
+ * that knows how to handle these types, and this parent parser will always
+ * delegate these tasks to the child pullparasers in effect this is one huge
+ * state machine that has only a few states and delegates things down to the
+ * child parsers whenever possible <p/>
+ *
+ * @version $Rev$ $Date$
+ */
+public class XMLFragmentStreamReaderImpl implements XMLFragmentStreamReader {
+
+ private static final int DELEGATED_STATE = 2;
+ private static final int END_ELEMENT_STATE = 1;
+ // states for this pullparser - it can only have four states
+ private static final int START_ELEMENT_STATE = 0;
+ private static final int TEXT_STATE = 3;
+
+ protected NamedProperty[] attributes;
+
+ // reference to the child reader
+ protected XMLFragmentStreamReader childReader;
+ // current property index
+ // initialized at zero
+ protected int index;
+ protected Map<String, String> declaredNamespaceMap = new HashMap<String, String>();
+ protected QName elementQName;
+
+ // we always create a new namespace context
+ protected DelegatingNamespaceContext namespaceContext = new DelegatingNamespaceContext();
+
+ protected NamedProperty[] elements;
+
+ // integer field that keeps the state of this
+ // parser.
+ protected int state = START_ELEMENT_STATE;
+
+ /*
+ * we need to pass in a namespace context since when delegated, we've no
+ * idea of the current namespace context. So it needs to be passed on here!
+ */
+ public XMLFragmentStreamReaderImpl(QName elementQName, NamedProperty[] elements, NamedProperty[] attributes) {
+ // validate the lengths, since both the arrays are supposed
+ // to have
+ this.elements = elements == null ? new NamedProperty[0] : elements;
+ this.elementQName = elementQName;
+ this.attributes = attributes == null ? new NamedProperty[0] : attributes;
+ }
+
+ protected XMLFragmentStreamReaderImpl(QName elementQName) {
+ this.elementQName = elementQName;
+ }
+
+ /**
+ * add the namespace context
+ */
+
+ public void setParentNamespaceContext(NamespaceContext nsContext) {
+ // register the namespace context passed in to this
+ this.namespaceContext.setParentNsContext(nsContext);
+
+ }
+
+ protected NamedProperty[] getElements() {
+ return elements;
+ }
+
+ protected NamedProperty[] getAttributes() {
+ return attributes;
+ }
+
+ protected QName[] getNamespaces() {
+ return new QName[0];
+ }
+
+ /**
+ * @param prefix
+ * @param uri
+ */
+ protected void addToNsMap(String prefix, String uri) {
+ if (!uri.equals(namespaceContext.getNamespaceURI(prefix))) {
+ namespaceContext.pushNamespace(prefix, uri);
+ declaredNamespaceMap.put(prefix, uri);
+ }
+ }
+
+ public void close() throws XMLStreamException {
+ // do nothing here - we have no resources to free
+ }
+
+ public int getAttributeCount() {
+ return (state == DELEGATED_STATE) ? childReader.getAttributeCount() : (state == START_ELEMENT_STATE
+ ? getAttributes().length : 0);
+ }
+
+ public String getAttributeLocalName(int i) {
+ if (state == DELEGATED_STATE) {
+ return childReader.getAttributeLocalName(i);
+ } else if (state == START_ELEMENT_STATE) {
+ QName name = getAttributeName(i);
+ if (name == null) {
+ return null;
+ } else {
+ return name.getLocalPart();
+ }
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * @param i
+ */
+ public QName getAttributeName(int i) {
+ if (state == DELEGATED_STATE) {
+ return childReader.getAttributeName(i);
+ } else if (state == START_ELEMENT_STATE) {
+ if ((i >= (getAttributes().length)) || i < 0) { // out of range
+ return null;
+ } else {
+ // get the attribute pointer
+ QName attribPointer = getAttributes()[i].getKey();
+ // case one - attrib name is null
+ // this should be the pointer to the OMAttribute then
+ if (attribPointer == null) {
+ throw new UnsupportedOperationException();
+ } else if (attribPointer instanceof QName) {
+ return (QName)attribPointer;
+ } else {
+ return null;
+ }
+ }
+ } else {
+ throw new IllegalStateException(); // as per the api contract
+ }
+
+ }
+
+ public String getAttributeNamespace(int i) {
+ if (state == DELEGATED_STATE) {
+ return childReader.getAttributeNamespace(i);
+ } else if (state == START_ELEMENT_STATE) {
+ QName name = getAttributeName(i);
+ if (name == null) {
+ return null;
+ } else {
+ return name.getNamespaceURI();
+ }
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributePrefix(int i) {
+ if (state == DELEGATED_STATE) {
+ return childReader.getAttributePrefix(i);
+ } else if (state == START_ELEMENT_STATE) {
+ QName name = getAttributeName(i);
+ if (name == null) {
+ return null;
+ } else {
+ return name.getPrefix();
+ }
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeType(int i) {
+ return null; // not supported
+ }
+
+ public String getAttributeValue(int i) {
+ if (state == DELEGATED_STATE) {
+ return childReader.getAttributeValue(i);
+ } else if (state == START_ELEMENT_STATE) {
+ if ((i >= (getAttributes().length)) || i < 0) { // out of range
+ return null;
+ } else {
+ // get the attribute pointer
+ QName attribPointer = getAttributes()[i].getKey();
+ Object omAttribObj = getAttributes()[i].getValue();
+ // case one - attrib name is null
+ // this should be the pointer to the OMAttribute then
+ if (attribPointer == null) {
+ throw new UnsupportedOperationException();
+ } else if (attribPointer instanceof QName) {
+ return (String)omAttribObj;
+ } else {
+ return null;
+ }
+ }
+ } else {
+ throw new IllegalStateException();
+ }
+
+ }
+
+ public String getAttributeValue(String nsUri, String localName) {
+
+ int attribCount = getAttributeCount();
+ String returnValue = null;
+ QName attribQualifiedName;
+ for (int i = 0; i < attribCount; i++) {
+ attribQualifiedName = getAttributeName(i);
+ if (nsUri == null) {
+ if (localName.equals(attribQualifiedName.getLocalPart())) {
+ returnValue = getAttributeValue(i);
+ break;
+ }
+ } else {
+ if (localName.equals(attribQualifiedName.getLocalPart()) && nsUri.equals(attribQualifiedName
+ .getNamespaceURI())) {
+ returnValue = getAttributeValue(i);
+ break;
+ }
+ }
+
+ }
+
+ return returnValue;
+ }
+
+ public String getCharacterEncodingScheme() {
+ return null; // todo - should we return something for this ?
+ }
+
+ /**
+ * todo implement the right contract for this
+ *
+ * @throws XMLStreamException
+ */
+ public String getElementText() throws XMLStreamException {
+ if (state == DELEGATED_STATE) {
+ return childReader.getElementText();
+ } else {
+ return null;
+ }
+
+ }
+
+ // /////////////////////////////////////////////////////////////////////////
+ // / attribute handling
+ // /////////////////////////////////////////////////////////////////////////
+
+ public String getEncoding() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getEncoding();
+ } else {
+ // we've no idea what the encoding is going to be in this case
+ // perhaps we ought to return some constant here, which the user
+ // might
+ // have access to change!
+ return null;
+ }
+ }
+
+ public int getEventType() {
+ if (state == START_ELEMENT_STATE) {
+ return START_ELEMENT;
+ } else if (state == END_ELEMENT_STATE) {
+ return END_ELEMENT;
+ } else if (state == TEXT_STATE) {
+ return CHARACTERS;
+ } else { // this is the delegated state
+ return childReader.getEventType();
+ }
+ }
+
+ public String getLocalName() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getLocalName();
+ } else if (state != TEXT_STATE) {
+ return elementQName.getLocalPart();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ */
+ public Location getLocation() {
+ // return a default location
+ return new Location() {
+ public int getCharacterOffset() {
+ return 0;
+ }
+
+ public int getColumnNumber() {
+ return 0;
+ }
+
+ public int getLineNumber() {
+ return 0;
+ }
+
+ public String getPublicId() {
+ return null;
+ }
+
+ public String getSystemId() {
+ return null;
+ }
+ };
+ }
+
+ public QName getName() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getName();
+ } else if (state != TEXT_STATE) {
+ return elementQName;
+ } else {
+ throw new IllegalStateException();
+ }
+
+ }
+
+ public NamespaceContext getNamespaceContext() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getNamespaceContext();
+ } else {
+ return namespaceContext;
+ }
+
+ }
+
+ public int getNamespaceCount() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getNamespaceCount();
+ } else {
+ return declaredNamespaceMap.size();
+ }
+ }
+
+ /**
+ * @param i
+ */
+ public String getNamespacePrefix(int i) {
+ if (state == DELEGATED_STATE) {
+ return childReader.getNamespacePrefix(i);
+ } else if (state != TEXT_STATE) {
+ // order the prefixes
+ String[] prefixes = makePrefixArray();
+ if ((i >= prefixes.length) || (i < 0)) {
+ return null;
+ } else {
+ return prefixes[i];
+ }
+
+ } else {
+ throw new IllegalStateException();
+ }
+
+ }
+
+ public String getNamespaceURI() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getNamespaceURI();
+ } else if (state == TEXT_STATE) {
+ return null;
+ } else {
+ return elementQName.getNamespaceURI();
+ }
+ }
+
+ // /////////////////////////////////////////////////////////////////////////
+ // //////////// end of attribute handling
+ // /////////////////////////////////////////////////////////////////////////
+
+ // //////////////////////////////////////////////////////////////////////////
+ // //////////// namespace handling
+ // //////////////////////////////////////////////////////////////////////////
+
+ public String getNamespaceURI(int i) {
+ if (state == DELEGATED_STATE) {
+ return childReader.getNamespaceURI(i);
+ } else if (state != TEXT_STATE) {
+ String namespacePrefix = getNamespacePrefix(i);
+ return namespacePrefix == null ? null : (String)declaredNamespaceMap.get(namespacePrefix);
+ } else {
+ throw new IllegalStateException();
+ }
+
+ }
+
+ public String getNamespaceURI(String prefix) {
+ return namespaceContext.getNamespaceURI(prefix);
+ }
+
+ public String getPIData() {
+ throw new UnsupportedOperationException("Yet to be implemented !!");
+ }
+
+ public String getPITarget() {
+ throw new UnsupportedOperationException("Yet to be implemented !!");
+ }
+
+ public String getPrefix() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getPrefix();
+ } else if (state == TEXT_STATE) {
+ return null;
+ } else {
+ String prefix = elementQName.getPrefix();
+ return "".equals(prefix) ? null : prefix;
+ }
+ }
+
+ // /////////////////////////////////////////////////////////////////////////
+ // /////// end of namespace handling
+ // /////////////////////////////////////////////////////////////////////////
+
+ /**
+ * @param key
+ * @throws IllegalArgumentException
+ */
+ public Object getProperty(String key) throws IllegalArgumentException {
+ if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) {
+ return null;
+ } else if (state == TEXT_STATE) {
+ return null;
+ } else if (state == DELEGATED_STATE) {
+ return childReader.getProperty(key);
+ } else {
+ return null;
+ }
+
+ }
+
+ public String getText() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getText();
+ } else if (state == TEXT_STATE) {
+ return (String)getElements()[index - 1].getValue();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public char[] getTextCharacters() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getTextCharacters();
+ } else if (state == TEXT_STATE) {
+ return getElements()[index - 1].getValue() == null ? new char[0] : ((String)getElements()[index - 1]
+ .getValue()).toCharArray();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ private int copy(int sourceStart, char[] target, int targetStart, int length) {
+ char[] source = getTextCharacters();
+ if (sourceStart > source.length) {
+ throw new IndexOutOfBoundsException("source start > source length");
+ }
+ int sourceLen = source.length - sourceStart;
+ if (length > sourceLen) {
+ length = sourceLen;
+ }
+ System.arraycopy(source, sourceStart, target, targetStart, length);
+ return sourceLen;
+ }
+
+ public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException {
+ if (state == DELEGATED_STATE) {
+ return childReader.getTextCharacters(i, chars, i1, i2);
+ } else if (state == TEXT_STATE) {
+ return copy(i, chars, i1, i2);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextLength() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getTextLength();
+ } else if (state == TEXT_STATE) {
+ return getTextCharacters().length;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextStart() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getTextStart();
+ } else if (state == TEXT_STATE) {
+ return 0; // assume text always starts at 0
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getVersion() {
+ return null;
+ }
+
+ public boolean hasName() {
+ // since this parser always has a name, the hasname
+ // has to return true if we are still navigating this element
+ // if not we should ask the child reader for it.
+ if (state == DELEGATED_STATE) {
+ return childReader.hasName();
+ } else {
+ return state != TEXT_STATE;
+ }
+ }
+
+ /**
+ * @throws XMLStreamException
+ */
+ public boolean hasNext() throws XMLStreamException {
+ if (state == DELEGATED_STATE) {
+ if (childReader.isDone()) {
+ // the child reader is done. We shouldn't be getting the
+ // hasnext result from the child pullparser then
+ return true;
+ } else {
+ return childReader.hasNext();
+ }
+ } else {
+ return state == START_ELEMENT_STATE || state == TEXT_STATE;
+
+ }
+ }
+
+ /**
+ * check the validity of this implementation
+ */
+ public boolean hasText() {
+ if (state == DELEGATED_STATE) {
+ return childReader.hasText();
+ } else {
+ return state == TEXT_STATE;
+ }
+
+ }
+
+ /**
+ * we need to split out the calling to the populate namespaces seperately
+ * since this needs to be done *after* setting the parent namespace context.
+ * We cannot assume it will happen at construction!
+ */
+ public void init() {
+ // here we have an extra issue to attend to. we need to look at the
+ // prefixes and uris (the combination) and populate a hashmap of
+ // namespaces. The hashmap of namespaces will be used to serve the
+ // namespace context
+
+ populateNamespaceContext();
+ }
+
+ public boolean isAttributeSpecified(int i) {
+ return false; // not supported
+ }
+
+ public boolean isCharacters() {
+ if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) {
+ return false;
+ }
+ return childReader.isCharacters();
+ }
+
+ /**
+ * are we done ?
+ */
+ public boolean isDone() {
+ return state == END_ELEMENT_STATE;
+ }
+
+ public boolean isEndElement() {
+ if (state == START_ELEMENT_STATE) {
+ return false;
+ } else if (state == END_ELEMENT_STATE) {
+ return true;
+ }
+ return childReader.isEndElement();
+ }
+
+ public boolean isStandalone() {
+ return true;
+ }
+
+ public boolean isStartElement() {
+ if (state == START_ELEMENT_STATE) {
+ return true;
+ } else if (state == END_ELEMENT_STATE) {
+ return false;
+ }
+ return childReader.isStartElement();
+ }
+
+ public boolean isWhiteSpace() {
+ if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) {
+ return false;
+ }
+ return childReader.isWhiteSpace();
+ }
+
+ /**
+ * Get the prefix list from the hastable and take that into an array
+ */
+ private String[] makePrefixArray() {
+ String[] prefixes = (String[])declaredNamespaceMap.keySet().toArray(new String[declaredNamespaceMap.size()]);
+ Arrays.sort(prefixes);
+ return prefixes;
+ }
+
+ /**
+ * By far this should be the most important method in this class this method
+ * changes the state of the parser
+ */
+ public int next() throws XMLStreamException {
+ int returnEvent = -1; // invalid state is the default state
+ switch (state) {
+ case START_ELEMENT_STATE:
+ // current element is start element. We should be looking at the
+ // property list and making a pullparser for the property value
+ if (getElements() == null || getElements().length == 0) {
+ // no properties - move to the end element state
+ // straightaway
+ state = END_ELEMENT_STATE;
+ returnEvent = END_ELEMENT;
+ } else {
+ // there are properties. now we should delegate this task to
+ // a
+ // child reader depending on the property type
+ returnEvent = processProperties();
+
+ }
+ break;
+ case END_ELEMENT_STATE:
+ // we've reached the end element already. If the user tries to
+ // push
+ // further ahead then it is an exception
+ throw new XMLStreamException("Trying to go beyond the end of the pullparser");
+
+ case DELEGATED_STATE:
+ if (childReader.isDone()) {
+ // we've reached the end!
+ if (index > (getElements().length - 1)) {
+ state = END_ELEMENT_STATE;
+ returnEvent = END_ELEMENT;
+ } else {
+ returnEvent = processProperties();
+ }
+ } else {
+ returnEvent = childReader.next();
+ }
+ break;
+
+ case TEXT_STATE:
+ // if there are any more event we should be delegating to
+ // processProperties. if not we just return an end element
+ if (index > (getElements().length - 1)) {
+ state = END_ELEMENT_STATE;
+ returnEvent = END_ELEMENT;
+ } else {
+ returnEvent = processProperties();
+ }
+ break;
+ }
+ return returnEvent;
+ }
+
+ // /////////////////////////////////////////////////////////////////////////
+ // / Other utility methods
+ // ////////////////////////////////////////////////////////////////////////
+
+ /**
+ * todo implement this
+ *
+ * @throws XMLStreamException
+ */
+ public int nextTag() throws XMLStreamException {
+ return 0;
+ }
+
+ /**
+ * Populates a namespace context
+ */
+ private void populateNamespaceContext() {
+
+ // first add the current element namespace to the namespace context
+ // declare it if not found
+ addToNsMap(elementQName.getPrefix(), elementQName.getNamespaceURI());
+
+ for (QName n : getNamespaces()) {
+ addToNsMap(n.getPrefix(), n.getNamespaceURI());
+ }
+
+ // traverse through the attributes and populate the namespace context
+ // the attrib list can be of many combinations
+ // the valid combinations are
+ // String - String
+ // QName - QName
+ // null - OMAttribute
+
+ for (int i = 0; i < getAttributes().length; i++) { // jump in two
+ QName attrQName = getAttributes()[i].getKey();
+ if (!"".equals(attrQName.getNamespaceURI())) {
+ addToNsMap(attrQName.getPrefix(), attrQName.getNamespaceURI());
+ }
+ }
+ }
+
+ /**
+ * A convenient method to reuse the properties
+ *
+ * @return event to be thrown
+ * @throws XMLStreamException
+ */
+ private int processProperties() throws XMLStreamException {
+ // move to the next property depending on the current property
+ // index
+ QName propertyQName = getElements()[index].getKey();
+ boolean textFound = false;
+ if (propertyQName == null) {
+ throw new XMLStreamException("property key cannot be null!");
+ } else if (ELEMENT_TEXT.equals(propertyQName.getLocalPart())) {
+ // propPointer being a String has a special case
+ // that is it can be a the special constant ELEMENT_TEXT that
+ // says this text event
+ textFound = true;
+ }
+
+ // ok! we got the key. Now look at the value
+ Object propertyValue = getElements()[index].getValue();
+ // cater for the special case now
+ if (textFound) {
+ // no delegation here - make the parser null and immediately
+ // return with the event characters
+ childReader = null;
+ state = TEXT_STATE;
+ ++index;
+ return CHARACTERS;
+ } else if (propertyValue == null) {
+ // if the value is null we delegate the work to a nullable
+ // parser
+ childReader = new NilElementStreamReader(propertyQName);
+ childReader.setParentNamespaceContext(this.namespaceContext);
+ childReader.init();
+ } else if (propertyValue instanceof String) {
+ // strings are handled by the NameValuePairStreamReader
+ childReader = new NameValuePairStreamReader(propertyQName, (String)propertyValue);
+ childReader.setParentNamespaceContext(this.namespaceContext);
+ childReader.init();
+ } else if (propertyValue instanceof String[]) {
+ // string[] are handled by the NameValueArrayStreamReader
+ // if the array is empty - skip it
+ if (((String[])propertyValue).length == 0) {
+ // advance the index
+ ++index;
+ return processProperties();
+ } else {
+ childReader = new NameValueArrayStreamReader(propertyQName, (String[])propertyValue);
+ childReader.setParentNamespaceContext(this.namespaceContext);
+ childReader.init();
+ }
+
+ } else if (propertyValue instanceof XMLStreamable) {
+ // ADBbean has it's own method to get a reader
+ XMLStreamReader reader = ((XMLStreamable)propertyValue).getXMLStreamReader(propertyQName);
+ // we know for sure that this is an ADB XMLStreamreader.
+ // However we need to make sure that it is compatible
+ if (reader instanceof XMLFragmentStreamReader) {
+ childReader = (XMLFragmentStreamReader)reader;
+ childReader.setParentNamespaceContext(this.namespaceContext);
+ childReader.init();
+ } else {
+ // wrap it to make compatible
+ childReader = new WrappingXMLStreamReader(reader);
+ }
+ } else if (propertyValue instanceof XMLStreamReader) {
+ XMLStreamReader reader = (XMLStreamReader)propertyValue;
+ if (reader instanceof XMLFragmentStreamReader) {
+ childReader = (XMLFragmentStreamReader)reader;
+ childReader.setParentNamespaceContext(this.namespaceContext);
+ childReader.init();
+ } else {
+ // wrap it to make compatible
+ childReader = new WrappingXMLStreamReader(reader);
+ }
+
+ } else {
+ // all special possiblilities has been tried! Let's treat
+ // the thing as a bean and try generating events from it
+ childReader = new WrappingXMLStreamReader(BeanUtil.getXMLStreamReader(propertyValue, propertyQName));
+ // we cannot register the namespace context here
+ }
+
+ // set the state here
+ state = DELEGATED_STATE;
+ // we are done with the delegation
+ // increment the property index
+ ++index;
+ return childReader.getEventType();
+ }
+
+ public void require(int i, String string, String string1) throws XMLStreamException {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean standaloneSet() {
+ return true;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLGroupDataBinding.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLGroupDataBinding.java
new file mode 100644
index 0000000000..d206ff8b2c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLGroupDataBinding.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.xml;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.lang.annotation.Annotation;
+
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+
+import org.apache.tuscany.core.databinding.impl.GroupDataBinding;
+import org.apache.tuscany.spi.idl.XMLType;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+
+/**
+ * A Group DataBinding
+ *
+ * @version $Rev$ $Date$
+ */
+public class XMLGroupDataBinding extends GroupDataBinding {
+
+ public XMLGroupDataBinding() {
+ super(new Class[] {InputStream.class, OutputStream.class, Reader.class, Writer.class, Source.class,
+ Result.class, InputSource.class, ContentHandler.class, XMLStreamReader.class,
+ XMLStreamWriter.class, XMLEventReader.class, XMLEventWriter.class});
+ }
+
+ @Override
+ protected Object getLogical(Class<?> markerType, Annotation[] annotations) {
+ return XMLType.UNKNOWN;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2Node.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2Node.java
new file mode 100644
index 0000000000..6ecaa85be4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2Node.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+
+/**
+ * Transform DOM Node to XML XMLStreamReader
+ */
+@Service(Transformer.class)
+public class XMLStreamReader2Node extends TransformerExtension<XMLStreamReader, Node> implements
+ PullTransformer<XMLStreamReader, Node> {
+ private SAX2DOMPipe pipe = new SAX2DOMPipe();
+
+ private XMLStreamReader2SAX stax2sax = new XMLStreamReader2SAX();
+
+ public Node transform(XMLStreamReader source, TransformationContext context) {
+ try {
+ stax2sax.transform(source, pipe.getSink(), context);
+ return pipe.getResult();
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return XMLStreamReader.class;
+ }
+
+ public Class getTargetType() {
+ return Node.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2SAX.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2SAX.java
new file mode 100644
index 0000000000..0c6f0b8df7
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2SAX.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.xml.sax.ContentHandler;
+
+/**
+ * XMLStreamReader to SAX events
+ */
+@Service(Transformer.class)
+public class XMLStreamReader2SAX extends TransformerExtension<XMLStreamReader, ContentHandler> implements
+ PushTransformer<XMLStreamReader, ContentHandler> {
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.PushTransformer#getSourceType()
+ */
+ public Class getTargetType() {
+ return ContentHandler.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.PushTransformer#getSourceType()
+ */
+ public Class getSourceType() {
+ return XMLStreamReader.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.PushTransformer#getWeight()
+ */
+ public int getWeight() {
+ return 20;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.PushTransformer#transform(java.lang.Object,
+ * java.lang.Object,
+ * org.apache.tuscany.spi.databinding.TransformationContext)
+ */
+ public void transform(XMLStreamReader source, ContentHandler sink, TransformationContext context) {
+ StAX2SAXAdapter adapter = new StAX2SAXAdapter(false);
+ try {
+ adapter.parse(source, sink);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2String.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2String.java
new file mode 100755
index 0000000000..85ac7b5af6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2String.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+
+@Service(Transformer.class)
+public class XMLStreamReader2String extends TransformerExtension<XMLStreamReader, String> implements
+ PullTransformer<XMLStreamReader, String> {
+
+ public String transform(XMLStreamReader source, TransformationContext context) {
+ try {
+ return StAXHelper.save(source);
+ } catch (XMLStreamException e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return XMLStreamReader.class;
+ }
+
+ public Class getTargetType() {
+ return String.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamSerializer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamSerializer.java
new file mode 100644
index 0000000000..8b44f526d0
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamSerializer.java
@@ -0,0 +1,266 @@
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+/**
+ * The XMLStreamSerializer pulls events from the XMLStreamReader and dumps into the XMLStreamWriter
+ */
+public class XMLStreamSerializer implements XMLStreamConstants {
+ public static final String NAMESPACE_PREFIX = "ns";
+ private static int namespaceSuffix;
+
+ /*
+ * The behavior of the serializer is such that it returns when it encounters the starting element for the second
+ * time. The depth variable tracks the depth of the serilizer and tells it when to return. Note that it is assumed
+ * that this serialization starts on an Element.
+ */
+
+ /**
+ * Field depth
+ */
+ private int depth;
+
+ /**
+ * Generates a unique namespace prefix that is not in the scope of the NamespaceContext
+ *
+ * @param nsCtxt
+ * @return string
+ */
+ private String generateUniquePrefix(NamespaceContext nsCtxt) {
+ String prefix = NAMESPACE_PREFIX + namespaceSuffix++;
+ // null should be returned if the prefix is not bound!
+ while (nsCtxt.getNamespaceURI(prefix) != null) {
+ prefix = NAMESPACE_PREFIX + namespaceSuffix++;
+ }
+
+ return prefix;
+ }
+
+ /**
+ * Method serialize.
+ *
+ * @param node
+ * @param writer
+ * @throws XMLStreamException
+ */
+ public void serialize(XMLStreamReader node, XMLStreamWriter writer) throws XMLStreamException {
+ serializeNode(node, writer);
+ }
+
+ /**
+ * @param reader
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void serializeAttributes(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException {
+ int count = reader.getAttributeCount();
+ String prefix;
+ String namespaceName;
+ String writerPrefix;
+ for (int i = 0; i < count; i++) {
+ prefix = reader.getAttributePrefix(i);
+ namespaceName = reader.getAttributeNamespace(i);
+ /*
+ * Due to parser implementations returning null as the namespace URI (for the empty namespace) we need to
+ * make sure that we deal with a namespace name that is not null. The best way to work around this issue is
+ * to set the namespace uri to "" if it is null
+ */
+ if (namespaceName == null) {
+ namespaceName = "";
+ }
+
+ writerPrefix = writer.getNamespaceContext().getPrefix(namespaceName);
+
+ if (!"".equals(namespaceName)) {
+ // prefix has already being declared but this particular
+ // attrib has a
+ // no prefix attached. So use the prefix provided by the
+ // writer
+ if (writerPrefix != null && (prefix == null || prefix.equals(""))) {
+ writer.writeAttribute(writerPrefix, namespaceName, reader.getAttributeLocalName(i), reader
+ .getAttributeValue(i));
+
+ // writer prefix is available but different from the
+ // current
+ // prefix of the attrib. We should be decalring the new
+ // prefix
+ // as a namespace declaration
+ } else if (prefix != null && !"".equals(prefix) && !prefix.equals(writerPrefix)) {
+ writer.writeNamespace(prefix, namespaceName);
+ writer.writeAttribute(prefix, namespaceName, reader.getAttributeLocalName(i), reader
+ .getAttributeValue(i));
+
+ // prefix is null (or empty), but the namespace name is
+ // valid! it has not
+ // being written previously also. So we need to generate
+ // a prefix
+ // here
+ } else if (prefix == null || prefix.equals("")) {
+ prefix = generateUniquePrefix(writer.getNamespaceContext());
+ writer.writeNamespace(prefix, namespaceName);
+ writer.writeAttribute(prefix, namespaceName, reader.getAttributeLocalName(i), reader
+ .getAttributeValue(i));
+ } else {
+ writer.writeAttribute(prefix, namespaceName, reader.getAttributeLocalName(i), reader
+ .getAttributeValue(i));
+ }
+ } else {
+ // empty namespace is equal to no namespace!
+ writer.writeAttribute(reader.getAttributeLocalName(i), reader.getAttributeValue(i));
+ }
+
+ }
+ }
+
+ /**
+ * Method serializeCData.
+ *
+ * @param reader
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void serializeCData(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException {
+ writer.writeCData(reader.getText());
+ }
+
+ /**
+ * Method serializeComment.
+ *
+ * @param reader
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void serializeComment(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException {
+ writer.writeComment(reader.getText());
+ }
+
+ /**
+ * @param reader
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void serializeElement(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException {
+ String prefix = reader.getPrefix();
+ String nameSpaceName = reader.getNamespaceURI();
+ if (nameSpaceName != null) {
+ String writerPrefix = writer.getPrefix(nameSpaceName);
+ if (writerPrefix != null) {
+ writer.writeStartElement(nameSpaceName, reader.getLocalName());
+ } else {
+ if (prefix != null) {
+ writer.writeStartElement(prefix, reader.getLocalName(), nameSpaceName);
+ writer.writeNamespace(prefix, nameSpaceName);
+ writer.setPrefix(prefix, nameSpaceName);
+ } else {
+ // [rfeng] We need to set default NS 1st before calling writeStateElement
+ writer.setDefaultNamespace(nameSpaceName);
+ writer.writeStartElement(nameSpaceName, reader.getLocalName());
+ writer.writeDefaultNamespace(nameSpaceName);
+ }
+ }
+ } else {
+ writer.writeStartElement(reader.getLocalName());
+ }
+
+ // add the namespaces
+ int count = reader.getNamespaceCount();
+ String namespacePrefix;
+ for (int i = 0; i < count; i++) {
+ namespacePrefix = reader.getNamespacePrefix(i);
+ // [rfeng] The following is commented out to allow to default ns
+ // if (namespacePrefix != null && namespacePrefix.length() == 0) {
+ // continue;
+ // }
+
+ serializeNamespace(namespacePrefix, reader.getNamespaceURI(i), writer);
+ }
+
+ // add attributes
+ serializeAttributes(reader, writer);
+
+ }
+
+ /**
+ * Method serializeEndElement.
+ *
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void serializeEndElement(XMLStreamWriter writer) throws XMLStreamException {
+ writer.writeEndElement();
+ }
+
+ /**
+ * Method serializeNamespace.
+ *
+ * @param prefix
+ * @param uri
+ * @param writer
+ * @throws XMLStreamException
+ */
+ private void serializeNamespace(String prefix, String uri, XMLStreamWriter writer) throws XMLStreamException {
+ String prefix1 = writer.getPrefix(uri);
+ if (prefix1 == null) {
+ writer.writeNamespace(prefix, uri);
+ writer.setPrefix(prefix, uri);
+ }
+ }
+
+ /**
+ * Method serializeNode.
+ *
+ * @param reader
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void serializeNode(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException {
+ while (true) {
+ int event = reader.getEventType();
+ if (event == START_ELEMENT) {
+ serializeElement(reader, writer);
+ depth++;
+ } else if (event == ATTRIBUTE) {
+ serializeAttributes(reader, writer);
+ } else if (event == CHARACTERS) {
+ serializeText(reader, writer);
+ } else if (event == COMMENT) {
+ serializeComment(reader, writer);
+ } else if (event == CDATA) {
+ serializeCData(reader, writer);
+ } else if (event == END_ELEMENT) {
+ serializeEndElement(writer);
+ depth--;
+ } else if (event == START_DOCUMENT) {
+ depth++; // if a start document is found then increment
+ writer.writeStartDocument();
+ // the depth
+ } else if (event == END_DOCUMENT) {
+ if (depth != 0) {
+ depth--; // for the end document - reduce the depth
+ }
+ writer.writeEndDocument();
+ }
+ if (depth == 0) {
+ break;
+ }
+ if (reader.hasNext()) {
+ reader.next();
+ } else {
+ break;
+ }
+ }
+ }
+
+ /**
+ * @param reader
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void serializeText(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException {
+ writer.writeCharacters(reader.getText());
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamable.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamable.java
new file mode 100644
index 0000000000..285e5cdf60
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamable.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamReader;
+
+/**
+ * An interface represents data that can be read using StAX streaming
+ *
+ * @version $Rev$ $Date$
+ */
+public interface XMLStreamable {
+ /**
+ * Get the XMLStreamReader for StAX processing
+ *
+ * @param rootElementName the name of the element to be generated
+ * @return Returns a pull parser.
+ */
+ XMLStreamReader getXMLStreamReader(QName rootElementName);
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStringDataBinding.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStringDataBinding.java
new file mode 100644
index 0000000000..4d8925c3b5
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStringDataBinding.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.xml;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.tuscany.spi.databinding.extension.DataBindingExtension;
+import org.apache.tuscany.spi.idl.XMLType;
+import org.apache.tuscany.spi.model.DataType;
+
+/**
+ * A DataBinding for the XML string
+ *
+ * @version $Rev$ $Date$
+ */
+public class XMLStringDataBinding extends DataBindingExtension {
+ public static final String NAME = String.class.getName();
+ public static final String[] ALIASES = new String[] {"xml.string"};
+
+ public XMLStringDataBinding() {
+ super(NAME, ALIASES, String.class);
+ }
+
+ @Override
+ public boolean introspect(DataType type, Annotation[] annotations) {
+ if (registry.getDataBinding(type.getDataBinding()) == this) {
+ type.setDataBinding(getName());
+ type.setLogical(XMLType.UNKNOWN);
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/AbstractDeploymentContext.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/AbstractDeploymentContext.java
new file mode 100644
index 0000000000..c931cccde9
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/AbstractDeploymentContext.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.deployer;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+
+/**
+ * Base class for DeploymentContext implementations.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractDeploymentContext implements DeploymentContext {
+ private final ClassLoader classLoader;
+ private final URL scdlLocation;
+ private final Map<String, Object> properties = new HashMap<String, Object>();
+
+ protected AbstractDeploymentContext(ClassLoader classLoader, URL scdlLocation) {
+ this.classLoader = classLoader;
+ this.scdlLocation = scdlLocation;
+ }
+
+ public ClassLoader getClassLoader() {
+ return classLoader;
+ }
+
+ public URL getScdlLocation() {
+ return scdlLocation;
+ }
+
+ public Object getExtension(String name) {
+ return properties.get(name);
+ }
+
+ public void putExtension(String name, Object value) {
+ if (value == null) {
+ properties.remove(name);
+ } else {
+ properties.put(name, value);
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/ChildDeploymentContext.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/ChildDeploymentContext.java
new file mode 100644
index 0000000000..c489ba04c3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/ChildDeploymentContext.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.deployer;
+
+import java.net.URL;
+import javax.xml.stream.XMLInputFactory;
+
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+
+/**
+ * An holder that can be used during the load process to store information that is not part of the logical assembly
+ * model. This should be regarded as transient and references to this context should not be stored inside the model.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ChildDeploymentContext extends AbstractDeploymentContext {
+ private final DeploymentContext parent;
+
+ /**
+ * Constructor specifying the loader for application resources.
+ *
+ * @param parent the parent of this context
+ * @param classLoader the loader for application resources
+ * @param scdlLocation the location of the SCDL being deployed
+ */
+ public ChildDeploymentContext(DeploymentContext parent, ClassLoader classLoader, URL scdlLocation) {
+ super(classLoader, scdlLocation);
+ assert parent != null;
+ this.parent = parent;
+ }
+
+ public DeploymentContext getParent() {
+ return parent;
+ }
+
+ public XMLInputFactory getXmlFactory() {
+ return parent.getXmlFactory();
+ }
+
+ public ScopeContainer getCompositeScope() {
+ return parent.getCompositeScope();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/DeployerImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/DeployerImpl.java
new file mode 100644
index 0000000000..ce5858ae1c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/DeployerImpl.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.deployer;
+
+import javax.xml.stream.XMLInputFactory;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.builder.Builder;
+import org.apache.tuscany.spi.builder.BuilderException;
+import org.apache.tuscany.spi.builder.BuilderInstantiationException;
+import org.apache.tuscany.spi.builder.BuilderRegistry;
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.ComponentRegistrationException;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.PrepareException;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.deployer.Deployer;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+import org.apache.tuscany.spi.loader.Loader;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.Implementation;
+
+import org.apache.tuscany.api.annotation.Monitor;
+import org.apache.tuscany.core.component.event.CompositeStop;
+import org.apache.tuscany.core.component.scope.CompositeScopeContainer;
+
+/**
+ * Default implementation of Deployer.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DeployerImpl implements Deployer {
+ private Loader loader;
+ protected XMLInputFactory xmlFactory;
+ protected Builder builder;
+ protected ScopeContainerMonitor monitor;
+
+ public DeployerImpl(XMLInputFactory xmlFactory, Loader loader, Builder builder) {
+ this.xmlFactory = xmlFactory;
+ this.loader = loader;
+ this.builder = builder;
+ }
+
+ public DeployerImpl() {
+ xmlFactory = XMLInputFactory.newInstance("javax.xml.stream.XMLInputFactory", getClass().getClassLoader());
+ }
+
+ @Autowire
+ public void setLoader(LoaderRegistry loader) {
+ this.loader = loader;
+ }
+
+ @Autowire
+ public void setBuilder(BuilderRegistry builder) {
+ this.builder = builder;
+ }
+
+ @Monitor
+ public void setMonitor(ScopeContainerMonitor monitor) {
+ this.monitor = monitor;
+ }
+
+ public <I extends Implementation<?>> Component deploy(CompositeComponent parent,
+ ComponentDefinition<I> componentDefinition)
+ throws LoaderException, BuilderException, PrepareException {
+ final ScopeContainer scopeContainer = new CompositeScopeContainer(monitor);
+ scopeContainer.start();
+ DeploymentContext deploymentContext = new RootDeploymentContext(null, xmlFactory, scopeContainer, null);
+ try {
+ load(parent, componentDefinition, deploymentContext);
+ } catch (LoaderException e) {
+ e.addContextName(componentDefinition.getName());
+ throw e;
+ }
+ Component component = (Component) build(parent, componentDefinition, deploymentContext);
+ // create a listener so the scope container is shutdown when the top-level composite stops
+ RuntimeEventListener listener = new RuntimeEventListener() {
+ public void onEvent(Event event) {
+ scopeContainer.onEvent(event);
+ if (event instanceof CompositeStop) {
+ scopeContainer.stop();
+ }
+ }
+ };
+ component.addListener(listener);
+ component.prepare();
+ try {
+ parent.register(component);
+ } catch (ComponentRegistrationException e) {
+ throw new BuilderInstantiationException("Error registering component", e);
+ }
+ return component;
+ }
+
+ public <I extends Implementation<?>> Component deployFromContribution(CompositeComponent parent,
+ ComponentDefinition<I> componentDefinition) throws BuilderException, PrepareException {
+ final ScopeContainer scopeContainer = new CompositeScopeContainer(monitor);
+ scopeContainer.start();
+ DeploymentContext deploymentContext = new RootDeploymentContext(null, xmlFactory, scopeContainer, null);
+// try {
+// load(parent, componentDefinition, deploymentContext);
+// } catch (LoaderException e) {
+// e.addContextName(componentDefinition.getName());
+// throw e;
+// }
+ Component component = (Component) build(parent, componentDefinition, deploymentContext);
+ // create a listener so the scope container is shutdown when the top-level composite stops
+ RuntimeEventListener listener = new RuntimeEventListener() {
+ public void onEvent(Event event) {
+ scopeContainer.onEvent(event);
+ if (event instanceof CompositeStop) {
+ scopeContainer.stop();
+ }
+ }
+ };
+ component.addListener(listener);
+ component.prepare();
+ try {
+ parent.register(component);
+ } catch (ComponentRegistrationException e) {
+ throw new BuilderInstantiationException("Error registering component", e);
+ }
+ return component;
+ }
+
+ /**
+ * Load the componentDefinition type information for the componentDefinition being deployed. For a typical
+ * deployment this will result in the SCDL definition being loaded.
+ *
+ * @param componentDefinition the componentDefinition being deployed
+ * @param deploymentContext the current deployment context
+ */
+ protected <I extends Implementation<?>> void load(CompositeComponent parent,
+ ComponentDefinition<I> componentDefinition,
+ DeploymentContext deploymentContext) throws LoaderException {
+ loader.loadComponentType(parent, componentDefinition.getImplementation(), deploymentContext);
+ }
+
+ /**
+ * Build the runtime context for a loaded componentDefinition.
+ *
+ * @param parent the context that will be the parent of the new sub-context
+ * @param componentDefinition the componentDefinition being deployed
+ * @param deploymentContext the current deployment context
+ * @return the new runtime context
+ */
+ protected <I extends Implementation<?>> SCAObject build(CompositeComponent parent,
+ ComponentDefinition<I> componentDefinition,
+ DeploymentContext deploymentContext)
+ throws BuilderException {
+ return builder.build(parent, componentDefinition, deploymentContext);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/RootDeploymentContext.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/RootDeploymentContext.java
new file mode 100644
index 0000000000..be5cc56d51
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/RootDeploymentContext.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.deployer;
+
+import java.net.URL;
+import javax.xml.stream.XMLInputFactory;
+
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+
+/**
+ * A holder that can be used during the load process to store information that is not part of the logical assembly
+ * model. This should be regarded as transient and references to this context should not be stored inside the model.
+ *
+ * @version $Rev$ $Date$
+ */
+public class RootDeploymentContext extends AbstractDeploymentContext {
+ private final XMLInputFactory xmlFactory;
+ private final ScopeContainer scopeContainer;
+
+ /**
+ * Constructor specifying the loader for application resources.
+ *
+ * @param classLoader the loader for application resources
+ * @param xmlFactory a factory that can be used to obtain an StAX XMLStreamReader
+ * @param scopeContainer the scope context representing this deployment's COMPOSITE scope
+ * @param scdlLocation the location of the SCDL being deployed
+ */
+ public RootDeploymentContext(ClassLoader classLoader,
+ XMLInputFactory xmlFactory,
+ ScopeContainer scopeContainer,
+ URL scdlLocation) {
+ super(classLoader, scdlLocation);
+ this.xmlFactory = xmlFactory;
+ this.scopeContainer = scopeContainer;
+ }
+
+ public DeploymentContext getParent() {
+ return null;
+ }
+
+ public XMLInputFactory getXmlFactory() {
+ return xmlFactory;
+ }
+
+ public ScopeContainer getCompositeScope() {
+ return scopeContainer;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/federation/FederatedDeployer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/federation/FederatedDeployer.java
new file mode 100644
index 0000000000..934510df27
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/deployer/federation/FederatedDeployer.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.deployer.federation;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.core.component.scope.CompositeScopeContainer;
+import org.apache.tuscany.core.deployer.DeployerImpl;
+import org.apache.tuscany.core.deployer.RootDeploymentContext;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.builder.BuilderException;
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.PrepareException;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.marshaller.MarshalException;
+import org.apache.tuscany.spi.marshaller.ModelMarshaller;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.services.discovery.DiscoveryService;
+import org.apache.tuscany.spi.services.discovery.RequestListener;
+
+/**
+ * Federated deployer that deploys components in response to asynchronous
+ * messages from the federated domain.
+ *
+ * @version $Revision$ $Date$
+ *
+ */
+public class FederatedDeployer extends DeployerImpl implements RequestListener {
+
+ /** QName of the message. */
+ private static final QName MESSAGE_TYPE = new QName("http://www.osoa.org/xmlns/sca/1.0", "composite");
+
+ /** Marshaller. */
+ private ModelMarshaller<ComponentDefinition<?>> marshaller;
+
+ /**
+ * Deploys the component.
+ * @param content SCDL content.
+ * @return Response to the request message.
+ *
+ * TODO Handle response messages.
+ */
+ public XMLStreamReader onRequest(XMLStreamReader content) {
+
+ // TODO get this from somewhere
+ final CompositeComponent parent = null;
+
+ final ScopeContainer scopeContainer = new CompositeScopeContainer(monitor);
+ scopeContainer.start();
+
+ final DeploymentContext deploymentContext = new RootDeploymentContext(null, xmlFactory, scopeContainer, null);
+
+ try {
+
+ final ComponentDefinition<?> definition = marshaller.unmarshall(content, false);
+ final Component component = (Component) builder.build(parent, definition, deploymentContext);
+
+ component.prepare();
+ component.start();
+
+ } catch (MarshalException ex) {
+ return null;
+ } catch (BuilderException ex) {
+ return null;
+ } catch (PrepareException ex) {
+ return null;
+ }
+
+ return null;
+ }
+
+ /**
+ * Injects the discovery service.
+ * @param discoveryService Discovery service to be injected.
+ */
+ @Autowire
+ public void setDiscoveryService(DiscoveryService discoveryService) {
+ discoveryService.registerRequestListener(MESSAGE_TYPE, this);
+ }
+
+ /**
+ * Injects the model marshaller.
+ * @param marshaller Marshaller.
+ */
+ @Autowire
+ public void setMarshaller(ModelMarshaller<ComponentDefinition<?>> marshaller) {
+ this.marshaller = marshaller;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/idl/java/IllegalCallbackException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/idl/java/IllegalCallbackException.java
new file mode 100644
index 0000000000..f52bd4cfb1
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/idl/java/IllegalCallbackException.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.idl.java;
+
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+
+/**
+ * Denotes an illegal callback interface
+ *
+ * @version $Rev$ $Date$
+ */
+
+public class IllegalCallbackException extends InvalidServiceContractException {
+
+ public IllegalCallbackException(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/idl/java/InterfaceJavaLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/idl/java/InterfaceJavaLoader.java
new file mode 100644
index 0000000000..5ca25bb0e1
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/idl/java/InterfaceJavaLoader.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.idl.java;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import static org.osoa.sca.Constants.SCA_NS;
+import org.osoa.sca.annotations.Constructor;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.loader.InvalidValueException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.LoaderUtil;
+import org.apache.tuscany.spi.model.DataType;
+import org.apache.tuscany.spi.model.InteractionScope;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.util.stax.StaxUtil;
+
+/**
+ * Loads a Java interface definition from an XML-based assembly file
+ *
+ * @version $Rev$ $Date$
+ */
+public class InterfaceJavaLoader extends LoaderExtension<JavaServiceContract> {
+ public static final QName INTERFACE_JAVA = new QName(SCA_NS, "interface.java");
+
+ private final JavaInterfaceProcessorRegistry interfaceRegsitry;
+
+ @Constructor({"registry", "interfaceRegsitry"})
+ public InterfaceJavaLoader(@Autowire LoaderRegistry registry,
+ @Autowire JavaInterfaceProcessorRegistry interfaceRegistry) {
+ super(registry);
+ this.interfaceRegsitry = interfaceRegistry;
+ }
+
+ public QName getXMLType() {
+ return INTERFACE_JAVA;
+ }
+
+ public JavaServiceContract load(CompositeComponent parent,
+ ModelObject object, XMLStreamReader reader,
+ DeploymentContext deploymentContext)
+ throws XMLStreamException, LoaderException {
+
+ assert INTERFACE_JAVA.equals(reader.getName());
+ InteractionScope interactionScope = StaxUtil.interactionScope(reader.getAttributeValue(null, "scope"));
+ String name = reader.getAttributeValue(null, "interface");
+ if (name == null) {
+ // allow "class" as well as seems to be a common mistake
+ name = reader.getAttributeValue(null, "class");
+ }
+ if (name == null) {
+ throw new InvalidValueException("interface name not supplied");
+ }
+ Class<?> interfaceClass = LoaderUtil.loadClass(name, deploymentContext.getClassLoader());
+
+ name = reader.getAttributeValue(null, "callbackInterface");
+ Class<?> callbackClass = (name != null) ? LoaderUtil.loadClass(name, deploymentContext.getClassLoader()) : null;
+
+ Map<Class<?>, ModelObject> extensions = new HashMap<Class<?>, ModelObject>();
+ while (true) {
+ int event = reader.next();
+ if (event == XMLStreamConstants.START_ELEMENT) {
+ ModelObject mo = registry.load(parent, null, reader, deploymentContext);
+ if (mo != null) {
+ extensions.put(mo.getClass(), mo);
+ }
+ } else if (event == XMLStreamConstants.END_ELEMENT && reader.getName().equals(INTERFACE_JAVA)) {
+ break;
+ }
+ }
+ JavaServiceContract serviceContract;
+ try {
+ serviceContract = interfaceRegsitry.introspect(interfaceClass, callbackClass, false);
+ } catch (InvalidServiceContractException e) {
+ throw new LoaderException(interfaceClass.getName(), e);
+ }
+
+ // Set databinding from the SCDL extension <databinding>
+ DataType<?> dataType = (DataType<?>) extensions.get(DataType.class);
+ if (dataType != null) {
+ serviceContract.setDataBinding(dataType.getDataBinding());
+ }
+ serviceContract.getExtensions().putAll(extensions);
+
+ serviceContract.setInteractionScope(interactionScope);
+ return serviceContract;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/idl/java/JavaInterfaceProcessorRegistryImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/idl/java/JavaInterfaceProcessorRegistryImpl.java
new file mode 100644
index 0000000000..b10474fb0f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/idl/java/JavaInterfaceProcessorRegistryImpl.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.idl.java;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.osoa.sca.annotations.Callback;
+import org.osoa.sca.annotations.EndsConversation;
+import org.osoa.sca.annotations.OneWay;
+import org.osoa.sca.annotations.Remotable;
+import org.osoa.sca.annotations.Scope;
+
+import org.apache.tuscany.spi.databinding.DataBinding;
+import org.apache.tuscany.spi.idl.InvalidConversationalOperationException;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.OverloadedOperationException;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessor;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.DataType;
+import org.apache.tuscany.spi.model.InteractionScope;
+import org.apache.tuscany.spi.model.Operation;
+import static org.apache.tuscany.spi.model.Operation.CONVERSATION_END;
+import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION;
+
+import static org.apache.tuscany.core.util.JavaIntrospectionHelper.getBaseName;
+
+/**
+ * Default implementation of an InterfaceJavaIntrospector.
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaInterfaceProcessorRegistryImpl implements JavaInterfaceProcessorRegistry {
+ private static final String UNKNOWN_DATABINDING = null;
+
+ private List<JavaInterfaceProcessor> processors = new ArrayList<JavaInterfaceProcessor>();
+
+ public JavaInterfaceProcessorRegistryImpl() {
+ }
+
+ public void registerProcessor(JavaInterfaceProcessor processor) {
+ processors.add(processor);
+ }
+
+ public void unregisterProcessor(JavaInterfaceProcessor processor) {
+ processors.remove(processor);
+ }
+
+ public <T> JavaServiceContract introspect(Class<T> type) throws InvalidServiceContractException {
+ return introspect(type, true);
+ }
+
+ public <T> JavaServiceContract introspect(Class<T> type, boolean deep) throws InvalidServiceContractException {
+ Class<?> callbackClass = null;
+ Callback callback = type.getAnnotation(Callback.class);
+ if (callback != null && !Void.class.equals(callback.value())) {
+ callbackClass = callback.value();
+ } else if (callback != null && Void.class.equals(callback.value())) {
+ throw new IllegalCallbackException("No callback interface specified on annotation", type.getName());
+ }
+ return introspect(type, callbackClass, deep);
+ }
+ public <I, C> JavaServiceContract introspect(Class<I> type, Class<C> callback, boolean deep)
+ throws InvalidServiceContractException {
+ JavaServiceContract contract = new JavaServiceContract();
+ contract.setInterfaceName(getBaseName(type));
+ contract.setInterfaceClass(type);
+ if (callback != null) {
+ contract.setCallbackName(getBaseName(callback));
+ contract.setCallbackClass(callback);
+ }
+ if (!deep) {
+ return contract;
+ }
+ boolean remotable = type.isAnnotationPresent(Remotable.class);
+ contract.setRemotable(remotable);
+ Scope interactionScope = type.getAnnotation(Scope.class);
+ boolean conversational = false;
+ if (interactionScope != null && "CONVERSATION".equalsIgnoreCase(interactionScope.value())) {
+ contract.setInteractionScope(InteractionScope.CONVERSATIONAL);
+ conversational = true;
+ } else {
+ contract.setInteractionScope(InteractionScope.NONCONVERSATIONAL);
+ }
+ contract.setOperations(getOperations(type, remotable, conversational));
+
+ if (callback != null) {
+ contract.setCallbackOperations(getOperations(callback, remotable, conversational));
+ }
+
+ for (JavaInterfaceProcessor processor : processors) {
+ processor.visitInterface(type, callback, contract);
+ }
+ return contract;
+ }
+
+ private <T> Map<String, Operation<Type>> getOperations(Class<T> type, boolean remotable, boolean conversational)
+ throws InvalidServiceContractException {
+ Method[] methods = type.getMethods();
+ Map<String, Operation<Type>> operations = new HashMap<String, Operation<Type>>(methods.length);
+ for (Method method : methods) {
+ String name = method.getName();
+ if (remotable && operations.containsKey(name)) {
+ throw new OverloadedOperationException(method);
+ }
+
+ Type returnType = method.getGenericReturnType();
+ Type[] paramTypes = method.getGenericParameterTypes();
+ Type[] faultTypes = method.getGenericExceptionTypes();
+ boolean nonBlocking = method.isAnnotationPresent(OneWay.class);
+ int conversationSequence = NO_CONVERSATION;
+ if (method.isAnnotationPresent(EndsConversation.class)) {
+ if (!conversational) {
+ throw new InvalidConversationalOperationException(
+ "Method is marked as end conversation but contract is not conversational",
+ method.getDeclaringClass().getName(),
+ method);
+ }
+ conversationSequence = CONVERSATION_END;
+ } else if (conversational) {
+ conversationSequence = Operation.CONVERSATION_CONTINUE;
+ }
+
+ DataType<Type> returnDataType = new DataType<Type>(UNKNOWN_DATABINDING, returnType, returnType);
+ List<DataType<Type>> paramDataTypes = new ArrayList<DataType<Type>>(paramTypes.length);
+ for (Type paramType : paramTypes) {
+ paramDataTypes.add(new DataType<Type>(UNKNOWN_DATABINDING, paramType, paramType));
+ }
+ List<DataType<Type>> faultDataTypes = new ArrayList<DataType<Type>>(faultTypes.length);
+ for (Type faultType : faultTypes) {
+ faultDataTypes.add(new DataType<Type>(UNKNOWN_DATABINDING, faultType, faultType));
+ }
+
+ DataType<List<DataType<Type>>> inputType =
+ new DataType<List<DataType<Type>>>(DataBinding.IDL_INPUT, Object[].class, paramDataTypes);
+ Operation<Type> operation = new Operation<Type>(name,
+ inputType,
+ returnDataType,
+ faultDataTypes,
+ nonBlocking,
+ UNKNOWN_DATABINDING,
+ conversationSequence);
+ operations.put(name, operation);
+ }
+ return operations;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/IntrospectionRegistryImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/IntrospectionRegistryImpl.java
new file mode 100644
index 0000000000..3dd1328b6a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/IntrospectionRegistryImpl.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessor;
+import org.apache.tuscany.spi.implementation.java.IntrospectionRegistry;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+import org.apache.tuscany.core.util.JavaIntrospectionHelper;
+
+/**
+ * Default implementation of the <code>IntrospectionRegistry</code>
+ *
+ * @version $Rev$ $Date$
+ */
+public class IntrospectionRegistryImpl implements IntrospectionRegistry {
+
+ private Monitor monitor;
+ private List<ImplementationProcessor> cache = new ArrayList<ImplementationProcessor>();
+
+ public IntrospectionRegistryImpl() {
+ }
+
+ public IntrospectionRegistryImpl(Monitor monitor) {
+ this.monitor = monitor;
+ }
+
+ @org.apache.tuscany.api.annotation.Monitor
+ public void setMonitor(Monitor monitor) {
+ this.monitor = monitor;
+ }
+
+ public void registerProcessor(ImplementationProcessor processor) {
+ monitor.register(processor);
+ cache.add(processor);
+ }
+
+ public void unregisterProcessor(ImplementationProcessor processor) {
+ monitor.unregister(processor);
+ cache.remove(processor);
+ }
+
+ public PojoComponentType introspect(CompositeComponent parent, Class<?> clazz,
+ PojoComponentType<JavaMappedService, JavaMappedReference,
+ JavaMappedProperty<?>> type,
+ DeploymentContext context)
+ throws ProcessingException {
+ for (ImplementationProcessor processor : cache) {
+ processor.visitClass(parent, clazz, type, context);
+ }
+
+ for (Constructor<?> constructor : clazz.getConstructors()) {
+ for (ImplementationProcessor processor : cache) {
+ processor.visitConstructor(parent, constructor, type, context);
+ }
+ }
+
+ Set<Method> methods = JavaIntrospectionHelper.getAllUniquePublicProtectedMethods(clazz);
+ for (Method method : methods) {
+ for (ImplementationProcessor processor : cache) {
+ processor.visitMethod(parent, method, type, context);
+ }
+ }
+
+ Set<Field> fields = JavaIntrospectionHelper.getAllPublicAndProtectedFields(clazz);
+ for (Field field : fields) {
+ for (ImplementationProcessor processor : cache) {
+ processor.visitField(parent, field, type, context);
+ }
+ }
+
+ Class superClass = clazz.getSuperclass();
+ if (superClass != null) {
+ visitSuperClass(parent, superClass, type, context);
+ }
+
+ for (ImplementationProcessor processor : cache) {
+ processor.visitEnd(parent, clazz, type, context);
+ }
+ return type;
+ }
+
+ private void visitSuperClass(CompositeComponent parent,
+ Class<?> clazz,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context)
+ throws ProcessingException {
+ if (!Object.class.equals(clazz)) {
+ for (ImplementationProcessor processor : cache) {
+ processor.visitSuperClass(parent, clazz, type, context);
+ }
+ clazz = clazz.getSuperclass();
+ if (clazz != null) {
+ visitSuperClass(parent, clazz, type, context);
+ }
+ }
+ }
+
+ public static interface Monitor {
+ void register(ImplementationProcessor processor);
+
+ void unregister(ImplementationProcessor processor);
+
+ void processing(ImplementationProcessor processor);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/PojoAtomicComponent.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/PojoAtomicComponent.java
new file mode 100644
index 0000000000..4ef4dc4d49
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/PojoAtomicComponent.java
@@ -0,0 +1,282 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.component.TargetInitializationException;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.extension.AtomicComponentExtension;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import org.apache.tuscany.core.injection.ArrayMultiplicityObjectFactory;
+import org.apache.tuscany.core.injection.ConversationIDObjectFactory;
+import org.apache.tuscany.core.injection.EventInvoker;
+import org.apache.tuscany.core.injection.FieldInjector;
+import org.apache.tuscany.core.injection.Injector;
+import org.apache.tuscany.core.injection.InvalidAccessorException;
+import org.apache.tuscany.core.injection.ListMultiplicityObjectFactory;
+import org.apache.tuscany.core.injection.MethodInjector;
+import org.apache.tuscany.core.injection.NoAccessorException;
+import org.apache.tuscany.core.injection.NoMultiplicityTypeException;
+import org.apache.tuscany.core.injection.ObjectCallbackException;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+
+/**
+ * Base implementation of an {@link org.apache.tuscany.spi.component.AtomicComponent} whose type is a Java class
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public abstract class PojoAtomicComponent extends AtomicComponentExtension {
+ protected EventInvoker<Object> initInvoker;
+ protected EventInvoker<Object> destroyInvoker;
+ protected PojoObjectFactory<?> instanceFactory;
+ protected List<String> constructorParamNames;
+ protected Map<String, Member> referenceSites;
+ protected Map<String, Member> resourceSites;
+ protected Map<String, Member> propertySites;
+ protected Map<String, Member> callbackSites;
+ protected List<Injector<Object>> injectors;
+ protected Class implementationClass;
+ private List<Class<?>> constructorParamTypes = new ArrayList<Class<?>>();
+
+ public PojoAtomicComponent(PojoConfiguration configuration) {
+ super(configuration.getName(),
+ configuration.getParent(),
+ configuration.getWireService(),
+ configuration.getWorkContext(),
+ configuration.getScheduler(),
+ configuration.getMonitor(),
+ configuration.getInitLevel(),
+ configuration.getMaxIdleTime(),
+ configuration.getMaxAge());
+ assert configuration.getInstanceFactory() != null : "Object factory was null";
+ initInvoker = configuration.getInitInvoker();
+ destroyInvoker = configuration.getDestroyInvoker();
+ instanceFactory = configuration.getInstanceFactory();
+ constructorParamNames = configuration.getConstructorParamNames();
+ constructorParamTypes = configuration.getConstructorParamTypes();
+ injectors = new ArrayList<Injector<Object>>();
+ referenceSites = configuration.getReferenceSite() != null ? configuration.getReferenceSite()
+ : new HashMap<String, Member>();
+ propertySites = configuration.getPropertySites() != null ? configuration.getPropertySites()
+ : new HashMap<String, Member>();
+ resourceSites = configuration.getResourceSites() != null ? configuration.getResourceSites()
+ : new HashMap<String, Member>();
+ callbackSites = configuration.getCallbackSite() != null ? configuration.getCallbackSite()
+ : new HashMap<String, Member>();
+ implementationClass = configuration.getImplementationClass();
+ }
+
+
+ public boolean isDestroyable() {
+ return destroyInvoker != null;
+ }
+
+ public void init(Object instance) throws TargetInitializationException {
+ if (initInvoker != null) {
+ try {
+ initInvoker.invokeEvent(instance);
+ } catch (ObjectCallbackException e) {
+ throw new TargetInitializationException("Error initializing component instance", getName(), e);
+ }
+ }
+ }
+
+ public void destroy(Object instance) throws TargetDestructionException {
+ if (destroyInvoker != null) {
+ try {
+ destroyInvoker.invokeEvent(instance);
+ } catch (ObjectCallbackException e) {
+ throw new TargetDestructionException("Error destroying component instance", getName(), e);
+ }
+ }
+ }
+
+ public boolean isOptimizable() {
+ // stateless implementations that require a destroy callback cannot be optimized since the callback is
+ // performed by the JavaTargetInvoker
+ return !(getScope() == Scope.STATELESS && isDestroyable());
+ }
+
+ public Object getTargetInstance() throws TargetResolutionException {
+ return scopeContainer.getInstance(this);
+ }
+
+ public Object getAssociatedTargetInstance() throws TargetResolutionException {
+ return scopeContainer.getAssociatedInstance(this);
+ }
+
+ public Object createInstance() throws ObjectCreationException {
+ Object instance = instanceFactory.getInstance();
+ // inject the instance with properties and references
+ for (Injector<Object> injector : injectors) {
+ injector.inject(instance);
+ }
+ return instance;
+ }
+
+ public void addPropertyFactory(String name, ObjectFactory<?> factory) {
+ Member member = propertySites.get(name);
+ if (member instanceof Field) {
+ injectors.add(new FieldInjector<Object>((Field) member, factory));
+ } else if (member instanceof Method) {
+ injectors.add(new MethodInjector<Object>((Method) member, factory));
+ }
+ // cycle through constructor param names as well
+ for (int i = 0; i < constructorParamNames.size(); i++) {
+ if (name.equals(constructorParamNames.get(i))) {
+ ObjectFactory[] initializerFactories = instanceFactory.getInitializerFactories();
+ initializerFactories[i] = factory;
+ break;
+ }
+ }
+ //FIXME throw an error if no injection site found
+ }
+
+ public void addResourceFactory(String name, ObjectFactory<?> factory) {
+ Member member = resourceSites.get(name);
+ if (member instanceof Field) {
+ injectors.add(new FieldInjector<Object>((Field) member, factory));
+ } else if (member instanceof Method) {
+ injectors.add(new MethodInjector<Object>((Method) member, factory));
+ }
+ // cycle through constructor param names as well
+ for (int i = 0; i < constructorParamNames.size(); i++) {
+ if (name.equals(constructorParamNames.get(i))) {
+ ObjectFactory[] initializerFactories = instanceFactory.getInitializerFactories();
+ initializerFactories[i] = factory;
+ break;
+ }
+ }
+ //FIXME throw an error if no injection site found
+ }
+
+ public void addConversationIDFactory(Member member) {
+ ObjectFactory<String> convIDObjectFactory = new ConversationIDObjectFactory(workContext);
+ if (member instanceof Field) {
+ injectors.add(new FieldInjector<Object>((Field) member, convIDObjectFactory));
+ } else if (member instanceof Method) {
+ injectors.add(new MethodInjector<Object>((Method) member, convIDObjectFactory));
+ } else {
+ throw new InvalidAccessorException("Member must be a field or method", member.getName());
+ }
+ }
+
+ protected void onReferenceWire(OutboundWire wire) {
+ String name = wire.getReferenceName();
+ Member member = referenceSites.get(name);
+ if (member != null) {
+ injectors.add(createInjector(member, wire));
+ }
+ // cycle through constructor param names as well
+ for (int i = 0; i < constructorParamNames.size(); i++) {
+ if (name.equals(constructorParamNames.get(i))) {
+ ObjectFactory[] initializerFactories = instanceFactory.getInitializerFactories();
+ initializerFactories[i] = createWireFactory(constructorParamTypes.get(i), wire);
+ break;
+ }
+ }
+ //TODO error if ref not set on constructor or ref site
+ }
+
+ public void onReferenceWires(List<OutboundWire> wires) {
+ assert wires.size() > 0 : "Wires were empty";
+ String referenceName = wires.get(0).getReferenceName();
+ Member member = referenceSites.get(referenceName);
+ if (member == null) {
+ if (constructorParamNames.contains(referenceName)) {
+ // injected on the constructor
+
+ } else {
+ throw new NoAccessorException(referenceName);
+ }
+ }
+ Class<?> type = wires.get(0).getServiceContract().getInterfaceClass();
+ if (type == null) {
+ throw new NoMultiplicityTypeException("Java interface must be specified for multiplicity", referenceName);
+ }
+ injectors.add(createMultiplicityInjector(member, type, wires));
+ //TODO multiplicity for constructor injection
+ }
+
+ public boolean implementsCallback(Class callbackClass) {
+ Class<?>[] implementedInterfaces = implementationClass.getInterfaces();
+ for (Class<?> implementedInterface : implementedInterfaces) {
+ if (implementedInterface.isAssignableFrom(callbackClass)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ protected Injector<Object> createInjector(Member member, OutboundWire wire) {
+ if (member instanceof Field) {
+ Class<?> type = ((Field) member).getType();
+ ObjectFactory<?> factory = createWireFactory(type, wire);
+ return new FieldInjector<Object>((Field) member, factory);
+ } else if (member instanceof Method) {
+ Class<?> type = ((Method) member).getParameterTypes()[0];
+ ObjectFactory<?> factory = createWireFactory(type, wire);
+ return new MethodInjector<Object>((Method) member, factory);
+ } else {
+ throw new InvalidAccessorException("Member must be a field or method", member.getName());
+ }
+ }
+
+ protected Injector<Object> createMultiplicityInjector(Member member,
+ Class<?> interfaceType,
+ List<OutboundWire> wireFactories) {
+ List<ObjectFactory<?>> factories = new ArrayList<ObjectFactory<?>>();
+ for (OutboundWire wire : wireFactories) {
+ factories.add(createWireFactory(interfaceType, wire));
+ }
+ if (member instanceof Field) {
+ Field field = (Field) member;
+ if (field.getType().isArray()) {
+ return new FieldInjector<Object>(field, new ArrayMultiplicityObjectFactory(interfaceType, factories));
+ } else {
+ return new FieldInjector<Object>(field, new ListMultiplicityObjectFactory(factories));
+ }
+ } else if (member instanceof Method) {
+ Method method = (Method) member;
+ if (method.getParameterTypes()[0].isArray()) {
+ return new MethodInjector<Object>(method, new ArrayMultiplicityObjectFactory(interfaceType, factories));
+ } else {
+ return new MethodInjector<Object>(method, new ListMultiplicityObjectFactory(factories));
+ }
+ } else {
+ throw new InvalidAccessorException("Member must be a field or method", member.getName());
+ }
+ }
+
+ protected abstract ObjectFactory<?> createWireFactory(Class<?> interfaze, OutboundWire wire);
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/PojoConfiguration.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/PojoConfiguration.java
new file mode 100644
index 0000000000..104b1f647e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/PojoConfiguration.java
@@ -0,0 +1,232 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation;
+
+import java.lang.reflect.Member;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.extension.ExecutionMonitor;
+import org.apache.tuscany.spi.services.work.WorkScheduler;
+import org.apache.tuscany.spi.wire.WireService;
+
+import org.apache.tuscany.core.injection.EventInvoker;
+import org.apache.tuscany.core.injection.Injector;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+
+/**
+ * Encapsulates confuration for a Java-based atomic component
+ *
+ * @version $Rev$ $Date$
+ */
+public class PojoConfiguration {
+ private String name;
+ private CompositeComponent parent;
+ //private ScopeContainer scopeContainer;
+ private PojoObjectFactory<?> instanceFactory;
+ private List<String> constructorParamNames = new ArrayList<String>();
+ private List<Class<?>> constructorParamTypes = new ArrayList<Class<?>>();
+ private int initLevel;
+ private EventInvoker<Object> initInvoker;
+ private EventInvoker<Object> destroyInvoker;
+ private List<Injector> propertyInjectors = new ArrayList<Injector>();
+ private Map<String, Member> referenceSites = new HashMap<String, Member>();
+ private Map<String, Member> propertySites = new HashMap<String, Member>();
+ private Map<String, Member> resourceSites = new HashMap<String, Member>();
+ private Map<String, Member> callbackSites = new HashMap<String, Member>();
+ private WireService wireService;
+ private WorkContext workContext;
+ private WorkScheduler scheduler;
+ private ExecutionMonitor monitor;
+ private long maxIdleTime = -1;
+ private long maxAge = -1;
+ private Class implementationClass;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public CompositeComponent getParent() {
+ return parent;
+ }
+
+ public void setParent(CompositeComponent parent) {
+ this.parent = parent;
+ }
+
+ public PojoObjectFactory<?> getInstanceFactory() {
+ return instanceFactory;
+ }
+
+ public void setInstanceFactory(PojoObjectFactory<?> objectFactory) {
+ this.instanceFactory = objectFactory;
+ }
+
+ public List<String> getConstructorParamNames() {
+ return constructorParamNames;
+ }
+
+ public void setConstructorParamNames(List<String> names) {
+ constructorParamNames = names;
+ }
+
+ public void addConstructorParamName(String name) {
+ constructorParamNames.add(name);
+ }
+
+ public List<Class<?>> getConstructorParamTypes() {
+ return constructorParamTypes;
+ }
+
+ public void setConstructorParamTypes(List<Class<?>> constructorParamTypes) {
+ this.constructorParamTypes = constructorParamTypes;
+ }
+
+ public void addConstructorParamType(Class<?> type) {
+ constructorParamTypes.add(type);
+ }
+
+ public int getInitLevel() {
+ return initLevel;
+ }
+
+ public void setInitLevel(int initLevel) {
+ this.initLevel = initLevel;
+ }
+
+ public long getMaxIdleTime() {
+ return maxIdleTime;
+ }
+
+ public void setMaxIdleTime(long maxIdleTime) {
+ this.maxIdleTime = maxIdleTime;
+ }
+
+ public long getMaxAge() {
+ return maxAge;
+ }
+
+ public void setMaxAge(long maxAge) {
+ this.maxAge = maxAge;
+ }
+
+ public EventInvoker<Object> getInitInvoker() {
+ return initInvoker;
+ }
+
+ public void setInitInvoker(EventInvoker<Object> initInvoker) {
+ this.initInvoker = initInvoker;
+ }
+
+ public EventInvoker<Object> getDestroyInvoker() {
+ return destroyInvoker;
+ }
+
+ public void setDestroyInvoker(EventInvoker<Object> destroyInvoker) {
+ this.destroyInvoker = destroyInvoker;
+ }
+
+ public List<Injector> getPropertyInjectors() {
+ return propertyInjectors;
+ }
+
+ public void addPropertyInjector(Injector injector) {
+ propertyInjectors.add(injector);
+ }
+
+ public Map<String, Member> getReferenceSite() {
+ return referenceSites;
+ }
+
+ public void addReferenceSite(String name, Member member) {
+ referenceSites.put(name, member);
+ }
+
+ public Map<String, Member> getResourceSites() {
+ return resourceSites;
+ }
+
+ public void addResourceSite(String name, Member member) {
+ resourceSites.put(name, member);
+ }
+
+ public Map<String, Member> getCallbackSite() {
+ return callbackSites;
+ }
+
+ public void addCallbackSite(String name, Member member) {
+ callbackSites.put(name, member);
+ }
+
+ public Map<String, Member> getPropertySites() {
+ return propertySites;
+ }
+
+ public void addPropertySite(String name, Member member) {
+ propertySites.put(name, member);
+ }
+
+ public WireService getWireService() {
+ return wireService;
+ }
+
+ public void setWireService(WireService wireService) {
+ this.wireService = wireService;
+ }
+
+ public WorkContext getWorkContext() {
+ return workContext;
+ }
+
+ public void setWorkContext(WorkContext workContext) {
+ this.workContext = workContext;
+ }
+
+ public WorkScheduler getScheduler() {
+ return scheduler;
+ }
+
+ public void setScheduler(WorkScheduler scheduler) {
+ this.scheduler = scheduler;
+ }
+
+ public ExecutionMonitor getMonitor() {
+ return monitor;
+ }
+
+ public void setMonitor(ExecutionMonitor monitor) {
+ this.monitor = monitor;
+ }
+
+ public Class getImplementationClass() {
+ return implementationClass;
+ }
+
+ public void setImplementationClass(Class implementationClass) {
+ this.implementationClass = implementationClass;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/AbstractCompositeBuilder.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/AbstractCompositeBuilder.java
new file mode 100644
index 0000000000..293ef81b3b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/AbstractCompositeBuilder.java
@@ -0,0 +1,61 @@
+package org.apache.tuscany.core.implementation.composite;
+
+import org.apache.tuscany.spi.builder.BuilderException;
+import org.apache.tuscany.spi.builder.BuilderInstantiationException;
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.ComponentRegistrationException;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.Reference;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.Service;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.ComponentBuilderExtension;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.CompositeReferenceDefinition;
+import org.apache.tuscany.spi.model.Implementation;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+/**
+ * Abstract builder for composites
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractCompositeBuilder<T extends Implementation<CompositeComponentType>> extends
+ ComponentBuilderExtension<T> {
+
+ public CompositeComponent build(CompositeComponent parent,
+ CompositeComponent component,
+ CompositeComponentType<?, ?, ?> componentType,
+ DeploymentContext deploymentContext) throws BuilderException {
+
+ for (ComponentDefinition<? extends Implementation<?>> definition : componentType.getComponents().values()) {
+ try {
+ Component child = builderRegistry.build(component, definition, deploymentContext);
+ component.register(child);
+ } catch (ComponentRegistrationException e) {
+ throw new BuilderInstantiationException("Error registering component", e);
+ }
+ }
+ for (ServiceDefinition definition : componentType.getServices().values()) {
+ try {
+ Service service = builderRegistry.build(component, definition, deploymentContext);
+ component.register(service);
+ } catch (ComponentRegistrationException e) {
+ throw new BuilderInstantiationException("Error registering service", e);
+ }
+ }
+ for (CompositeReferenceDefinition definition : componentType.getReferences().values()) {
+ try {
+ Reference child = builderRegistry.build(component, definition, deploymentContext);
+ component.register(child);
+ } catch (ComponentRegistrationException e) {
+ throw new BuilderInstantiationException("Error registering reference", e);
+ }
+ }
+ return component;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/AbstractCompositeComponent.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/AbstractCompositeComponent.java
new file mode 100644
index 0000000000..0f10703802
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/AbstractCompositeComponent.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.w3c.dom.Document;
+
+import org.apache.tuscany.spi.builder.Connector;
+import org.apache.tuscany.spi.component.ComponentRegistrationException;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.TargetInvokerCreationException;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.extension.CompositeComponentExtension;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import org.apache.tuscany.core.component.event.CompositeStart;
+import org.apache.tuscany.core.component.event.CompositeStop;
+
+/**
+ * The base implementation of a composite context
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractCompositeComponent extends CompositeComponentExtension {
+ public static final int DEFAULT_WAIT = 1000 * 60;
+ // Blocking latch to ensure the composite is initialized exactly once prior to servicing requests
+ protected CountDownLatch initializeLatch = new CountDownLatch(1);
+ protected final Object lock = new Object();
+ // Indicates whether the composite context has been initialized
+ protected boolean initialized;
+
+
+ /**
+ * @param name the name of the SCA composite
+ * @param parent the SCA composite parent
+ * @param connector the connector for fusing wires
+ * @param propertyValues the values of this composite's Properties
+ */
+ public AbstractCompositeComponent(String name,
+ CompositeComponent parent,
+ Connector connector,
+ Map<String, Document> propertyValues) {
+ super(name, parent, connector, propertyValues);
+ }
+
+ public <S, I extends S> void registerJavaObject(String name, Class<S> service, I instance)
+ throws ComponentRegistrationException {
+ register(new SystemSingletonAtomicComponent<S, I>(name, this, service, instance));
+ }
+
+ public <S, I extends S> void registerJavaObject(String name, List<Class<?>> services, I instance)
+ throws ComponentRegistrationException {
+ register(new SystemSingletonAtomicComponent<S, I>(name, this, services, instance));
+ }
+
+ public void start() {
+ synchronized (lock) {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Composite not in UNINITIALIZED state");
+ }
+
+ for (SCAObject child : systemChildren.values()) {
+ child.start();
+ }
+ for (SCAObject child : children.values()) {
+ child.start();
+ }
+ initializeLatch.countDown();
+ initialized = true;
+ lifecycleState = INITIALIZED;
+ }
+ publish(new CompositeStart(this, this));
+ }
+
+ public void stop() {
+ if (lifecycleState == STOPPED) {
+ return;
+ }
+
+ for (SCAObject child : children.values()) {
+ child.stop();
+ }
+ for (SCAObject child : systemChildren.values()) {
+ child.stop();
+ }
+ publish(new CompositeStop(this, this));
+ // need to block a start until reset is complete
+ initializeLatch = new CountDownLatch(2);
+ lifecycleState = STOPPING;
+ initialized = false;
+ // allow initialized to be called
+ initializeLatch.countDown();
+ lifecycleState = STOPPED;
+ }
+
+ public void publish(Event event) {
+ if (lifecycleState == STOPPED) {
+ return;
+ }
+ checkInit();
+ super.publish(event);
+ }
+
+ public TargetInvoker createTargetInvoker(String targetName, Operation operation, InboundWire callbackWire)
+ throws TargetInvokerCreationException {
+ return null;
+ }
+
+ /**
+ * Blocks until the composite context has been initialized
+ */
+ protected void checkInit() throws ComponentTimeoutException {
+ if (!initialized) {
+ try {
+ /* block until the composite has initialized */
+ boolean success = initializeLatch.await(AbstractCompositeComponent.DEFAULT_WAIT,
+ TimeUnit.MILLISECONDS);
+ if (!success) {
+ throw new ComponentTimeoutException("Timeout waiting for context to initialize");
+ }
+ } catch (InterruptedException e) { // should not happen
+ }
+ }
+
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/AbstractCompositeContext.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/AbstractCompositeContext.java
new file mode 100644
index 0000000000..9aaf677be8
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/AbstractCompositeContext.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import org.osoa.sca.CompositeContext;
+import org.osoa.sca.ServiceRuntimeException;
+
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.Reference;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.Service;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Wire;
+import org.apache.tuscany.spi.wire.WireService;
+
+/**
+ * Base implementation of the {@link org.osoa.sca.CompositeContext}
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractCompositeContext implements CompositeContext {
+ protected final CompositeComponent composite;
+ protected final WireService wireService;
+
+ public AbstractCompositeContext(final CompositeComponent composite, final WireService wireService) {
+ this.composite = composite;
+ this.wireService = wireService;
+ }
+
+ public String getName() {
+ return composite.getName();
+ }
+
+ public String getURI() {
+ throw new UnsupportedOperationException();
+ }
+
+ public <T> T locateService(Class<T> serviceInterface, String serviceName) throws ServiceRuntimeException {
+ QualifiedName qName = new QualifiedName(serviceName);
+ if (qName.getPortName() == null) {
+ String name = serviceInterface.getSimpleName();
+ qName = new QualifiedName(qName.getPartName(), name);
+ }
+ SCAObject child = composite.getChild(qName.getPartName());
+ InboundWire wire = getInboundWire(child, qName);
+ if (wire.isOptimizable()
+ && wire.getServiceContract().getInterfaceClass() != null
+ && serviceInterface.isAssignableFrom(wire.getServiceContract().getInterfaceClass())) {
+ try {
+ return serviceInterface.cast(wire.getTargetService());
+ } catch (TargetResolutionException e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+ return wireService.createProxy(serviceInterface, wire);
+ }
+
+ protected InboundWire getInboundWire(SCAObject child, QualifiedName qName) {
+ InboundWire wire = null;
+ if (child instanceof Component) {
+ wire = ((Component) child).getInboundWire(qName.getPortName());
+ if (wire == null) {
+ throw new ServiceRuntimeException("Service not found [" + qName + "]");
+ }
+ } else if (child instanceof Service) {
+ Service service = (Service) child;
+ for (ServiceBinding binding : service.getServiceBindings()) {
+ if (Wire.LOCAL_BINDING.equals(binding.getInboundWire().getBindingType())) {
+ wire = binding.getInboundWire();
+ break;
+ }
+ }
+ if (wire == null) {
+ throw new ServiceRuntimeException("Local binding for service not found [" + qName + "]");
+ }
+ } else if (child instanceof Reference) {
+ Reference service = (Reference) child;
+ if (service.getReferenceBindings().isEmpty()) {
+ throw new ServiceRuntimeException("No binding for reference [" + qName + "]");
+ }
+ for (ReferenceBinding binding : service.getReferenceBindings()) {
+ if (Wire.LOCAL_BINDING.equals(binding.getInboundWire().getBindingType())) {
+ wire = binding.getInboundWire();
+ break;
+ }
+ }
+ if (wire == null) {
+ // pick the first one
+ wire = service.getReferenceBindings().get(0).getInboundWire();
+ }
+ } else if (child == null) {
+ throw new ServiceRuntimeException("Service not found [" + qName + "]");
+ } else {
+ throw new ServiceRuntimeException("Invalid service type [" + child.getClass().getName() + "]");
+ }
+ return wire;
+ }
+
+ public CompositeComponent getComposite() {
+ return composite;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ComponentTimeoutException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ComponentTimeoutException.java
new file mode 100644
index 0000000000..ed64cb1236
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ComponentTimeoutException.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import org.apache.tuscany.spi.component.ComponentRuntimeException;
+
+/**
+ * Denotes a condition where a component times out waiting to perform an operation
+ *
+ * @version $Rev$ $Date$
+ */
+public class ComponentTimeoutException extends ComponentRuntimeException {
+
+ public ComponentTimeoutException(String message) {
+ super(message);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeBuilder.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeBuilder.java
new file mode 100644
index 0000000000..008c99db8d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeBuilder.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import org.apache.tuscany.spi.builder.BuilderException;
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.CompositeImplementation;
+
+/**
+ * Instantiates a composite component from an assembly definition
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompositeBuilder extends AbstractCompositeBuilder<CompositeImplementation> {
+
+ public Component build(CompositeComponent parent,
+ ComponentDefinition<CompositeImplementation> componentDefinition,
+ DeploymentContext deploymentContext) throws BuilderException {
+ CompositeImplementation implementation = componentDefinition.getImplementation();
+ CompositeComponentType<?, ?, ?> componentType = implementation.getComponentType();
+ String name = componentDefinition.getName();
+ CompositeComponentImpl component = new CompositeComponentImpl(name, parent, connector, null);
+
+ return build(parent, component, componentType, deploymentContext);
+ }
+
+ protected Class<CompositeImplementation> getImplementationType() {
+ return CompositeImplementation.class;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImpl.java
new file mode 100644
index 0000000000..75bc2d8c78
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImpl.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.util.Map;
+
+import org.w3c.dom.Document;
+
+import org.apache.tuscany.spi.builder.Connector;
+import org.apache.tuscany.spi.component.CompositeComponent;
+
+/**
+ * The standard implementation of a composite component. Autowiring is performed by delegating to the parent composite.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompositeComponentImpl extends AbstractCompositeComponent {
+ private String uri;
+ private boolean systemComposite;
+
+ /**
+ * Constructor specifying property values
+ *
+ * @param name the name of this Component
+ * @param parent this component's parent
+ * @param connector the connector to use for wires
+ * @param propertyValues this composite's Property values
+ */
+ public CompositeComponentImpl(String name,
+ CompositeComponent parent,
+ Connector connector,
+ Map<String, Document> propertyValues) {
+ this(name, null, parent, connector, propertyValues);
+ }
+
+ /**
+ * Constructor specifying if the composite is a system composite
+ *
+ * @param name the name of this Component
+ * @param parent this component's parent
+ * @param connector the connector to use for wires
+ * @param systemComposite true if the composite is a system composite
+ */
+ public CompositeComponentImpl(String name,
+ CompositeComponent parent,
+ Connector connector,
+ boolean systemComposite) {
+ this(name, null, parent, connector, null, systemComposite);
+ }
+
+ /**
+ * Constructor specifying name and URI.
+ *
+ * @param name the name of this Component
+ * @param uri the unique identifier for this component
+ * @param parent this component's parent
+ * @param connector the connector to use for wires
+ * @param propertyValues this composite's Property values
+ */
+ public CompositeComponentImpl(String name,
+ String uri,
+ CompositeComponent parent,
+ Connector connector,
+ Map<String, Document> propertyValues) {
+ super(name, parent, connector, propertyValues);
+ this.uri = uri;
+ }
+
+ /**
+ * Constructor specifying name and URI.
+ *
+ * @param name the name of this Component
+ * @param uri the unique identifier for this component
+ * @param parent this component's parent
+ * @param connector the connector to use for wires
+ * @param propertyValues this composite's Property values
+ * @param systemComposite true if the composite is a system composite
+ */
+ public CompositeComponentImpl(String name,
+ String uri,
+ CompositeComponent parent,
+ Connector connector,
+ Map<String, Document> propertyValues,
+ boolean systemComposite) {
+ super(name, parent, connector, propertyValues);
+ this.uri = uri;
+ this.systemComposite = systemComposite;
+ }
+
+ public String getURI() {
+ return uri;
+ }
+
+ public boolean isSystem() {
+ return systemComposite;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeComponentTypeLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeComponentTypeLoader.java
new file mode 100644
index 0000000000..c55f1b8ffa
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeComponentTypeLoader.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.net.URL;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.CompositeClassLoader;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.ComponentTypeLoaderExtension;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.CompositeImplementation;
+
+import org.apache.tuscany.core.deployer.ChildDeploymentContext;
+
+/**
+ * Loads a composite component type
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompositeComponentTypeLoader extends ComponentTypeLoaderExtension<CompositeImplementation> {
+ public CompositeComponentTypeLoader() {
+ }
+
+ public CompositeComponentTypeLoader(LoaderRegistry loaderRegistry) {
+ super(loaderRegistry);
+ }
+
+ protected Class<CompositeImplementation> getImplementationClass() {
+ return CompositeImplementation.class;
+ }
+
+ public void load(CompositeComponent parent, CompositeImplementation implementation,
+ DeploymentContext deploymentContext)
+ throws LoaderException {
+ URL scdlLocation = implementation.getScdlLocation();
+ ClassLoader cl = new CompositeClassLoader(implementation.getClassLoader());
+ deploymentContext = new ChildDeploymentContext(deploymentContext, cl, scdlLocation);
+ CompositeComponentType componentType = loadFromSidefile(parent, scdlLocation, deploymentContext);
+ implementation.setComponentType(componentType);
+ }
+
+ protected CompositeComponentType loadFromSidefile(CompositeComponent parent,
+ URL url,
+ DeploymentContext deploymentContext)
+ throws LoaderException {
+ return loaderRegistry.load(parent, null, url, CompositeComponentType.class, deploymentContext);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeLoader.java
new file mode 100644
index 0000000000..c268d342b5
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/CompositeLoader.java
@@ -0,0 +1,426 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+import static org.osoa.sca.Constants.SCA_NS;
+
+import java.net.URI;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.core.property.PropertyHelper;
+import org.apache.tuscany.core.util.ReferenceLoaderHelper;
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.CompositeClassLoader;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.loader.InvalidPromotedReferenceException;
+import org.apache.tuscany.spi.loader.InvalidServiceException;
+import org.apache.tuscany.spi.loader.InvalidWireException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.ReferenceMultiplicityOverridingException;
+import org.apache.tuscany.spi.model.BindingDefinition;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.ComponentReferenceDefinition;
+import org.apache.tuscany.spi.model.ComponentType;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.CompositeReferenceDefinition;
+import org.apache.tuscany.spi.model.Implementation;
+import org.apache.tuscany.spi.model.Include;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.model.Multiplicity;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ReferenceTarget;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.apache.tuscany.spi.model.WireDefinition;
+import org.apache.tuscany.spi.services.artifact.Artifact;
+import org.apache.tuscany.spi.services.artifact.ArtifactRepository;
+
+/**
+ * Loads a composite component definition from an XML-based assembly file
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompositeLoader extends LoaderExtension<CompositeComponentType> {
+ public static final QName COMPOSITE = new QName(SCA_NS, "composite");
+ public static final String URI_DELIMITER = "/";
+
+ @Autowire
+ protected JavaInterfaceProcessorRegistry processorRegistry;
+
+ private final ArtifactRepository artifactRepository;
+
+ public CompositeLoader(@Autowire
+ LoaderRegistry registry, @Autowire
+ ArtifactRepository artifactRepository) {
+ super(registry);
+ this.artifactRepository = artifactRepository;
+ }
+
+ public QName getXMLType() {
+ return COMPOSITE;
+ }
+
+ public CompositeComponentType load(CompositeComponent parent,
+ ModelObject object,
+ XMLStreamReader reader,
+ DeploymentContext deploymentContext) throws XMLStreamException,
+ LoaderException {
+ CompositeComponentType<ServiceDefinition, CompositeReferenceDefinition, Property<?>> composite =
+ new CompositeComponentType<ServiceDefinition, CompositeReferenceDefinition, Property<?>>();
+ composite.setName(reader.getAttributeValue(null, "name"));
+ boolean done = false;
+ while (!done) {
+ switch (reader.next()) {
+ case START_ELEMENT:
+ ModelObject o = registry.load(parent, composite, reader, deploymentContext);
+ if (o instanceof ServiceDefinition) {
+ composite.add((ServiceDefinition)o);
+ } else if (o instanceof CompositeReferenceDefinition) {
+ composite.add((CompositeReferenceDefinition)o);
+ } else if (o instanceof Property<?>) {
+ composite.add((Property<?>)o);
+ } else if (o instanceof ComponentDefinition<?>) {
+ composite.add((ComponentDefinition<?>)o);
+ } else if (o instanceof Include) {
+ composite.add((Include)o);
+ } else if (o instanceof Dependency) {
+ Artifact artifact = ((Dependency)o).getArtifact();
+ if (artifactRepository != null) {
+ // default to jar type if not specified
+ if (artifact.getType() == null) {
+ artifact.setType("jar");
+ }
+ artifactRepository.resolve(artifact);
+ }
+ if (artifact.getUrl() != null) {
+ ClassLoader classLoader = deploymentContext.getClassLoader();
+ if (classLoader instanceof CompositeClassLoader) {
+ CompositeClassLoader ccl = (CompositeClassLoader)classLoader;
+ for (URL dep : artifact.getUrls()) {
+ ccl.addURL(dep);
+ }
+ }
+ }
+ } else if (o instanceof WireDefinition) {
+ composite.add((WireDefinition)o);
+ } else {
+ // add as an unknown model extension
+ if (o != null) {
+ composite.getDeclaredExtensions().put(o.getClass(), o);
+ }
+ }
+ reader.next();
+ break;
+ case END_ELEMENT:
+ if (COMPOSITE.equals(reader.getName())) {
+ // if there are wire defintions then link them up to the
+ // relevant components
+ resolveWires(composite);
+ validateCompositeDefintion(composite);
+ //verifyCompositeCompleteness(composite);
+ done = true;
+ break;
+ }
+ }
+ }
+ processJavaInterfaces(composite);
+ for (ComponentDefinition<? extends Implementation<?>> c : composite.getComponents()
+ .values()) {
+ processJavaInterfaces(c.getImplementation().getComponentType());
+ PropertyHelper.processProperties(composite, c, deploymentContext);
+ }
+ return composite;
+ }
+
+ protected void processJavaInterfaces(ComponentType componentType) throws LoaderException {
+ if (processorRegistry == null) {
+ return;
+ }
+ try {
+ for (Object s : componentType.getServices().values()) {
+ ServiceContract<?> contract = ((ServiceDefinition)s).getServiceContract();
+ if (JavaServiceContract.class.isInstance(contract)) {
+ contract =
+ processorRegistry.introspect(contract.getInterfaceClass(), contract
+ .getCallbackClass(), true);
+ ((ServiceDefinition)s).setServiceContract(contract);
+ }
+ }
+ for (Object r : componentType.getReferences().values()) {
+ ServiceContract<?> contract = ((AbstractReferenceDefinition)r).getServiceContract();
+ if (JavaServiceContract.class.isInstance(contract)) {
+ contract =
+ processorRegistry.introspect(contract.getInterfaceClass(), contract
+ .getCallbackClass(), true);
+ ((AbstractReferenceDefinition)r).setServiceContract(contract);
+ }
+ }
+ } catch (InvalidServiceContractException e) {
+ throw new LoaderException(e);
+ }
+
+ }
+
+ protected void resolveWires(CompositeComponentType<ServiceDefinition, CompositeReferenceDefinition, Property<?>> composite) throws InvalidWireException,
+ InvalidPromotedReferenceException {
+ QualifiedName sourceName;
+ ComponentDefinition componentDefinition;
+ ServiceDefinition serviceDefinition;
+ List<WireDefinition> wireDefns = composite.getDeclaredWires();
+ for (WireDefinition wire : wireDefns) {
+ URI targetUri = wire.getTarget();
+ // validate the target before finding the source
+ validateTarget(targetUri, composite);
+
+ sourceName = new QualifiedName(wire.getSource().getPath());
+ serviceDefinition = composite.getDeclaredServices().get(sourceName.getPartName());
+ if (serviceDefinition != null) {
+ serviceDefinition.setTarget(wire.getTarget());
+ } else {
+ componentDefinition =
+ composite.getDeclaredComponents().get(sourceName.getPartName());
+ if (componentDefinition != null) {
+ if (sourceName.getPortName() == null || sourceName.getPortName().length() == 0) {
+ if (componentDefinition.getReferences().size() > 1 || componentDefinition
+ .getReferences().isEmpty()) {
+ throw new InvalidWireException("Unable to determine unique source reference");
+ } else {
+ ComponentReferenceDefinition ref =
+ (ComponentReferenceDefinition)componentDefinition.getReferences()
+ .values().iterator().next();
+ ref.addTarget(targetUri);
+ }
+ } else {
+ ((ComponentReferenceDefinition)componentDefinition.getReferences()
+ .get(sourceName.getPortName())).addTarget(targetUri);
+ }
+
+ } else {
+ throw new InvalidWireException("Source not found", sourceName.toString());
+ }
+ }
+ }
+
+ QualifiedName targetName = null;
+ ComponentReferenceDefinition promotedComponentRef = null;
+ for (CompositeReferenceDefinition compositeRefDef : composite.getDeclaredReferences()
+ .values()) {
+ for (URI promotedComponentRefUri : compositeRefDef.getPromotedReferences()) {
+ targetName = new QualifiedName(promotedComponentRefUri.toString());
+ componentDefinition = composite.getComponents().get(targetName.getPartName());
+ if (componentDefinition != null) {
+ if (targetName.getPortName() != null) {
+ promotedComponentRef =
+ (ComponentReferenceDefinition)componentDefinition.getReferences()
+ .get(targetName.getPortName());
+ } else {
+ promotedComponentRef =
+ (ComponentReferenceDefinition)componentDefinition.getReferences()
+ .values().iterator().next();
+ }
+ if (promotedComponentRef != null) {
+ promotedComponentRef.addTarget(URI.create(compositeRefDef.getName()));
+ } else {
+ throw new InvalidPromotedReferenceException("Invalid promoted reference ",
+ targetName.toString());
+ }
+ } else {
+ throw new InvalidPromotedReferenceException("Invalid promoted reference ",
+ targetName.toString());
+ }
+
+ }
+ }
+ }
+
+ protected void validateCompositeDefintion(
+ CompositeComponentType<ServiceDefinition, CompositeReferenceDefinition, Property<?>> composite)
+ throws LoaderException {
+ verifyCompositeCompleteness(composite);
+ validateCompositeReferenceDefinition(composite);
+ }
+
+ protected void verifyCompositeCompleteness(
+ CompositeComponentType<ServiceDefinition, CompositeReferenceDefinition, Property<?>> composite)
+ throws InvalidServiceException {
+ // check if all of the composite services have been wired
+ for (ServiceDefinition svcDefn : composite.getDeclaredServices().values()) {
+ if (svcDefn.getTarget() == null) {
+ throw new InvalidServiceException("Composite service not wired to a target",
+ svcDefn.getName());
+ }
+ }
+ }
+
+ protected void verifyReferenceInterfaceCompatibility(CompositeReferenceDefinition compositeRefDefn,
+ ComponentReferenceDefinition componentRefDefn)
+ throws LoaderException {
+ if (compositeRefDefn.getServiceContract() != null) {
+ //TODO : Since the JavaInterfaceProcessorRegistryImpl does not do a deep introspection
+ //this comparison is not possible. This will be uncommented once that is fixed.
+ /*ReferenceLoaderHelper.checkInterfaceCompatibility(componentRefDefn.getServiceContract(),
+ compositeRefDefn.getServiceContract(),
+ false);*/
+ } else {
+ //FIXME : the wireservice needs a service contract in the composite ref. def
+ //so filling up with one of the promoted component ref. defn's service contract
+ compositeRefDefn.setServiceContract(componentRefDefn.getServiceContract());
+ }
+ }
+
+ protected Multiplicity deriveReferenceMultiplicity(CompositeReferenceDefinition compositeRefDefn,
+ ComponentReferenceDefinition componentRefDefn,
+ Multiplicity leastMultiplicity)
+ throws LoaderException
+ {
+ if (compositeRefDefn.getMultiplicity() != null) {
+ if (!ReferenceLoaderHelper.
+ isValidMultiplicityOverride(componentRefDefn.getMultiplicity(),
+ compositeRefDefn.getMultiplicity())) {
+ throw new ReferenceMultiplicityOverridingException(compositeRefDefn.getName(),
+ componentRefDefn.getMultiplicity(),
+ compositeRefDefn.getMultiplicity());
+ }
+ } else {
+ if (leastMultiplicity != null) {
+ if (!ReferenceLoaderHelper.isCompatibleMultiplicity(componentRefDefn.getMultiplicity(),
+ leastMultiplicity)) {
+ throw new ReferenceMultiplicityOverridingException(compositeRefDefn.getName(),
+ componentRefDefn.getMultiplicity(),
+ leastMultiplicity);
+ } else {
+ if (!ReferenceLoaderHelper.
+ isValidMultiplicityOverride(componentRefDefn.getMultiplicity(),
+ leastMultiplicity)) {
+ leastMultiplicity = componentRefDefn.getMultiplicity();
+ }
+ }
+ }
+ else {
+ leastMultiplicity = componentRefDefn.getMultiplicity();
+ }
+ }
+ return leastMultiplicity;
+ }
+
+ protected void validateCompositeReferenceDefinition(CompositeComponentType<ServiceDefinition, CompositeReferenceDefinition, Property<?>> composite) throws LoaderException {
+ QualifiedName promotedName = null;
+ ComponentDefinition promotedComponentDefinition = null;
+ ComponentReferenceDefinition promotedComponentReference = null;
+
+ for (CompositeReferenceDefinition compositeRefDefn : composite.getDeclaredReferences().values()) {
+ // ensure if there is a service contract defined, then it is
+ // compatible with all
+ // promoted component reference interfaces
+ Multiplicity leastMultiplicity = null;
+ boolean bindingsOverriden = compositeRefDefn.getBindings().size() > 0;
+ for (URI promotedRef : compositeRefDefn.getPromotedReferences()) {
+ // check for valid promotions
+ promotedName = new QualifiedName(promotedRef.toString());
+ promotedComponentDefinition =
+ composite.getComponents().get(promotedName.getPartName());
+ if (promotedComponentDefinition != null) {
+ if (promotedName.getPortName() != null) {
+ promotedComponentReference =
+ (ComponentReferenceDefinition)promotedComponentDefinition
+ .getReferences().get(promotedName.getPortName());
+ } else {
+ promotedComponentReference =
+ (ComponentReferenceDefinition)promotedComponentDefinition
+ .getReferences().values().iterator().next();
+ }
+ // check for service contract compatibility
+ if (promotedComponentReference != null) {
+ verifyReferenceInterfaceCompatibility(compositeRefDefn,
+ promotedComponentReference);
+ leastMultiplicity =
+ deriveReferenceMultiplicity(compositeRefDefn,
+ promotedComponentReference,
+ leastMultiplicity);
+
+ // if bindings have not been overridden int the composite then copy them
+ // over for convenience so that when accessed, traversing of all promoted
+ // references can be avoided
+ if (!bindingsOverriden) {
+ for (BindingDefinition refBinding : promotedComponentReference
+ .getBindings()) {
+ compositeRefDefn.addBinding((BindingDefinition)refBinding.clone());
+ }
+ }
+ } else {
+ throw new InvalidPromotedReferenceException("Invalid promoted reference ",
+ promotedRef.toString());
+ }
+ } else {
+ throw new InvalidPromotedReferenceException("Invalid promoted reference ",
+ promotedRef.toString());
+ }
+
+ }
+ if (compositeRefDefn.getMultiplicity() == null) {
+ compositeRefDefn.setMultiplicity(leastMultiplicity);
+ }
+
+ }
+ }
+
+ private void validateTarget(URI target,
+ CompositeComponentType<ServiceDefinition, CompositeReferenceDefinition, Property<?>> composite) throws InvalidWireException {
+ QualifiedName targetName = new QualifiedName(target.getPath());
+ // if target is not a reference of the composite
+ if (composite.getReferences().get(targetName.getPartName()) == null) {
+ ComponentDefinition<?> targetDefinition =
+ composite.getDeclaredComponents().get(targetName.getPartName());
+ // if a target component exists in this composite
+ if (targetDefinition != null) {
+ Implementation<?> implementation = targetDefinition.getImplementation();
+ ComponentType<?, ?, ?> componentType = implementation.getComponentType();
+ Map<String, ? extends ServiceDefinition> services = componentType.getServices();
+ if (targetName.getPortName() == null) {
+ if (services.size() > 1 || services.isEmpty()) {
+ throw new InvalidWireException("Ambiguous target", targetName.toString());
+ }
+ } else {
+ if (services.get(targetName.getPortName()) == null) {
+ throw new InvalidWireException("Invalid target service", targetName
+ .toString());
+ }
+ }
+ } else {
+ throw new InvalidWireException("Target not found", targetName.toString());
+ }
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/Dependency.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/Dependency.java
new file mode 100644
index 0000000000..808f36072f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/Dependency.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.services.artifact.Artifact;
+
+/**
+ * A model object that represents a dependency on an external artifact.
+ *
+ * @version $Rev$ $Date$
+ */
+public class Dependency extends ModelObject {
+ private Artifact artifact;
+
+ public Artifact getArtifact() {
+ return artifact;
+ }
+
+ public void setArtifact(Artifact artifact) {
+ this.artifact = artifact;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ImplementationCompositeLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ImplementationCompositeLoader.java
new file mode 100644
index 0000000000..ac744d5905
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ImplementationCompositeLoader.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Set;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.osoa.sca.Constants;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.CompositeClassLoader;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.InvalidValueException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.LoaderUtil;
+import org.apache.tuscany.spi.loader.MissingResourceException;
+import org.apache.tuscany.spi.model.CompositeImplementation;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.services.artifact.Artifact;
+import org.apache.tuscany.spi.services.artifact.ArtifactRepository;
+
+/**
+ * Loader that handles an &lt;implementation.composite&gt; element.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ImplementationCompositeLoader extends LoaderExtension<CompositeImplementation> {
+ private static final QName IMPLEMENTATION_COMPOSITE =
+ new QName(Constants.SCA_NS, "implementation.composite");
+
+ private final ArtifactRepository artifactRepository;
+
+ public ImplementationCompositeLoader(@Autowire LoaderRegistry registry,
+ @Autowire ArtifactRepository artifactRepository) {
+ super(registry);
+ this.artifactRepository = artifactRepository;
+ }
+
+ public QName getXMLType() {
+ return IMPLEMENTATION_COMPOSITE;
+ }
+
+ public CompositeImplementation load(CompositeComponent parent,
+ ModelObject object, XMLStreamReader reader,
+ DeploymentContext deploymentContext)
+ throws XMLStreamException, LoaderException {
+
+ assert IMPLEMENTATION_COMPOSITE.equals(reader.getName());
+ String name = reader.getAttributeValue(null, "name");
+ String group = reader.getAttributeValue(null, "group");
+ String version = reader.getAttributeValue(null, "version");
+ String scdlLocation = reader.getAttributeValue(null, "scdlLocation");
+ String jarLocation = reader.getAttributeValue(null, "jarLocation");
+ LoaderUtil.skipToEndElement(reader);
+
+ CompositeImplementation impl = new CompositeImplementation();
+ impl.setName(name);
+ if (scdlLocation != null) {
+ try {
+ impl.setScdlLocation(new URL(deploymentContext.getScdlLocation(), scdlLocation));
+ } catch (MalformedURLException e) {
+ throw new InvalidValueException(scdlLocation, name, e);
+ }
+ impl.setClassLoader(deploymentContext.getClassLoader());
+ } else if (jarLocation != null) {
+ URL jarUrl;
+ try {
+ jarUrl = new URL(deploymentContext.getScdlLocation(), jarLocation);
+ } catch (MalformedURLException e) {
+ throw new InvalidValueException(jarLocation, name, e);
+ }
+ try {
+ impl.setScdlLocation(new URL("jar:" + jarUrl.toExternalForm() + "!/META-INF/sca/default.scdl"));
+ } catch (MalformedURLException e) {
+ throw new AssertionError("Could not convert URL to a jar: url");
+ }
+ impl.setClassLoader(new CompositeClassLoader(new URL[]{jarUrl}, deploymentContext.getClassLoader()));
+ } else if (artifactRepository != null && group != null && version != null) {
+ Artifact artifact = new Artifact();
+ artifact.setGroup(group);
+ artifact.setName(name);
+ artifact.setVersion(version);
+ artifact.setType("jar");
+ artifactRepository.resolve(artifact);
+ if (artifact.getUrl() == null) {
+ throw new MissingResourceException(artifact.toString(), name);
+ }
+ try {
+ impl.setScdlLocation(new URL("jar:" + artifact.getUrl() + "!/META-INF/sca/default.scdl"));
+ } catch (MalformedURLException e) {
+ throw new AssertionError(e);
+ }
+ Set<URL> artifactURLs = artifact.getUrls();
+ URL[] urls = new URL[artifactURLs.size()];
+ int i = 0;
+ for (URL artifactURL : artifactURLs) {
+ urls[i++] = artifactURL;
+ }
+ impl.setClassLoader(new CompositeClassLoader(urls, deploymentContext.getClassLoader()));
+ }
+ return impl;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ManagedRequestContext.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ManagedRequestContext.java
new file mode 100644
index 0000000000..f2a8109ee3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ManagedRequestContext.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import javax.security.auth.Subject;
+
+import org.osoa.sca.RequestContext;
+import org.osoa.sca.ServiceReference;
+import org.osoa.sca.CallableReference;
+
+import org.apache.tuscany.spi.component.WorkContext;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ManagedRequestContext implements RequestContext {
+ private WorkContext workContext;
+
+ public ManagedRequestContext(WorkContext workContext) {
+ this.workContext = workContext;
+ }
+
+ public Subject getSecuritySubject() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getServiceName() {
+ return workContext.getCurrentServiceName();
+ }
+
+ public <B> ServiceReference<B> getServiceReference() {
+ throw new UnsupportedOperationException();
+ }
+
+ public <CB> CB getCallback() {
+ throw new UnsupportedOperationException();
+ }
+
+ public <CB> CallableReference<CB> getCallbackReference() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ReferenceImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ReferenceImpl.java
new file mode 100644
index 0000000000..3fcba7b054
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ReferenceImpl.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.tuscany.spi.component.AbstractSCAObject;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.Reference;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+
+/**
+ * The default implementation of a {@link org.apache.tuscany.spi.component.Reference}
+ *
+ * @version $Rev$ $Date$
+ */
+public class ReferenceImpl extends AbstractSCAObject implements Reference {
+ private ServiceContract<?> serviceContract;
+ private List<ReferenceBinding> bindings = new ArrayList<ReferenceBinding>();
+ private boolean system;
+
+ public ReferenceImpl(String name, CompositeComponent parent, ServiceContract<?> contract) {
+ this(name, parent, contract, false);
+ }
+
+ public ReferenceImpl(String name,
+ CompositeComponent parent,
+ ServiceContract<?> contract,
+ boolean system) {
+ super(name, parent);
+ this.serviceContract = contract;
+ this.system = system;
+ }
+
+ public Scope getScope() {
+ return Scope.SYSTEM;
+ }
+
+ public ServiceContract<?> getServiceContract() {
+ return serviceContract;
+ }
+
+ public List<ReferenceBinding> getReferenceBindings() {
+ return Collections.unmodifiableList(bindings);
+ }
+
+ public void addReferenceBinding(ReferenceBinding binding) {
+ binding.setReference(this);
+ bindings.add(binding);
+ }
+
+ public void start() {
+ super.start();
+ for (ReferenceBinding binding : bindings) {
+ binding.start();
+ }
+ }
+
+ public void stop() {
+ super.stop();
+ for (ReferenceBinding binding : bindings) {
+ binding.stop();
+ }
+ }
+
+ @Override
+ public boolean isSystem() {
+ return system;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ServiceImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ServiceImpl.java
new file mode 100644
index 0000000000..2db8519ccc
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/ServiceImpl.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.tuscany.spi.component.AbstractSCAObject;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.Service;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+
+/**
+ * The default implementation of a {@link Service}
+ *
+ * @version $Rev$ $Date$
+ */
+public class ServiceImpl extends AbstractSCAObject implements Service {
+ private ServiceContract<?> serviceContract;
+ private List<ServiceBinding> bindings = new ArrayList<ServiceBinding>();
+ private boolean system;
+ private URI targetUri;
+
+ public ServiceImpl(String name, CompositeComponent parent, ServiceContract<?> contract) {
+ this(name, parent, contract, null, false);
+ }
+
+ public ServiceImpl(String name,
+ CompositeComponent parent,
+ ServiceContract<?> contract,
+ URI targetUri,
+ boolean system) {
+ super(name, parent);
+ this.serviceContract = contract;
+ this.system = system;
+ this.targetUri = targetUri;
+ }
+
+ public Scope getScope() {
+ return Scope.SYSTEM;
+ }
+
+ public ServiceContract<?> getServiceContract() {
+ return serviceContract;
+ }
+
+ public URI getTargetUri() {
+ return targetUri;
+ }
+
+ public List<ServiceBinding> getServiceBindings() {
+ return Collections.unmodifiableList(bindings);
+ }
+
+ public void addServiceBinding(ServiceBinding binding) {
+ binding.setService(this);
+ bindings.add(binding);
+ }
+
+ public void start() {
+ super.start();
+ for (ServiceBinding binding : bindings) {
+ binding.start();
+ }
+ }
+
+ public void stop() {
+ super.stop();
+ for (ServiceBinding binding : bindings) {
+ binding.stop();
+ }
+ }
+
+ @Override
+ public boolean isSystem() {
+ return system;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/SystemCompositeBuilder.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/SystemCompositeBuilder.java
new file mode 100644
index 0000000000..82fb5bf62e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/SystemCompositeBuilder.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import org.apache.tuscany.spi.builder.BuilderException;
+import org.apache.tuscany.spi.builder.BuilderRegistry;
+import org.apache.tuscany.spi.builder.Connector;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.services.management.TuscanyManagementService;
+
+import org.apache.tuscany.core.implementation.system.model.SystemCompositeImplementation;
+
+/**
+ * Produces system composite components by evaluating an assembly.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemCompositeBuilder extends AbstractCompositeBuilder<SystemCompositeImplementation> {
+ private TuscanyManagementService managementService;
+
+ public SystemCompositeBuilder() {
+ }
+
+ public SystemCompositeBuilder(BuilderRegistry builderRegistry,
+ Connector connector,
+ TuscanyManagementService managementService) {
+ this.builderRegistry = builderRegistry;
+ this.connector = connector;
+ this.managementService = managementService;
+ }
+
+ public CompositeComponent build(CompositeComponent parent,
+ ComponentDefinition<SystemCompositeImplementation> componentDefinition,
+ DeploymentContext deploymentContext) throws BuilderException {
+ SystemCompositeImplementation impl = componentDefinition.getImplementation();
+ CompositeComponentType<?, ?, ?> componentType = impl.getComponentType();
+ String name = componentDefinition.getName();
+ CompositeComponent component = new CompositeComponentImpl(name, parent, connector, true);
+ component.setManagementService(managementService);
+ build(parent, component, componentType, deploymentContext);
+ return component;
+ }
+
+ protected Class<SystemCompositeImplementation> getImplementationType() {
+ return SystemCompositeImplementation.class;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/SystemSingletonAtomicComponent.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/SystemSingletonAtomicComponent.java
new file mode 100644
index 0000000000..952533e476
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/composite/SystemSingletonAtomicComponent.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.core.wire.jdk.JDKWireService;
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.component.TargetInitializationException;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.extension.AbstractComponentExtension;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.apache.tuscany.spi.wire.WireService;
+
+/**
+ * An {@link org.apache.tuscany.spi.component.AtomicComponent} used when registering objects directly into a composite
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class SystemSingletonAtomicComponent<S, T extends S> extends AbstractComponentExtension
+ implements AtomicComponent {
+ private T instance;
+ private Map<String, InboundWire> inboundWires;
+ private WireService wireService = new JDKWireService();
+
+ public SystemSingletonAtomicComponent(String name, CompositeComponent parent, Class<S> interfaze, T instance) {
+ super(name, parent);
+ this.instance = instance;
+ inboundWires = new HashMap<String, InboundWire>();
+ initWire(interfaze);
+ }
+
+
+ public SystemSingletonAtomicComponent(String name,
+ CompositeComponent parent,
+ List<Class<?>> services,
+ T instance) {
+ super(name, parent);
+ this.instance = instance;
+ inboundWires = new HashMap<String, InboundWire>();
+ for (Class<?> interfaze : services) {
+ initWire(interfaze);
+ }
+ }
+
+ public Scope getScope() {
+ return Scope.COMPOSITE;
+ }
+
+ public boolean isEagerInit() {
+ return false;
+ }
+
+ public boolean isDestroyable() {
+ return false;
+ }
+
+ public int getInitLevel() {
+ return 0;
+ }
+
+ public long getMaxIdleTime() {
+ return -1;
+ }
+
+ public long getMaxAge() {
+ return -1;
+ }
+
+ public T getTargetInstance() throws TargetResolutionException {
+ return instance;
+ }
+
+ public void init(Object instance) throws TargetInitializationException {
+
+ }
+
+ public void destroy(Object instance) throws TargetDestructionException {
+
+ }
+
+ public Object createInstance() throws ObjectCreationException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void removeInstance() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void addInboundWire(InboundWire wire) {
+ inboundWires.put(wire.getServiceName(), wire);
+ }
+
+ public Collection<InboundWire> getInboundWires() {
+ return Collections.unmodifiableCollection(inboundWires.values());
+ }
+
+ public InboundWire getInboundWire(String serviceName) {
+ return inboundWires.get(serviceName);
+ }
+
+ public void addOutboundWire(OutboundWire wire) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void addOutboundWires(List<OutboundWire> wires) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Map<String, List<OutboundWire>> getOutboundWires() {
+ return Collections.emptyMap();
+ }
+
+
+ public TargetInvoker createTargetInvoker(String targetName, Operation operation, InboundWire callbackWire) {
+ return null;
+ }
+
+ public boolean isSystem() {
+ return true;
+ }
+
+ private void initWire(Class<?> interfaze) {
+ JavaServiceContract serviceContract = new JavaServiceContract(interfaze);
+ ServiceDefinition def = new ServiceDefinition(interfaze.getName(), serviceContract, false);
+ InboundWire wire = wireService.createWire(def);
+ wire.setContainer(this);
+ inboundWires.put(wire.getServiceName(), wire);
+ }
+
+ @Override
+ public boolean isOptimizable() {
+ return true;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponent.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponent.java
new file mode 100644
index 0000000000..bc087dd4c2
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponent.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.ObjectFactory;
+import static org.apache.tuscany.spi.idl.java.JavaIDLUtils.findMethod;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.apache.tuscany.core.wire.WireObjectFactory;
+
+import org.apache.tuscany.core.implementation.PojoAtomicComponent;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.injection.CallbackWireObjectFactory;
+import org.apache.tuscany.core.injection.FieldInjector;
+import org.apache.tuscany.core.injection.Injector;
+import org.apache.tuscany.core.injection.InvalidAccessorException;
+import org.apache.tuscany.core.injection.MethodInjector;
+
+/**
+ * The runtime instantiation of Java component implementations
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaAtomicComponent extends PojoAtomicComponent {
+
+ public JavaAtomicComponent(PojoConfiguration configuration) {
+ super(configuration);
+ }
+
+ public TargetInvoker createTargetInvoker(String targetName, Operation operation, InboundWire callbackWire) {
+ Method[] methods;
+ Class callbackClass = null;
+ if (operation.isCallback()) {
+ callbackClass = operation.getServiceContract().getCallbackClass();
+ methods = callbackClass.getMethods();
+
+ } else {
+ methods = operation.getServiceContract().getInterfaceClass().getMethods();
+ }
+ Method method = findMethod(operation, methods);
+ return new JavaTargetInvoker(method, this, callbackWire, callbackClass, workContext, monitor);
+ }
+
+ protected void onServiceWire(InboundWire wire) {
+ String name = wire.getCallbackReferenceName();
+ if (name == null) {
+ // It's ok not to have one, we just do nothing
+ return;
+ }
+ Member member = callbackSites.get(name);
+ if (member != null) {
+ injectors.add(createCallbackInjector(member, wire.getServiceContract(), wire));
+ }
+ }
+
+ protected Injector<Object> createCallbackInjector(Member member,
+ ServiceContract<?> contract,
+ InboundWire inboundWire) {
+ if (member instanceof Field) {
+ Field field = (Field) member;
+ ObjectFactory<?> factory = new CallbackWireObjectFactory(field.getType(), wireService, inboundWire);
+ return new FieldInjector<Object>(field, factory);
+ } else if (member instanceof Method) {
+ Method method = (Method) member;
+ Class<?> type = method.getParameterTypes()[0];
+ ObjectFactory<?> factory = new CallbackWireObjectFactory(type, wireService, inboundWire);
+ return new MethodInjector<Object>(method, factory);
+ } else {
+ throw new InvalidAccessorException("Member must be a field or method", member.getName());
+ }
+ }
+
+ @SuppressWarnings({"unchecked"})
+ protected ObjectFactory<?> createWireFactory(Class<?> interfaze, OutboundWire wire) {
+ return new WireObjectFactory(interfaze, wire, wireService);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilder.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilder.java
new file mode 100644
index 0000000000..7d11dc9e78
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilder.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.injection.MethodEventInvoker;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.injection.ResourceObjectFactory;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.builder.BuilderConfigException;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.ComponentBuilderExtension;
+import org.apache.tuscany.spi.host.ResourceHost;
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.Resource;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.ComponentType;
+import org.apache.tuscany.spi.model.PropertyValue;
+
+/**
+ * Builds a Java-based atomic context from a component definition
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class JavaComponentBuilder extends ComponentBuilderExtension<JavaImplementation> {
+
+ private ResourceHost host;
+
+ @Autowire
+ public void setHost(ResourceHost host) {
+ this.host = host;
+ }
+
+ @SuppressWarnings("unchecked")
+ public AtomicComponent build(CompositeComponent parent,
+ ComponentDefinition<JavaImplementation> definition,
+ DeploymentContext deployment) throws BuilderConfigException {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> componentType =
+ definition.getImplementation().getComponentType();
+
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setParent(parent);
+ if (definition.getInitLevel() != null) {
+ configuration.setInitLevel(definition.getInitLevel());
+ } else {
+ configuration.setInitLevel(componentType.getInitLevel());
+ }
+ if (componentType.getMaxAge() > 0) {
+ configuration.setMaxAge(componentType.getMaxAge());
+ } else if (componentType.getMaxIdleTime() > 0) {
+ configuration.setMaxIdleTime(componentType.getMaxIdleTime());
+ }
+ Method initMethod = componentType.getInitMethod();
+ if (initMethod != null) {
+ configuration.setInitInvoker(new MethodEventInvoker(initMethod));
+ }
+ Method destroyMethod = componentType.getDestroyMethod();
+ if (destroyMethod != null) {
+ configuration.setDestroyInvoker(new MethodEventInvoker(destroyMethod));
+ }
+
+ configuration.setWireService(wireService);
+ configuration.setWorkContext(workContext);
+ configuration.setScheduler(workScheduler);
+ configuration.setImplementationClass(definition.getImplementation().getImplementationClass());
+
+ // setup property injection sites
+ for (JavaMappedProperty<?> property : componentType.getProperties().values()) {
+ configuration.addPropertySite(property.getName(), property.getMember());
+ }
+
+ // setup reference injection sites
+ try {
+
+ for (JavaMappedReference reference : componentType.getReferences().values()) {
+ Member member = reference.getMember();
+ if (member != null) {
+ // could be null if the reference is mapped to a constructor
+ configuration.addReferenceSite(reference.getName(), member);
+ }
+ }
+ } catch ( Exception e ) {
+ e.printStackTrace();
+ }
+
+ for (Resource resource : componentType.getResources().values()) {
+ Member member = resource.getMember();
+ if (member != null) {
+ // could be null if the resource is mapped to a constructor
+ configuration.addResourceSite(resource.getName(), member);
+ }
+ }
+
+ // setup constructor injection
+ ConstructorDefinition<?> ctorDef = componentType.getConstructorDefinition();
+ Constructor<?> constr = ctorDef.getConstructor();
+ PojoObjectFactory<?> instanceFactory = new PojoObjectFactory(constr);
+ configuration.setInstanceFactory(instanceFactory);
+ configuration.getConstructorParamNames().addAll(ctorDef.getInjectionNames());
+ for (Class<?> clazz : constr.getParameterTypes()) {
+ configuration.addConstructorParamType(clazz);
+ }
+ configuration.setMonitor(monitor);
+ configuration.setName(definition.getName());
+ JavaAtomicComponent component = new JavaAtomicComponent(configuration);
+
+ // handle properties
+ handleProperties(definition, component);
+
+ // handle resources
+ handleResources(componentType, component, parent);
+
+ handleCallbackSites(componentType, configuration);
+
+ // FIXME JFM this should be refactored to be by operation
+ // as per the Java C&I @AllowsPassByReference can be at the class level (applying to all methods in
+ //...the class or at the method level applying only to the specific method
+ component.setAllowsPassByReference(componentType.isAllowsPassByReference());
+ component.setPassByReferenceMethods(componentType.getPassByReferenceMethods());
+
+ if (componentType.getConversationIDMember() != null) {
+ component.addConversationIDFactory(componentType.getConversationIDMember());
+ }
+
+ return component;
+ }
+
+ private void handleCallbackSites(ComponentType componentType, PojoConfiguration configuration) {
+ for (Object sd : componentType.getServices().values()) {
+ // TODO: TUSCANY-1111, if using componentType side file with wsdl idl then may not get JavaMappedService
+ if (sd instanceof JavaMappedService) {
+ JavaMappedService service = (JavaMappedService) sd;
+ // setup callback injection sites
+ if (service.getCallbackReferenceName() != null) {
+ // Only if there is a callback reference in the service
+ configuration.addCallbackSite(service.getCallbackReferenceName(), service.getCallbackMember());
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings({"unchecked"})
+ private void handleResources(
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> componentType,
+ JavaAtomicComponent component,
+ CompositeComponent parent) {
+ for (Resource resource : componentType.getResources().values()) {
+ ObjectFactory<?> objectFactory = resource.getObjectFactory();
+ if (objectFactory != null) {
+ component.addResourceFactory(resource.getName(), objectFactory);
+ } else {
+ String name = resource.getName();
+ boolean optional = resource.isOptional();
+ Class<Object> type = (Class<Object>) resource.getType();
+ ResourceObjectFactory<Object> factory;
+ String mappedName = resource.getMappedName();
+ if (mappedName == null) {
+ // by type
+ factory = new ResourceObjectFactory<Object>(type, optional, parent, host);
+ } else {
+ factory = new ResourceObjectFactory<Object>(type, mappedName, optional, parent, host);
+ }
+ component.addResourceFactory(name, factory);
+ }
+ }
+ }
+
+ private void handleProperties(ComponentDefinition<JavaImplementation> definition, JavaAtomicComponent component) {
+ for (PropertyValue<?> property : definition.getPropertyValues().values()) {
+ ObjectFactory<?> factory = property.getValueFactory();
+ if (factory != null) {
+ component.addPropertyFactory(property.getName(), factory);
+ }
+ }
+ }
+
+ protected Class<JavaImplementation> getImplementationType() {
+ return JavaImplementation.class;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaComponentTypeLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaComponentTypeLoader.java
new file mode 100644
index 0000000000..6eaba3bf2f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaComponentTypeLoader.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.net.URI;
+import java.net.URL;
+import java.util.Iterator;
+
+import org.apache.tuscany.core.util.JavaIntrospectionHelper;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.ComponentTypeLoaderExtension;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.implementation.java.IntrospectionRegistry;
+import org.apache.tuscany.spi.implementation.java.Introspector;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.osoa.sca.annotations.Constructor;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JavaComponentTypeLoader extends ComponentTypeLoaderExtension<JavaImplementation> {
+ @Autowire
+ protected JavaInterfaceProcessorRegistry processorRegistry;
+
+ private Introspector introspector;
+
+ @Constructor( {"registry", "introspector"})
+ public JavaComponentTypeLoader(@Autowire
+ LoaderRegistry loaderRegistry, @Autowire
+ IntrospectionRegistry introspector) {
+ super(loaderRegistry);
+ this.introspector = introspector;
+ }
+
+ @Override
+ protected Class<JavaImplementation> getImplementationClass() {
+ return JavaImplementation.class;
+ }
+
+ public void load(CompositeComponent parent, JavaImplementation implementation, DeploymentContext deploymentContext)
+ throws LoaderException {
+ Class<?> implClass = implementation.getImplementationClass();
+ PojoComponentType<JavaMappedService, ComponentTypeReferenceDefinition, JavaMappedProperty<?>> componentType = loadByIntrospection(parent, implementation, deploymentContext);
+ URL resource = implClass.getResource(JavaIntrospectionHelper.getBaseName(implClass) + ".componentType");
+ if (resource != null) {
+ // TODO: TUSCANY-1111, How to merge the component type loaded from the file into the PojoComponentType
+ PojoComponentType<?, ComponentTypeReferenceDefinition, ?> sideFileCT = loadFromSidefile(parent, resource, deploymentContext);
+
+ // TODO: TUSCANY-1111, hack to get the sidefile defined WSDLServiceContract used
+ // only works with a single service
+ Iterator it = componentType.getServices().values().iterator();
+ for (Object o : sideFileCT.getServices().values()) {
+ ServiceDefinition sideFileSD = (ServiceDefinition)o;
+ ServiceDefinition actualSD = (ServiceDefinition)it.next();
+ ServiceContract<?> newServiceContract = sideFileSD.getServiceContract();
+ ServiceContract<?> contract = actualSD.getServiceContract();
+ if (JavaServiceContract.class.isInstance(contract)) {
+ try {
+ // [rfeng] AS we now defer the java interface processing for TUSCANY-1165
+ // We need to do the full introspection now
+ contract =
+ processorRegistry.introspect(contract.getInterfaceClass(),
+ contract.getCallbackClass(),
+ true);
+ } catch (InvalidServiceContractException e) {
+ throw new LoaderException(e);
+ }
+ }
+ // TODO: TUSCANY-1111, runtime requires interfaceClass
+ // but currently there's no way of gen'ing that from WSDL
+ newServiceContract.setInterfaceClass(contract.getInterfaceClass());
+ newServiceContract.setDataBinding(contract.getDataBinding());
+ actualSD.setServiceContract(newServiceContract);
+ }
+
+ //TODO: if introspection has not yeilded any info, then atleast pick up things in the sidefile
+ //[svkrish] needed this for references overriding verification
+ ComponentTypeReferenceDefinition ctRefSideFile = null;
+ for (ComponentTypeReferenceDefinition ctRefIntrospection : componentType.getReferences().values()) {
+ if(ctRefIntrospection.getTargets() == null | ctRefIntrospection.getTargets().size() == 0) {
+ ctRefSideFile = sideFileCT.getReferences().get(ctRefIntrospection.getName());
+ if (ctRefSideFile != null) {
+ for(URI uri : ctRefSideFile.getTargets()) {
+ ctRefIntrospection.addTarget(uri);
+ }
+ }
+ }
+ }
+ }
+ implementation.setComponentType(componentType);
+ }
+
+ protected PojoComponentType loadByIntrospection(CompositeComponent parent,
+ JavaImplementation implementation,
+ DeploymentContext deploymentContext) throws ProcessingException {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> componentType =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Class<?> implClass = implementation.getImplementationClass();
+ introspector.introspect(parent, implClass, componentType, deploymentContext);
+ return componentType;
+ }
+
+ protected PojoComponentType loadFromSidefile(CompositeComponent parent, URL url, DeploymentContext deploymentContext)
+ throws LoaderException {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> componentType =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ return loaderRegistry.load(parent, componentType, url, PojoComponentType.class, deploymentContext);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaImplementation.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaImplementation.java
new file mode 100644
index 0000000000..432bf31d63
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaImplementation.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import org.apache.tuscany.spi.model.AtomicImplementation;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public class JavaImplementation extends AtomicImplementation<PojoComponentType> {
+ private String className;
+ private Class<?> implementationClass;
+
+ public JavaImplementation() {
+ }
+
+ public JavaImplementation(Class<?> implementationClass) {
+ this.implementationClass = implementationClass;
+ this.className = implementationClass.getName();
+ }
+
+ public JavaImplementation(Class<?> implementationClass, PojoComponentType componentType) {
+ super(componentType);
+ this.implementationClass = implementationClass;
+ this.className = implementationClass == null ? null : implementationClass.getName();
+ }
+
+ public String getClassName() {
+ return className;
+ }
+
+ public void setClassName(String className) {
+ this.className = className;
+ this.implementationClass = null;
+ }
+
+ public Class<?> getImplementationClass() {
+ return implementationClass;
+ }
+
+ public void setImplementationClass(Class<?> implementationClass) {
+ this.implementationClass = implementationClass;
+ this.className = implementationClass.getName();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaImplementationLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaImplementationLoader.java
new file mode 100644
index 0000000000..0f458c7ab4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaImplementationLoader.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import static org.osoa.sca.Constants.SCA_NS;
+import org.osoa.sca.annotations.Constructor;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderUtil;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.annotation.Autowire;
+
+public class JavaImplementationLoader extends LoaderExtension {
+ public static final QName IMPLEMENTATION_JAVA = new QName(SCA_NS, "implementation.java");
+
+ @Constructor({"registry"})
+ public JavaImplementationLoader(@Autowire LoaderRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public QName getXMLType() {
+ return IMPLEMENTATION_JAVA;
+ }
+
+ public ModelObject load(CompositeComponent parent, ModelObject object, XMLStreamReader reader,
+ DeploymentContext deploymentContext)
+ throws XMLStreamException, LoaderException {
+ assert IMPLEMENTATION_JAVA.equals(reader.getName());
+ String implClass = reader.getAttributeValue(null, "class");
+ Class<?> implementationClass = LoaderUtil.loadClass(implClass, deploymentContext.getClassLoader());
+
+ JavaImplementation implementation = new JavaImplementation();
+ implementation.setClassName(implClass);
+ implementation.setImplementationClass(implementationClass);
+ registry.loadComponentType(parent, implementation, deploymentContext);
+ LoaderUtil.skipToEndElement(reader);
+ return implementation;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaTargetInvoker.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaTargetInvoker.java
new file mode 100644
index 0000000000..6da60304fa
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/java/JavaTargetInvoker.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Set;
+
+import org.osoa.sca.NoRegisteredCallbackException;
+
+import org.apache.tuscany.spi.component.ComponentException;
+import org.apache.tuscany.spi.component.InvalidConversationSequenceException;
+import org.apache.tuscany.spi.component.TargetException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.extension.ExecutionMonitor;
+import org.apache.tuscany.spi.extension.TargetInvokerExtension;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import static org.apache.tuscany.core.util.JavaIntrospectionHelper.findClosestMatchingMethod;
+import static org.apache.tuscany.core.util.JavaIntrospectionHelper.getAllUniquePublicProtectedMethods;
+
+/**
+ * Responsible for synchronously dispatching an invocation to a Java component implementation instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaTargetInvoker extends TargetInvokerExtension {
+ protected Method operation;
+ protected JavaAtomicComponent component;
+ protected Object target;
+ protected Class callbackClass;
+ protected boolean stateless;
+
+ public JavaTargetInvoker(Method operation,
+ JavaAtomicComponent component,
+ InboundWire wire,
+ Class callbackClass,
+ WorkContext context,
+ ExecutionMonitor monitor) {
+ super(wire, context, monitor);
+ assert operation != null : "Operation method cannot be null";
+ this.operation = operation;
+ this.component = component;
+ stateless = Scope.STATELESS == component.getScope();
+ this.callbackClass = callbackClass;
+ }
+
+ public JavaTargetInvoker(Method operation,
+ JavaAtomicComponent component,
+ InboundWire callbackWire,
+ WorkContext context,
+ ExecutionMonitor monitor) {
+ this(operation, component, callbackWire, null, context, monitor);
+ }
+
+ public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException {
+ try {
+ Object instance = getInstance(sequence);
+ if (callbackClass != null && !callbackClass.isInstance(instance)) {
+ throw new InvocationTargetException(
+ new NoRegisteredCallbackException("Instance is does not implement callback ["
+ + callbackClass.toString() + "]"));
+ }
+ if (!operation.getDeclaringClass().isInstance(instance)) {
+ Set<Method> methods = getAllUniquePublicProtectedMethods(instance.getClass());
+ Method newOperation = findClosestMatchingMethod(operation.getName(),
+ operation.getParameterTypes(), methods);
+ if (newOperation != null) {
+ operation = newOperation;
+ }
+ }
+ Object ret;
+ if (payload != null && !payload.getClass().isArray()) {
+ ret = operation.invoke(instance, payload);
+ } else {
+ ret = operation.invoke(instance, (Object[]) payload);
+ }
+ if (stateless) {
+ // notify a stateless instance of a destruction event after the invoke
+ component.destroy(instance);
+ } else if (sequence == END) {
+ component.destroy(instance);
+ // if end conversation, remove resource
+ component.removeInstance();
+ }
+ return ret;
+ } catch (IllegalAccessException e) {
+ throw new InvocationTargetException(e);
+ } catch (ComponentException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+
+ @Override
+ public JavaTargetInvoker clone() throws CloneNotSupportedException {
+ try {
+ JavaTargetInvoker invoker = (JavaTargetInvoker) super.clone();
+ invoker.target = null;
+ return invoker;
+ } catch (CloneNotSupportedException e) {
+ return null; // will not happen
+ }
+ }
+
+ /**
+ * Resolves the target service instance or returns a cached one
+ */
+ protected Object getInstance(short sequence) throws TargetException {
+ if (!cacheable) {
+ if (sequence == START || sequence == NONE) {
+ return component.getTargetInstance();
+ } else if (sequence == CONTINUE || sequence == END) {
+ return component.getAssociatedTargetInstance();
+ } else {
+ throw new InvalidConversationSequenceException("Unknown sequence type", String.valueOf(sequence));
+ }
+ } else {
+ assert sequence == NONE; // conversations are not cacheable
+ if (target == null) {
+ target = component.getTargetInstance();
+ }
+ return target;
+ }
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/AllowsPassByReferenceProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/AllowsPassByReferenceProcessor.java
new file mode 100644
index 0000000000..19244810fd
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/AllowsPassByReferenceProcessor.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Method;
+
+import org.osoa.sca.annotations.AllowsPassByReference;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Processes {@link AllowsPassByReference} on an implementation
+ *
+ * @version $Rev: 479093 $ $Date: 2006-11-25 12:34:41 +0530 (Sat, 25 Nov 2006) $
+ */
+public class AllowsPassByReferenceProcessor extends ImplementationProcessorExtension {
+
+ public <T> void visitClass(CompositeComponent parent,
+ Class<T> clazz,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context) throws ProcessingException {
+ AllowsPassByReference annotation = clazz.getAnnotation(AllowsPassByReference.class);
+ if (annotation != null) {
+ type.setAllowsPassByReference(true);
+ } else {
+ type.setAllowsPassByReference(false);
+ }
+
+ }
+
+ public void visitMethod(CompositeComponent parent, Method method,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context)throws ProcessingException {
+
+ AllowsPassByReference annotation = method.getAnnotation(AllowsPassByReference.class);
+ if (annotation != null) {
+ type.getPassByReferenceMethods().add(method.getName());
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/AmbiguousConstructorException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/AmbiguousConstructorException.java
new file mode 100644
index 0000000000..03d092880d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/AmbiguousConstructorException.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Thrown when constructor parameters cannot be unambiguously resolved to a property or reference
+ *
+ * @version $Rev$ $Date$
+ */
+public class AmbiguousConstructorException extends ProcessingException {
+
+ public AmbiguousConstructorException(String message) {
+ super(message);
+ }
+
+ public AmbiguousConstructorException(String message, String identifier) {
+ super(message, identifier);
+ }
+
+ public AmbiguousConstructorException(String message, String identifier, Throwable cause) {
+ super(message, identifier, cause);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessor.java
new file mode 100644
index 0000000000..50f60147ee
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessor.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.util.List;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+
+/**
+ * Handles processing of a constructor decorated with {@link org.osoa.sca.annotations.Constructor}
+ *
+ * @version $Rev$ $Date$
+ */
+@SuppressWarnings("unchecked")
+public class ConstructorProcessor extends ImplementationProcessorExtension {
+
+ private ImplementationProcessorService service;
+
+ public ConstructorProcessor(@Autowire ImplementationProcessorService service) {
+ this.service = service;
+ }
+
+ public <T> void visitClass(CompositeComponent parent, Class<T> clazz,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context) throws ProcessingException {
+ Constructor[] ctors = clazz.getConstructors();
+ boolean found = false;
+ for (Constructor constructor : ctors) {
+ if (constructor.getAnnotation(org.osoa.sca.annotations.Constructor.class) != null) {
+ if (found) {
+ String name = constructor.getDeclaringClass().getName();
+ throw new DuplicateConstructorException("Multiple constructors marked with @Constructor", name);
+ }
+ found = true;
+ }
+ }
+ }
+
+ public <T> void visitConstructor(CompositeComponent parent, Constructor<T> constructor,
+ PojoComponentType<JavaMappedService, JavaMappedReference,
+ JavaMappedProperty<?>> type,
+ DeploymentContext context) throws ProcessingException {
+ org.osoa.sca.annotations.Constructor annotation =
+ constructor.getAnnotation(org.osoa.sca.annotations.Constructor.class);
+ if (annotation == null) {
+ return;
+ }
+ ConstructorDefinition<?> definition = type.getConstructorDefinition();
+ if (definition != null && !definition.getConstructor().equals(constructor)) {
+ String name = constructor.getDeclaringClass().getName();
+ throw new DuplicateConstructorException("Multiple constructor definitions found", name);
+ } else if (definition == null) {
+ definition = new ConstructorDefinition(constructor);
+ }
+ Class<?>[] params = constructor.getParameterTypes();
+ String[] names = annotation.value();
+ Annotation[][] annotations = constructor.getParameterAnnotations();
+ List<String> injectionNames = definition.getInjectionNames();
+ for (int i = 0; i < params.length; i++) {
+ Class<?> param = params[i];
+ Annotation[] paramAnnotations = annotations[i];
+ try {
+ if (!service.processParam(param,
+ constructor.getGenericParameterTypes()[i],
+ paramAnnotations,
+ names,
+ i,
+ type,
+ injectionNames)) {
+ String name = (i < names.length) ? names[i] : "";
+ service.addName(injectionNames, i, name);
+ }
+ } catch (ProcessingException e) {
+ e.setMember(constructor);
+ throw e;
+ }
+ }
+ if (names.length != 0 && names[0].length() != 0 && names.length != params.length) {
+ throw new InvalidConstructorException("Names in @Constructor do not match number of parameters");
+ }
+ type.setConstructorDefinition(definition);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ContextProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ContextProcessor.java
new file mode 100644
index 0000000000..c207fdb5c4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ContextProcessor.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.osoa.sca.CompositeContext;
+import org.osoa.sca.RequestContext;
+import org.osoa.sca.ComponentContext;
+import org.osoa.sca.annotations.Context;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+import org.apache.tuscany.spi.implementation.java.Resource;
+import org.apache.tuscany.spi.wire.WireService;
+
+import org.apache.tuscany.core.injection.CompositeContextObjectFactory;
+import org.apache.tuscany.core.injection.RequestContextObjectFactory;
+import org.apache.tuscany.core.util.JavaIntrospectionHelper;
+
+/**
+ * Processes {@link @Context} annotations on a component implementation and adds a {@link JavaMappedProperty} to the
+ * component type which will be used to inject the appropriate context
+ *
+ * @version $Rev$ $Date$
+ */
+public class ContextProcessor extends ImplementationProcessorExtension {
+ private WireService wireService;
+ private WorkContext workContext;
+
+ @Autowire
+ public void setWireService(WireService wireService) {
+ this.wireService = wireService;
+ }
+
+ @Autowire
+ public void setWorkContext(WorkContext workContext) {
+ this.workContext = workContext;
+ }
+
+ public void visitMethod(CompositeComponent parent,
+ Method method,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context)
+ throws ProcessingException {
+ if (method.getAnnotation(Context.class) == null) {
+ return;
+ }
+ if (method.getParameterTypes().length != 1) {
+ throw new IllegalContextException("Context setter must have one parameter", method.toString());
+ }
+ Class<?> paramType = method.getParameterTypes()[0];
+ if (ComponentContext.class.equals(paramType)) {
+ // FIXME: handle injection of ComponentContext
+ throw new UnsupportedOperationException();
+/*
+ String name = method.getName();
+ name = JavaIntrospectionHelper.toPropertyName(name);
+ Resource resource = new Resource();
+ resource.setName(name);
+ resource.setMember(method);
+ resource.setObjectFactory(new CompositeContextObjectFactory(parent, wireService));
+ type.getResources().put(name, resource);
+*/
+ } else if (RequestContext.class.equals(paramType)) {
+ String name = method.getName();
+ name = JavaIntrospectionHelper.toPropertyName(name);
+ Resource resource = new Resource();
+ resource.setName(name);
+ resource.setMember(method);
+ resource.setObjectFactory(new RequestContextObjectFactory(workContext));
+ type.getResources().put(name, resource);
+ } else {
+ throw new UnknownContextTypeException(paramType.getName());
+ }
+ }
+
+ public void visitField(CompositeComponent parent, Field field,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context) throws ProcessingException {
+ if (field.getAnnotation(Context.class) == null) {
+ return;
+ }
+ Class<?> paramType = field.getType();
+ if (ComponentContext.class.equals(paramType)) {
+ // FIXME: handle injection of ComponentContext
+ throw new UnsupportedOperationException();
+/*
+ String name = field.getName();
+ Resource resource = new Resource();
+ resource.setName(name);
+ resource.setMember(field);
+ resource.setObjectFactory(new CompositeContextObjectFactory(parent, wireService));
+ type.getResources().put(name, resource);
+*/
+ } else if (CompositeContext.class.equals(paramType)) {
+ String name = field.getName();
+ Resource resource = new Resource();
+ resource.setName(name);
+ resource.setMember(field);
+ resource.setObjectFactory(new CompositeContextObjectFactory(parent, wireService));
+ type.getResources().put(name, resource);
+ } else if (RequestContext.class.equals(paramType)) {
+ String name = field.getName();
+ name = JavaIntrospectionHelper.toPropertyName(name);
+ Resource resource = new Resource();
+ resource.setName(name);
+ resource.setMember(field);
+ resource.setObjectFactory(new RequestContextObjectFactory(workContext));
+ type.getResources().put(name, resource);
+ } else {
+ throw new UnknownContextTypeException(paramType.getName());
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ConversationProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ConversationProcessor.java
new file mode 100644
index 0000000000..fa369f72c6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ConversationProcessor.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+import org.osoa.sca.annotations.ConversationAttributes;
+import org.osoa.sca.annotations.ConversationID;
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ConversationProcessor extends ImplementationProcessorExtension {
+ private static final String SECONDS = " SECONDS";
+ private static final String MINUTES = " MINUTES";
+ private static final String HOURS = " HOURS";
+ private static final String DAYS = " DAYS";
+ private static final String YEARS = " YEARS";
+
+ public <T> void visitClass(CompositeComponent parent,
+ Class<T> clazz,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context) throws ProcessingException {
+
+ ConversationAttributes conversation = clazz.getAnnotation(ConversationAttributes.class);
+ if (conversation == null) {
+ return;
+ }
+ Scope scope = clazz.getAnnotation(Scope.class);
+ if (scope == null) {
+ // implicitly assume conversation
+ type.setImplementationScope(org.apache.tuscany.spi.model.Scope.CONVERSATION);
+ } else if (scope != null && !"CONVERSATION".equals(scope.value().toUpperCase())) {
+ throw new InvalidConversationalImplementation(
+ "Service is marked with @ConversationAttributes but the scope is not @Scope(\"CONVERSATION\")",
+ clazz.getName());
+ } else if (conversation != null) {
+ long maxAge;
+ long maxIdleTime;
+ String maxAgeVal = conversation.maxAge();
+ String maxIdleTimeVal = conversation.maxIdleTime();
+ if (maxAgeVal.length() > 0 && maxIdleTimeVal.length() > 0) {
+ throw new InvalidConversationalImplementation("Max idle time and age both specified", clazz.getName());
+ }
+ try {
+ if (maxAgeVal.length() > 0) {
+ maxAge = convertTimeMillis(maxAgeVal);
+ type.setMaxAge(maxAge);
+ }
+ } catch (NumberFormatException e) {
+ throw new InvalidConversationalImplementation("Invalid maximum age", clazz.getName(), e);
+ }
+ try {
+ if (maxIdleTimeVal.length() > 0) {
+ maxIdleTime = convertTimeMillis(maxIdleTimeVal);
+ type.setMaxIdleTime(maxIdleTime);
+ }
+ } catch (NumberFormatException e) {
+ throw new InvalidConversationalImplementation("Invalid maximum idle time", clazz.getName(), e);
+ }
+ }
+
+ }
+
+ public void visitMethod(CompositeComponent parent, Method method,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context)
+ throws ProcessingException {
+ ConversationID conversationID = method.getAnnotation(ConversationID.class);
+ if (conversationID == null) {
+ return;
+ }
+ type.setConversationIDMember(method);
+ }
+
+ public void visitField(CompositeComponent parent, Field field,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context) throws ProcessingException {
+ ConversationID conversationID = field.getAnnotation(ConversationID.class);
+ if (conversationID == null) {
+ return;
+ }
+ type.setConversationIDMember(field);
+ }
+
+ protected long convertTimeMillis(String expr) throws NumberFormatException {
+ expr = expr.trim().toUpperCase();
+ int i = expr.lastIndexOf(SECONDS);
+ if (i >= 0) {
+ String units = expr.substring(0, i);
+ return Long.parseLong(units) * 1000;
+ }
+ i = expr.lastIndexOf(MINUTES);
+ if (i >= 0) {
+ String units = expr.substring(0, i);
+ return Long.parseLong(units) * 60000;
+ }
+
+ i = expr.lastIndexOf(HOURS);
+ if (i >= 0) {
+ String units = expr.substring(0, i);
+ return Long.parseLong(units) * 3600000;
+ }
+ i = expr.lastIndexOf(DAYS);
+ if (i >= 0) {
+ String units = expr.substring(0, i);
+ return Long.parseLong(units) * 86400000;
+ }
+ i = expr.lastIndexOf(YEARS);
+ if (i >= 0) {
+ String units = expr.substring(0, i);
+ return Long.parseLong(units) * 31556926000L;
+ }
+ return Long.parseLong(expr) * 1000; // assume seconds if no suffix specified
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DestroyProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DestroyProcessor.java
new file mode 100644
index 0000000000..7ef540432f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DestroyProcessor.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.osoa.sca.annotations.Destroy;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Processes the {@link @Destroy} annotation on a component implementation and updates the component type with the
+ * decorated destructor method
+ *
+ * @version $Rev$ $Date$
+ */
+public class DestroyProcessor extends ImplementationProcessorExtension {
+
+ public void visitMethod(CompositeComponent parent, Method method,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context)
+ throws ProcessingException {
+ Destroy annotation = method.getAnnotation(Destroy.class);
+ if (annotation == null) {
+ return;
+ }
+ if (method.getParameterTypes().length != 0) {
+ throw new IllegalDestructorException("Destructor must not have argments", method.toString());
+ }
+ if (type.getDestroyMethod() != null) {
+ throw new DuplicateDestructorException("More than one destructor found on implementation");
+ }
+ if (Modifier.isProtected(method.getModifiers())) {
+ method.setAccessible(true);
+ }
+ type.setDestroyMethod(method);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateConstructorException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateConstructorException.java
new file mode 100644
index 0000000000..88db7ebb79
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateConstructorException.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Thrown when more than one component implementation constructor is annotated with {@link
+ * org.osoa.sca.annotations.Constructor}
+ *
+ * @version $Rev$ $Date$
+ */
+public class DuplicateConstructorException extends ProcessingException {
+
+ public DuplicateConstructorException(String message) {
+ super(message);
+ }
+
+ public DuplicateConstructorException(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateDestructorException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateDestructorException.java
new file mode 100644
index 0000000000..6225bd6219
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateDestructorException.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Thrown when an implementation is annotated multiple times with {@link org.osoa.sca.annotations.Destroy}
+ *
+ * @version $Rev$ $Date$
+ */
+public class DuplicateDestructorException extends ProcessingException {
+
+ public DuplicateDestructorException(String message) {
+ super(message);
+ }
+
+ public DuplicateDestructorException(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateInitException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateInitException.java
new file mode 100644
index 0000000000..105edee1a2
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateInitException.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Thrown when an implementation is annotated multiple times with {@link @org.osoa.sca.annotations.Init}
+ *
+ * @version $Rev$ $Date$
+ */
+public class DuplicateInitException extends ProcessingException {
+
+ public DuplicateInitException(String message) {
+ super(message);
+ }
+
+ public DuplicateInitException(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateReferenceException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateReferenceException.java
new file mode 100644
index 0000000000..5eae1461c2
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateReferenceException.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Thrown when an implementation has more than one reference injection site with the same name
+ *
+ * @version $Rev$ $Date$
+ */
+public class DuplicateReferenceException extends ProcessingException {
+
+ public DuplicateReferenceException(String message) {
+ super(message);
+ }
+
+
+ public DuplicateReferenceException(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateResourceException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateResourceException.java
new file mode 100644
index 0000000000..9dd718c03e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/DuplicateResourceException.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Thrown when an implementation has more than one resource injection site with the same name
+ *
+ * @version $Rev$ $Date$
+ */
+public class DuplicateResourceException extends ProcessingException {
+
+ public DuplicateResourceException(String message) {
+ super(message);
+ }
+
+ public DuplicateResourceException(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/EagerInitProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/EagerInitProcessor.java
new file mode 100644
index 0000000000..a2431dc5b1
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/EagerInitProcessor.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.osoa.sca.annotations.EagerInit;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Handles processing of {@link org.osoa.sca.annotations.EagerInit}
+ *
+ * @version $Rev$ $Date$
+ */
+public class EagerInitProcessor extends ImplementationProcessorExtension {
+
+ public <T> void visitClass(CompositeComponent parent, Class<T> clazz,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context) throws ProcessingException {
+ super.visitClass(parent, clazz, type, context);
+ EagerInit annotation = clazz.getAnnotation(EagerInit.class);
+ if (annotation == null) {
+ Class<?> superClass = clazz.getSuperclass();
+ while (!Object.class.equals(superClass)) {
+ annotation = superClass.getAnnotation(EagerInit.class);
+ if (annotation != null) {
+ break;
+ }
+ superClass = superClass.getSuperclass();
+ }
+ if (annotation == null) {
+ return;
+ }
+ }
+ type.setInitLevel(50);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/HeuristicPojoProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/HeuristicPojoProcessor.java
new file mode 100644
index 0000000000..e00c96664b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/HeuristicPojoProcessor.java
@@ -0,0 +1,550 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import static org.apache.tuscany.core.util.JavaIntrospectionHelper.getAllInterfaces;
+import static org.apache.tuscany.core.util.JavaIntrospectionHelper.getAllPublicAndProtectedFields;
+import static org.apache.tuscany.core.util.JavaIntrospectionHelper.getAllUniquePublicProtectedMethods;
+import static org.apache.tuscany.core.util.JavaIntrospectionHelper.getBaseName;
+import static org.apache.tuscany.core.util.JavaIntrospectionHelper.toPropertyName;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.TypeInfo;
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+import org.osoa.sca.annotations.Remotable;
+import org.osoa.sca.annotations.Service;
+
+/**
+ * Heuristically evaluates an un-annotated Java implementation type to determine services, references, and properties
+ * according to the algorithm described in the SCA Java Client and Implementation Model Specification <p/> TODO
+ * Implement:
+ * <p/>
+ * When no service inteface is annotated, need to calculate a single service comprising all public methods that are not
+ * reference or property injection sites. If that service can be exactly mapped to an interface implemented by the class
+ * then the service interface will be defined in terms of that interface.
+ *
+ * @version $Rev$ $Date$
+ */
+public class HeuristicPojoProcessor extends ImplementationProcessorExtension {
+ private SimpleTypeMapperExtension typeMapper = new SimpleTypeMapperExtension();
+ private ImplementationProcessorService implService;
+
+ public HeuristicPojoProcessor(@Autowire ImplementationProcessorService service) {
+ this.implService = service;
+ }
+
+ public <T> void visitEnd(
+ CompositeComponent parent,
+ Class<T> clazz,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context) throws ProcessingException {
+ Map<String, JavaMappedService> services = type.getServices();
+ if (services.isEmpty()) {
+ // heuristically determine the service
+ // TODO finish algorithm
+ Set<Class> interfaces = getAllInterfaces(clazz);
+ if (interfaces.size() == 0) {
+ // class is the interface
+ JavaMappedService service;
+ try {
+ service = implService.createService(clazz);
+ } catch (InvalidServiceContractException e) {
+ throw new ProcessingException(e);
+ }
+ type.getServices().put(service.getName(), service);
+ } else if (interfaces.size() == 1) {
+ JavaMappedService service;
+ try {
+ service = implService.createService(interfaces.iterator().next());
+ } catch (InvalidServiceContractException e) {
+ throw new ProcessingException(e);
+ }
+ type.getServices().put(service.getName(), service);
+ }
+ }
+ Set<Method> methods = getAllUniquePublicProtectedMethods(clazz);
+ if (!type.getReferences().isEmpty() || !type.getProperties().isEmpty()) {
+ // references and properties have been explicitly defined
+ if (type.getServices().isEmpty()) {
+ calculateServiceInterface(clazz, type, methods);
+ if (type.getServices().isEmpty()) {
+ throw new ServiceTypeNotFoundException(clazz.getName());
+ }
+ }
+ evaluateConstructor(type, clazz);
+ return;
+ }
+ calcPropRefs(methods, services, type, clazz);
+ evaluateConstructor(type, clazz);
+ }
+
+ private <T> void calcPropRefs(Set<Method> methods,
+ Map<String, JavaMappedService> services,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ Class<T> clazz) throws ProcessingException {
+ // heuristically determine the properties references
+ // make a first pass through all public methods with one param
+ for (Method method : methods) {
+ if (method.getParameterTypes().length != 1 || !Modifier.isPublic(method.getModifiers())
+ || !method.getName().startsWith("set")
+ || method.getReturnType() != void.class) {
+ continue;
+ }
+ if (!isInServiceInterface(method, services)) {
+ String name = toPropertyName(method.getName());
+ // avoid duplicate property or ref names
+ if (!type.getProperties().containsKey(name) && !type.getReferences().containsKey(name)) {
+ Class<?> param = method.getParameterTypes()[0];
+ Type genericType = method.getGenericParameterTypes()[0];
+ if (isReferenceType(genericType)) {
+ type.add(createReference(name, method, param));
+ } else {
+ type.add(createProperty(name, method, param));
+ }
+ }
+ }
+ }
+ // second pass for protected methods with one param
+ for (Method method : methods) {
+ if (method.getParameterTypes().length != 1 || !Modifier.isProtected(method.getModifiers())
+ || !method.getName().startsWith("set")
+ || method.getReturnType() != void.class) {
+ continue;
+ }
+ Class<?> param = method.getParameterTypes()[0];
+ String name = toPropertyName(method.getName());
+ // avoid duplicate property or ref names
+ if (!type.getProperties().containsKey(name) && !type.getReferences().containsKey(name)) {
+ if (isReferenceType(param)) {
+ type.add(createReference(name, method, param));
+ } else {
+ type.add(createProperty(name, method, param));
+ }
+ }
+ }
+ Set<Field> fields = getAllPublicAndProtectedFields(clazz);
+ for (Field field : fields) {
+ Class<?> paramType = field.getType();
+ if (isReferenceType(paramType)) {
+ type.add(createReference(field.getName(), field, paramType));
+ } else {
+ type.add(createProperty(field.getName(), field, paramType));
+ }
+ }
+ }
+
+ /**
+ * Determines the constructor to use based on the component type's references and properties
+ *
+ * @param type the component type
+ * @param clazz the implementation class corresponding to the component type
+ * @throws NoConstructorException if no suitable constructor is found
+ * @throws AmbiguousConstructorException if the parameters of a constructor cannot be unambiguously mapped to
+ * references and properties
+ */
+ @SuppressWarnings("unchecked")
+ private <T> void evaluateConstructor(
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ Class<T> clazz) throws ProcessingException {
+ // determine constructor if one is not annotated
+ ConstructorDefinition<?> definition = type.getConstructorDefinition();
+ Constructor constructor;
+ boolean explict = false;
+ if (definition != null
+ && definition.getConstructor().getAnnotation(org.osoa.sca.annotations.Constructor.class) != null) {
+ // the constructor was already defined explicitly
+ return;
+ } else if (definition != null) {
+ explict = true;
+ constructor = definition.getConstructor();
+ } else {
+ // no definition, heuristically determine constructor
+ Constructor[] constructors = clazz.getConstructors();
+ if (constructors.length == 0) {
+ throw new NoConstructorException("No public constructor for class", clazz.getName());
+ } else if (constructors.length == 1) {
+ constructor = constructors[0];
+ } else {
+ // FIXME multiple constructors, none yet done
+ Constructor<T> selected = null;
+ int sites = type.getProperties().size() + type.getReferences().size();
+ for (Constructor<T> ctor : constructors) {
+ if (ctor.getParameterTypes().length == 0) {
+ selected = ctor;
+ }
+ if (ctor.getParameterTypes().length == sites) {
+ // TODO finish
+ // selected = constructor;
+ // select constructor
+ // break;
+ }
+ }
+ if (selected == null) {
+ throw new NoConstructorException();
+ }
+ constructor = selected;
+ definition = new ConstructorDefinition<T>(selected);
+ type.setConstructorDefinition(definition);
+ // return;
+ }
+ definition = new ConstructorDefinition<T>(constructor);
+ type.setConstructorDefinition(definition);
+ }
+ Class[] params = constructor.getParameterTypes();
+ if (params.length == 0) {
+ return;
+ }
+ List<String> paramNames = definition.getInjectionNames();
+ Map<String, JavaMappedProperty<?>> props = type.getProperties();
+ Map<String, JavaMappedReference> refs = type.getReferences();
+ Annotation[][] annotations = constructor.getParameterAnnotations();
+ if (!explict) {
+ // the constructor wasn't defined by an annotation, so check to see if any of the params have an annotation
+ // which we can impute as explicitly defining the constructor, e.g. @Property, @Reference, or @Autowire
+ explict = implService.injectionAnnotationsPresent(annotations);
+ }
+ if (explict) {
+ for (int i = 0; i < params.length; i++) {
+ Class param = params[i];
+ implService.processParam(param,
+ constructor.getGenericParameterTypes()[i],
+ annotations[i],
+ new String[0],
+ i,
+ type,
+ paramNames);
+ }
+ } else {
+ if (!implService.areUnique(params)) {
+ throw new AmbiguousConstructorException("Cannot resolve non-unique parameter types, use @Constructor");
+ }
+ if (!calcPropRefUniqueness(props.values(), refs.values())) {
+ throw new AmbiguousConstructorException("Cannot resolve non-unique parameter types, use @Constructor");
+ }
+ boolean empty = props.size() + refs.size() == 0;
+ if (!empty) {
+ calcParamNames(params, props, refs, paramNames);
+ } else {
+ heuristicParamNames(params, refs, props, paramNames);
+
+ }
+ }
+ }
+
+ private void calcParamNames(Class[] params,
+ Map<String, JavaMappedProperty<?>> props,
+ Map<String, JavaMappedReference> refs,
+ List<String> paramNames)
+ throws AmbiguousConstructorException {
+ // the constructor param types must unambiguously match defined reference or property types
+ for (Class param : params) {
+ String name = findReferenceOrProperty(param, props, refs);
+ if (name == null) {
+ throw new AmbiguousConstructorException(param.getName());
+ }
+ paramNames.add(name);
+ }
+ }
+
+ private void heuristicParamNames(Class[] params,
+ Map<String, JavaMappedReference> refs,
+ Map<String, JavaMappedProperty<?>> props,
+ List<String> paramNames)
+ throws ProcessingException {
+ // heuristically determine refs and props from the parameter types
+ for (Class<?> param : params) {
+ String name = getBaseName(param).toLowerCase();
+ if (isReferenceType(param)) {
+ refs.put(name, createReference(name, null, param));
+ } else {
+ props.put(name, createProperty(name, null, param));
+ }
+ paramNames.add(name);
+ }
+ }
+
+ /**
+ * Returns true if the union of the given collections of properties and references have unique Java types
+ */
+ private boolean calcPropRefUniqueness(
+ Collection<JavaMappedProperty<?>> props,
+ Collection<JavaMappedReference> refs) {
+
+ Class[] classes = new Class[props.size() + refs.size()];
+ int i = 0;
+ for (JavaMappedProperty<?> property : props) {
+ classes[i] = property.getJavaType();
+ i++;
+ }
+ for (JavaMappedReference reference : refs) {
+ classes[i] = reference.getServiceContract().getInterfaceClass();
+ i++;
+ }
+ return implService.areUnique(classes);
+ }
+
+ /**
+ * Unambiguously finds the reference or property associated with the given type
+ *
+ * @return the name of the reference or property if found, null if not
+ * @throws AmbiguousConstructorException if the constructor parameter cannot be resolved to a property or reference
+ */
+ private String findReferenceOrProperty(
+ Class<?> type,
+ Map<String, JavaMappedProperty<?>> props,
+ Map<String, JavaMappedReference> refs) throws AmbiguousConstructorException {
+
+ String name = null;
+ for (JavaMappedProperty<?> property : props.values()) {
+ if (property.getJavaType().equals(type)) {
+ if (name != null) {
+ throw new AmbiguousConstructorException("Ambiguous property or reference for constructor type",
+ type.getName());
+ }
+ name = property.getName();
+ // do not break since ambiguities must be checked, i.e. more than one prop or ref of the same type
+ }
+ }
+ for (JavaMappedReference reference : refs.values()) {
+ if (reference.getServiceContract().getInterfaceClass().equals(type)) {
+ if (name != null) {
+ throw new AmbiguousConstructorException("Ambiguous property or reference for constructor type",
+ type.getName());
+ }
+ name = reference.getName();
+ // do not break since ambiguities must be checked, i.e. more than one prop or ref of the same type
+ }
+ }
+ return name;
+ }
+
+ /**
+ * Returns true if a given type is reference according to the SCA specification rules for determining reference
+ * types
+ */
+ private boolean isReferenceType(Type operationType) {
+ Class<?> rawType;
+ Class<?> referenceType = null;
+ if (operationType instanceof ParameterizedType) {
+ ParameterizedType parameterizedType = (ParameterizedType) operationType;
+ rawType = (Class<?>) parameterizedType.getRawType();
+ Type[] typeArgs = parameterizedType.getActualTypeArguments();
+ if (typeArgs.length == 1) {
+ referenceType = (Class<?>) typeArgs[0];
+ }
+ } else {
+ rawType = (Class<?>) operationType;
+ }
+ if (rawType.isArray()) {
+ referenceType = rawType.getComponentType();
+ } else if (Collection.class.isAssignableFrom(rawType) && referenceType == null) {
+ return true;
+ }
+ if (referenceType != null) {
+ return referenceType.getAnnotation(Remotable.class) != null
+ || referenceType.getAnnotation(Service.class) != null;
+ } else {
+ return rawType.getAnnotation(Remotable.class) != null || rawType.getAnnotation(Service.class) != null;
+ }
+ }
+
+ /**
+ * Returns true if the given operation is defined in the collection of service interfaces
+ */
+ private boolean isInServiceInterface(Method operation, Map<String, JavaMappedService> services) {
+ for (JavaMappedService service : services.values()) {
+ Class<?> clazz = service.getServiceContract().getInterfaceClass();
+ if (operation.getDeclaringClass().equals(clazz)) {
+ return true;
+ }
+ Method[] methods = service.getServiceContract().getInterfaceClass().getMethods();
+ for (Method method : methods) {
+ if (operation.getName().equals(method.getName())
+ && operation.getParameterTypes().length == method.getParameterTypes().length) {
+ Class<?>[] methodTypes = method.getParameterTypes();
+ for (int i = 0; i < operation.getParameterTypes().length; i++) {
+ Class<?> paramType = operation.getParameterTypes()[i];
+ if (!paramType.equals(methodTypes[i])) {
+ break;
+ } else if (i == operation.getParameterTypes().length - 1) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Creates a mapped reference
+ *
+ * @param name the reference name
+ * @param member the injection site the reference maps to
+ * @param paramType the service interface of the reference
+ */
+ private JavaMappedReference createReference(String name, Member member, Class<?> paramType)
+ throws ProcessingException {
+ return implService.createReference(name, member, paramType);
+ }
+
+ /**
+ * Creates a mapped property
+ *
+ * @param name the property name
+ * @param member the injection site the reference maps to
+ * @param paramType the property type
+ */
+ private <T> JavaMappedProperty<T> createProperty(String name, Member member, Class<T> paramType) {
+ JavaMappedProperty<T> property = new JavaMappedProperty<T>();
+ property.setName(name);
+ property.setMember(member);
+ property.setMustSupply(false);
+ property.setJavaType(paramType);
+ TypeInfo xmlType = typeMapper.getXMLType(paramType);
+ if (xmlType != null) {
+ property.setXmlType(xmlType.getQName());
+ }
+
+ return property;
+ }
+
+ /**
+ * Populates a component type with a service whose interface type is determined by examining all implemented
+ * interfaces of the given class and chosing one whose operations match all of the class's non-property and
+ * non-reference methods
+ *
+ * @param clazz the class to examine
+ * @param type the component type
+ * @param methods all methods in the class to examine
+ */
+ private void calculateServiceInterface(
+ Class<?> clazz,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ Set<Method> methods) throws ProcessingException {
+ List<Method> nonPropRefMethods = new ArrayList<Method>();
+ // Map<String, JavaMappedService> services = type.getServices();
+ Map<String, JavaMappedReference> references = type.getReferences();
+ Map<String, JavaMappedProperty<?>> properties = type.getProperties();
+ // calculate methods that are not properties or references
+ for (Method method : methods) {
+ String name = toPropertyName(method.getName());
+ if (!references.containsKey(name) && !properties.containsKey(name)) {
+ nonPropRefMethods.add(method);
+ }
+ }
+ // determine if an implemented interface matches all of the non-property and non-reference methods
+ Class[] interfaces = clazz.getInterfaces();
+ if (interfaces.length == 0) {
+ return;
+ }
+ for (Class interfaze : interfaces) {
+ if (analyzeInterface(interfaze, nonPropRefMethods)) {
+ JavaMappedService service;
+ try {
+ service = implService.createService(interfaze);
+ } catch (InvalidServiceContractException e) {
+ throw new ProcessingException(e);
+ }
+ type.getServices().put(service.getName(), service);
+ }
+ }
+ }
+
+ /**
+ * Determines if the methods of a given interface match the given list of methods
+ *
+ * @param interfaze the interface to examine
+ * @param nonPropRefMethods the list of methods to match against
+ * @return true if the interface matches
+ */
+ private boolean analyzeInterface(Class<?> interfaze, List<Method> nonPropRefMethods) {
+ Method[] interfaceMethods = interfaze.getMethods();
+ if (nonPropRefMethods.size() != interfaceMethods.length) {
+ return false;
+ }
+ for (Method method : nonPropRefMethods) {
+ boolean found = false;
+ for (Method interfaceMethod : interfaceMethods) {
+ if (interfaceMethod.getName().equals(method.getName())) {
+ Class<?>[] interfaceParamTypes = interfaceMethod.getParameterTypes();
+ Class<?>[] methodParamTypes = method.getParameterTypes();
+ if (interfaceParamTypes.length == methodParamTypes.length) {
+ if (interfaceParamTypes.length == 0) {
+ found = true;
+ } else {
+ for (int i = 0; i < methodParamTypes.length; i++) {
+ Class<?> param = methodParamTypes[i];
+ if (!param.equals(interfaceParamTypes[i])) {
+ break;
+ }
+ if (i == methodParamTypes.length - 1) {
+ found = true;
+ }
+ }
+ }
+ }
+ if (found) {
+ break;
+ }
+ }
+ }
+ if (!found) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
+
+/*
+ * 1) public setter methods that are not included in any service interface 2) protected setter methods 3) public or
+ * protected fields unless there is a setter method for the same name If the type associated with the member is an array
+ * or a java.util.Collection, then the basetype will be the element type of the array or the parameterized type of the
+ * Collection, otherwise the basetype will be the member type. If the basetype is an interface with an @Remotable or
+ * @Service annotation then the member will be defined as a reference, otherwise it will be defined as a property.
+ *
+ *
+ */
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalCallbackReferenceException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalCallbackReferenceException.java
new file mode 100644
index 0000000000..4581faa872
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalCallbackReferenceException.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Denotes an illegcal use of {@link org.osoa.sca.annotations.Callback} on a reference
+ *
+ * @version $Rev$ $Date$
+ */
+public class IllegalCallbackReferenceException extends ProcessingException {
+
+ public IllegalCallbackReferenceException(String message) {
+ super(message);
+ }
+
+ public IllegalCallbackReferenceException(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalContextException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalContextException.java
new file mode 100644
index 0000000000..8c56cade83
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalContextException.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Denotes an illegal signature for a method decorated with {@link org.osoa.sca.annotations.Context}
+ *
+ * @version $Rev$ $Date$
+ */
+public class IllegalContextException extends ProcessingException {
+
+ public IllegalContextException(String message) {
+ super(message);
+ }
+
+ public IllegalContextException(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalDestructorException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalDestructorException.java
new file mode 100644
index 0000000000..fee42ea5c8
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalDestructorException.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Denotes an illegal signature for a method decorated with {@link org.osoa.sca.annotations.Destroy}
+ *
+ * @version $Rev$ $Date$
+ */
+public class IllegalDestructorException extends ProcessingException {
+
+ public IllegalDestructorException(String message) {
+ super(message);
+ }
+
+ public IllegalDestructorException(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalInitException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalInitException.java
new file mode 100644
index 0000000000..219074b785
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalInitException.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Denotes an illegal signature for a method decorated with {@link @org.osoa.sca.annotations.Init}
+ *
+ * @version $Rev$ $Date$
+ */
+public class IllegalInitException extends ProcessingException {
+ public IllegalInitException(String message) {
+ super(message);
+ }
+
+ public IllegalInitException(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalReferenceException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalReferenceException.java
new file mode 100644
index 0000000000..11137bcaba
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalReferenceException.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Denotes an illegal reference definition in a component type
+ *
+ * @version $Rev$ $Date$
+ */
+public class IllegalReferenceException extends ProcessingException {
+
+ public IllegalReferenceException(String message) {
+ super(message);
+ }
+
+ public IllegalReferenceException(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalResourceException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalResourceException.java
new file mode 100644
index 0000000000..e25c1174e2
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalResourceException.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Denotes an illegal resource definition in a component type
+ *
+ * @version $Rev$ $Date$
+ */
+public class IllegalResourceException extends ProcessingException {
+
+ public IllegalResourceException(String message) {
+ super(message);
+ }
+
+ public IllegalResourceException(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalServiceDefinitionException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalServiceDefinitionException.java
new file mode 100644
index 0000000000..1d9079636a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/IllegalServiceDefinitionException.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Denotes an illegal use of the {@link @org.osoa.sca.annotations.Service} annotation
+ *
+ * @version $Rev$ $Date$
+ */
+public class IllegalServiceDefinitionException extends ProcessingException {
+
+ public IllegalServiceDefinitionException(String message) {
+ super(message);
+ }
+
+ public IllegalServiceDefinitionException(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceImpl.java
new file mode 100644
index 0000000000..44e35fab14
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceImpl.java
@@ -0,0 +1,469 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import static org.apache.tuscany.core.util.JavaIntrospectionHelper.getBaseName;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Member;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.core.idl.java.IllegalCallbackException;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.TypeInfo;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.implementation.java.DuplicatePropertyException;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+import org.apache.tuscany.spi.model.Multiplicity;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.osoa.sca.annotations.Callback;
+import org.osoa.sca.annotations.Property;
+import org.osoa.sca.annotations.Reference;
+import org.osoa.sca.annotations.Remotable;
+import org.apache.tuscany.api.annotation.Resource;
+
+/**
+ * The default implementation of an <code>ImplementationProcessorService</code>
+ *
+ * @version $Rev$ $Date$
+ */
+public class ImplementationProcessorServiceImpl implements ImplementationProcessorService {
+ private JavaInterfaceProcessorRegistry registry;
+ private SimpleTypeMapperExtension typeMapper = new SimpleTypeMapperExtension();
+
+ public ImplementationProcessorServiceImpl(@Autowire JavaInterfaceProcessorRegistry registry) {
+ this.registry = registry;
+ }
+
+ public JavaMappedService createService(Class<?> interfaze) throws InvalidServiceContractException {
+ JavaMappedService service = new JavaMappedService();
+ service.setName(interfaze.getSimpleName());
+ service.setRemotable(interfaze.getAnnotation(Remotable.class) != null);
+ ServiceContract<?> contract = registry.introspect(interfaze, false);
+ service.setServiceContract(contract);
+ return service;
+ }
+
+ public void processCallback(Class<?> interfaze, ServiceContract<?> contract) throws IllegalCallbackException {
+ Callback callback = interfaze.getAnnotation(Callback.class);
+ if (callback != null && !Void.class.equals(callback.value())) {
+ Class<?> callbackClass = callback.value();
+ contract.setCallbackClass(callbackClass);
+ contract.setCallbackName(getBaseName(callbackClass));
+ } else if (callback != null && Void.class.equals(callback.value())) {
+ throw new IllegalCallbackException("No callback interface specified on annotation", interfaze.getName());
+ }
+ }
+
+ public boolean areUnique(Class[] collection) {
+ if (collection.length == 0) {
+ return true;
+ }
+ return areUnique(collection, 0);
+ }
+
+ public void addName(List<String> names, int pos, String name) {
+ if (names.size() < pos) {
+ for (int i = 0; i < pos; i++) {
+ names.add(i, "");
+ }
+ names.add(name);
+ } else if (names.size() > pos) {
+ names.remove(pos);
+ names.add(pos, name);
+ } else {
+ names.add(pos, name);
+ }
+ }
+
+ public boolean processParam(
+ Class<?> param,
+ Type genericParam,
+ Annotation[] paramAnnotations,
+ String[] constructorNames,
+ int pos,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ List<String> injectionNames) throws ProcessingException {
+ boolean processed = false;
+ for (Annotation annot : paramAnnotations) {
+ if (Autowire.class.equals(annot.annotationType())) {
+ processed = true;
+ processAutowire(annot, constructorNames, pos, param, genericParam, type, injectionNames);
+ } else if (Property.class.equals(annot.annotationType())) {
+ processed = true;
+ processProperty(annot, constructorNames, pos, type, param, genericParam, injectionNames);
+ } else if (Reference.class.equals(annot.annotationType())) {
+ processed = true;
+ processReference(annot, constructorNames, pos, type, param, genericParam, injectionNames);
+ } else if (Resource.class.equals(annot.annotationType())) {
+ processed = true;
+ processResource((Resource) annot, constructorNames, pos, type, param, injectionNames);
+ }
+ }
+ return processed;
+ }
+
+ public boolean injectionAnnotationsPresent(Annotation[][] annots) {
+ for (Annotation[] annotations : annots) {
+ for (Annotation annotation : annotations) {
+ Class<? extends Annotation> annotType = annotation.annotationType();
+ if (annotType.equals(Autowire.class) || annotType.equals(Property.class)
+ || annotType.equals(Reference.class)
+ || annotType.equals(Resource.class)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public JavaMappedReference createReference(String name, Member member, Class<?> paramType)
+ throws ProcessingException {
+ JavaMappedReference reference = new JavaMappedReference();
+ reference.setName(name);
+ reference.setMember(member);
+ //reference.setRequired(false);
+ ServiceContract contract;
+ try {
+ contract = registry.introspect(paramType, false);
+ } catch (InvalidServiceContractException e1) {
+ throw new ProcessingException(e1);
+ }
+ try {
+ processCallback(paramType, contract);
+ } catch (IllegalCallbackException e) {
+ throw new ProcessingException(e);
+ }
+ reference.setServiceContract(contract);
+ return reference;
+ }
+
+ /**
+ * Determines if all the members of a collection have unique types
+ *
+ * @param collection the collection to analyze
+ * @param start the position in the collection to start
+ * @return true if the types are unique
+ */
+ private boolean areUnique(Class[] collection, int start) {
+ Object compare = collection[start];
+ for (int i = start + 1; i < collection.length; i++) {
+ if (compare.equals(collection[i])) {
+ return false;
+ }
+ }
+ if (start + 1 < collection.length) {
+ return areUnique(collection, start + 1);
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Processes autowire metadata for a constructor parameter
+ *
+ * @param annot the autowire annotation
+ * @param constructorNames the parameter names as specified in an {@link org.osoa.sca.annotations.Constructor}
+ * annotation
+ * @param pos the position of the parameter in the constructor's parameter list
+ * @param param the parameter type
+ * @param type the component type associated with the implementation being processed
+ * @param injectionNames the collection of injection names to update
+ * @throws InvalidAutowireException
+ * @throws InvalidConstructorException
+ */
+ private void processAutowire(
+ Annotation annot,
+ String[] constructorNames,
+ int pos,
+ Class<?> param,
+ Type genericParam,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ List<String> injectionNames) throws ProcessingException {
+ // the param is marked as an autowire
+ Autowire autowireAnnot = (Autowire) annot;
+ JavaMappedReference reference = new JavaMappedReference();
+ reference.setAutowire(true);
+ String name = autowireAnnot.name();
+ if (name == null || name.length() == 0) {
+ if (constructorNames.length > 1 && (constructorNames.length < pos + 1 || constructorNames[pos] == null)) {
+ throw new InvalidAutowireException("Names in @Constructor and autowire parameter do not match at "
+ + (pos + 1));
+ } else if (constructorNames.length == 1 && constructorNames[0].length() == 0) {
+ // special case when @Constructor present with all autowire params not specifying any name
+ name = param.getName() + String.valueOf(pos);
+ } else if (constructorNames.length == 1
+ && (constructorNames.length < pos + 1 || constructorNames[pos] == null)) {
+ throw new InvalidAutowireException("Names in @Constructor and autowire parameter do not match at "
+ + (pos + 1));
+ } else if (constructorNames.length == 1 && constructorNames[0].length() > 0) {
+ name = constructorNames[pos];
+ } else if (constructorNames.length == 0 || constructorNames[pos].length() == 0) {
+ name = param.getName() + String.valueOf(pos);
+ } else {
+ name = constructorNames[pos];
+ }
+ } else if (pos < constructorNames.length && constructorNames[pos] != null
+ && constructorNames[pos].length() != 0 && !name.equals(constructorNames[pos])) {
+ String paramNum = String.valueOf(pos + 1);
+ throw new InvalidConstructorException("Name specified by @Constructor does not match autowire name",
+ paramNum);
+ }
+ reference.setName(name);
+ boolean required = autowireAnnot.required();
+ //reference.setRequired(required);
+ try {
+ Class<?> rawType = param;
+ if (rawType.isArray() || Collection.class.isAssignableFrom(rawType)) {
+ if (required) {
+ reference.setMultiplicity(Multiplicity.ONE_N);
+ } else {
+ reference.setMultiplicity(Multiplicity.ZERO_N);
+ }
+ } else {
+ if (required) {
+ reference.setMultiplicity(Multiplicity.ONE_ONE);
+ } else {
+ reference.setMultiplicity(Multiplicity.ZERO_ONE);
+ }
+ }
+ Class<?> baseType = getBaseType(rawType, genericParam);
+ ServiceContract<?> contract = registry.introspect(baseType, false);
+ reference.setServiceContract(contract);
+ } catch (InvalidServiceContractException e) {
+ throw new ProcessingException(e);
+ }
+ type.getReferences().put(name, reference);
+ addName(injectionNames, pos, name);
+ }
+
+ /**
+ * Processes parameter metadata for a constructor parameter
+ *
+ * @param annot the parameter annotation
+ * @param constructorNames the parameter names as specified in an {@link org.osoa.sca.annotations.Constructor}
+ * annotation
+ * @param pos the position of the parameter in the constructor's parameter list
+ * @param type the component type associated with the implementation being processed
+ * @param param the parameter type
+ * @param explicitNames the collection of injection names to update
+ * @throws ProcessingException
+ */
+ @SuppressWarnings("unchecked")
+ private void processProperty(
+ Annotation annot,
+ String[] constructorNames,
+ int pos,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ Class<?> param,
+ Type genericParam,
+ List<String> explicitNames) throws ProcessingException {
+ // the param is marked as a property
+ Property propAnnot = (Property) annot;
+ JavaMappedProperty property = new JavaMappedProperty();
+ Class<?> baseType = getBaseType(param, genericParam);
+ if (param.isArray() || Collection.class.isAssignableFrom(param)) {
+ property.setMany(true);
+ }
+ property.setJavaType(baseType);
+ String name = propAnnot.name();
+ if (name == null || name.length() == 0) {
+ if (constructorNames.length < pos + 1 || constructorNames[pos] == null
+ || constructorNames[pos].length() == 0) {
+ throw new InvalidPropertyException("No name specified for property parameter " + (pos + 1));
+ }
+ name = constructorNames[pos];
+ } else if (pos < constructorNames.length && constructorNames[pos] != null
+ && constructorNames[pos].length() != 0 && !name.equals(constructorNames[pos])) {
+ String paramNum = String.valueOf(pos + 1);
+ throw new InvalidConstructorException("Name specified by @Constructor does not match property name",
+ paramNum);
+ }
+ if (type.getProperties().get(name) != null) {
+ throw new DuplicatePropertyException(name);
+ }
+ property.setName(name);
+ property.setMustSupply(propAnnot.required());
+
+ String xmlType = propAnnot.xmlType();
+ if (xmlType != null && xmlType.length() != 0) {
+ property.setXmlType(QName.valueOf(xmlType));
+ } else {
+ TypeInfo typeInfo = typeMapper.getXMLType(property.getJavaType());
+ if (typeInfo != null) {
+ property.setXmlType(typeInfo.getQName());
+ }
+ }
+ type.getProperties().put(name, property);
+ addName(explicitNames, pos, name);
+ }
+
+ /**
+ * Processes reference metadata for a constructor parameter
+ *
+ * @param annot the parameter annotation
+ * @param constructorNames the parameter names as specified in an {@link org.osoa.sca.annotations.Constructor}
+ * annotation
+ * @param pos the position of the parameter in the constructor's parameter list
+ * @param type the component type associated with the implementation being processed
+ * @param param the parameter type
+ * @param explicitNames the collection of injection names to update
+ * @throws ProcessingException
+ */
+ private void processReference(
+ Annotation annot,
+ String[] constructorNames,
+ int pos,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ Class<?> param,
+ Type genericParam,
+ List<String> explicitNames) throws ProcessingException {
+
+ // TODO multiplicity
+ // the param is marked as a reference
+ Reference refAnnotation = (Reference) annot;
+ JavaMappedReference reference = new JavaMappedReference();
+ String name = refAnnotation.name();
+ if (name == null || name.length() == 0) {
+ if (constructorNames.length < pos + 1 || constructorNames[pos] == null
+ || constructorNames[pos].length() == 0) {
+ throw new InvalidReferenceException("No name specified for reference parameter " + (pos + 1));
+ }
+ name = constructorNames[pos];
+ } else if (pos < constructorNames.length && constructorNames[pos] != null
+ && constructorNames[pos].length() != 0 && !name.equals(constructorNames[pos])) {
+ String paramNum = String.valueOf(pos + 1);
+ throw new InvalidConstructorException("Name specified by @Constructor does not match reference name",
+ paramNum);
+ }
+ if (type.getReferences().get(name) != null) {
+ throw new DuplicateReferenceException(name);
+ }
+ reference.setName(name);
+ boolean required = refAnnotation.required();
+ //reference.setRequired(required);
+ try {
+ Class<?> rawType = param;
+ if (rawType.isArray() || Collection.class.isAssignableFrom(rawType)) {
+ if (required) {
+ reference.setMultiplicity(Multiplicity.ONE_N);
+ } else {
+ reference.setMultiplicity(Multiplicity.ZERO_N);
+ }
+ } else {
+ if (required) {
+ reference.setMultiplicity(Multiplicity.ONE_ONE);
+ } else {
+ reference.setMultiplicity(Multiplicity.ZERO_ONE);
+ }
+ }
+ Class<?> baseType = getBaseType(rawType, genericParam);
+ ServiceContract<?> contract = registry.introspect(baseType, false);
+ reference.setServiceContract(contract);
+ } catch (InvalidServiceContractException e) {
+ throw new ProcessingException(e);
+ }
+ type.getReferences().put(name, reference);
+ addName(explicitNames, pos, name);
+ }
+
+ /**
+ * Processes resource metadata for a constructor parameter
+ *
+ * @param resourceAnnot the resource annotation
+ * @param constructorNames the parameter names as specified in an {@link org.osoa.sca.annotations.Constructor}
+ * annotation
+ * @param pos the position of the parameter in the constructor's parameter list
+ * @param type the component type associated with the implementation being processed
+ * @param param the parameter type
+ * @param explicitNames the collection of injection names to update
+ * @throws ProcessingException
+ */
+ private <T> void processResource(
+ Resource resourceAnnot,
+ String[] constructorNames,
+ int pos,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ Class<T> param,
+ List<String> explicitNames) throws ProcessingException {
+
+ org.apache.tuscany.spi.implementation.java.Resource resource =
+ new org.apache.tuscany.spi.implementation.java.Resource();
+ String name = resourceAnnot.name();
+ if (name == null || name.length() == 0) {
+ if (constructorNames.length < pos + 1 || constructorNames[pos] == null
+ || constructorNames[pos].length() == 0) {
+ String paramNum = String.valueOf(pos + 1);
+ throw new InvalidResourceException("No name specified for resource parameter", paramNum);
+ }
+ name = constructorNames[pos];
+ } else if (pos < constructorNames.length && constructorNames[pos] != null
+ && constructorNames[pos].length() != 0 && !name.equals(constructorNames[pos])) {
+ String paramNum = String.valueOf(pos + 1);
+ throw new InvalidConstructorException("Name specified by @Constructor does not match resource name",
+ paramNum);
+ }
+ if (type.getResources().get(name) != null) {
+ throw new DuplicateResourceException(name);
+ }
+ resource.setName(name);
+ resource.setOptional(resourceAnnot.optional());
+ resource.setType(param);
+ String mappedName = resourceAnnot.mappedName();
+ if (mappedName.length() > 0) {
+ resource.setMappedName(mappedName);
+ }
+ type.add(resource);
+ addName(explicitNames, pos, name);
+ }
+
+ protected static Class<?> getBaseType(Class<?> cls, Type genericType) {
+ if (cls.isArray()) {
+ return cls.getComponentType();
+ } else if (Collection.class.isAssignableFrom(cls)) {
+ if (genericType == cls) {
+ return Object.class;
+ } else {
+ ParameterizedType parameterizedType = (ParameterizedType) genericType;
+ Type baseType = parameterizedType.getActualTypeArguments()[0];
+ if (baseType instanceof Class) {
+ return (Class<?>) baseType;
+ } else if (baseType instanceof ParameterizedType) {
+ return (Class<?>) ((ParameterizedType) baseType).getRawType();
+ } else {
+ return null;
+ }
+ }
+ } else {
+ return cls;
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InitProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InitProcessor.java
new file mode 100644
index 0000000000..be5ac78008
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InitProcessor.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.osoa.sca.annotations.Init;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Processes the {@link @Init} annotation on a component implementation and updates the component type with the
+ * decorated initializer method
+ *
+ * @version $Rev$ $Date$
+ */
+public class InitProcessor extends ImplementationProcessorExtension {
+
+ public void visitMethod(CompositeComponent parent, Method method,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context)
+ throws ProcessingException {
+ Init annotation = method.getAnnotation(Init.class);
+ if (annotation == null) {
+ return;
+ }
+ if (method.getParameterTypes().length != 0) {
+ throw new IllegalInitException("Initializer must not have argments", method.toString());
+ }
+ if (type.getInitMethod() != null) {
+ throw new DuplicateInitException("More than one initializer found on implementaton");
+ }
+ if (Modifier.isProtected(method.getModifiers())) {
+ method.setAccessible(true);
+ }
+ type.setInitMethod(method);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidAutowireException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidAutowireException.java
new file mode 100644
index 0000000000..92a2a0923d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidAutowireException.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Denotes an invalid usage of {@link org.apache.tuscany.spi.annotation.Autowire}
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidAutowireException extends ProcessingException {
+
+ public InvalidAutowireException(String message) {
+ super(message);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidConstructorException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidConstructorException.java
new file mode 100644
index 0000000000..a2dd3f09c4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidConstructorException.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Denotes an invalid constructor definition, e.g. when the number of injection names specified in {@link
+ * org.osoa.sca.annotations.Constructor} do not match the number of actual constructor parameters
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidConstructorException extends ProcessingException {
+
+ public InvalidConstructorException(String message) {
+ super(message);
+ }
+
+ public InvalidConstructorException(String message, String identifier) {
+ super(message, identifier);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidConversationalImplementation.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidConversationalImplementation.java
new file mode 100644
index 0000000000..28bd65200e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidConversationalImplementation.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Raised when an implementation specifies improper conversational metadata
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidConversationalImplementation extends ProcessingException {
+
+ public InvalidConversationalImplementation(String message) {
+ super(message);
+ }
+
+ public InvalidConversationalImplementation(String message, String identifier) {
+ super(message, identifier);
+ }
+
+ public InvalidConversationalImplementation(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvalidConversationalImplementation(String message, String identifier, Throwable cause) {
+ super(message, identifier, cause);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidPropertyException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidPropertyException.java
new file mode 100644
index 0000000000..5d4c245764
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidPropertyException.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Denotes an invalid usage of {@link org.osoa.sca.annotations.Property}
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidPropertyException extends ProcessingException {
+
+ public InvalidPropertyException(String message) {
+ super(message);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidReferenceException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidReferenceException.java
new file mode 100644
index 0000000000..8fbc07aa1c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidReferenceException.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Denotes an invalid usage of {@link org.osoa.sca.annotations.Reference}
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidReferenceException extends ProcessingException {
+
+ public InvalidReferenceException(String message) {
+ super(message);
+ }
+
+ public InvalidReferenceException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvalidReferenceException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidResourceException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidResourceException.java
new file mode 100644
index 0000000000..4ed6d93994
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidResourceException.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Denotes an invalid usage of {@link @org.apache.tuscany.api.annotation.Resource}
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidResourceException extends ProcessingException {
+
+ public InvalidResourceException(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidServiceType.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidServiceType.java
new file mode 100644
index 0000000000..f3d0367661
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/InvalidServiceType.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Thrown when a service type specified by an {@link org.osoa.sca.annotations.Service} annotation is invalid, e.g. it is
+ * not an interface
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidServiceType extends ProcessingException {
+
+ public InvalidServiceType(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/MonitorProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/MonitorProcessor.java
new file mode 100644
index 0000000000..e7acce2973
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/MonitorProcessor.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.AbstractPropertyProcessor;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+
+import org.apache.tuscany.api.annotation.Monitor;
+import org.apache.tuscany.core.injection.SingletonObjectFactory;
+import org.apache.tuscany.host.MonitorFactory;
+
+/**
+ * Processes an {@link @Monitor} annotation, updating the component type with corresponding {@link
+ * org.apache.tuscany.spi.implementation.java.JavaMappedProperty}
+ *
+ * @version $Rev$ $Date$
+ */
+public class MonitorProcessor extends AbstractPropertyProcessor<Monitor> {
+ private MonitorFactory monitorFactory;
+
+ public MonitorProcessor(@Autowire MonitorFactory monitorFactory, @Autowire ImplementationProcessorService service) {
+ super(Monitor.class, service);
+ this.monitorFactory = monitorFactory;
+ }
+
+ protected String getName(Monitor annotation) {
+ return null;
+ }
+
+ protected <T> void initProperty(JavaMappedProperty<T> property,
+ Monitor annotation,
+ CompositeComponent parent,
+ DeploymentContext context) {
+ Class<T> javaType = property.getJavaType();
+ property.setDefaultValueFactory(new SingletonObjectFactory<T>(monitorFactory.getMonitor(javaType)));
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/NoConstructorException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/NoConstructorException.java
new file mode 100644
index 0000000000..f36b7900a4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/NoConstructorException.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Thrown when a suitable constructor for a component implementation cannot be found
+ *
+ * @version $Rev$ $Date$
+ */
+public class NoConstructorException extends ProcessingException {
+
+ public NoConstructorException() {
+ }
+
+ public NoConstructorException(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/PropertyProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/PropertyProcessor.java
new file mode 100644
index 0000000000..000422ee6f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/PropertyProcessor.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Constructor;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.idl.TypeInfo;
+import org.apache.tuscany.spi.implementation.java.AbstractPropertyProcessor;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+import org.osoa.sca.annotations.Property;
+
+/**
+ * Processes an {@link @Property} annotation, updating the component type with
+ * corresponding {@link JavaMappedProperty}
+ *
+ * @version $Rev$ $Date$
+ */
+public class PropertyProcessor extends AbstractPropertyProcessor<Property> {
+ private SimpleTypeMapperExtension typeMapper = new SimpleTypeMapperExtension();
+
+ public PropertyProcessor(@Autowire
+ ImplementationProcessorService service) {
+ super(Property.class, service);
+ }
+
+ protected String getName(Property annotation) {
+ return annotation.name();
+ }
+
+ protected <T> void initProperty(JavaMappedProperty<T> property,
+ Property annotation,
+ CompositeComponent parent,
+ DeploymentContext context) {
+ String xmlType = annotation.xmlType();
+ if (xmlType != null && xmlType.length() != 0) {
+ property.setXmlType(QName.valueOf(annotation.xmlType()));
+ } else {
+ TypeInfo type = typeMapper.getXMLType(property.getJavaType());
+ if (type != null) {
+ property.setXmlType(type.getQName());
+ }
+ }
+ }
+
+ public <T> void visitConstructor(CompositeComponent parent,
+ Constructor<T> constructor,
+ PojoComponentType<JavaMappedService, JavaMappedReference,
+ JavaMappedProperty<?>> type,
+ DeploymentContext context) throws ProcessingException {
+ // override since heuristic pojo processor evalautes properties
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ReferenceProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ReferenceProcessor.java
new file mode 100644
index 0000000000..12aba4c94e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ReferenceProcessor.java
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Collection;
+
+import org.osoa.sca.annotations.Reference;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+import org.apache.tuscany.spi.model.Multiplicity;
+import org.apache.tuscany.spi.model.ServiceContract;
+
+import static org.apache.tuscany.core.util.JavaIntrospectionHelper.toPropertyName;
+
+/**
+ * Processes an {@link @Reference} annotation, updating the component type with corresponding {@link
+ * org.apache.tuscany.spi.implementation.java.JavaMappedReference}
+ *
+ * @version $Rev$ $Date$
+ */
+public class ReferenceProcessor extends ImplementationProcessorExtension {
+
+ private JavaInterfaceProcessorRegistry regsitry;
+
+ public ReferenceProcessor(@Autowire
+ JavaInterfaceProcessorRegistry registry) {
+ this.regsitry = registry;
+ }
+
+ public void visitMethod(CompositeComponent parent,
+ Method method,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context) throws ProcessingException {
+ Reference annotation = method.getAnnotation(Reference.class);
+ Autowire autowire = method.getAnnotation(Autowire.class);
+ boolean isAutowire = autowire != null;
+ if (annotation == null && !isAutowire) {
+ return; // Not a reference or autowire annotation.
+ }
+ if (method.getParameterTypes().length != 1) {
+ throw new IllegalReferenceException("Setter must have one parameter", method.toString());
+ }
+ // process autowire required first let reference override. or if
+ // conflicting should this fault?
+ boolean required = false;
+ if (isAutowire) {
+ required = autowire.required();
+ }
+
+ String name = null;
+
+ if (annotation != null) {
+ if (annotation.name() != null && annotation.name().length() > 0) {
+ name = annotation.name();
+ }
+ required = annotation.required();
+ }
+ if (name == null) {
+ name = toPropertyName(method.getName());
+ }
+ if (type.getReferences().get(name) != null) {
+ throw new DuplicateReferenceException(name);
+ }
+
+ JavaMappedReference reference = new JavaMappedReference();
+ reference.setMember(method);
+ reference.setAutowire(isAutowire);
+ //reference.setRequired(required);
+ reference.setName(name);
+ ServiceContract contract;
+ try {
+ Class<?> rawType = method.getParameterTypes()[0];
+ if (rawType.isArray() || Collection.class.isAssignableFrom(rawType)) {
+ if (required) {
+ reference.setMultiplicity(Multiplicity.ONE_N);
+ } else {
+ reference.setMultiplicity(Multiplicity.ZERO_N);
+ }
+ } else {
+ if (required) {
+ reference.setMultiplicity(Multiplicity.ONE_ONE);
+ } else {
+ reference.setMultiplicity(Multiplicity.ZERO_ONE);
+ }
+ }
+ Class<?> baseType = getBaseType(rawType, method.getGenericParameterTypes()[0]);
+ contract = regsitry.introspect(baseType);
+ } catch (InvalidServiceContractException e) {
+ throw new ProcessingException(e);
+ }
+ reference.setServiceContract(contract);
+ type.getReferences().put(name, reference);
+ }
+
+ public void visitField(CompositeComponent parent,
+ Field field,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context) throws ProcessingException {
+ Reference annotation = field.getAnnotation(Reference.class);
+ boolean autowire = field.getAnnotation(Autowire.class) != null;
+ if (annotation == null && !autowire) {
+ return;
+ }
+ String name = field.getName();
+ boolean required = false;
+ if (annotation != null) {
+ if (annotation.name() != null) {
+ name = annotation.name();
+ }
+ required = annotation.required();
+ }
+ if (name.length() == 0) {
+ name = field.getName();
+ }
+ if (type.getReferences().get(name) != null) {
+ throw new DuplicateReferenceException(name);
+ }
+ JavaMappedReference reference = new JavaMappedReference();
+ reference.setMember(field);
+ //reference.setRequired(required);
+ reference.setAutowire(autowire);
+ reference.setName(name);
+ ServiceContract contract;
+ try {
+ Class<?> rawType = field.getType();
+ if (rawType.isArray() || Collection.class.isAssignableFrom(rawType)) {
+ if (required) {
+ reference.setMultiplicity(Multiplicity.ONE_N);
+ } else {
+ reference.setMultiplicity(Multiplicity.ZERO_N);
+ }
+ } else {
+ if (required) {
+ reference.setMultiplicity(Multiplicity.ONE_ONE);
+ } else {
+ reference.setMultiplicity(Multiplicity.ZERO_ONE);
+ }
+ }
+ Class<?> baseType = getBaseType(rawType, field.getGenericType());
+ contract = regsitry.introspect(baseType);
+ } catch (InvalidServiceContractException e) {
+ throw new ProcessingException(e);
+ }
+ reference.setServiceContract(contract);
+ type.getReferences().put(name, reference);
+ }
+
+ public <T> void visitConstructor(CompositeComponent parent,
+ Constructor<T> constructor,
+ PojoComponentType<JavaMappedService,
+ JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context) throws ProcessingException {
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ResourceProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ResourceProcessor.java
new file mode 100644
index 0000000000..29773f5e80
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ResourceProcessor.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+import org.apache.tuscany.spi.implementation.java.Resource;
+
+import static org.apache.tuscany.core.util.JavaIntrospectionHelper.toPropertyName;
+
+/**
+ * Processes an {@link @Resource} annotation, updating the component type with corresponding {@link
+ * org.apache.tuscany.spi.implementation.java.Resource}
+ *
+ * @version $Rev$ $Date$
+ */
+public class ResourceProcessor extends ImplementationProcessorExtension {
+
+ public ResourceProcessor() {
+ }
+
+ public void visitMethod(CompositeComponent parent, Method method,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context)
+ throws ProcessingException {
+ org.apache.tuscany.api.annotation.Resource annotation =
+ method.getAnnotation(org.apache.tuscany.api.annotation.Resource.class);
+ if (annotation == null) {
+ return;
+ }
+ if (method.getParameterTypes().length != 1) {
+ throw new IllegalResourceException("Resource setter must have one parameter", method.toString());
+ }
+ String name = annotation.name();
+ if (name.length() < 1) {
+ name = toPropertyName(method.getName());
+ }
+ if (type.getResources().get(name) != null) {
+ throw new DuplicateResourceException(name);
+ }
+
+ String mappedName = annotation.mappedName();
+ Resource resource = new Resource();
+ resource.setMember(method);
+ resource.setType(method.getParameterTypes()[0]);
+ resource.setOptional(annotation.optional());
+ resource.setName(name);
+ if (mappedName.length() > 0) {
+ resource.setMappedName(mappedName);
+ }
+ type.add(resource);
+ }
+
+ public void visitField(CompositeComponent parent, Field field,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context) throws ProcessingException {
+
+ org.apache.tuscany.api.annotation.Resource annotation =
+ field.getAnnotation(org.apache.tuscany.api.annotation.Resource.class);
+ if (annotation == null) {
+ return;
+ }
+ String name = annotation.name();
+ if (name.length() < 1) {
+ name = field.getName();
+ }
+ if (type.getResources().get(name) != null) {
+ throw new DuplicateResourceException(name);
+ }
+
+ String mappedName = annotation.mappedName();
+ Resource resource = new Resource();
+ resource.setMember(field);
+ resource.setType(field.getType());
+ resource.setOptional(annotation.optional());
+ resource.setName(name);
+ if (mappedName.length() > 0) {
+ resource.setMappedName(mappedName);
+ }
+ type.add(resource);
+ }
+
+ public <T> void visitConstructor(CompositeComponent parent, Constructor<T> constructor,
+ PojoComponentType<JavaMappedService, JavaMappedReference,
+ JavaMappedProperty<?>> type,
+ DeploymentContext context) throws ProcessingException {
+
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ScopeProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ScopeProcessor.java
new file mode 100644
index 0000000000..634aff0377
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ScopeProcessor.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+import org.apache.tuscany.spi.model.Scope;
+
+/**
+ * Processes the {@link Scope} annotation and updates the component type with the corresponding implmentation scope
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScopeProcessor extends ImplementationProcessorExtension {
+
+ public <T> void visitClass(CompositeComponent parent, Class<T> clazz,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context)
+ throws ProcessingException {
+ org.osoa.sca.annotations.Scope annotation = clazz.getAnnotation(org.osoa.sca.annotations.Scope.class);
+ if (annotation == null) {
+ type.setImplementationScope(Scope.STATELESS);
+ return;
+ }
+ String name = annotation.value();
+ Scope scope;
+ if ("COMPOSITE".equals(name)) {
+ scope = Scope.COMPOSITE;
+ } else if ("SESSION".equals(name)) {
+ scope = Scope.SESSION;
+ } else if ("CONVERSATION".equals(name)) {
+ scope = Scope.CONVERSATION;
+ } else if ("REQUEST".equals(name)) {
+ scope = Scope.REQUEST;
+ } else if ("SYSTEM".equals(name)) {
+ scope = Scope.SYSTEM;
+ } else {
+ scope = new Scope(name);
+ }
+ type.setImplementationScope(scope);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ServiceProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ServiceProcessor.java
new file mode 100644
index 0000000000..6f96c92006
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ServiceProcessor.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Set;
+
+import org.osoa.sca.annotations.Callback;
+import org.osoa.sca.annotations.Remotable;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorExtension;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService;
+import org.apache.tuscany.spi.model.ServiceContract;
+
+import static org.apache.tuscany.core.util.JavaIntrospectionHelper.getAllInterfaces;
+import static org.apache.tuscany.core.util.JavaIntrospectionHelper.toPropertyName;
+
+/**
+ * Processes an {@link org.osoa.sca.annotations.Service} annotation and updates the component type with corresponding
+ * {@link JavaMappedService}s. Also processes related {@link org.osoa.sca.annotations.Callback} annotations.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ServiceProcessor extends ImplementationProcessorExtension {
+
+ private ImplementationProcessorService implService;
+
+ public ServiceProcessor(@Autowire ImplementationProcessorService implService) {
+ this.implService = implService;
+ }
+
+ public <T> void visitClass(CompositeComponent parent, Class<T> clazz,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context) throws ProcessingException {
+ org.osoa.sca.annotations.Service annotation = clazz.getAnnotation(org.osoa.sca.annotations.Service.class);
+ if (annotation == null) {
+ // scan intefaces for remotable
+ Set<Class> interfaces = getAllInterfaces(clazz);
+ for (Class<?> interfaze : interfaces) {
+ if (interfaze.getAnnotation(Remotable.class) != null) {
+ JavaMappedService service;
+ try {
+ service = implService.createService(interfaze);
+ } catch (InvalidServiceContractException e) {
+ throw new ProcessingException(e);
+ }
+ type.getServices().put(service.getName(), service);
+ }
+ }
+ return;
+ }
+ Class<?>[] interfaces = annotation.interfaces();
+ if (interfaces.length == 0) {
+ Class<?> interfaze = annotation.value();
+ if (Void.class.equals(interfaze)) {
+ throw new IllegalServiceDefinitionException("No interfaces specified");
+ } else {
+ interfaces = new Class<?>[1];
+ interfaces[0] = interfaze;
+ }
+ }
+ for (Class<?> interfaze : interfaces) {
+ if (!interfaze.isInterface()) {
+ throw new InvalidServiceType("Service must be an interface", interfaze.getName());
+ }
+ JavaMappedService service;
+ try {
+ service = implService.createService(interfaze);
+ } catch (InvalidServiceContractException e) {
+ throw new ProcessingException(e);
+ }
+ type.getServices().put(service.getName(), service);
+ }
+ }
+
+
+ public void visitMethod(CompositeComponent parent,
+ Method method,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context) throws ProcessingException {
+
+ Callback annotation = method.getAnnotation(Callback.class);
+ if (annotation == null) {
+ return;
+ }
+ if (method.getParameterTypes().length != 1) {
+ throw new IllegalCallbackReferenceException("Setter must have one parameter", method.toString());
+ }
+ String name = toPropertyName(method.getName());
+ JavaMappedService callbackService = null;
+ Class<?> callbackClass = method.getParameterTypes()[0];
+ for (JavaMappedService service : type.getServices().values()) {
+ ServiceContract serviceContract = service.getServiceContract();
+ if (serviceContract.getCallbackClass().equals(callbackClass)) {
+ callbackService = service;
+ }
+ }
+ if (callbackService == null) {
+ throw new IllegalCallbackReferenceException("Callback type does not match a service callback interface");
+ }
+ callbackService.setCallbackReferenceName(name);
+ callbackService.setCallbackMember(method);
+ }
+
+ public void visitField(CompositeComponent parent, Field field,
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type,
+ DeploymentContext context) throws ProcessingException {
+
+ Callback annotation = field.getAnnotation(Callback.class);
+ if (annotation == null) {
+ return;
+ }
+ String name = field.getName();
+ JavaMappedService callbacksService = null;
+ Class<?> callbackClass = field.getType();
+ for (JavaMappedService service : type.getServices().values()) {
+ ServiceContract serviceContract = service.getServiceContract();
+ if (serviceContract.getCallbackClass().equals(callbackClass)) {
+ callbacksService = service;
+ }
+ }
+ if (callbacksService == null) {
+ throw new IllegalCallbackReferenceException("Callback type does not match a service callback interface");
+ }
+ callbacksService.setCallbackReferenceName(name);
+ callbacksService.setCallbackMember(field);
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ServiceTypeNotFoundException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ServiceTypeNotFoundException.java
new file mode 100644
index 0000000000..8a0d4afc3d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/ServiceTypeNotFoundException.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+/**
+ * Thrown when a service interface cannot be determined based on a heuristic evaluation of an implementation
+ *
+ * @version $Rev$ $Date$
+ */
+public class ServiceTypeNotFoundException extends ProcessingException {
+
+ public ServiceTypeNotFoundException(String message) {
+ super(message);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/UnknownContextTypeException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/UnknownContextTypeException.java
new file mode 100644
index 0000000000..a7868349a6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/processor/UnknownContextTypeException.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+/**
+ * Thrown when a method or field marked with {@link org.osoa.sca.annotations.Context} takes an unknown type
+ *
+ * @version $Rev$ $Date$
+ */
+public class UnknownContextTypeException extends IllegalContextException {
+
+ public UnknownContextTypeException(String message) {
+ super(message);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/builder/SystemComponentBuilder.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/builder/SystemComponentBuilder.java
new file mode 100644
index 0000000000..33cbbe1232
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/builder/SystemComponentBuilder.java
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.system.builder;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.builder.BuilderConfigException;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.ComponentBuilderExtension;
+import org.apache.tuscany.spi.host.ResourceHost;
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.Resource;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.PropertyValue;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl;
+import org.apache.tuscany.core.implementation.system.model.SystemImplementation;
+import org.apache.tuscany.core.injection.MethodEventInvoker;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.injection.ResourceObjectFactory;
+
+/**
+ * Produces system atomic components from a component definition
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class SystemComponentBuilder extends ComponentBuilderExtension<SystemImplementation> {
+ private ResourceHost host;
+
+ protected Class<SystemImplementation> getImplementationType() {
+ return SystemImplementation.class;
+ }
+
+ @Autowire
+ public void setHost(ResourceHost host) {
+ this.host = host;
+ }
+
+ @SuppressWarnings("unchecked")
+ public AtomicComponent build(CompositeComponent parent,
+ ComponentDefinition<SystemImplementation> definition,
+ DeploymentContext deploymentContext) throws BuilderConfigException {
+ PojoComponentType<ServiceDefinition, JavaMappedReference, JavaMappedProperty<?>> componentType =
+ definition.getImplementation().getComponentType();
+
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setParent(parent);
+ if (definition.getInitLevel() != null) {
+ configuration.setInitLevel(definition.getInitLevel());
+ } else {
+ configuration.setInitLevel(componentType.getInitLevel());
+ }
+ Method initMethod = componentType.getInitMethod();
+ if (initMethod != null) {
+ configuration.setInitInvoker(new MethodEventInvoker<Object>(initMethod));
+ }
+ Method destroyMethod = componentType.getDestroyMethod();
+ if (destroyMethod != null) {
+ configuration.setDestroyInvoker(new MethodEventInvoker<Object>(destroyMethod));
+ }
+ // setup property injection sites
+ for (JavaMappedProperty<?> property : componentType.getProperties().values()) {
+ configuration.addPropertySite(property.getName(), property.getMember());
+ }
+ // setup reference injection sites
+ for (JavaMappedReference reference : componentType.getReferences().values()) {
+ Member member = reference.getMember();
+ if (member != null) {
+ // could be null if the reference is mapped to a constructor
+ configuration.addReferenceSite(reference.getName(), member);
+ }
+ }
+
+ for (Resource resource : componentType.getResources().values()) {
+ Member member = resource.getMember();
+ if (member != null) {
+ // could be null if the resource is mapped to a constructor
+ configuration.addResourceSite(resource.getName(), member);
+ }
+ }
+
+ // setup constructor injection
+ ConstructorDefinition<?> ctorDef = componentType.getConstructorDefinition();
+ Constructor<?> constr = ctorDef.getConstructor();
+ PojoObjectFactory<?> instanceFactory = new PojoObjectFactory(constr);
+ configuration.setInstanceFactory(instanceFactory);
+ configuration.getConstructorParamNames().addAll(ctorDef.getInjectionNames());
+ for (Class<?> clazz : constr.getParameterTypes()) {
+ configuration.addConstructorParamType(clazz);
+ }
+ configuration.setName(definition.getName());
+ SystemAtomicComponentImpl component = new SystemAtomicComponentImpl(configuration);
+ // handle properties
+ Map<String, PropertyValue<?>> propertyValues = definition.getPropertyValues();
+ processProperties(propertyValues, componentType.getProperties().values(), component);
+
+ // handle resources
+ for (Resource resource : componentType.getResources().values()) {
+ String name = resource.getName();
+ boolean optional = resource.isOptional();
+ Class<Object> type = (Class<Object>) resource.getType();
+ ResourceObjectFactory<Object> factory;
+ String mappedName = resource.getMappedName();
+ if (mappedName == null) {
+ // by type
+ factory = new ResourceObjectFactory<Object>(type, optional, parent, host);
+ } else {
+ factory = new ResourceObjectFactory<Object>(type, mappedName, optional, parent, host);
+ }
+ component.addResourceFactory(name, factory);
+
+ }
+ return component;
+ }
+
+// private void processReferences(ComponentDefinition<SystemImplementation> definition,
+// Map<String, JavaMappedReference> references,
+// CompositeComponent parent,
+// SystemAtomicComponentImpl component) {
+// // no proxies needed for system components
+// for (ReferenceTarget target : definition.getReferenceTargets().values()) {
+// String referenceName = target.getReferenceName();
+// JavaMappedReference referenceDefiniton = references.get(referenceName);
+// Class interfaze = referenceDefiniton.getServiceContract().getInterfaceClass();
+// OutboundWire wire;
+// if (referenceDefiniton.isAutowire()) {
+// boolean required = referenceDefiniton.isRequired();
+// wire = new SystemOutboundAutowire(referenceName, interfaze, parent, required);
+// } else {
+// //FIXME support multiplicity!
+// assert target.getTargets().size() == 1 : "Multiplicity not yet implemented";
+// QualifiedName targetName = new QualifiedName(target.getTargets().get(0).getPath());
+// wire = new SystemOutboundWireImpl(referenceName, targetName, interfaze);
+// }
+// component.addOutboundWire(wire);
+// }
+// }
+
+ private void processProperties(Map<String, PropertyValue<?>> propertyValues,
+ Collection<JavaMappedProperty<?>> properties,
+ SystemAtomicComponentImpl component) {
+ for (JavaMappedProperty<?> property : properties) {
+ PropertyValue value = propertyValues.get(property.getName());
+ ObjectFactory<?> factory;
+ if (value != null) {
+ factory = value.getValueFactory();
+ } else {
+ factory = property.getDefaultValueFactory();
+ }
+ if (factory != null) {
+ component.addPropertyFactory(property.getName(), factory);
+ }
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentImpl.java
new file mode 100644
index 0000000000..c43b0d1ee9
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentImpl.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.system.component;
+
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import org.apache.tuscany.core.implementation.PojoAtomicComponent;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.wire.OptimizedWireObjectFactory;
+
+/**
+ * Default implementation of a system atomic context
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class SystemAtomicComponentImpl extends PojoAtomicComponent {
+
+ public SystemAtomicComponentImpl(PojoConfiguration configuration) {
+ super(configuration);
+ scope = Scope.COMPOSITE;
+ }
+
+ public TargetInvoker createTargetInvoker(String targetName, Operation operation, InboundWire callbackWire) {
+ return null;
+ }
+
+ public boolean isSystem() {
+ return true;
+ }
+
+ protected ObjectFactory<?> createWireFactory(Class<?> interfaze, OutboundWire wire) {
+ return new OptimizedWireObjectFactory(wire);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemComponentTypeLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemComponentTypeLoader.java
new file mode 100644
index 0000000000..2c7141044b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemComponentTypeLoader.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.system.loader;
+
+import java.net.URL;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.ComponentTypeLoaderExtension;
+import org.apache.tuscany.spi.implementation.java.IntrospectionRegistry;
+import org.apache.tuscany.spi.implementation.java.Introspector;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.Scope;
+
+import org.apache.tuscany.core.implementation.system.model.SystemImplementation;
+import org.apache.tuscany.core.util.JavaIntrospectionHelper;
+
+/**
+ * Loads a system component type
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemComponentTypeLoader extends ComponentTypeLoaderExtension<SystemImplementation> {
+ private Introspector introspector;
+
+ public SystemComponentTypeLoader() {
+ }
+
+ public SystemComponentTypeLoader(Introspector introspector) {
+ this.introspector = introspector;
+ }
+
+ public SystemComponentTypeLoader(LoaderRegistry loaderRegistry, Introspector introspector) {
+ super(loaderRegistry);
+ this.introspector = introspector;
+ }
+
+ //FIXME autowire to support multiple interfaces
+ @Autowire
+ public void setIntrospector(IntrospectionRegistry introspector) {
+ this.introspector = introspector;
+ }
+
+ public void load(CompositeComponent parent,
+ SystemImplementation implementation,
+ DeploymentContext deploymentContext) throws LoaderException {
+ Class<?> implClass = implementation.getImplementationClass();
+ URL sidefile = implClass.getResource(JavaIntrospectionHelper.getBaseName(implClass) + ".componentType");
+ PojoComponentType componentType;
+ if (sidefile == null) {
+ componentType = loadByIntrospection(parent, implementation, deploymentContext);
+ } else {
+ componentType = loadFromSidefile(sidefile, deploymentContext);
+ }
+ // this means system components are always composite scoped
+ componentType.setImplementationScope(Scope.COMPOSITE);
+ implementation.setComponentType(componentType);
+ }
+
+ protected Class<SystemImplementation> getImplementationClass() {
+ return SystemImplementation.class;
+ }
+
+ protected PojoComponentType loadByIntrospection(CompositeComponent parent,
+ SystemImplementation implementation,
+ DeploymentContext deploymentContext) throws ProcessingException {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> componentType =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Class<?> implClass = implementation.getImplementationClass();
+ introspector.introspect(parent, implClass, componentType, deploymentContext);
+ return componentType;
+ }
+
+
+ protected PojoComponentType loadFromSidefile(URL url, DeploymentContext deploymentContext) throws LoaderException {
+ return loaderRegistry.load(null, null, url, PojoComponentType.class, deploymentContext);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemCompositeComponentTypeLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemCompositeComponentTypeLoader.java
new file mode 100644
index 0000000000..0e05041ea5
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemCompositeComponentTypeLoader.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.system.loader;
+
+import java.net.URL;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.ComponentTypeLoaderExtension;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+
+import org.apache.tuscany.core.deployer.ChildDeploymentContext;
+import org.apache.tuscany.core.implementation.system.model.SystemCompositeImplementation;
+
+/**
+ * Loads a system composite component type
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemCompositeComponentTypeLoader extends ComponentTypeLoaderExtension<SystemCompositeImplementation> {
+ public SystemCompositeComponentTypeLoader() {
+ }
+
+ public SystemCompositeComponentTypeLoader(LoaderRegistry loaderRegistry) {
+ super(loaderRegistry);
+ }
+
+ protected Class<SystemCompositeImplementation> getImplementationClass() {
+ return SystemCompositeImplementation.class;
+ }
+
+ public void load(CompositeComponent parent, SystemCompositeImplementation implementation,
+ DeploymentContext deploymentContext)
+ throws LoaderException {
+ URL scdlLocation = implementation.getScdlLocation();
+ if (scdlLocation == null) {
+ throw new LoaderException("SCDL location not found");
+ }
+ ClassLoader cl = implementation.getClassLoader();
+ deploymentContext = new ChildDeploymentContext(deploymentContext, cl, scdlLocation);
+ CompositeComponentType componentType = loadFromSidefile(parent, scdlLocation, deploymentContext);
+ implementation.setComponentType(componentType);
+ }
+
+
+ protected CompositeComponentType loadFromSidefile(CompositeComponent parent,
+ URL url,
+ DeploymentContext deploymentContext)
+ throws LoaderException {
+ return loaderRegistry.load(parent, null, url, CompositeComponentType.class, deploymentContext);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemImplementationLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemImplementationLoader.java
new file mode 100644
index 0000000000..d5d4269880
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/loader/SystemImplementationLoader.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.system.loader;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.LoaderUtil;
+import org.apache.tuscany.spi.loader.UnrecognizedElementException;
+import org.apache.tuscany.spi.model.ModelObject;
+
+import org.apache.tuscany.core.implementation.system.model.SystemImplementation;
+
+/**
+ * Loads information for a system implementation
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemImplementationLoader extends LoaderExtension<SystemImplementation> {
+ public static final QName SYSTEM_IMPLEMENTATION =
+ new QName("http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT", "implementation.system");
+
+ public SystemImplementationLoader(@Autowire LoaderRegistry registry) {
+ super(registry);
+ }
+
+ public SystemImplementation load(CompositeComponent parent,
+ ModelObject object, XMLStreamReader reader,
+ DeploymentContext deploymentContext)
+ throws XMLStreamException, LoaderException {
+ assert SYSTEM_IMPLEMENTATION.equals(reader.getName());
+ SystemImplementation implementation = new SystemImplementation();
+ String implClass = reader.getAttributeValue(null, "class");
+ Class<?> implementationClass = LoaderUtil.loadClass(implClass, deploymentContext.getClassLoader());
+ implementation.setImplementationClass(implementationClass);
+ registry.loadComponentType(parent, implementation, deploymentContext);
+ while (true) {
+ int code = reader.next();
+ if (code == XMLStreamConstants.START_ELEMENT) {
+ throw new UnrecognizedElementException(reader.getName());
+ } else if (code == XMLStreamConstants.END_ELEMENT) {
+ return implementation;
+ }
+ }
+ }
+
+ public QName getXMLType() {
+ return SYSTEM_IMPLEMENTATION;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/model/SystemCompositeImplementation.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/model/SystemCompositeImplementation.java
new file mode 100644
index 0000000000..e634609c5b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/model/SystemCompositeImplementation.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.system.model;
+
+import java.net.URL;
+
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.Implementation;
+
+/**
+ * Represents a system composite type
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemCompositeImplementation extends Implementation<CompositeComponentType> {
+ private URL scdlLocation;
+ private ClassLoader classLoader;
+
+ public SystemCompositeImplementation() {
+ }
+
+ public SystemCompositeImplementation(CompositeComponentType componentType) {
+ super(componentType);
+ }
+
+ public URL getScdlLocation() {
+ return scdlLocation;
+ }
+
+ public void setScdlLocation(URL scdlLocation) {
+ this.scdlLocation = scdlLocation;
+ }
+
+ public ClassLoader getClassLoader() {
+ return classLoader;
+ }
+
+ public void setClassLoader(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/model/SystemImplementation.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/model/SystemImplementation.java
new file mode 100644
index 0000000000..ce48ed3fe5
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/implementation/system/model/SystemImplementation.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.system.model;
+
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.model.AtomicImplementation;
+
+/**
+ * Represents the system composite implementation
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemImplementation extends AtomicImplementation<PojoComponentType> {
+ private Class<?> implementationClass;
+
+ public SystemImplementation(PojoComponentType componentType, Class<?> implementationClass) {
+ super(componentType);
+ this.implementationClass = implementationClass;
+ }
+
+ public SystemImplementation() {
+ }
+
+ public SystemImplementation(Class<?> implementationClass) {
+ this.implementationClass = implementationClass;
+ }
+
+ public Class<?> getImplementationClass() {
+ return implementationClass;
+ }
+
+ public void setImplementationClass(Class<?> implementationClass) {
+ this.implementationClass = implementationClass;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ArrayMultiplicityObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ArrayMultiplicityObjectFactory.java
new file mode 100644
index 0000000000..1a441dcf87
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ArrayMultiplicityObjectFactory.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import java.lang.reflect.Array;
+import java.util.List;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+
+/**
+ * Resolves targets configured in a multiplicity by delegating to object factories and returning an <code>Array</code>
+ * containing object instances
+ *
+ * @version $Rev$ $Date$
+ */
+public class ArrayMultiplicityObjectFactory implements ObjectFactory<Object> {
+
+ private ObjectFactory[] factories;
+
+ private Class interfaceType;
+
+ public ArrayMultiplicityObjectFactory(Class interfaceType, List<ObjectFactory<?>> factories) {
+ assert interfaceType != null : "Interface type was null";
+ assert factories != null : "Object factories were null";
+ this.interfaceType = interfaceType;
+ this.factories = factories.toArray(new ObjectFactory[factories.size()]);
+ }
+
+ public Object getInstance() throws ObjectCreationException {
+ Object array = Array.newInstance(interfaceType, factories.length);
+ for (int i = 0; i < factories.length; i++) {
+ Array.set(array, i, factories[i].getInstance());
+ }
+ return array;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/CallbackWireObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/CallbackWireObjectFactory.java
new file mode 100644
index 0000000000..fc389a23cf
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/CallbackWireObjectFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.WireService;
+
+/**
+ * Returns proxy instance for a wire callback
+ *
+ * @version $Rev$ $Date$
+ */
+public class CallbackWireObjectFactory implements ObjectFactory {
+
+ private WireService wireService;
+ private Class<?> interfaze;
+ private InboundWire wire;
+
+ public CallbackWireObjectFactory(Class<?> interfaze, WireService wireService, InboundWire wire) {
+ this.interfaze = interfaze;
+ this.wireService = wireService;
+ this.wire = wire;
+ }
+
+ public Object getInstance() throws ObjectCreationException {
+ return wireService.createCallbackProxy(interfaze, wire);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/CompositeContextObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/CompositeContextObjectFactory.java
new file mode 100644
index 0000000000..e44c8124d5
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/CompositeContextObjectFactory.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import org.apache.tuscany.core.launcher.CompositeContextImpl;
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.wire.WireService;
+import org.osoa.sca.CompositeContext;
+
+/**
+ * Creates instances of {@link org.apache.tuscany.core.implementation.composite.ManagedCompositeContext} for injection
+ * on component implementation instances
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompositeContextObjectFactory implements ObjectFactory<CompositeContext> {
+ private CompositeComponent composite;
+ private WireService wireService;
+
+ public CompositeContextObjectFactory(CompositeComponent composite, WireService wireService) {
+ assert composite != null;
+ assert wireService != null;
+ this.composite = composite;
+ this.wireService = wireService;
+ }
+
+ public CompositeContext getInstance() throws ObjectCreationException {
+ return new CompositeContextImpl(composite, wireService);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ContextInjector.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ContextInjector.java
new file mode 100644
index 0000000000..a422500f3c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ContextInjector.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+
+/**
+ * Implementations inject a pre-configured context type (interface) on an instance.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ContextInjector<S, T> extends Injector<T> {
+
+ void setContext(S context) throws ObjectCreationException;
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ConversationIDObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ConversationIDObjectFactory.java
new file mode 100644
index 0000000000..8dbc0a3a83
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ConversationIDObjectFactory.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+
+public class ConversationIDObjectFactory implements ObjectFactory<String> {
+
+ private WorkContext workContext;
+
+ public ConversationIDObjectFactory(WorkContext workContext) {
+ this.workContext = workContext;
+ }
+
+ public String getInstance() {
+ return (String)workContext.getIdentifier(Scope.CONVERSATION);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/EventInvoker.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/EventInvoker.java
new file mode 100644
index 0000000000..af2382b36a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/EventInvoker.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+/**
+ * Performs an invocation on an instance
+ *
+ * @version $Rev$ $Date$
+ */
+public interface EventInvoker<T> {
+
+ /**
+ * Performs the invocation on a given instance
+ *
+ * @throws ObjectCallbackException
+ */
+ void invokeEvent(T instance) throws ObjectCallbackException;
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/FieldInjector.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/FieldInjector.java
new file mode 100644
index 0000000000..e9f8f42aa1
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/FieldInjector.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import java.lang.reflect.Field;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+
+/**
+ * Injects a value created by an {@link org.apache.tuscany.spi.ObjectFactory} on a given field
+ *
+ * @version $Rev$ $Date$
+ */
+public class FieldInjector<T> implements Injector<T> {
+
+ private final Field field;
+
+ private final ObjectFactory<?> objectFactory;
+
+ /**
+ * Create an injector and have it use the given <code>ObjectFactory</code> to inject a value on the instance using
+ * the reflected <code>Field</code>
+ */
+ public FieldInjector(Field field, ObjectFactory<?> objectFactory) {
+ this.field = field;
+ this.field.setAccessible(true);
+ this.objectFactory = objectFactory;
+ }
+
+ /**
+ * Inject a new value on the given isntance
+ */
+ public void inject(T instance) throws ObjectCreationException {
+ try {
+ field.set(instance, objectFactory.getInstance());
+ } catch (IllegalAccessException e) {
+ throw new AssertionError("Field is not accessible [" + field + "]");
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/InjectionRuntimeException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/InjectionRuntimeException.java
new file mode 100644
index 0000000000..c5f037d931
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/InjectionRuntimeException.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import org.apache.tuscany.api.TuscanyRuntimeException;
+
+/**
+ * Root unchecked exception for the injection package
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class InjectionRuntimeException extends TuscanyRuntimeException {
+
+ public InjectionRuntimeException() {
+ super();
+ }
+
+ public InjectionRuntimeException(String message) {
+ super(message);
+ }
+
+
+ protected InjectionRuntimeException(String message, String identifier) {
+ super(message, identifier);
+ }
+
+ public InjectionRuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ protected InjectionRuntimeException(String message, String identifier, Throwable cause) {
+ super(message, identifier, cause);
+ }
+
+ public InjectionRuntimeException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/Injector.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/Injector.java
new file mode 100644
index 0000000000..c2125d8212
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/Injector.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+
+/**
+ * Implementations inject a pre-configured value on an instance
+ *
+ * @version $Rev$ $Date$
+ */
+public interface Injector<T> {
+
+ /**
+ * Inject a value on the given instance
+ */
+ void inject(T instance) throws ObjectCreationException;
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/InvalidAccessorException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/InvalidAccessorException.java
new file mode 100644
index 0000000000..2e7ff0e754
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/InvalidAccessorException.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public class InvalidAccessorException extends InjectionRuntimeException {
+
+ public InvalidAccessorException(String message) {
+ super(message);
+ }
+
+ public InvalidAccessorException(String message, String identifier) {
+ super(message, identifier);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/InvalidResourceTypeException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/InvalidResourceTypeException.java
new file mode 100644
index 0000000000..1a3eaf4d1a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/InvalidResourceTypeException.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+
+/**
+ * Denotes an invalid resource type, i.e. that is not a component
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidResourceTypeException extends ObjectCreationException {
+
+ public InvalidResourceTypeException(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/JNDIListObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/JNDIListObjectFactory.java
new file mode 100644
index 0000000000..bf2a7a103e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/JNDIListObjectFactory.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+
+/**
+ * An implementation of ObjectFactory that creates instances by looking them up in a JNDI context.
+ *
+ * @version $Rev: 430937 $ $Date: 2006-08-12 06:47:56 +0530 (Sat, 12 Aug 2006) $
+ */
+public class JNDIListObjectFactory<T> implements ObjectFactory<List<T>> {
+ private final Context context;
+ private List<String> nameList;
+
+ public JNDIListObjectFactory(Context context, List<String> name) {
+ this.context = context;
+ this.nameList = Collections.unmodifiableList(name);
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public List<T> getInstance() throws ObjectCreationException {
+ try {
+ List<T> instanceList = new ArrayList<T>();
+ for (int count = 0 ; count < instanceList.size() ; ++count) {
+ instanceList.add((T) context.lookup(nameList.get(count)));
+ }
+ return instanceList;
+ } catch (NamingException e) {
+ throw new ObjectCreationException(e);
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/JNDIObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/JNDIObjectFactory.java
new file mode 100644
index 0000000000..0189d8245b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/JNDIObjectFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+
+/**
+ * An implementation of ObjectFactory that creates instances by looking them up in a JNDI context.
+ *
+ * @version $Rev$ $Date$
+ */
+public class JNDIObjectFactory<T> implements ObjectFactory<T> {
+ private final Context context;
+ private final String name;
+
+ public JNDIObjectFactory(Context context, String name) {
+ this.context = context;
+ this.name = name;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public T getInstance() throws ObjectCreationException {
+ try {
+ return (T) context.lookup(name);
+ } catch (NamingException e) {
+ throw new ObjectCreationException(e);
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ListMultiplicityObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ListMultiplicityObjectFactory.java
new file mode 100644
index 0000000000..b261bcda53
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ListMultiplicityObjectFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+
+/**
+ * Resolves targets configured in a multiplicity by delegating to object factories and returning an <code>List</code>
+ * containing object instances
+ *
+ * @version $Rev$ $Date$
+ */
+public class ListMultiplicityObjectFactory implements ObjectFactory<List> {
+
+ private ObjectFactory[] factories;
+
+ public ListMultiplicityObjectFactory(List<ObjectFactory<?>> factories) {
+ assert factories != null : "Object factories were null";
+ this.factories = factories.toArray(new ObjectFactory[factories.size()]);
+ }
+
+ public List getInstance() throws ObjectCreationException {
+ List<Object> list = new ArrayList<Object>();
+ for (ObjectFactory factory : factories) {
+ list.add(factory.getInstance());
+ }
+ return list;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/MethodEventInvoker.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/MethodEventInvoker.java
new file mode 100644
index 0000000000..e43a1e1fa6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/MethodEventInvoker.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Performs an wire on a method of a given instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class MethodEventInvoker<T> implements EventInvoker<T> {
+ private final Method method;
+
+ /**
+ * Intantiates an invoker for the given method
+ */
+ public MethodEventInvoker(Method method) {
+ assert method != null;
+ this.method = method;
+ }
+
+ public void invokeEvent(T instance) throws ObjectCallbackException {
+ try {
+ method.invoke(instance, (Object[]) null);
+ } catch (IllegalArgumentException e) {
+ String name = method.getName();
+ throw new ObjectCallbackException("Exception thrown by callback method [" + name + "]", e.getCause());
+ } catch (IllegalAccessException e) {
+ String name = method.getName();
+ throw new AssertionError("Method is not accessible [" + name + "]");
+ } catch (InvocationTargetException e) {
+ String name = method.getName();
+ throw new ObjectCallbackException("Exception thrown by callback method [" + name + "]", e.getCause());
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/MethodInjector.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/MethodInjector.java
new file mode 100644
index 0000000000..258f0817dd
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/MethodInjector.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+
+/**
+ * Injects a value created by an {@link org.apache.tuscany.spi.ObjectFactory} using a given method
+ *
+ * @version $Rev$ $Date$
+ */
+public class MethodInjector<T> implements Injector<T> {
+ private final Method method;
+ private final ObjectFactory<?> objectFactory;
+
+ public MethodInjector(Method method, ObjectFactory<?> objectFactory) {
+ assert method != null;
+ assert objectFactory != null;
+ this.method = method;
+ this.method.setAccessible(true);
+ this.objectFactory = objectFactory;
+ }
+
+ public void inject(T instance) throws ObjectCreationException {
+ try {
+ method.invoke(instance, objectFactory.getInstance());
+ } catch (IllegalAccessException e) {
+ throw new AssertionError("Method is not accessible [" + method + "]");
+ } catch (IllegalArgumentException e) {
+ throw new ObjectCreationException("Exception thrown by setter", method.getName(), e);
+ } catch (InvocationTargetException e) {
+ throw new ObjectCreationException("Exception thrown by setter", method.getName(), e);
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/NoAccessorException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/NoAccessorException.java
new file mode 100644
index 0000000000..b3109074e3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/NoAccessorException.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public class NoAccessorException extends InjectionRuntimeException {
+ public NoAccessorException() {
+ }
+
+ public NoAccessorException(String message) {
+ super(message);
+ }
+
+ public NoAccessorException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public NoAccessorException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/NoMultiplicityTypeException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/NoMultiplicityTypeException.java
new file mode 100644
index 0000000000..a86451525b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/NoMultiplicityTypeException.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class NoMultiplicityTypeException extends InjectionRuntimeException {
+
+ public NoMultiplicityTypeException(String message, String identifier) {
+ super(message, identifier);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ObjectCallbackException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ObjectCallbackException.java
new file mode 100644
index 0000000000..ff830aab4b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ObjectCallbackException.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+/**
+ * Denotes an error when invoking on an object
+ *
+ * @version $Rev$ $Date$
+ */
+public class ObjectCallbackException extends InjectionRuntimeException {
+
+ public ObjectCallbackException() {
+ super();
+ }
+
+ public ObjectCallbackException(String message) {
+ super(message);
+ }
+
+ public ObjectCallbackException(String message, String identifier) {
+ super(message, identifier);
+ }
+
+ public ObjectCallbackException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ObjectCallbackException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/PojoObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/PojoObjectFactory.java
new file mode 100644
index 0000000000..cf446a35fc
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/PojoObjectFactory.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+
+/**
+ * Creates new instances of a Java class
+ *
+ * @version $Rev$ $Date$
+ * @see org.apache.tuscany.core.injection.Injector
+ */
+public class PojoObjectFactory<T> implements ObjectFactory<T> {
+
+ private final Constructor<T> ctr;
+ private ObjectFactory[] initializerFactories;
+
+ /**
+ * Creates the object factory
+ *
+ * @param ctr the constructor to use when instantiating a new object
+ */
+ public PojoObjectFactory(Constructor<T> ctr) {
+ assert ctr != null;
+ this.ctr = ctr;
+ initializerFactories = new ObjectFactory[ctr.getParameterTypes().length];
+ }
+
+ /**
+ * Creates the object factory
+ *
+ * @param ctr the constructor to use when instantiating a new object
+ * @param factories an ordered list of <code>ObjectFactory</code>s to use for returning constructor parameters
+ */
+ public PojoObjectFactory(Constructor<T> ctr, List<ObjectFactory> factories) {
+ assert ctr != null;
+ int params = ctr.getParameterTypes().length;
+ assert params == factories.size();
+ this.ctr = ctr;
+ initializerFactories = new ObjectFactory[params];
+ int i = 0;
+ for (ObjectFactory factory : factories) {
+ initializerFactories[i] = factory;
+ i++;
+ }
+ }
+
+ /**
+ * Returns the ordered array of <code>ObjectFactory</code>s use in creating constructor parameters
+ */
+ public ObjectFactory[] getInitializerFactories() {
+ return initializerFactories;
+ }
+
+ /**
+ * Sets an <code>ObjectFactory</code>s to use in creating constructor parameter
+ *
+ * @param pos the constructor parameter position
+ * @param factory the object factory
+ */
+ public void setInitializerFactory(int pos, ObjectFactory factory) {
+ assert pos < initializerFactories.length;
+ initializerFactories[pos] = factory;
+ }
+
+ /**
+ * Creates a new instance of an object
+ */
+ public T getInstance() throws ObjectCreationException {
+ int size = initializerFactories.length;
+ Object[] initargs = new Object[size];
+ // create the constructor arg array
+ for (int i = 0; i < size; i++) {
+ ObjectFactory<?> objectFactory = initializerFactories[i];
+ if (objectFactory == null) {
+ // [rfeng] Set it to null for property with default values
+ initargs[i] = null;
+ // String name = ctr.getName();
+ // throw new ObjectCallbackException("Null object factory for
+ // constructor parameter [" + i + "]", name);
+ } else {
+ initargs[i] = objectFactory.getInstance();
+ }
+ }
+ try {
+ ctr.setAccessible(true);
+ return ctr.newInstance(initargs);
+ } catch (IllegalArgumentException e) {
+ String name = ctr.getName();
+ throw new ObjectCreationException("Exception thrown by constructor", name, e);
+ } catch (InstantiationException e) {
+ String name = ctr.getDeclaringClass().getName();
+ throw new AssertionError("Class is not instantiable [" + name + "]");
+ } catch (IllegalAccessException e) {
+ String name = ctr.getName();
+ throw new AssertionError("Constructor is not accessible [" + name + "]");
+ } catch (InvocationTargetException e) {
+ String name = ctr.getName();
+ throw new ObjectCreationException("Exception thrown by constructor", name, e);
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/RequestContextObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/RequestContextObjectFactory.java
new file mode 100644
index 0000000000..9a9d97a273
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/RequestContextObjectFactory.java
@@ -0,0 +1,26 @@
+package org.apache.tuscany.core.injection;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.WorkContext;
+
+import org.apache.tuscany.core.implementation.composite.ManagedRequestContext;
+
+/**
+ * Creates instances of {@link org.apache.tuscany.core.implementation.composite.ManagedRequestContext} for injection on
+ * component implementation instances
+ *
+ * @version $Rev$ $Date$
+ */
+public class RequestContextObjectFactory implements ObjectFactory<ManagedRequestContext> {
+ private WorkContext workContext;
+
+ public RequestContextObjectFactory(WorkContext workContext) {
+ assert workContext != null;
+ this.workContext = workContext;
+ }
+
+ public ManagedRequestContext getInstance() throws ObjectCreationException {
+ return new ManagedRequestContext(workContext);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ResourceNotFoundException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ResourceNotFoundException.java
new file mode 100644
index 0000000000..ed3ac20631
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ResourceNotFoundException.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+
+/**
+ * Denotes an exception thrown when a runtime resource is not found
+ *
+ * @version $Rev$ $Date$
+ */
+public class ResourceNotFoundException extends ObjectCreationException {
+
+ public ResourceNotFoundException(String message, String identifier) {
+ super(message, identifier);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ResourceObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ResourceObjectFactory.java
new file mode 100644
index 0000000000..45df502256
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/ResourceObjectFactory.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.host.ResourceHost;
+import org.apache.tuscany.spi.host.ResourceResolutionException;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+/**
+ * Resolves a runtime resource to be injected on a field or method of a Java component type marked with {@link
+ * org.apache.tuscany.api.annotation.Resource}. If the mapped name of the resource is an absolute URI such as
+ * <code>sca://localhost</code> or <code>jndi://localhost</code> the host container namespace is searched; otherwise the
+ * URI is assumed to be relative and the parent composite is searched. If a mapped name is not provided, i.e. resolution
+ * is by type, the parent composite is first searched followed by the host namespace.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ResourceObjectFactory<T> implements ObjectFactory<T> {
+
+ private Class<T> type;
+ private String mappedName;
+ private CompositeComponent parent;
+ private ResourceHost host;
+ private boolean resolveFromHost;
+ private boolean optional;
+
+ /**
+ * Instantiates a factory that resolves resources by type
+ *
+ * @param type the type of the resource to inject
+ * @param optional true if an error should be thrown if the resource is not found
+ * @param parent the parent composite of the component to inject on
+ * @param host the runtime resource provider
+ */
+ public ResourceObjectFactory(Class<T> type,
+ boolean optional,
+ CompositeComponent parent,
+ ResourceHost host) {
+ this.type = type;
+ this.parent = parent;
+ this.host = host;
+ this.optional = optional;
+ }
+
+ /**
+ * Instantiates a factory that resolves resources by mapped name
+ *
+ * @param type the type of the resource to inject
+ * @param mappedName the resource name
+ * @param optional true if an error should be thrown if the resource is not found
+ * @param parent the parent composite of the component to inject on
+ * @param host the runtime resource provider
+ */
+ public ResourceObjectFactory(Class<T> type,
+ String mappedName,
+ boolean optional,
+ CompositeComponent parent,
+ ResourceHost host) {
+ this.type = type;
+ this.parent = parent;
+ this.host = host;
+ if (mappedName.indexOf("://") >= 0) {
+ this.resolveFromHost = true;
+ }
+ this.mappedName = mappedName;
+ this.optional = optional;
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public T getInstance() throws ObjectCreationException {
+ if (resolveFromHost) {
+ return resolveInstance();
+ } else {
+ T instance = null;
+ if (mappedName == null) {
+ try {
+ InboundWire wire = parent.resolveSystemAutowire(type);
+ if (wire != null) {
+ instance = (T) wire.getTargetService();
+ }
+ } catch (TargetResolutionException e) {
+ throw new ObjectCreationException(e);
+ }
+ if (instance == null) {
+ // if not found in parent scope, search the host namespace
+ resolveFromHost = true;
+ instance = resolveInstance();
+ }
+ if (instance == null && !optional) {
+ throw new ResourceNotFoundException("No resource found matching type", type.getName());
+ }
+ return instance;
+ } else {
+ SCAObject child = parent.getSystemChild(mappedName);
+ if (child instanceof AtomicComponent) {
+ try {
+ AtomicComponent component = (AtomicComponent) child;
+ instance = type.cast(component.getTargetInstance());
+ } catch (TargetResolutionException e) {
+ throw new ObjectCreationException(e);
+ }
+ } else if (child != null) {
+ throw new InvalidResourceTypeException("Invalid resource type", mappedName);
+ } else if (!optional) {
+ throw new ResourceNotFoundException("No resource found for URI", mappedName);
+ }
+ return instance;
+ }
+ }
+ }
+
+ private T resolveInstance() {
+ try {
+ if (mappedName == null) {
+ return host.resolveResource(type);
+ } else {
+ return host.resolveResource(type, mappedName);
+ }
+ } catch (ResourceResolutionException e) {
+ throw new ObjectCreationException(e);
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/SingletonListObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/SingletonListObjectFactory.java
new file mode 100644
index 0000000000..fe503bfd68
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/SingletonListObjectFactory.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.tuscany.spi.ObjectFactory;
+
+/**
+ * Implementation of ObjectFactory that returns a single instance, typically an immutable type.
+ *
+ * @version $Rev: 430937 $ $Date: 2006-08-12 06:47:56 +0530 (Sat, 12 Aug 2006) $
+ */
+public class SingletonListObjectFactory<T> implements ObjectFactory<List<T>> {
+ private List<T> instance;
+
+ public SingletonListObjectFactory(List<T> instance) {
+ this.instance = Collections.unmodifiableList(instance);
+ }
+
+ public List<T> getInstance() {
+ return instance;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/SingletonObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/SingletonObjectFactory.java
new file mode 100644
index 0000000000..713c1ae54f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/injection/SingletonObjectFactory.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import org.apache.tuscany.spi.ObjectFactory;
+
+/**
+ * Implementation of ObjectFactory that returns a single instance, typically an immutable type.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SingletonObjectFactory<T> implements ObjectFactory<T> {
+ private final T instance;
+
+ public SingletonObjectFactory(T instance) {
+ this.instance = instance;
+ }
+
+ public T getInstance() {
+ return instance;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/launcher/CompositeContextImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/launcher/CompositeContextImpl.java
new file mode 100644
index 0000000000..246ef8bdf7
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/launcher/CompositeContextImpl.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.launcher;
+
+import org.osoa.sca.RequestContext;
+import org.osoa.sca.ServiceReference;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.wire.WireService;
+
+import org.apache.tuscany.core.implementation.composite.AbstractCompositeContext;
+
+
+/**
+ * Default implementation of the {@link org.osoa.sca.CompositeContext} for non-managed code
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompositeContextImpl extends AbstractCompositeContext {
+
+ public CompositeContextImpl(final CompositeComponent composite, final WireService wireService) {
+ super(composite, wireService);
+ }
+
+ public ServiceReference createServiceReferenceForSession(Object arg0) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ServiceReference createServiceReferenceForSession(Object arg0, String arg1) {
+ throw new UnsupportedOperationException();
+ }
+
+ public RequestContext getRequestContext() {
+ throw new UnsupportedOperationException();
+ }
+
+ public ServiceReference newSession(String arg0) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ServiceReference newSession(String arg0, Object arg1) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/launcher/LaunchException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/launcher/LaunchException.java
new file mode 100644
index 0000000000..730f29611a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/launcher/LaunchException.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.launcher;
+
+import org.apache.tuscany.api.TuscanyException;
+
+/**
+ * Exception indicating that there was a problem launching an application.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class LaunchException extends TuscanyException {
+
+ protected LaunchException(String message) {
+ super(message);
+ }
+
+ protected LaunchException(String message, String identifier) {
+ super(message, identifier);
+ }
+
+ protected LaunchException(String message, String identifier, Throwable cause) {
+ super(message, identifier, cause);
+ }
+
+ protected LaunchException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ protected LaunchException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/launcher/LauncherImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/launcher/LauncherImpl.java
new file mode 100644
index 0000000000..6f968b5209
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/launcher/LauncherImpl.java
@@ -0,0 +1,250 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.launcher;
+
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.stream.XMLInputFactory;
+
+import org.osoa.sca.CompositeContext;
+
+import org.apache.tuscany.spi.bootstrap.ComponentNames;
+import org.apache.tuscany.spi.bootstrap.RuntimeComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.deployer.Deployer;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.CompositeImplementation;
+import org.apache.tuscany.spi.services.management.TuscanyManagementService;
+
+import org.apache.tuscany.api.TuscanyException;
+import org.apache.tuscany.core.bootstrap.Bootstrapper;
+import org.apache.tuscany.core.bootstrap.DefaultBootstrapper;
+import org.apache.tuscany.core.implementation.system.model.SystemCompositeImplementation;
+import org.apache.tuscany.host.launcher.Launcher;
+import org.apache.tuscany.host.MonitorFactory;
+import org.apache.tuscany.host.RuntimeInfo;
+import org.apache.tuscany.host.runtime.InitializationException;
+import org.apache.tuscany.host.monitor.FormatterRegistry;
+
+/**
+ * Basic launcher implementation.
+ *
+ * @version $Rev$ $Date$
+ */
+public class LauncherImpl implements Launcher {
+ /**
+ * A conventional META-INF based location for the system SCDL.
+ *
+ * @see #bootRuntime(URL,MonitorFactory)
+ */
+ public static final String METAINF_SYSTEM_SCDL_PATH = "META-INF/tuscany/system.scdl";
+
+ /**
+ * A conventional META-INF based location for the application SCDL.
+ */
+ public static final String METAINF_APPLICATION_SCDL_PATH = "META-INF/sca/default.scdl";
+
+ private ClassLoader applicationLoader;
+
+ private RuntimeComponent runtime;
+
+ private Deployer deployer;
+
+ private CompositeComponent composite;
+
+ public CompositeContext bootApplication(URL applicationScdl, ClassLoader applicationClassLoader) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void bootRuntime(URL systemScdl, ClassLoader systemClassLoader, MonitorFactory monitor)
+ throws TuscanyException {
+ if (systemScdl == null) {
+ throw new LoaderException("Null system SCDL URL");
+ }
+
+ XMLInputFactory xmlFactory = XMLInputFactory.newInstance("javax.xml.stream.XMLInputFactory", systemClassLoader);
+ TuscanyManagementService managementService = null;
+ Bootstrapper bootstrapper = new DefaultBootstrapper(monitor, xmlFactory, managementService);
+ Deployer bootDeployer = bootstrapper.createDeployer();
+
+ // create and start the core runtime
+ runtime = bootstrapper.createRuntime();
+ runtime.start();
+
+ // initialize the runtime info
+ CompositeComponent parent = runtime.getSystemComponent();
+ RuntimeInfo runtimeInfo = new LauncherRuntimeInfo(getInstallDirectory(), getApplicationRootDirectory(), true);
+ parent.registerJavaObject("RuntimeInfo", RuntimeInfo.class, runtimeInfo);
+
+ // register the monitor factory
+ if (monitor instanceof FormatterRegistry) {
+ List<Class<?>> interfazes = new ArrayList<Class<?>>(2);
+ interfazes.add(MonitorFactory.class);
+ interfazes.add(FormatterRegistry.class);
+ parent.registerJavaObject("MonitorFactory", interfazes, monitor);
+ } else {
+ parent.registerJavaObject("MonitorFactory", MonitorFactory.class, monitor);
+ }
+ parent.start();
+ // create a ComponentDefinition to represent the component we are going to deploy
+ SystemCompositeImplementation compositeImplementation = new SystemCompositeImplementation();
+ compositeImplementation.setScdlLocation(systemScdl);
+ compositeImplementation.setClassLoader(systemClassLoader);
+ ComponentDefinition<SystemCompositeImplementation> definition =
+ new ComponentDefinition<SystemCompositeImplementation>(
+ ComponentNames.TUSCANY_SYSTEM, compositeImplementation);
+ try {
+ // deploy the component into the runtime under the system parent
+ composite = (CompositeComponent) bootDeployer.deploy(parent, definition);
+ } catch (TuscanyException e) {
+ e.addContextName(definition.getName());
+ throw e;
+ }
+ // start the system
+ composite.start();
+
+ SCAObject child = composite.getSystemChild(ComponentNames.TUSCANY_DEPLOYER);
+ if (!(child instanceof AtomicComponent)) {
+ throw new InitializationException("Deployer must be an atomic component");
+ }
+ deployer = (Deployer) ((AtomicComponent) child).getTargetInstance();
+ runtime.getRootComponent().start();
+ }
+
+ /**
+ * Shuts down the active runtime being managed by this instance.
+ */
+ public void shutdownRuntime() {
+ if (composite != null) {
+ composite.stop();
+ composite = null;
+ }
+
+ if (runtime != null) {
+ runtime.stop();
+ runtime = null;
+ }
+ }
+
+ /**
+ * Returns the classloader for application classes.
+ *
+ * @return the classloader for application classes
+ */
+ public ClassLoader getApplicationLoader() {
+ return applicationLoader;
+ }
+
+ /**
+ * Set the classloader to be used for application classes. You should almost always supply your own application
+ * classloader, based on the hosting environment that the runtime is embedded in.
+ *
+ * @param applicationLoader the classloader to be used for application classes
+ */
+ public void setApplicationLoader(ClassLoader applicationLoader) {
+ this.applicationLoader = applicationLoader;
+ }
+
+ /**
+ * Boots the runtime defined by the specified SCDL.
+ *
+ * @param systemScdl a resource path to the SCDL defining the system.
+ * @return a CompositeComponent for the newly booted runtime system
+ * @throws LoaderException
+ */
+ @Deprecated
+ public CompositeComponent bootRuntime(URL systemScdl, MonitorFactory monitor) throws TuscanyException {
+ ClassLoader systemClassLoader = getClass().getClassLoader();
+ bootRuntime(systemScdl, systemClassLoader, monitor);
+ return composite;
+ }
+
+ /**
+ * Boots the application defined by the specified SCDL.
+ *
+ * @param name the name of the application component
+ * @param appScdl URL to the SCDL defining the application
+ * @return a CompositeComponent for the newly booted application
+ * @throws LoaderException
+ */
+ @Deprecated
+ public CompositeComponent bootApplication(String name, URL appScdl) throws TuscanyException {
+ ClassLoader applicationLoader = getApplicationLoader();
+
+ if (appScdl == null) {
+ throw new LoaderException("No application scdl found");
+ }
+
+ // create a ComponentDefinition to represent the component we are going to deploy
+ CompositeImplementation impl = new CompositeImplementation();
+ impl.setScdlLocation(appScdl);
+ impl.setClassLoader(applicationLoader);
+ ComponentDefinition<CompositeImplementation> definition =
+ new ComponentDefinition<CompositeImplementation>(name, impl);
+
+ // deploy the component into the runtime under the system parent
+ CompositeComponent parent = runtime.getRootComponent();
+ // FIXME andyp -- this seems bogus when running inside an appserver
+ ClassLoader ccl = Thread.currentThread().getContextClassLoader();
+
+ try {
+
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+ return (CompositeComponent) deployer.deploy(parent, definition);
+ } finally {
+ Thread.currentThread().setContextClassLoader(ccl);
+ }
+ }
+
+ public File getInstallDirectory() {
+ String property = System.getProperty("tuscany.installDir");
+ if (property != null) {
+ return new File(property);
+ }
+
+ // TODO: TUSCANY-648, should this throw an exception if it not running from a jar?
+
+ URL url = getClass().getResource("LauncherImpl.class");
+ String jarLocation = url.toString();
+ if ("jar".equals(url.getProtocol())) {
+ jarLocation = jarLocation.substring(4, jarLocation.lastIndexOf("!/"));
+ }
+ if (jarLocation.startsWith("file:")) {
+ jarLocation = jarLocation.substring(5);
+ }
+
+ File jarFile = new File(jarLocation);
+ return jarFile.getParentFile().getParentFile();
+ }
+
+ public File getApplicationRootDirectory() {
+ String property = System.getProperty("tuscany.applicationRootDir");
+ if (property != null) {
+ return new File(property);
+ }
+
+ return new File(System.getProperty("user.dir"));
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/launcher/LauncherRuntimeInfo.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/launcher/LauncherRuntimeInfo.java
new file mode 100644
index 0000000000..a46631508b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/launcher/LauncherRuntimeInfo.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.core.launcher;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URI;
+
+import org.apache.tuscany.host.RuntimeInfo;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class LauncherRuntimeInfo implements RuntimeInfo {
+
+ /** Install directory */
+ private final File installDirectory;
+
+ /** Application root directory */
+ private final File applicationRootDirectory;
+
+ private final boolean online;
+
+ /**
+ * Initializes the installation and application root directories.
+ *
+ * @param installDirectory Installation directory.
+ * @param applicationRootDirectory Application root directory.
+ */
+ public LauncherRuntimeInfo(File installDirectory, File applicationRootDirectory, boolean online) {
+ this.installDirectory = installDirectory;
+ this.applicationRootDirectory = applicationRootDirectory;
+ this.online = online;
+ }
+
+ public URI getDomain() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Return the directory where the running runtime was installed.
+ *
+ * @return the directory where the runtime was installed
+ */
+ public File getInstallDirectory() {
+ return installDirectory;
+ }
+
+ /**
+ * Return the root directory used to resolve application file paths.
+ *
+ * @return the directory used to resolve application file paths.
+ */
+ public File getApplicationRootDirectory() {
+ return applicationRootDirectory;
+ }
+
+ /**
+ * Gets the base URL for the runtime.
+ *
+ * @return The base URL for the runtime.
+ */
+ public URL getBaseURL() {
+ try {
+ return installDirectory.toURL();
+ } catch (MalformedURLException e) {
+ // TODO Decide on how to handle the exception
+ throw new RuntimeException(e);
+ }
+ }
+
+ public boolean isOnline() {
+ return online;
+ }
+
+ public String getRuntimeId() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ComponentLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ComponentLoader.java
new file mode 100644
index 0000000000..796ec2b77e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ComponentLoader.java
@@ -0,0 +1,524 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+import static org.osoa.sca.Constants.SCA_NS;
+
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.core.binding.local.LocalBindingDefinition;
+import org.apache.tuscany.core.implementation.system.model.SystemImplementation;
+import org.apache.tuscany.core.util.ReferenceLoaderHelper;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.databinding.extension.DOMHelper;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.InvalidReferenceException;
+import org.apache.tuscany.spi.loader.InvalidValueException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.LoaderUtil;
+import org.apache.tuscany.spi.loader.MissingImplementationException;
+import org.apache.tuscany.spi.loader.MissingPropertyValueException;
+import org.apache.tuscany.spi.loader.MissingReferenceException;
+import org.apache.tuscany.spi.loader.PropertyObjectFactory;
+import org.apache.tuscany.spi.loader.ReferenceMultiplicityOverridingException;
+import org.apache.tuscany.spi.loader.ReferenceMultiplicityViolationException;
+import org.apache.tuscany.spi.loader.UndefinedPropertyException;
+import org.apache.tuscany.spi.loader.UndefinedReferenceException;
+import org.apache.tuscany.spi.loader.UnrecognizedElementException;
+import org.apache.tuscany.spi.model.BindingDefinition;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.ComponentReferenceDefinition;
+import org.apache.tuscany.spi.model.ComponentType;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.Implementation;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.model.Multiplicity;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.PropertyValue;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.apache.tuscany.spi.util.stax.StaxUtil;
+import org.osoa.sca.annotations.Constructor;
+import org.w3c.dom.Element;
+
+/**
+ * Loads a component definition from an XML-based assembly file
+ *
+ * @version $Rev$ $Date$
+ */
+public class ComponentLoader extends LoaderExtension<ComponentDefinition<?>> {
+ private static final QName COMPONENT = new QName(SCA_NS, "component");
+
+ private static final QName PROPERTY = new QName(SCA_NS, "property");
+
+ private static final QName REFERENCE = new QName(SCA_NS, "reference");
+
+ private static final String COMPONENT_NAME_ATTR = "name";
+
+ private static final String COMPONENT_INIT_ATTR = "initLevel";
+
+ private static final String AUTOWIRE_ATTR = "autowire";
+
+ private static final String PROPERTY_FILE_ATTR = "file";
+
+ private static final String PROPERTY_SOURCE_ATTR = "source";
+
+ private static final String PROPERTY_NAME_ATTR = "name";
+
+ private static final String PROPERTY_TYPE_ATTR = "type";
+
+ private static final String PROPERTY_ELEMENT_ATTR = "element";
+
+ public static final String REF_NAME_ATTR = "name";
+
+ public static final String REF_MULTIPLICITY_ATTR = "multiplicity";
+
+ public static final String REF_TARGET_ATTR = "target";
+
+ public static final char COLON = ':';
+
+ private PropertyObjectFactory propertyFactory;
+
+ @Constructor
+ public ComponentLoader(@Autowire
+ LoaderRegistry registry, @Autowire
+ PropertyObjectFactory propertyFactory) {
+ super(registry);
+ this.propertyFactory = propertyFactory;
+ }
+
+ public QName getXMLType() {
+ return COMPONENT;
+ }
+
+ @SuppressWarnings("unchecked")
+ public ComponentDefinition<?> load(CompositeComponent parent,
+ ModelObject object,
+ XMLStreamReader reader,
+ DeploymentContext deploymentContext) throws XMLStreamException,
+ LoaderException {
+ assert COMPONENT.equals(reader.getName());
+ String name = reader.getAttributeValue(null, COMPONENT_NAME_ATTR);
+ String initLevel = reader.getAttributeValue(null, COMPONENT_INIT_ATTR);
+ String autowire = reader.getAttributeValue(null, AUTOWIRE_ATTR);
+
+ try {
+ Implementation<?> impl = loadImplementation(parent, reader, deploymentContext);
+ registry.loadComponentType(parent, impl, deploymentContext);
+
+ ComponentDefinition<Implementation<?>> componentDefinition =
+ new ComponentDefinition<Implementation<?>>(name, impl);
+ if (autowire != null) {
+ componentDefinition.setAutowire(Boolean.parseBoolean(autowire));
+ } else {
+ if (object instanceof CompositeComponentType) {
+ componentDefinition.setAutowire(((CompositeComponentType)object).isAutowire());
+ }
+ }
+
+ if (initLevel != null) {
+ if (initLevel.length() == 0) {
+ componentDefinition.setInitLevel(0);
+ } else {
+ try {
+ componentDefinition.setInitLevel(Integer.valueOf(initLevel));
+ } catch (NumberFormatException e) {
+ throw new InvalidValueException(initLevel, "initValue", e);
+ }
+ }
+ }
+
+ while (true) {
+ switch (reader.next()) {
+ case START_ELEMENT:
+ QName qname = reader.getName();
+ if (PROPERTY.equals(qname)) {
+ loadProperty(reader, deploymentContext, componentDefinition);
+ } else if (REFERENCE.equals(qname)) {
+ loadReference(parent, reader, deploymentContext, componentDefinition);
+ } else {
+ throw new UnrecognizedElementException(qname);
+ }
+ //reader.next();
+ break;
+ case END_ELEMENT:
+ if (reader.getName().equals(COMPONENT)) {
+ // hack to leave alone SystemImplementation
+ if (!((Implementation)componentDefinition.getImplementation() instanceof SystemImplementation)) {
+ populatePropertyValues(componentDefinition);
+ }
+ populateReferences(componentDefinition);
+ /*ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> type =
+ (ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>)componentDefinition
+ .getImplementation().getComponentType();
+ for (ReferenceDefinition ref : type.getReferences().values()) {
+ if (ref.isAutowire()) {
+ ReferenceTarget referenceTarget = new ReferenceTarget();
+ referenceTarget.setReferenceName(ref.getName());
+ componentDefinition.add(referenceTarget);
+ }
+ }*/
+ //validate(componentDefinition);
+ return componentDefinition;
+ }
+ break;
+ }
+ }
+ } catch (LoaderException e) {
+ e.addContextName(name);
+ throw e;
+ }
+ }
+
+ protected Implementation<?> loadImplementation(CompositeComponent parent,
+ XMLStreamReader reader,
+ DeploymentContext deploymentContext) throws XMLStreamException,
+ LoaderException {
+ reader.nextTag();
+ ModelObject o = registry.load(parent, null, reader, deploymentContext);
+ if (!(o instanceof Implementation)) {
+ throw new MissingImplementationException();
+ }
+ return (Implementation<?>)o;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void loadProperty(XMLStreamReader reader,
+ DeploymentContext deploymentContext,
+ ComponentDefinition<?> componentDefinition) throws XMLStreamException,
+ LoaderException {
+ String name = reader.getAttributeValue(null, PROPERTY_NAME_ATTR);
+ Implementation<?> implementation = componentDefinition.getImplementation();
+ ComponentType<?, ?, ?> componentType = implementation.getComponentType();
+ Property<Type> property = componentType.getProperty(name);
+ if (property == null) {
+ throw new UndefinedPropertyException(name);
+ }
+
+ PropertyValue<Type> propertyValue;
+ readPropertyType(reader, property);
+
+ String source = reader.getAttributeValue(null, PROPERTY_SOURCE_ATTR);
+ String file = reader.getAttributeValue(null, PROPERTY_FILE_ATTR);
+
+ if (source != null || file != null) {
+ propertyValue = new PropertyValue<Type>(name, source, file);
+ propertyValue.setValue(property.getDefaultValues());
+ LoaderUtil.skipToEndElement(reader);
+ } else {
+ try {
+ DocumentBuilder documentBuilder = DOMHelper.newDocumentBuilder();
+ List<Element> values =
+ StaxUtil.createPropertyValues(reader, property.getXmlType(), property
+ .getXmlElement(), property.isMany(), documentBuilder);
+ propertyValue = new PropertyValue<Type>(name, values);
+ if (!property.isMany() && values.size() > 1) {
+ ManyPropertyValueLoaderException ex = new ManyPropertyValueLoaderException();
+ ex.setPropertyName(name);
+ ex.setLine(reader.getLocation().getLineNumber());
+ ex.setColumn(reader.getLocation().getColumnNumber());
+ throw ex;
+ }
+ } catch (ParserConfigurationException e) {
+ throw new LoaderException(e);
+ }
+ }
+
+ ObjectFactory<?> objectFactory = null;
+ if (property.isMany()) {
+ objectFactory = propertyFactory.createListObjectFactory(property, propertyValue);
+ } else {
+ objectFactory = propertyFactory.createObjectFactory(property, propertyValue);
+ }
+ // propertyValue.setValueFactory(new
+ // SimplePropertyObjectFactory(property, propertyValue.getValue()));
+ propertyValue.setValueFactory(objectFactory);
+ componentDefinition.add(propertyValue);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void loadReference(CompositeComponent parent,
+ XMLStreamReader reader,
+ DeploymentContext deploymentContext,
+ ComponentDefinition<?> componentDefinition) throws XMLStreamException,
+ LoaderException {
+
+ ComponentReferenceDefinition componentReference = null;
+ Implementation<?> impl = componentDefinition.getImplementation();
+ ComponentType<?, ComponentTypeReferenceDefinition, ?> componentType =
+ impl.getComponentType();
+
+ String name = reader.getAttributeValue(null, REF_NAME_ATTR);
+
+ if (name == null) {
+ throw new InvalidReferenceException("No name specified");
+ } else if (!componentType.getReferences().containsKey(name)) {
+ throw new UndefinedReferenceException(name);
+ } else {
+ componentReference =
+ new ComponentReferenceDefinition(componentType.getReferences().get(name));
+ }
+
+ String multiplicityVal = reader.getAttributeValue(null, REF_MULTIPLICITY_ATTR);
+ Multiplicity multiplicity =
+ StaxUtil.multiplicity(multiplicityVal, componentType.getReferences().get(name)
+ .getMultiplicity());
+ if (!ReferenceLoaderHelper.isValidMultiplicityOverride(componentType.getReferences()
+ .get(name).getMultiplicity(), multiplicity)) {
+ throw new ReferenceMultiplicityOverridingException(name, componentType.getReferences()
+ .get(name).getMultiplicity(), multiplicity);
+ } else {
+ componentReference.setMultiplicity(multiplicity);
+ }
+
+ String autowire = reader.getAttributeValue(null, AUTOWIRE_ATTR);
+ if (autowire == null) {
+ componentReference.setAutowire(componentDefinition.isAutowire());
+ } else {
+ componentReference.setAutowire(Boolean.parseBoolean(autowire));
+ }
+
+ String targets = reader.getAttributeValue(null, REF_TARGET_ATTR);
+ if (targets != null && targets.length() > 0) {
+ ReferenceLoaderHelper.populateRefTargets(componentReference, targets);
+ /*if (!ReferenceLoaderHelper.validateMultiplicityAndTargets(multiplicity,
+ componentReference
+ .getTargets())) {
+ throw new ReferenceMultiplicityViolationException(name,
+ multiplicity,
+ componentReference
+ .getTargets().size());
+ }*/
+ }
+
+ ComponentTypeReferenceDefinition ctReference = componentType.getReferences().get(name);
+ boolean isBindingsOverriden = false;
+ while (true) {
+ switch (reader.next()) {
+ case START_ELEMENT:
+ ModelObject o = registry.load(parent, null, reader, deploymentContext);
+ if (o instanceof ServiceContract) {
+ ServiceContract overridenSvcContract = (ServiceContract)o;
+ ServiceContract implSvcContract = ctReference.getServiceContract();
+ //TODO : Since the JavaInterfaceProcessorRegistryImpl does not do a deep introspection
+ //this comparison is not possible. This will be uncommented once that is fixed.
+ /*ReferenceLoaderHelper.checkInterfaceCompatibility(implSvcContract,
+ overridenSvcContract,
+ false);*/
+ componentReference.setServiceContract(overridenSvcContract);
+ } else if (o instanceof BindingDefinition) {
+ componentReference.addBinding((BindingDefinition)o);
+ isBindingsOverriden = true;
+ } else {
+ throw new UnrecognizedElementException(reader.getName());
+ }
+ //reader.next();
+ break;
+ case END_ELEMENT:
+ if (REFERENCE.equals(reader.getName())) {
+ if (componentType instanceof CompositeComponentType) {
+ //AbstractReferenceDefinition definition = componentType.getReferences().get(name);
+ //if there were targets overridden, then its better to copy the componentType
+ //bindings from the underlying componentType and set the overriden target
+ if (targets != null && targets.length() > 0) {
+ if (componentReference.getBindings().isEmpty()) {
+ for (URI targetUri : componentReference.getTargets()) {
+ // TODO JFM allow selection of a default binding
+ LocalBindingDefinition binding =
+ new LocalBindingDefinition(targetUri);
+ componentReference.addBinding(binding);
+ //HACK [svkrish]: to get composite implementations working.. not sure
+ //why the componentType should be updated for bindings and targets
+ componentReference.getAssociatedCompTypeRefDefn()
+ .addBinding(binding);
+ }
+ } else {
+ for (URI targetUri : componentReference.getTargets()) {
+ if (isBindingsOverriden) {
+ for (BindingDefinition binding : componentReference
+ .getBindings()) {
+ binding.setTargetUri(targetUri);
+ }
+ } else {
+ BindingDefinition clone = null;
+ for (BindingDefinition binding : componentReference
+ .getAssociatedCompTypeRefDefn().getBindings()) {
+ clone = (BindingDefinition)binding.clone();
+ clone.setTargetUri(targetUri);
+ componentReference.addBinding(clone);
+ //HACK [svkrish]: to get composite implementations working.. not sure
+ //why the componentType should be updated for bindings and targets
+ binding.setTargetUri(targetUri);
+ }
+ }
+ }
+ }
+ }
+ }
+ componentDefinition.add(componentReference);
+ return;
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void populatePropertyValues(ComponentDefinition<Implementation<?>> componentDefinition) throws LoaderException,
+ MissingPropertyValueException {
+ ComponentType componentType = componentDefinition.getImplementation().getComponentType();
+ if (componentType != null) {
+ Map<String, Property<?>> properties = componentType.getProperties();
+ Map<String, PropertyValue<?>> propertyValues = componentDefinition.getPropertyValues();
+
+ for (Property<?> aProperty : properties.values()) {
+ if (propertyValues.get(aProperty.getName()) == null) {
+ if (aProperty.isMustSupply()) {
+ throw new MissingPropertyValueException(aProperty.getName());
+ } else if (aProperty.getDefaultValues() != null) {
+ PropertyValue propertyValue = new PropertyValue();
+ propertyValue.setName(aProperty.getName());
+ propertyValue.setValue(aProperty.getDefaultValues());
+ propertyValue.setValueFactory(propertyFactory
+ .createObjectFactory(aProperty, propertyValue));
+ /*
+ * propertyValue.setValueFactory(new SimplePropertyObjectFactory(aProperty,
+ * propertyValue.getValue()));
+ */
+ propertyValues.put(aProperty.getName(), propertyValue);
+ }
+ }
+ }
+ }
+ }
+
+ private void readPropertyType(XMLStreamReader reader, Property property) throws MissingTypePropertyLoaderException {
+
+ String typeName = reader.getAttributeValue(null, PROPERTY_TYPE_ATTR);
+ String elementName = reader.getAttributeValue(null, PROPERTY_ELEMENT_ATTR);
+ QName xmlElement = null;
+ QName xmlType = null;
+
+ if (typeName != null) {
+ int index = typeName.indexOf(COLON);
+ if (index != -1) {
+ String prefix = typeName.substring(0, index);
+ String localName = typeName.substring(index + 1);
+ String ns = reader.getNamespaceURI(prefix);
+ xmlType = new QName(ns, localName, prefix);
+ }
+ } else if (elementName != null) {
+ int index = elementName.indexOf(COLON);
+ if (index != -1) {
+ String prefix = elementName.substring(0, index);
+ String localName = elementName.substring(index + 1);
+ String ns = reader.getNamespaceURI(prefix);
+ xmlElement = new QName(ns, localName, prefix);
+ // FIXME :
+ // need to figure out how to determine the xmltype from this
+ // xmlelement
+ // this need access to the global xml element thro
+ // schemalocation or thro
+ // artifact repository
+ xmlType = null;
+ }
+ }
+
+ if (xmlType != null) {
+ property.setXmlType(xmlType);
+ }
+
+ if (xmlElement != null) {
+ property.setXmlElement(xmlElement);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void populateReferences(ComponentDefinition<Implementation<?>> componentDefinition) {
+ //bring the component definition in sync with the componenttype for reference definitions
+ ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> componentType =
+ componentDefinition.getImplementation().getComponentType();
+
+ for (ComponentTypeReferenceDefinition refDefn : componentType.getReferences().values()) {
+ if (componentDefinition.getReferences().get(refDefn.getName()) == null) {
+ componentDefinition.add(new ComponentReferenceDefinition(refDefn));
+ }
+ }
+ }
+
+ /**
+ * Validates a component definition, ensuring all component type configuration elements are satisfied
+ */
+ protected void validate(ComponentDefinition<Implementation<?>> definition) throws LoaderException {
+ // validate refererences
+ Implementation<?> implementation = definition.getImplementation();
+ ComponentType<?, ?, ?> type = implementation.getComponentType();
+ if (type == null) {
+ return;
+ }
+ for (ComponentReferenceDefinition referenceDef : definition.getReferences().values()) {
+ if (referenceDef.isAutowire()) {
+ continue;
+ }
+ String name = referenceDef.getName();
+ List<URI> targets = definition.getReferences().get(name).getTargets();
+ if (targets == null) {
+ throw new MissingReferenceException(name);
+ }
+ int count = targets.size();
+ Multiplicity multiplicity = referenceDef.getMultiplicity();
+ switch (multiplicity) {
+ case ZERO_N:
+ break;
+ case ZERO_ONE:
+ if (count > 1) {
+ throw new ReferenceMultiplicityViolationException(name, multiplicity, count);
+ }
+ break;
+ case ONE_ONE:
+ if (count != 1) {
+ throw new ReferenceMultiplicityViolationException(name, multiplicity, count);
+ }
+ break;
+ case ONE_N:
+ if (count < 1) {
+ throw new ReferenceMultiplicityViolationException(name, multiplicity, count);
+ }
+ break;
+ }
+
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ComponentTypeElementLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ComponentTypeElementLoader.java
new file mode 100644
index 0000000000..5313f32aa1
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ComponentTypeElementLoader.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+import static org.osoa.sca.Constants.SCA_NS;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.ComponentType;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.osoa.sca.annotations.Constructor;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ComponentTypeElementLoader extends LoaderExtension<ComponentType> {
+ public static final QName COMPONENT_TYPE = new QName(SCA_NS, "componentType");
+
+ @Constructor
+ public ComponentTypeElementLoader(@Autowire LoaderRegistry registry) {
+ super(registry);
+ }
+
+ public QName getXMLType() {
+ return COMPONENT_TYPE;
+ }
+
+ @SuppressWarnings("unchecked")
+ public ComponentType load(CompositeComponent parent,
+ ModelObject object,
+ XMLStreamReader reader,
+ DeploymentContext deploymentContext) throws XMLStreamException, LoaderException {
+ assert COMPONENT_TYPE.equals(reader.getName());
+ ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> componentType;
+ if (object != null) {
+ assert object instanceof ComponentType;
+ // a specialized component type was passed in
+ componentType = (ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>) object;
+ } else {
+ componentType = new ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ }
+
+ while (true) {
+ switch (reader.next()) {
+ case START_ELEMENT:
+ ModelObject o = registry.load(parent, componentType, reader, deploymentContext);
+ if (o instanceof ServiceDefinition) {
+ componentType.add((ServiceDefinition) o);
+ } else if (o instanceof ComponentTypeReferenceDefinition) {
+ componentType.add((ComponentTypeReferenceDefinition) o);
+ } else if (o instanceof Property) {
+ componentType.add((Property<?>) o);
+ }
+ break;
+ case END_ELEMENT:
+ return componentType;
+ }
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/DefaultPropertyValueLoaderException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/DefaultPropertyValueLoaderException.java
new file mode 100644
index 0000000000..adcde47dda
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/DefaultPropertyValueLoaderException.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+
+/**
+ * Root unchecked exception for the injection package
+ *
+ * @version $Rev: 487057 $ $Date: 2006-12-14 12:50:44 +0530 (Thu, 14 Dec 2006) $
+ */
+public class DefaultPropertyValueLoaderException extends PropertyLoaderException {
+
+ public DefaultPropertyValueLoaderException() {
+ super("Default Property Value must be supplied only when 'mustSupply' attribute is set to 'false'");
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/DependencyLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/DependencyLoader.java
new file mode 100644
index 0000000000..66aafb6525
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/DependencyLoader.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.UnrecognizedElementException;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.services.artifact.Artifact;
+
+import org.apache.tuscany.core.implementation.composite.Dependency;
+
+/**
+ * Loader for handling <dependency> elements.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DependencyLoader extends LoaderExtension<Dependency> {
+ private static final String NS = "http://tuscany.apache.org/xmlns/1.0-SNAPSHOT";
+ private static final QName DEPENDENCY = new QName(NS, "dependency");
+ private static final QName GROUP = new QName(NS, "group");
+ private static final QName NAME = new QName(NS, "name");
+ private static final QName VERSION = new QName(NS, "version");
+ private static final QName CLASSIFIER = new QName(NS, "classifier");
+ private static final QName TYPE = new QName(NS, "type");
+
+ public DependencyLoader(@Autowire LoaderRegistry registry) {
+ super(registry);
+ }
+
+ public QName getXMLType() {
+ return DEPENDENCY;
+ }
+
+ public Dependency load(CompositeComponent parent,
+ ModelObject object,
+ XMLStreamReader reader,
+ DeploymentContext deploymentContext)
+ throws XMLStreamException, LoaderException {
+
+ Artifact artifact = new Artifact();
+ while (reader.nextTag() == XMLStreamConstants.START_ELEMENT) {
+ QName name = reader.getName();
+ String text = reader.getElementText();
+ if (GROUP.equals(name)) {
+ artifact.setGroup(text);
+ } else if (NAME.equals(name)) {
+ artifact.setName(text);
+ } else if (VERSION.equals(name)) {
+ artifact.setVersion(text);
+ } else if (CLASSIFIER.equals(name)) {
+ artifact.setClassifier(text);
+ } else if (TYPE.equals(name)) {
+ artifact.setType(text);
+ } else {
+ throw new UnrecognizedElementException(name);
+ }
+ }
+ Dependency dependency = new Dependency();
+ dependency.setArtifact(artifact);
+ return dependency;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/IncludeLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/IncludeLoader.java
new file mode 100644
index 0000000000..c1de002936
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/IncludeLoader.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import static org.osoa.sca.Constants.SCA_NS;
+import org.osoa.sca.annotations.Constructor;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.LoaderUtil;
+import org.apache.tuscany.spi.loader.MissingIncludeException;
+import org.apache.tuscany.spi.loader.MissingResourceException;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.Include;
+import org.apache.tuscany.spi.model.ModelObject;
+
+import org.apache.tuscany.core.deployer.ChildDeploymentContext;
+
+/**
+ * Loader that handles &lt;include&gt; elements.
+ *
+ * @version $Rev$ $Date$
+ */
+public class IncludeLoader extends LoaderExtension<Include> {
+ private static final QName INCLUDE = new QName(SCA_NS, "include");
+
+ @Constructor({"registry"})
+ public IncludeLoader(@Autowire LoaderRegistry registry) {
+ super(registry);
+ }
+
+ public QName getXMLType() {
+ return INCLUDE;
+ }
+
+ public Include load(CompositeComponent parent, ModelObject object, XMLStreamReader reader,
+ DeploymentContext deploymentContext)
+ throws XMLStreamException, LoaderException {
+
+ assert INCLUDE.equals(reader.getName());
+ String name = reader.getAttributeValue(null, "name");
+ String scdlLocation = reader.getAttributeValue(null, "scdlLocation");
+ String scdlResource = reader.getAttributeValue(null, "scdlResource");
+ LoaderUtil.skipToEndElement(reader);
+
+ ClassLoader cl = deploymentContext.getClassLoader();
+ URL url;
+ if (scdlLocation != null) {
+ try {
+ url = new URL(deploymentContext.getScdlLocation(), scdlLocation);
+ } catch (MalformedURLException e) {
+ throw new MissingResourceException(scdlLocation, name, e);
+ }
+ } else if (scdlResource != null) {
+ url = cl.getResource(scdlResource);
+ if (url == null) {
+ throw new MissingResourceException(scdlResource, name);
+ }
+ } else {
+ throw new MissingIncludeException("No SCDL location or resource specified", name);
+ }
+
+ DeploymentContext childContext = new ChildDeploymentContext(deploymentContext, cl, url);
+ CompositeComponentType composite;
+ try {
+ composite = loadFromSidefile(parent, url, childContext);
+ } catch (LoaderException e) {
+ e.addContextName(name);
+ throw e;
+ }
+
+ Include include = new Include();
+ include.setName(name);
+ include.setScdlLocation(url);
+ include.setIncluded(composite);
+ return include;
+ }
+
+ protected CompositeComponentType loadFromSidefile(CompositeComponent parent,
+ URL url,
+ DeploymentContext deploymentContext)
+ throws LoaderException {
+ return registry.load(parent, null, url, CompositeComponentType.class, deploymentContext);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/JNDIPropertyFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/JNDIPropertyFactory.java
new file mode 100644
index 0000000000..32678a6179
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/JNDIPropertyFactory.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.PropertyObjectFactory;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.PropertyValue;
+
+import org.apache.tuscany.core.injection.JNDIListObjectFactory;
+import org.apache.tuscany.core.injection.JNDIObjectFactory;
+
+/**
+ * A StAXPropertyFactory that creates property values by looking them up in the default JNDI InitialContext. <p/> This
+ * can be used to locate resources in a J2EE environment and inject them as configuration properties. For example, to
+ * access a database a component could write: <code> &at;Property DataSource myDB; </code> and configure with <code>
+ * &lt;properties&gt; &lt;v:myDb&gt;java:comp/env/jdbc/MyDatabase&lt;/v:myDB&gt; &lt;/properties&gt; </code>
+ *
+ * @version $Rev$ $Date$
+ */
+public class JNDIPropertyFactory implements PropertyObjectFactory {
+ public <T> ObjectFactory<T> createObjectFactory(Property<T> property, PropertyValue<T> value)
+ throws LoaderException {
+ String text = value.getValue().get(0).getTextContent();
+ try {
+ Context context = new InitialContext();
+ return new JNDIObjectFactory<T>(context, text);
+ } catch (NamingException e) {
+ throw new LoaderException(e);
+ }
+ }
+
+ public <T> ObjectFactory<List<T>> createListObjectFactory(Property<T> property, PropertyValue<T> value)
+ throws LoaderException {
+ try {
+ List<T> instances = new ArrayList<T>();
+ Context context = new InitialContext();
+ List<String> text = new ArrayList<String>();
+ for (int count = 0 ; count < instances.size() ; ++count) {
+ text.add(value.getValue().get(count).getTextContent());
+ }
+ return new JNDIListObjectFactory<T>(context, text);
+ } catch (NamingException e) {
+ throw new LoaderException(e);
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/LoaderExceptionFormatter.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/LoaderExceptionFormatter.java
new file mode 100644
index 0000000000..4fad10c95f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/LoaderExceptionFormatter.java
@@ -0,0 +1,50 @@
+package org.apache.tuscany.core.loader;
+
+import java.io.PrintWriter;
+
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.EagerInit;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.loader.LoaderException;
+
+import org.apache.tuscany.host.monitor.ExceptionFormatter;
+import org.apache.tuscany.host.monitor.FormatterRegistry;
+
+/**
+ * Formats {@link org.apache.tuscany.spi.loader.LoaderException} events
+ *
+ * @version $Rev$ $Date$
+ */
+@EagerInit
+public class LoaderExceptionFormatter implements ExceptionFormatter {
+ private FormatterRegistry factory;
+
+ public LoaderExceptionFormatter(@Autowire FormatterRegistry factory) {
+ this.factory = factory;
+ factory.register(this);
+ }
+
+ public boolean canFormat(Class<?> type) {
+ return LoaderException.class.isAssignableFrom(type);
+ }
+
+ @Destroy
+ public void destroy() {
+ factory.unregister(this);
+ }
+
+ public PrintWriter write(PrintWriter writer, Throwable exception) {
+ assert exception instanceof LoaderException;
+ LoaderException e = (LoaderException) exception;
+ e.appendBaseMessage(writer);
+ if (e.getLine() != LoaderException.UNDEFINED) {
+ writer.write("\nLine: " + e.getLine() + "\n");
+ writer.write("Column: " + e.getColumn());
+ } else {
+ writer.write("\n");
+ }
+ e.appendContextStack(writer).append("\n");
+ return writer;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/LoaderRegistryImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/LoaderRegistryImpl.java
new file mode 100644
index 0000000000..69c182cb6d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/LoaderRegistryImpl.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.osoa.sca.annotations.EagerInit;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.loader.ComponentTypeLoader;
+import org.apache.tuscany.spi.loader.InvalidConfigurationException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.StAXElementLoader;
+import org.apache.tuscany.spi.loader.UnrecognizedComponentTypeException;
+import org.apache.tuscany.spi.loader.UnrecognizedElementException;
+import org.apache.tuscany.spi.model.Implementation;
+import org.apache.tuscany.spi.model.ModelObject;
+
+/**
+ * The default implementation of a loader registry
+ *
+ * @version $Rev$ $Date$
+ */
+@EagerInit
+public class LoaderRegistryImpl implements LoaderRegistry {
+ private Monitor monitor;
+ private final Map<QName, StAXElementLoader<? extends ModelObject>> loaders =
+ new HashMap<QName, StAXElementLoader<? extends ModelObject>>();
+ private final Map<Class<? extends Implementation<?>>,
+ ComponentTypeLoader<? extends Implementation<?>>> componentTypeLoaders =
+ new HashMap<Class<? extends Implementation<?>>, ComponentTypeLoader<? extends Implementation<?>>>();
+
+ public LoaderRegistryImpl(@org.apache.tuscany.api.annotation.Monitor Monitor monitor) {
+ this.monitor = monitor;
+ }
+
+ public <T extends ModelObject> void registerLoader(QName element, StAXElementLoader<T> loader) {
+ monitor.registeringLoader(element);
+ loaders.put(element, loader);
+ }
+
+ public <T extends ModelObject> void unregisterLoader(QName element, StAXElementLoader<T> loader) {
+ monitor.unregisteringLoader(element);
+ loaders.remove(element);
+ }
+
+ public ModelObject load(CompositeComponent parent,
+ ModelObject object,
+ XMLStreamReader reader,
+ DeploymentContext deploymentContext) throws XMLStreamException, LoaderException {
+ QName name = reader.getName();
+ monitor.elementLoad(name);
+ StAXElementLoader<? extends ModelObject> loader = loaders.get(name);
+ if (loader == null) {
+ throw new UnrecognizedElementException(name);
+ }
+ return loader.load(parent, object, reader, deploymentContext);
+ }
+
+ public <MO extends ModelObject> MO load(CompositeComponent parent,
+ ModelObject object,
+ URL url,
+ Class<MO> type,
+ DeploymentContext ctx) throws LoaderException {
+ try {
+ XMLStreamReader reader;
+ InputStream is;
+ is = url.openStream();
+ try {
+ XMLInputFactory factory = ctx.getXmlFactory();
+ reader = factory.createXMLStreamReader(is);
+ try {
+ reader.nextTag();
+ QName name = reader.getName();
+ ModelObject mo = load(parent, object, reader, ctx);
+ if (type.isInstance(mo)) {
+ return type.cast(mo);
+ } else {
+ UnrecognizedElementException e = new UnrecognizedElementException(name);
+ e.setResourceURI(url.toString());
+ throw e;
+ }
+ } catch (LoaderException e) {
+ Location location = reader.getLocation();
+ e.setLine(location.getLineNumber());
+ e.setColumn(location.getColumnNumber());
+ throw e;
+ } finally {
+ try {
+ reader.close();
+ } catch (XMLStreamException e) {
+ // ignore
+ }
+ }
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ } catch (IOException e) {
+ LoaderException sfe = new LoaderException(e);
+ sfe.setResourceURI(url.toString());
+ throw sfe;
+ } catch (XMLStreamException e) {
+ throw new InvalidConfigurationException("Invalid or missing resource", url.toString(), e);
+ }
+ }
+
+ public <I extends Implementation<?>> void registerLoader(Class<I> key, ComponentTypeLoader<I> loader) {
+ componentTypeLoaders.put(key, loader);
+ }
+
+ public <I extends Implementation<?>> void unregisterLoader(Class<I> key) {
+ componentTypeLoaders.remove(key);
+ }
+
+ @SuppressWarnings("unchecked")
+ public <I extends Implementation<?>> void loadComponentType(CompositeComponent parent,
+ I implementation,
+ DeploymentContext deploymentContext)
+ throws LoaderException {
+ Class<I> key = (Class<I>) implementation.getClass();
+ ComponentTypeLoader<I> loader = (ComponentTypeLoader<I>) componentTypeLoaders.get(key);
+ if (loader == null) {
+ throw new UnrecognizedComponentTypeException(key);
+ }
+ try {
+ loader.load(parent, implementation, deploymentContext);
+ } catch ( Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static interface Monitor {
+ /**
+ * Event emitted when a StAX element loader is registered.
+ *
+ * @param xmlType the QName of the element the loader will handle
+ */
+ void registeringLoader(QName xmlType);
+
+ /**
+ * Event emitted when a StAX element loader is unregistered.
+ *
+ * @param xmlType the QName of the element the loader will handle
+ */
+ void unregisteringLoader(QName xmlType);
+
+ /**
+ * Event emitted when a request is made to load an element.
+ *
+ * @param xmlType the QName of the element that should be loaded
+ */
+ void elementLoad(QName xmlType);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ManyPropertyValueLoaderException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ManyPropertyValueLoaderException.java
new file mode 100644
index 0000000000..e0893994a8
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ManyPropertyValueLoaderException.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+
+/**
+ * Root unchecked exception for the injection package
+ *
+ * @version $Rev: 487057 $ $Date: 2006-12-14 12:50:44 +0530 (Thu, 14 Dec 2006) $
+ */
+public class ManyPropertyValueLoaderException extends PropertyLoaderException {
+
+ public ManyPropertyValueLoaderException() {
+ super("Multiple property values may be supplied only if 'many' attribute is set to 'true'");
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/MissingTypePropertyLoaderException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/MissingTypePropertyLoaderException.java
new file mode 100644
index 0000000000..9ec0ac2a68
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/MissingTypePropertyLoaderException.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+
+/**
+ * Root unchecked exception for the injection package
+ *
+ * @version $Rev: 487057 $ $Date: 2006-12-14 12:50:44 +0530 (Thu, 14 Dec 2006) $
+ */
+public class MissingTypePropertyLoaderException extends PropertyLoaderException {
+
+ public MissingTypePropertyLoaderException() {
+ super("Property type missing - either one of 'type' or 'element' must be specified ");
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/PolicySetLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/PolicySetLoader.java
new file mode 100644
index 0000000000..7f9df442e5
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/PolicySetLoader.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.namespace.QName;
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import static org.osoa.sca.Constants.SCA_NS;
+import org.osoa.sca.annotations.Constructor;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.LoaderUtil;
+import org.apache.tuscany.spi.model.IntentMap;
+import org.apache.tuscany.spi.model.IntentName;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.model.PolicySet;
+import org.apache.tuscany.spi.model.PolicySetReference;
+import org.apache.tuscany.spi.model.Qualifier;
+import org.apache.tuscany.spi.model.WSPolicyAttachment;
+
+/**
+ * Loads a PolicySet definition from an SCDL file.
+ *
+ * @version $Rev$ $Date$
+ */
+public class PolicySetLoader extends LoaderExtension<PolicySet> {
+
+ private static final String WSPOLICY_NAMESPACE = "http://schemas.xmlsoap.org/ws/2004/09/policy";
+
+ private static final QName POLICYSET = new QName(SCA_NS, "policySet");
+
+ private static final QName INTENTMAP = new QName(SCA_NS, "intentMap");
+
+ private static final QName QUALIFIER = new QName(SCA_NS, "qualifier");
+
+ private static final QName POLICYSETREFERENCE = new QName(SCA_NS, "policySetReference");
+
+ private static final QName WSPOLICYATTACHMENT = new QName(WSPOLICY_NAMESPACE, "PolicyAttachment");
+
+ @Constructor({"registry"})
+ public PolicySetLoader(@Autowire LoaderRegistry registry) {
+ super(registry);
+
+ }
+
+ @Override
+ public QName getXMLType() {
+ return POLICYSET;
+ }
+
+ public PolicySet load(CompositeComponent parent, ModelObject object, XMLStreamReader reader,
+ DeploymentContext deploymentContext)
+ throws XMLStreamException {
+ assert POLICYSET.equals(reader.getName());
+ String name = reader.getAttributeValue(null, "name");
+ String provides = reader.getAttributeValue(null, "provides");
+ String appliesTo = reader.getAttributeValue(null, "appliesTo");
+ PolicySet policySet = new PolicySet(new QName(SCA_NS, name), parseIntentName(provides));
+ String[] appliesToArtifact = split(appliesTo);
+ for (String artifact : appliesToArtifact) {
+ policySet.addAppliedArtifacts(new QName(SCA_NS, artifact));
+ }
+ while (true) {
+ switch (reader.next()) {
+ case START_ELEMENT:
+ QName qname = reader.getName();
+ if (INTENTMAP.equals(qname)) {
+ policySet.addIntentMap(loadIntentMap(reader, deploymentContext));
+ } else if (POLICYSETREFERENCE.equals(qname)) {
+ policySet.addPolicySetReference(loadPolicyReference(reader, deploymentContext));
+ } else if (WSPOLICYATTACHMENT.equals(qname)) {
+ policySet.addWsPolicyAttachment(loadWSPolicyAttachment(reader, deploymentContext));
+ }
+
+ reader.next();
+ break;
+ case END_ELEMENT:
+ if (reader.getName().equals(POLICYSET)) {
+ return policySet;
+ }
+ break;
+ }
+ }
+
+ }
+
+ private PolicySetReference loadPolicyReference(XMLStreamReader reader, DeploymentContext deploymentContext)
+ throws XMLStreamException {
+ assert POLICYSETREFERENCE.equals(reader.getName());
+ String name = reader.getAttributeValue(null, "name");
+ LoaderUtil.skipToEndElement(reader);
+ return new PolicySetReference(new QName(SCA_NS, name));
+ }
+
+ private IntentMap loadIntentMap(XMLStreamReader reader, DeploymentContext deploymentContext)
+ throws XMLStreamException {
+ assert INTENTMAP.equals(reader.getName());
+ String defaultIntentAttr = reader.getAttributeValue(null, "default");
+ String provides = reader.getAttributeValue(null, "provides");
+ IntentMap intentMap = new IntentMap(defaultIntentAttr, java.util.Arrays.asList(split(provides)));
+ //parentPolicySet.addIntentMap(intentMap);
+
+ while (true) {
+ switch (reader.next()) {
+ case START_ELEMENT:
+ QName qname = reader.getName();
+ if (QUALIFIER.equals(qname)) {
+ intentMap.addQualifier(loadQualifier(reader, deploymentContext));
+ }
+ reader.next();
+ break;
+ case END_ELEMENT:
+ if (reader.getName().equals(INTENTMAP)) {
+ return intentMap;
+ }
+ }
+ }
+
+ }
+
+ private Qualifier loadQualifier(XMLStreamReader reader, DeploymentContext deploymentContext)
+ throws XMLStreamException {
+ assert QUALIFIER.equals(reader.getName());
+ String name = reader.getAttributeValue(null, "name");
+ Qualifier qualifier = new Qualifier(name);
+ while (true) {
+ switch (reader.next()) {
+ case START_ELEMENT:
+ QName qname = reader.getName();
+ if (INTENTMAP.equals(qname)) {
+ qualifier.setIntentMap(loadIntentMap(reader, deploymentContext));
+ } else if (WSPOLICYATTACHMENT.equals(qname)) {
+ qualifier.addWsPolicyAttachment(loadWSPolicyAttachment(reader, deploymentContext));
+ }
+ reader.next();
+ break;
+ case END_ELEMENT:
+ if (reader.getName().equals(QUALIFIER)) {
+ return qualifier;
+ }
+ }
+ }
+
+ }
+
+ private WSPolicyAttachment loadWSPolicyAttachment(XMLStreamReader reader, DeploymentContext deploymentContext)
+ throws XMLStreamException {
+ return new WSPolicyAttachment();
+ }
+
+ /**
+ * Split a string to string array separated by " "
+ */
+ private static String[] split(String string) {
+ if (string == null) {
+ return new String[0];
+ }
+ String[] intents = string.split("[ ]+");
+ return intents;
+ }
+
+ private static List<IntentName> parseIntentName(String attributes) {
+ String[] intents = split(attributes);
+ List<IntentName> result = new ArrayList<IntentName>(intents.length);
+ for (String intent : intents) {
+ result.add(new IntentName(intent));
+ }
+ return result;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/PropertyLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/PropertyLoader.java
new file mode 100644
index 0000000000..41113d1da2
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/PropertyLoader.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import static org.osoa.sca.Constants.SCA_NS;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.util.stax.StaxUtil;
+import org.osoa.sca.annotations.Constructor;
+import org.w3c.dom.Element;
+
+/**
+ * Loads a property from an XML-based assembly file
+ *
+ * @version $Rev$ $Date$
+ */
+public class PropertyLoader extends LoaderExtension<Property> {
+ public static final String PROPERTY_NAME_ATTR = "name";
+ public static final String PROPERTY_TYPE_ATTR = "type";
+ public static final String PROPERTY_ELEMENT_ATTR = "element";
+ public static final String PROPERTY_MANY_ATTR = "many";
+ public static final String PROPERTY_NO_DEFAULT_ATTR = "mustSupply";
+ public static final String DEFAULT_PREFIX = "xs";
+ public static final String DEFAULT_SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
+ public static final char COLON = ':';
+
+ public static final QName PROPERTY = new QName(SCA_NS, "property");
+ private final DocumentBuilder documentBuilder;
+
+ @Constructor( {"registry"})
+ public PropertyLoader(@Autowire
+ LoaderRegistry registry) {
+ super(registry);
+ try {
+ documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ // we should be able to construct the default DocumentBuilder
+ throw new AssertionError(e);
+ }
+ }
+
+ public QName getXMLType() {
+ return PROPERTY;
+ }
+
+ public Property<?> load(CompositeComponent parent,
+ ModelObject object,
+ XMLStreamReader reader,
+ DeploymentContext ctx) throws XMLStreamException,
+ PropertyLoaderException {
+ assert PROPERTY.equals(reader.getName());
+ String name = reader.getAttributeValue(null, PROPERTY_NAME_ATTR);
+ String typeName = reader.getAttributeValue(null, PROPERTY_TYPE_ATTR);
+ String elementName = reader.getAttributeValue(null, PROPERTY_ELEMENT_ATTR);
+ QName xmlElement = null;
+ QName xmlType = null;
+
+ if (typeName != null) {
+ int index = typeName.indexOf(COLON);
+ if (index != -1) {
+ String prefix = typeName.substring(0, index);
+ if (prefix == null || prefix.length() == 0) {
+ prefix = DEFAULT_PREFIX;
+ }
+
+ String localName = typeName.substring(index + 1);
+ String ns = reader.getNamespaceURI(prefix);
+ if (ns == null || ns.length() == 0) {
+ ns = DEFAULT_SCHEMA_NS;
+ }
+ xmlType = new QName(ns, localName, prefix);
+ }
+ } else if (elementName != null) {
+ int index = elementName.indexOf(COLON);
+ if (index != -1) {
+ String prefix = elementName.substring(0, index);
+ String localName = elementName.substring(index + 1);
+ String ns = reader.getNamespaceURI(prefix);
+ xmlElement = new QName(ns, localName, prefix);
+ // FIXME :
+ // need to figure out how to determine the xmltype from this
+ // xmlelement
+ // this need access to the global xml element thro
+ // schemalocation or thro
+ // artifact repository
+ xmlType = null;
+ }
+ }
+
+ if (xmlType == null && xmlElement == null) {
+ MissingTypePropertyLoaderException ex = new MissingTypePropertyLoaderException();
+ ex.setPropertyName(name);
+ ex.setLine(reader.getLocation().getLineNumber());
+ ex.setColumn(reader.getLocation().getColumnNumber());
+ throw ex;
+ }
+
+ boolean many = false;
+ boolean mustSupply = false;
+ String attrValue = null;
+ attrValue = reader.getAttributeValue(null, PROPERTY_MANY_ATTR);
+ if (attrValue != null) {
+ many = Boolean.parseBoolean(attrValue);
+ }
+
+ attrValue = reader.getAttributeValue(null, PROPERTY_NO_DEFAULT_ATTR);
+ if (attrValue != null) {
+ mustSupply = Boolean.parseBoolean(attrValue);
+ }
+
+ List<Element> defaultValues =
+ StaxUtil.createPropertyValues(reader, xmlType, xmlElement, many, documentBuilder);
+
+ if (mustSupply && defaultValues.size() > 0) {
+ DefaultPropertyValueLoaderException ex = new DefaultPropertyValueLoaderException();
+ ex.setPropertyName(name);
+ ex.setLine(reader.getLocation().getLineNumber());
+ ex.setColumn(reader.getLocation().getColumnNumber());
+ throw ex;
+ }
+
+ if (!many && defaultValues.size() > 1) {
+ ManyPropertyValueLoaderException ex = new ManyPropertyValueLoaderException();
+ ex.setPropertyName(name);
+ ex.setLine(reader.getLocation().getLineNumber());
+ ex.setColumn(reader.getLocation().getColumnNumber());
+ throw ex;
+ }
+
+ Property<?> property = new Property();
+ property.setName(name);
+ property.setXmlType(xmlType);
+ property.setXmlElement(xmlElement);
+ property.setMany(many);
+ property.setMustSupply(mustSupply);
+ property.setDefaultValues(defaultValues);
+ return property;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/PropertyLoaderException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/PropertyLoaderException.java
new file mode 100644
index 0000000000..9e08396a68
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/PropertyLoaderException.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import org.apache.tuscany.spi.loader.LoaderException;
+
+/**
+ * Root unchecked exception for the injection package
+ *
+ * @version $Rev: 487057 $ $Date: 2006-12-14 12:50:44 +0530 (Thu, 14 Dec 2006) $
+ */
+public class PropertyLoaderException extends LoaderException {
+
+ private String propertyName;
+
+ public PropertyLoaderException() {
+ super();
+ }
+
+ public PropertyLoaderException(String message) {
+ super(message);
+ }
+
+
+ protected PropertyLoaderException(String message, String identifier) {
+ super(message, identifier);
+ }
+
+ public PropertyLoaderException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ protected PropertyLoaderException(String message, String identifier, Throwable cause) {
+ super(message, identifier, cause);
+ }
+
+ public PropertyLoaderException(Throwable cause) {
+ super(cause);
+ }
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ public void setPropertyName(String propertyName) {
+ this.propertyName = propertyName;
+ }
+
+ public String getMessage() {
+ return super.getMessage() + " in " + getPropertyName();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ReferenceLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ReferenceLoader.java
new file mode 100644
index 0000000000..37acbcbf55
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ReferenceLoader.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+import static org.osoa.sca.Constants.SCA_NS;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.core.util.ReferenceLoaderHelper;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.DuplicateReferenceNameException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.ReferenceMultiplicityViolationException;
+import org.apache.tuscany.spi.loader.UnrecognizedElementException;
+import org.apache.tuscany.spi.model.BindingDefinition;
+import org.apache.tuscany.spi.model.ComponentType;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.CompositeReferenceDefinition;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.model.Multiplicity;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.util.stax.StaxUtil;
+import org.osoa.sca.annotations.Constructor;
+
+/**
+ * Loads a reference from an XML-based assembly file
+ *
+ * @version $Rev$ $Date$
+ */
+public class ReferenceLoader extends LoaderExtension<ComponentTypeReferenceDefinition> {
+ public static final String NAME_ATTR = "name";
+
+ public static final String MULTIPLICITY_ATTR = "multiplicity";
+
+ public static final String WIRED_BY_IMPL_ATTR = "wiredByImpl";
+
+ public static final String TARGET_ATTR = "target";
+
+ public static final String PROMOTE_ATTR = "promote";
+
+ public static final QName REFERENCE = new QName(SCA_NS, "reference");
+
+ @Constructor
+ public ReferenceLoader(@Autowire
+ LoaderRegistry registry) {
+ super(registry);
+ }
+
+ public QName getXMLType() {
+ return REFERENCE;
+ }
+
+ public ComponentTypeReferenceDefinition load(CompositeComponent parent,
+ ModelObject object,
+ XMLStreamReader reader,
+ DeploymentContext deploymentContext) throws XMLStreamException, LoaderException {
+ if (object instanceof CompositeComponentType<?, ?, ?>) {
+ return loadCompositeReference(parent, object, reader, deploymentContext);
+ //return loadComponentType(parent, object, reader, deploymentContext);
+ } else {
+ return loadComponentTypeReference(parent, object, reader, deploymentContext);
+ }
+ }
+
+
+
+ public ComponentTypeReferenceDefinition loadComponentTypeReference(CompositeComponent parent,
+ ModelObject object,
+ XMLStreamReader reader,
+ DeploymentContext deploymentContext) throws XMLStreamException, LoaderException {
+
+ assert REFERENCE.equals(reader.getName());
+ String name = reader.getAttributeValue(null, NAME_ATTR);
+ String multiplicityVal = reader.getAttributeValue(null, MULTIPLICITY_ATTR);
+ String wiredByImpl = reader.getAttributeValue(null, WIRED_BY_IMPL_ATTR);
+ String targets = reader.getAttributeValue(null, TARGET_ATTR);
+ Multiplicity multiplicity = StaxUtil.multiplicity(multiplicityVal, Multiplicity.ONE_ONE);
+
+
+
+ ComponentType<?, ?, ?> componentType = (ComponentType<?, ?, ?>)object;
+ if ( componentType.getReferences().get(name) != null) {
+ throw new DuplicateReferenceNameException(name,
+ DuplicateReferenceNameException.COMPONENT_TYPE,
+ "");
+ }
+ ComponentTypeReferenceDefinition referenceDefinition = new ComponentTypeReferenceDefinition();
+ referenceDefinition.setName(name);
+ referenceDefinition.setMultiplicity(multiplicity);
+ referenceDefinition.setName(name);
+ referenceDefinition.setWiredByImpl(Boolean.parseBoolean(wiredByImpl));
+
+ if (targets != null && targets.length() > 0 )
+ ReferenceLoaderHelper.populateRefTargets(referenceDefinition, targets);
+
+ /*if (!ReferenceLoaderHelper.validateMultiplicityAndTargets(multiplicity, referenceDefinition
+ .getTargets())) {
+ throw new ReferenceMultiplicityViolationException(name, multiplicity, referenceDefinition.getTargets().size());
+ }*/
+
+ while (true) {
+ switch (reader.next()) {
+ case START_ELEMENT:
+ ModelObject o = registry.load(parent, null, reader, deploymentContext);
+ if (o instanceof ServiceContract) {
+ referenceDefinition.setServiceContract((ServiceContract)o);
+ } else if (o instanceof BindingDefinition) {
+ referenceDefinition.addBinding((BindingDefinition)o);
+ } else {
+ throw new UnrecognizedElementException(reader.getName());
+ }
+ break;
+ case END_ELEMENT:
+ return referenceDefinition;
+ }
+ }
+ }
+
+ public CompositeReferenceDefinition loadCompositeReference(CompositeComponent parent,
+ ModelObject object,
+ XMLStreamReader reader,
+ DeploymentContext deploymentContext) throws XMLStreamException, LoaderException {
+
+ String name = reader.getAttributeValue(null, NAME_ATTR);
+ String multiplicityVal = reader.getAttributeValue(null, MULTIPLICITY_ATTR);
+ String wiredByImpl = reader.getAttributeValue(null, WIRED_BY_IMPL_ATTR);
+ String targets = reader.getAttributeValue(null, TARGET_ATTR);
+ String promotedComponentRefs = reader.getAttributeValue(null, PROMOTE_ATTR);
+ //if multiplicity is not set, it will be derived in the composite loader by looking
+ //at the multiplicity of all promoted references - which can be done only after the composite
+ //is completelly loaded
+ Multiplicity multiplicity = StaxUtil.multiplicity(multiplicityVal, null);
+
+
+ CompositeComponentType<?, ?, ?> compositeCompType = (CompositeComponentType<?, ?, ?>)object;
+ if ( compositeCompType.getDeclaredReferences().get(name) != null) {
+ throw new DuplicateReferenceNameException(name,
+ DuplicateReferenceNameException.COMPOSITE,
+ compositeCompType.getName());
+ }
+ CompositeReferenceDefinition referenceDefinition = new CompositeReferenceDefinition();
+ referenceDefinition.setName(name);
+ referenceDefinition.setMultiplicity(multiplicity);
+
+ if (promotedComponentRefs != null && promotedComponentRefs.length() > 0) {
+ ReferenceLoaderHelper.populatePromotedRefs(referenceDefinition, promotedComponentRefs);
+ }
+
+ if (targets != null && targets.length() > 0 )
+ ReferenceLoaderHelper.populateRefTargets(referenceDefinition, targets);
+
+ referenceDefinition.setWiredByImpl(Boolean.parseBoolean(wiredByImpl));
+
+ while (true) {
+ switch (reader.next()) {
+ case START_ELEMENT:
+ ModelObject o = registry.load(parent, null, reader, deploymentContext);
+ if (o instanceof ServiceContract) {
+ referenceDefinition.setServiceContract((ServiceContract)o);
+ } else if (o instanceof BindingDefinition) {
+ referenceDefinition.addBinding((BindingDefinition)o);
+ } else {
+ throw new UnrecognizedElementException(reader.getName());
+ }
+ break;
+ case END_ELEMENT:
+ return referenceDefinition;
+ }
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ServiceLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ServiceLoader.java
new file mode 100644
index 0000000000..a365a281b5
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/ServiceLoader.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import javax.xml.namespace.QName;
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import static org.osoa.sca.Constants.SCA_NS;
+import org.osoa.sca.annotations.Constructor;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.InvalidReferenceException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.UnrecognizedElementException;
+import org.apache.tuscany.spi.model.BindingDefinition;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+/**
+ * Loads a service definition from an XML-based assembly file
+ *
+ * @version $Rev$ $Date$
+ */
+public class ServiceLoader extends LoaderExtension<ServiceDefinition> {
+ private static final QName SERVICE = new QName(SCA_NS, "service");
+ private static final QName REFERENCE = new QName(SCA_NS, "reference");
+
+ @Constructor
+ public ServiceLoader(@Autowire LoaderRegistry registry) {
+ super(registry);
+ }
+
+ public QName getXMLType() {
+ return SERVICE;
+ }
+
+ public ServiceDefinition load(CompositeComponent parent,
+ ModelObject object,
+ XMLStreamReader reader,
+ DeploymentContext deploymentContext) throws XMLStreamException, LoaderException {
+ assert SERVICE.equals(reader.getName());
+ String name = reader.getAttributeValue(null, "name");
+ String target = null;
+ ServiceDefinition def = new ServiceDefinition();
+ def.setName(name);
+ while (true) {
+ int i = reader.next();
+ switch (i) {
+ case START_ELEMENT:
+ // there is a reference already using this qname which doesn't seem appropriate.
+ if (REFERENCE.equals(reader.getName())) {
+ String text = reader.getElementText();
+ target = text != null ? text.trim() : null;
+ } else {
+ ModelObject o = registry.load(parent, null, reader, deploymentContext);
+ if (o instanceof ServiceContract) {
+ def.setServiceContract((ServiceContract) o);
+ } else if (o instanceof BindingDefinition) {
+ def.addBinding((BindingDefinition) o);
+ } else {
+ throw new UnrecognizedElementException(reader.getName());
+ }
+ }
+ break;
+ case END_ELEMENT:
+ if (SERVICE.equals(reader.getName())) {
+ if (target != null) {
+ try {
+ def.setTarget(new URI(target));
+ } catch (URISyntaxException e) {
+ throw new InvalidReferenceException(target, name);
+ }
+ }
+ return def;
+ }
+ break;
+ }
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/StringParserPropertyFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/StringParserPropertyFactory.java
new file mode 100644
index 0000000000..965dbcf8d5
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/StringParserPropertyFactory.java
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import java.beans.PropertyEditor;
+import java.beans.PropertyEditorManager;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.tuscany.core.injection.SingletonListObjectFactory;
+import org.apache.tuscany.core.injection.SingletonObjectFactory;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.PropertyObjectFactory;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.PropertyValue;
+
+/**
+ * Implementation of StAXPropertyFactory that interprets the XML as
+ *
+ * @version $Rev$ $Date$
+ */
+public class StringParserPropertyFactory implements PropertyObjectFactory {
+
+ public <T> ObjectFactory<T> createObjectFactory(Property<T> property, PropertyValue<T> value)
+ throws LoaderException {
+ String text = value.getValue().get(0).getTextContent();
+ return new SingletonObjectFactory<T>(createInstance(text, property.getJavaType()));
+ }
+
+ public <T> ObjectFactory<List<T>> createListObjectFactory(Property<T> property, PropertyValue<T> value)
+ throws LoaderException {
+ String text = null;
+ List<T> instances = new ArrayList<T>();
+ for (int count = 0 ; count < value.getValue().size() ; ++count) {
+ text = value.getValue().get(count).getTextContent();
+ instances.add(createInstance(text, property.getJavaType()));
+ }
+ return new SingletonListObjectFactory<T>(instances);
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> T createInstance(String text, Class<T> type) throws LoaderException {
+ // Class<T> type = property.getJavaType();
+ assert type != null : "property type is null";
+
+ // degenerate case where property type is a String
+ if (String.class.equals(type)) {
+ return type.cast(text);
+ }
+
+ // special handler to convert hexBinary to a byte[]
+ if (byte[].class.equals(type)) {
+ byte[] instance = new byte[text.length() >> 1];
+ for (int i = 0; i < instance.length; i++) {
+ instance[i] =
+ (byte) (Character.digit(text.charAt(i << 1), 16) << 4 | Character.digit(text
+ .charAt((i << 1) + 1), 16));
+ }
+ return type.cast(instance);
+ }
+
+ // does this type have a static valueOf(String) method?
+ try {
+ Method valueOf = type.getMethod("valueOf", String.class);
+ if (Modifier.isStatic(valueOf.getModifiers())) {
+ try {
+ return type.cast(valueOf.invoke(null, text));
+ } catch (IllegalAccessException e) {
+ throw new AssertionError("getMethod returned an inaccessible method");
+ } catch (InvocationTargetException e) {
+ // FIXME we should throw something better
+ throw new LoaderException(e.getCause());
+ }
+ }
+ } catch (NoSuchMethodException e) {
+ // try something else
+ }
+
+ // does this type have a constructor that takes a String?
+ try {
+ Constructor<T> ctr = type.getConstructor(String.class);
+ return ctr.newInstance(text);
+ } catch (NoSuchMethodException e) {
+ // try something else
+ } catch (IllegalAccessException e) {
+ throw new AssertionError("getConstructor returned an inaccessible method");
+ } catch (InstantiationException e) {
+ throw new LoaderException("Property type cannot be instantiated: " + type.getName());
+ } catch (InvocationTargetException e) {
+ // FIXME we should throw something better
+ throw new LoaderException(e.getCause());
+ }
+
+ // do we have a property editor for it?
+ PropertyEditor editor = PropertyEditorManager.findEditor(type);
+ if (editor != null) {
+ try {
+ editor.setAsText(text);
+ return (T) editor.getValue();
+ } catch (IllegalArgumentException e) {
+ // FIXME we should throw something better
+ throw new LoaderException(e);
+
+ }
+ }
+
+ // FIXME we should throw something better
+ throw new LoaderException("Do not have a way to parse a String into a " + type.getName());
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> ObjectFactory<T> createObjectFactory(String text, Property<T> property)
+ throws XMLStreamException, LoaderException {
+ Class<T> type = property.getJavaType();
+ assert type != null : "property type is null";
+
+ // degenerate case where property type is a String
+ if (String.class.equals(type)) {
+ return new SingletonObjectFactory<T>(type.cast(text));
+ }
+
+ // special handler to convert hexBinary to a byte[]
+ if (byte[].class.equals(type)) {
+ byte[] instance = new byte[text.length() >> 1];
+ for (int i = 0; i < instance.length; i++) {
+ instance[i] =
+ (byte) (Character.digit(text.charAt(i << 1), 16) << 4 | Character.digit(text
+ .charAt((i << 1) + 1), 16));
+ }
+ return new SingletonObjectFactory<T>(type.cast(instance));
+ }
+
+ // does this type have a static valueOf(String) method?
+ try {
+ Method valueOf = type.getMethod("valueOf", String.class);
+ if (Modifier.isStatic(valueOf.getModifiers())) {
+ try {
+ return new SingletonObjectFactory<T>(type.cast(valueOf.invoke(null, text)));
+ } catch (IllegalAccessException e) {
+ throw new AssertionError("getMethod returned an inaccessible method");
+ } catch (InvocationTargetException e) {
+ // FIXME we should throw something better
+ throw new LoaderException(e.getCause());
+ }
+ }
+ } catch (NoSuchMethodException e) {
+ // try something else
+ }
+
+ // does this type have a constructor that takes a String?
+ try {
+ Constructor<T> ctr = type.getConstructor(String.class);
+ return new SingletonObjectFactory<T>(ctr.newInstance(text));
+ } catch (NoSuchMethodException e) {
+ // try something else
+ } catch (IllegalAccessException e) {
+ throw new AssertionError("getConstructor returned an inaccessible method");
+ } catch (InstantiationException e) {
+ throw new LoaderException("Property type cannot be instantiated: " + type.getName());
+ } catch (InvocationTargetException e) {
+ // FIXME we should throw something better
+ throw new LoaderException(e.getCause());
+ }
+
+ // do we have a property editor for it?
+ PropertyEditor editor = PropertyEditorManager.findEditor(type);
+ if (editor != null) {
+ try {
+ editor.setAsText(text);
+ return new SingletonObjectFactory<T>((T) editor.getValue());
+ } catch (IllegalArgumentException e) {
+ // FIXME we should throw something better
+ throw new LoaderException(e);
+
+ }
+ }
+
+ // FIXME we should throw something better
+ throw new LoaderException("Do not have a way to parse a String into a " + type.getName());
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/WireLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/WireLoader.java
new file mode 100644
index 0000000000..c6863ec140
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/loader/WireLoader.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import javax.xml.namespace.QName;
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import static org.osoa.sca.Constants.SCA_NS;
+import org.osoa.sca.annotations.Constructor;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.InvalidWireException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.model.WireDefinition;
+
+/**
+ * Loads a wire from an XML-based assembly file
+ *
+ * @version $Rev: 465084 $ $Date: 2006-10-18 04:00:49 +0530 (Wed, 18 Oct 2006) $
+ */
+public class WireLoader extends LoaderExtension<WireDefinition> {
+ private static final QName WIRE = new QName(SCA_NS, "wire");
+ private static final QName SOURCE_URI = new QName(SCA_NS, "source.uri");
+ private static final QName TARGET_URI = new QName(SCA_NS, "target.uri");
+
+ @Constructor({"registry"})
+ public WireLoader(@Autowire LoaderRegistry registry) {
+ super(registry);
+ }
+
+ public QName getXMLType() {
+ return WIRE;
+ }
+
+ public WireDefinition load(CompositeComponent parent,
+ ModelObject object,
+ XMLStreamReader reader,
+ DeploymentContext deploymentContext) throws XMLStreamException, LoaderException {
+ assert WIRE.equals(reader.getName());
+ WireDefinition wireDefn;
+ URI sourceURI = null;
+ URI targetURI = null;
+ String uriString;
+ while (true) {
+ switch (reader.next()) {
+ case START_ELEMENT:
+ try {
+ if (reader.getName().equals(SOURCE_URI)) {
+ uriString = reader.getElementText();
+ if (uriString != null && uriString.trim().length() > 0) {
+ sourceURI = new URI(uriString);
+ } else {
+ throw new InvalidWireException("Wire source not defined");
+ }
+ } else if (reader.getName().equals(TARGET_URI)) {
+ uriString = reader.getElementText();
+ if (uriString != null && uriString.trim().length() > 0) {
+ targetURI = new URI(uriString);
+ } else {
+ throw new InvalidWireException("Wire target not defined");
+ }
+ } else {
+ QName name = reader.getName();
+ throw new InvalidWireException("Unrecognized element in wire ", name.toString());
+ }
+ } catch (URISyntaxException e) {
+ throw new InvalidWireException("Invalid wire uri", e);
+ }
+
+ reader.next();
+ break;
+ case END_ELEMENT:
+ if (reader.getName().equals(WIRE)) {
+ if (sourceURI != null && targetURI != null) {
+ wireDefn = new WireDefinition();
+ wireDefn.setSource(sourceURI);
+ wireDefn.setTarget(targetURI);
+ } else {
+ throw new InvalidWireException("Incomplete wire definition");
+ }
+ return wireDefn;
+ }
+ }
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/marshaller/ComponentDefinitionMarshaller.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/marshaller/ComponentDefinitionMarshaller.java
new file mode 100644
index 0000000000..b1510b67e0
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/marshaller/ComponentDefinitionMarshaller.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.marshaller;
+
+import static javax.xml.stream.XMLStreamConstants.END_DOCUMENT;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.tuscany.spi.marshaller.MarshalException;
+import org.apache.tuscany.spi.marshaller.ModelMarshaller;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+
+/**
+ * Marshaller used for marshalling and unmarshalling component definition.
+ *
+ * @version $Rev$ $Date$
+ *
+ */
+public class ComponentDefinitionMarshaller implements ModelMarshaller<ComponentDefinition<?>> {
+
+ /**
+ * Marshalls the component definition object to the specified stream writer.
+ *
+ * @param modelObject Component definition object to be serialized.
+ * @param writer Stream writer to which the infoset is serialized.
+ * @throws MarshalException In case of any marshalling error.
+ */
+ public void marshall(ComponentDefinition<?> modelObject, XMLStreamWriter writer) throws MarshalException {
+
+ try {
+ writer.writeStartDocument();
+ writer.writeEndDocument();
+ } catch (XMLStreamException ex) {
+ throw new MarshalException(ex);
+ }
+
+ }
+
+ /**
+ * Unmarshalls the component definition object from an XML stream.
+ *
+ * @param reader XML stream from where the marshalled XML is read.
+ * @param upconvert Whether to upconvert the object is the current runtime
+ * supports a higher version of the model object.
+ * @return Hydrated component definition object.
+ * @throws MarshalException In case of any unmarshalling error.
+ */
+ public ComponentDefinition<?> unmarshall(XMLStreamReader reader, boolean upconvert) throws MarshalException {
+ try {
+ while (true) {
+ ComponentDefinition<?> definition = null;
+ switch (reader.next()) {
+ case END_DOCUMENT:
+ return definition;
+ }
+ }
+ } catch (XMLStreamException ex) {
+ throw new MarshalException(ex);
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/DefaultExceptionFormatter.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/DefaultExceptionFormatter.java
new file mode 100644
index 0000000000..686c74c7f8
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/DefaultExceptionFormatter.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.monitor;
+
+import java.io.PrintWriter;
+
+import org.apache.tuscany.api.TuscanyException;
+import org.apache.tuscany.api.TuscanyRuntimeException;
+import org.apache.tuscany.host.monitor.ExceptionFormatter;
+
+/**
+ * Performs basics formatting of exceptions for JDK logging
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefaultExceptionFormatter implements ExceptionFormatter {
+
+ public DefaultExceptionFormatter() {
+ }
+
+ public boolean canFormat(Class<?> type) {
+ return Throwable.class.isAssignableFrom(type);
+ }
+
+ public PrintWriter write(PrintWriter writer, Throwable exception) {
+ if (exception instanceof TuscanyException) {
+ TuscanyException e = (TuscanyException) exception;
+ e.appendContextStack(e.appendBaseMessage(writer));
+ } else if (exception instanceof TuscanyRuntimeException) {
+ TuscanyRuntimeException e = (TuscanyRuntimeException) exception;
+ e.appendContextStack(e.appendBaseMessage(writer));
+ }
+ writer.append("\n");
+ return writer;
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/InvalidLevelException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/InvalidLevelException.java
new file mode 100644
index 0000000000..cf07b0f914
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/InvalidLevelException.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.monitor;
+
+/**
+ * Exception indicating an invalid log level has been passed.
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidLevelException extends IllegalArgumentException {
+ private static final long serialVersionUID = 7767234706427841915L;
+ private final String method;
+ private final String level;
+
+ /**
+ * Constructor specifying the method name and the level affected.
+ *
+ * @param method the name of the method being monitored
+ * @param level the invalid log level value
+ */
+ public InvalidLevelException(String method, String level) {
+ super();
+ this.method = method;
+ this.level = level;
+ }
+
+ /**
+ * Returns the name of the method being monitored.
+ *
+ * @return the name of the method being monitored
+ */
+ public String getMethod() {
+ return method;
+ }
+
+ /**
+ * Returns the invalid log level specified.
+ *
+ * @return the invalid log level that was specified
+ */
+ public String getLevel() {
+ return level;
+ }
+
+ public String getMessage() {
+ return "Invalid level for method " + method + " : " + level;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/JavaLoggingMonitorFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/JavaLoggingMonitorFactory.java
new file mode 100644
index 0000000000..019dcbdcd3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/JavaLoggingMonitorFactory.java
@@ -0,0 +1,321 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.monitor;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.WeakHashMap;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import org.osoa.sca.annotations.Service;
+
+import org.apache.tuscany.api.annotation.LogLevel;
+import org.apache.tuscany.host.MonitorFactory;
+import org.apache.tuscany.host.monitor.ExceptionFormatter;
+import org.apache.tuscany.host.monitor.FormatterRegistry;
+
+/**
+ * A factory for monitors that forwards events to a {@link java.util.logging.Logger Java Logging (JSR47) Logger}.
+ *
+ * @version $Rev$ $Date$
+ * @see java.util.logging
+ */
+@Service(interfaces = {MonitorFactory.class, FormatterRegistry.class})
+public class JavaLoggingMonitorFactory implements MonitorFactory, FormatterRegistry {
+ private String bundleName;
+ private Level defaultLevel;
+ private Map<String, Level> levels;
+ private List<ExceptionFormatter> formatters = new ArrayList<ExceptionFormatter>();
+ private ExceptionFormatter defaultFormatter = new DefaultExceptionFormatter();
+ private Map<Class<?>, WeakReference<?>> proxies = new WeakHashMap<Class<?>, WeakReference<?>>();
+
+ /**
+ * Construct a MonitorFactory that will monitor the specified methods at the specified levels and generate messages
+ * using java.util.logging.
+ * <p/>
+ * The supplied Properties can be used to specify custom log levels for specific monitor methods. The key should be
+ * the method name in form returned by <code>Class.getName() + '#' + Method.getName()</code> and the value the log
+ * level to use as defined by {@link java.util.logging.Level}.
+ *
+ * @param levels definition of custom levels for specific monitored methods, may be null or empty.
+ * @param defaultLevel the default log level to use
+ * @param bundleName the name of a resource bundle that will be passed to the logger
+ * @see java.util.logging.Logger
+ */
+ public JavaLoggingMonitorFactory(Properties levels, Level defaultLevel, String bundleName) {
+ Map<String, Object> configProperties = new HashMap<String, Object>();
+ configProperties.put("levels", levels);
+ configProperties.put("defaultLevel", defaultLevel);
+ configProperties.put("bundleName", bundleName);
+ initInternal(configProperties);
+ }
+
+ /**
+ * Constructs a MonitorFactory that needs to be subsequently configured via a call to {@link #initialize}.
+ */
+ public JavaLoggingMonitorFactory() {
+ }
+
+ public void initialize(Map<String, Object> configProperties) {
+ if (configProperties == null) {
+ return;
+ }
+ initInternal(configProperties);
+ }
+
+ private void initInternal(Map<String, Object> configProperties) {
+ try {
+ this.defaultLevel = (Level) configProperties.get("defaultLevel");
+ this.bundleName = (String) configProperties.get("bundleName");
+ Properties levels = (Properties) configProperties.get("levels");
+
+ this.levels = new HashMap<String, Level>();
+ if (levels != null) {
+ for (Map.Entry<Object, Object> entry : levels.entrySet()) {
+ String method = (String) entry.getKey();
+ String level = (String) entry.getValue();
+ try {
+ this.levels.put(method, Level.parse(level));
+ } catch (IllegalArgumentException e) {
+ throw new InvalidLevelException(method, level);
+ }
+ }
+ }
+ } catch (ClassCastException cce) {
+ throw new IllegalArgumentException(cce.getLocalizedMessage());
+ }
+ }
+
+ public synchronized <T> T getMonitor(Class<T> monitorInterface) {
+ T proxy = getCachedMonitor(monitorInterface);
+ if (proxy == null) {
+ proxy = createMonitor(monitorInterface, bundleName);
+ proxies.put(monitorInterface, new WeakReference<T>(proxy));
+ }
+ return proxy;
+ }
+
+ private <T> T getCachedMonitor(Class<T> monitorInterface) {
+ WeakReference<?> ref = proxies.get(monitorInterface);
+ return (ref != null) ? monitorInterface.cast(ref.get()) : null;
+ }
+
+ private <T> T createMonitor(Class<T> monitorInterface, String bundleName) {
+ String className = monitorInterface.getName();
+ Logger logger = Logger.getLogger(className);
+ Method[] methods = monitorInterface.getMethods();
+ Map<String, Level> levels = new HashMap<String, Level>(methods.length);
+ for (Method method : methods) {
+ String key = className + '#' + method.getName();
+ Level level = null;
+ if (this.levels != null) {
+ this.levels.get(key);
+ }
+ // if not specified the in config properties, look for an annotation on the method
+ if (level == null) {
+ LogLevel annotation = method.getAnnotation(LogLevel.class);
+ if (annotation != null && annotation.value() != null) {
+ try {
+ level = Level.parse(annotation.value());
+ } catch (IllegalArgumentException e) {
+ // bad value, just use the default
+ level = defaultLevel;
+ }
+ }
+ }
+ if (level == null) {
+ level = defaultLevel;
+ }
+ levels.put(method.getName(), level);
+ }
+
+ ResourceBundle bundle = locateBundle(monitorInterface, bundleName);
+
+ InvocationHandler handler = new LoggingHandler(logger, levels, bundle, formatters, defaultFormatter);
+ return monitorInterface
+ .cast(Proxy.newProxyInstance(monitorInterface.getClassLoader(), new Class<?>[]{monitorInterface}, handler));
+ }
+
+ private static <T> ResourceBundle locateBundle(Class<T> monitorInterface, String bundleName) {
+ Locale locale = Locale.getDefault();
+ ClassLoader cl = monitorInterface.getClassLoader();
+ String packageName = monitorInterface.getPackage().getName();
+ while (true) {
+ try {
+ return ResourceBundle.getBundle(packageName + '.' + bundleName, locale, cl);
+ } catch (MissingResourceException e) {
+ //ok
+ }
+ int index = packageName.lastIndexOf('.');
+ if (index == -1) {
+ break;
+ }
+ packageName = packageName.substring(0, index);
+ }
+ try {
+ return ResourceBundle.getBundle(bundleName, locale, cl);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public void register(ExceptionFormatter formatter) {
+ formatters.add(formatter);
+ }
+
+ public void unregister(ExceptionFormatter formatter) {
+ formatters.remove(formatter);
+ }
+
+ private static final class LoggingHandler implements InvocationHandler {
+ private final Logger logger;
+ private final Map<String, Level> methodLevels;
+ private final ResourceBundle bundle;
+ private List<ExceptionFormatter> formatters;
+ private ExceptionFormatter defaultFormatter;
+
+ public LoggingHandler(Logger logger,
+ Map<String, Level> methodLevels,
+ ResourceBundle bundle,
+ List<ExceptionFormatter> formatters,
+ ExceptionFormatter defaultFormatter) {
+ this.logger = logger;
+ this.methodLevels = methodLevels;
+ this.bundle = bundle;
+ this.formatters = formatters;
+ this.defaultFormatter = defaultFormatter;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ String sourceMethod = method.getName();
+ Level level = methodLevels.get(sourceMethod);
+ if (level != null && logger.isLoggable(level)) {
+ // construct the key for the resource bundle
+ String className = logger.getName();
+ String key = className + '#' + sourceMethod;
+
+ LogRecord logRecord = new LogRecord(level, key);
+ logRecord.setLoggerName(className);
+ logRecord.setSourceClassName(className);
+ logRecord.setSourceMethodName(sourceMethod);
+ logRecord.setParameters(args);
+ if (args != null) {
+ for (Object o : args) {
+ if (o instanceof Throwable) {
+ Throwable e = (Throwable) o;
+ ExceptionFormatter formatter = null;
+ for (ExceptionFormatter candidate : formatters) {
+ if (candidate.canFormat(e.getClass())) {
+ formatter = candidate;
+ break;
+ }
+ }
+ StringWriter writer = new StringWriter();
+ PrintWriter pw = new PrintWriter(writer);
+ if (formatter != null) {
+ formatter.write(pw, e);
+ } else {
+ defaultFormatter.write(pw, e);
+ }
+ format(pw, e);
+ pw.close();
+ logRecord.setMessage(writer.toString());
+ break;
+ }
+ }
+ }
+ logRecord.setResourceBundle(bundle);
+ logger.log(logRecord);
+ }
+ return null;
+ }
+
+ private void format(PrintWriter writer, Throwable throwable) {
+ writer.println(throwable.getClass().getName());
+ StackTraceElement[] trace = throwable.getStackTrace();
+ for (StackTraceElement aTrace : trace) {
+ writer.println("\tat " + aTrace);
+ }
+ Throwable ourCause = throwable.getCause();
+
+ if (ourCause != null) {
+ printStackTraceAsCause(writer, ourCause, trace);
+ }
+ }
+
+ private void printStackTraceAsCause(PrintWriter pw,
+ Throwable throwable,
+ StackTraceElement[] causedTrace) {
+
+ // Compute number of frames in common between this and caused
+ StackTraceElement[] trace = throwable.getStackTrace();
+ int m = trace.length - 1;
+ int n = causedTrace.length - 1;
+ while (m >= 0 && n >= 0 && trace[m].equals(causedTrace[n])) {
+ m--;
+ n--;
+ }
+ int framesInCommon = trace.length - 1 - m;
+
+ pw.println("Caused by: " + throwable.getClass().getName());
+
+ ExceptionFormatter formatter = null;
+ for (ExceptionFormatter candidate : formatters) {
+ if (candidate.canFormat(throwable.getClass())) {
+ formatter = candidate;
+ break;
+ }
+ }
+ if (formatter != null) {
+ formatter.write(pw, throwable);
+ } else {
+ defaultFormatter.write(pw, throwable);
+ }
+
+
+ for (int i = 0; i <= m; i++) {
+ pw.println("\tat " + trace[i]);
+ }
+ if (framesInCommon != 0) {
+ pw.println("\t... " + framesInCommon + " more");
+ }
+
+ // Recurse if we have a cause
+ Throwable ourCause = throwable.getCause();
+ if (ourCause != null) {
+ printStackTraceAsCause(pw, ourCause, trace);
+ }
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/MonitorFactoryUtil.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/MonitorFactoryUtil.java
new file mode 100644
index 0000000000..92224d469f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/MonitorFactoryUtil.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.monitor;
+
+import org.apache.tuscany.host.MonitorFactory;
+
+import java.util.Map;
+
+/**
+ * Helper for creating MonitorFactory instances.
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+
+public final class MonitorFactoryUtil {
+ /**
+ * Hide the constructor
+ */
+ private MonitorFactoryUtil() {
+ }
+
+ /**
+ * Creates a MonitorFactory instance of the specified type.
+ * @param name fully qualified classname of the desired MonitorFactory type
+ * @param props collection of initialization properties
+ * @return a configured MonitorFactory instance, or null if the factory could not be instantiated.
+ */
+ @SuppressWarnings("unchecked")
+ public static MonitorFactory createMonitorFactory(String name, Map<String, Object> props) {
+ Class<? extends MonitorFactory> clazz;
+ try {
+ clazz = (Class<? extends MonitorFactory>) Class.forName(name);
+ } catch (ClassNotFoundException cnfe) {
+ return null;
+ } catch (ClassCastException cce) {
+ return null;
+ }
+
+ return createMonitorFactory(clazz, props);
+ }
+
+ /**
+ * Creates a MonitorFactory instance of the specified type.
+ * @param mfc class of the desired MonitorFactory type
+ * @param props collection of initialization properties
+ * @return a configured MonitorFactory instance, or null if the factory could not be instantiated.
+ */
+ public static MonitorFactory createMonitorFactory(Class<? extends MonitorFactory> mfc, Map<String, Object> props) {
+ MonitorFactory mf;
+ try {
+ mf = mfc.newInstance();
+ mf.initialize(props);
+ } catch (InstantiationException e) {
+ throw new AssertionError(e);
+ } catch (IllegalAccessException e) {
+ throw new AssertionError(e);
+ }
+ // allow IllegalArgumentException to propogate out
+
+ return mf;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/NullMonitorFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/NullMonitorFactory.java
new file mode 100644
index 0000000000..8ba3053c2f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/monitor/NullMonitorFactory.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.monitor;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Map;
+
+import org.osoa.sca.annotations.EagerInit;
+
+import org.apache.tuscany.host.MonitorFactory;
+
+/**
+ * Implementation of a {@link MonitorFactory} that produces implementations that simply return.
+ *
+ * @version $Rev$ $Date$
+ */
+@EagerInit
+public class NullMonitorFactory implements MonitorFactory {
+ /**
+ * Singleton wire hander that does nothing.
+ */
+ private static final InvocationHandler NULL_MONITOR = new InvocationHandler() {
+ public Object invoke(Object proxy, Method method, Object[] args) {
+ return null;
+ }
+ };
+
+ public void initialize(Map<String, Object> configProperties) {
+ }
+
+ public <T> T getMonitor(Class<T> monitorInterface) {
+ /*
+ * This uses a reflection proxy to implement the monitor interface which
+ * is a simple but perhaps not very performant solution. Performance
+ * might be improved by code generating an implementation with empty methods.
+ */
+ return monitorInterface.cast(
+ Proxy.newProxyInstance(monitorInterface.getClassLoader(), new Class<?>[]{monitorInterface}, NULL_MONITOR));
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/policy/IntentRegistryImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/policy/IntentRegistryImpl.java
new file mode 100644
index 0000000000..5ea24e4c9b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/policy/IntentRegistryImpl.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.model.Intent;
+import org.apache.tuscany.spi.model.IntentName;
+import org.apache.tuscany.spi.policy.IntentRegistry;
+
+/**
+ * The default implementation of a data intent registry
+ */
+public class IntentRegistryImpl implements IntentRegistry {
+ private final Map<IntentName, IntentEntry> intentRepo = new HashMap<IntentName, IntentEntry>();
+
+ public Collection<IntentName> getQualifiedIntents(final IntentName qualifiable, final QName artifact) {
+ List<IntentName> result = new ArrayList<IntentName>();
+ for (IntentName intentName : intentRepo.keySet()) {
+ if (intentRepo.get(intentName).getAppliedArtifacts().contains(artifact)
+ && PolicyHelper.isQualifiedIntentFor(intentName, qualifiable, true)) {
+ result.add(intentName);
+ }
+ }
+ return result;
+ }
+
+ public Collection<IntentName> inlineProfileIntent(final Collection<IntentName> intentNameList,
+ final QName artifact) {
+
+ return getConcretIntentsInternal(intentNameList, artifact);
+ }
+
+ private Collection<IntentName> getConcretIntentsInternal(final Collection<IntentName> intentNameList,
+ QName artifact) {
+ List<IntentName> result = new ArrayList<IntentName>();
+ for (IntentName intentName : intentNameList) {
+ IntentEntry intentEntry = intentRepo.get(intentName);
+ if (!intentEntry.isProfileIntent()) {
+ if (intentEntry.getAppliedArtifacts().contains(artifact)) {
+ result.add(intentEntry.getName());
+ }
+ } else {
+ result.addAll(getConcretIntentsInternal(intentEntry.getRequriedIntents(), artifact));
+ }
+ }
+ return result;
+ }
+
+ public boolean isApplicable(IntentName intentName, QName artifact) {
+ if (intentRepo.containsKey(intentName)) {
+ return intentRepo.get(intentName).getAppliedArtifacts().contains(artifact);
+ }
+ return false;
+ }
+
+ public void register(Intent intent) {
+
+ IntentEntry entry = new IntentEntry(intent);
+ // if the qualified intents have been registered, make the intent qualifiable(unqualified)
+ if (!getQualifiedIntents(intent.getName()).isEmpty()) {
+ entry.setQualified(false);
+ }
+ intentRepo.put(intent.getName(), entry);
+ List<IntentName> qualifiables = getAllQualifiableIntent(intent.getName());
+ // set qualifiable intent of this intent unqualified
+ for (IntentName qualifiable : qualifiables) {
+ IntentEntry qualifiableEntry = intentRepo.get(qualifiable);
+ qualifiableEntry.setQualified(false);
+ for (QName artifact : intent.getAppliedArtifacts()) {
+ qualifiableEntry.addAppliedArtifacts(artifact);
+ }
+ }
+ }
+
+ public void unRegister(Intent intent) {
+ if (intentRepo.containsKey(intent.getName())) {
+ IntentEntry intentEntry = intentRepo.get(intent.getName());
+ List<QName> appliedArtifacts = intent.getAppliedArtifacts();
+ for (QName artifact : appliedArtifacts) {
+ if (intentEntry.getAppliedArtifacts().contains(artifact)) {
+ intentEntry.removeappliedArtifact(artifact);
+ }
+ }
+ if (intentEntry.getAppliedArtifacts().isEmpty()) {
+ intentRepo.remove(intent.getName());
+ }
+ }
+ }
+
+ public boolean isQualifiedIntent(IntentName name) {
+ IntentEntry intentEntry = intentRepo.get(name);
+ return intentEntry.isQualified();
+ }
+
+ private List<IntentName> getQualifiedIntents(final IntentName qualifiable) {
+ List<IntentName> result = new ArrayList<IntentName>();
+ for (IntentName intentName : intentRepo.keySet()) {
+ if (PolicyHelper.isQualifiedIntentFor(intentName, qualifiable, true)) {
+ result.add(intentName);
+ }
+ }
+ return result;
+ }
+
+ private List<IntentName> getAllQualifiableIntent(final IntentName qualified) {
+
+ List<IntentName> result = new ArrayList<IntentName>();
+ for (IntentName intentName : intentRepo.keySet()) {
+ if (PolicyHelper.isQualifiedIntentFor(qualified, intentName, false)) {
+ result.add(intentName);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Wrapper class for intent used internally
+ */
+ private static final class IntentEntry extends Intent {
+
+ /**
+ * Whether this intent is qualified, defaults to true
+ */
+ private boolean isQualified = true;
+
+ private IntentEntry(Intent intent) {
+ super(intent.getName(), intent.getDescription());
+ appliedArtifacts.addAll(intent.getAppliedArtifacts());
+ requriedIntents.addAll(intent.getRequriedIntents());
+ }
+
+ public boolean isQualified() {
+ return isQualified;
+ }
+
+ public void setQualified(boolean isQualified) {
+ this.isQualified = isQualified;
+ }
+
+ public void removeappliedArtifact(QName artifact) {
+ appliedArtifacts.remove(artifact);
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/policy/PolicyBuilderRegistryImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/policy/PolicyBuilderRegistryImpl.java
new file mode 100644
index 0000000000..94703f6abf
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/policy/PolicyBuilderRegistryImpl.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.policy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.builder.BuilderException;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.apache.tuscany.spi.policy.PolicyBuilderRegistry;
+import org.apache.tuscany.spi.policy.SourcePolicyBuilder;
+import org.apache.tuscany.spi.policy.TargetPolicyBuilder;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+/**
+ * The default policy builder
+ *
+ * @version $Rev$ $Date$
+ */
+public class PolicyBuilderRegistryImpl implements PolicyBuilderRegistry {
+
+ private final List<List<SourcePolicyBuilder>> sourceBuilders;
+ private final List<List<TargetPolicyBuilder>> targetBuilders;
+
+ public PolicyBuilderRegistryImpl() {
+ sourceBuilders = new ArrayList<List<SourcePolicyBuilder>>();
+ targetBuilders = new ArrayList<List<TargetPolicyBuilder>>();
+ for (int i = 0; i <= FINAL; i++) {
+ sourceBuilders.add(new ArrayList<SourcePolicyBuilder>());
+ targetBuilders.add(new ArrayList<TargetPolicyBuilder>());
+ }
+ }
+
+ public void registerTargetBuilder(int phase, TargetPolicyBuilder builder) {
+ assert INITIAL <= phase && phase <= FINAL : "Illegal phase";
+ targetBuilders.get(phase).add(builder);
+ }
+
+ public void registerSourceBuilder(int phase, SourcePolicyBuilder builder) {
+ assert INITIAL <= phase && phase <= FINAL : "Illegal phase";
+ sourceBuilders.get(phase).add(builder);
+ }
+
+
+ public void buildSource(AbstractReferenceDefinition referenceDefinition, OutboundWire wire) throws BuilderException {
+ for (List<SourcePolicyBuilder> builders : sourceBuilders) {
+ for (SourcePolicyBuilder builder : builders) {
+ builder.build(referenceDefinition, wire);
+ }
+ }
+ }
+
+ public void buildTarget(ServiceDefinition serviceDefinition, InboundWire wire) throws BuilderException {
+ for (List<TargetPolicyBuilder> builders : targetBuilders) {
+ for (TargetPolicyBuilder builder : builders) {
+ builder.build(serviceDefinition, wire);
+ }
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/policy/PolicyEngineImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/policy/PolicyEngineImpl.java
new file mode 100644
index 0000000000..308e43c038
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/policy/PolicyEngineImpl.java
@@ -0,0 +1,297 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.model.IntentMap;
+import org.apache.tuscany.spi.model.IntentName;
+import org.apache.tuscany.spi.model.PolicyContentModel;
+import org.apache.tuscany.spi.model.PolicyModel;
+import org.apache.tuscany.spi.model.PolicySet;
+import org.apache.tuscany.spi.model.PolicySetReference;
+import org.apache.tuscany.spi.model.Qualifier;
+import org.apache.tuscany.spi.policy.IntentRegistry;
+import org.apache.tuscany.spi.policy.PolicyEngine;
+import org.apache.tuscany.spi.policy.PolicySetContainer;
+import org.apache.tuscany.spi.policy.SCATypeManager;
+
+/**
+ * Default implementation of a polciy engine
+ */
+public class PolicyEngineImpl implements PolicyEngine {
+ private final IntentRegistry intentRegistry;
+ private final PolicySetContainer policySetContainer;
+ private final SCATypeManager scaTypeManager;
+
+ public PolicyEngineImpl(IntentRegistry intentRegistry,
+ PolicySetContainer policySetContainer,
+ SCATypeManager scaTypeManager) {
+ this.intentRegistry = intentRegistry;
+ this.policySetContainer = policySetContainer;
+ this.scaTypeManager = scaTypeManager;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Collection<PolicyModel> getPolicy(final IntentName[] requires,
+ final QName[] policySetNames,
+ final QName artifactType) {
+ if (requires == null || requires.length == 0) {
+ return Collections.EMPTY_LIST;
+ }
+ Collection<PolicyModel> result = new ArrayList<PolicyModel>();
+ Collection<IntentName> requiredIntents = java.util.Arrays.asList(requires);
+ Collection<IntentName> matchings;
+
+ //handle profile intents
+ requiredIntents = intentRegistry.inlineProfileIntent(requiredIntents, artifactType);
+ //
+ if (policySetNames != null && policySetNames.length != 0) {
+ Collection<PolicySet> explicitPolicySet = getExplicitPolicySet(policySetNames);
+ matchings = calculateExplicitPolicySet(requiredIntents, explicitPolicySet, artifactType, result);
+ //remove satisfied intent
+ requiredIntents.removeAll(matchings);
+ }
+ //
+ if (requiredIntents.size() > 0) {
+ matchings = findingAdditionalMatching(requiredIntents, artifactType, result);
+ requiredIntents.removeAll(matchings);
+ }
+ //If no collection of policySets covers all required intents, the configuration is not valid.
+ if (requiredIntents.size() > 0) {
+ //TODO
+ }
+ return result;
+ }
+
+
+ private boolean introspectPolicySet(PolicySet policySet, IntentName intent, QName artifactType,
+ Collection<PolicyModel> matchings) {
+ Collection<QName> appliedArtifacts = policySet.getAppliedArtifacts();
+ boolean provide = false;
+ for (QName name : appliedArtifacts) {
+ if (this.scaTypeManager.isTypeOf(artifactType, name)) {
+ provide = true;
+ break;
+ }
+ }
+ if (!provide) {
+ return false;
+ }
+ //1. The required intent matches a provides intent in a policySet exactly.
+ if (policySet.getProvideIntents().contains(intent)) {
+ if (intentRegistry.isQualifiedIntent(intent)) {
+ addMatching(matchings, policySet);
+ } else {
+ Collection<IntentMap> intentMaps = policySet.getIntentMaps();
+ provide = searchIntentMaps(intent, intent, matchings, intentMaps);
+ if (provide) {
+ return true;
+ }
+ }
+ } else if (provideAbstract(intent, policySet.getProvideIntents())) {
+ // 2. The provides intent is a parent (e.g. prefix) of the required intent (in this case the policySet must
+ // have an intentMap entry for the requested qualifier)
+ Collection<IntentMap> intentMaps = policySet.getIntentMaps();
+ IntentName satisfiedIntent = getSatisfiedIntent(intent, policySet.getProvideIntents());
+ provide = searchIntentMaps(intent, satisfiedIntent, matchings, intentMaps);
+ if (provide) {
+ return true;
+ }
+ } else if (provideQualifier(intent, policySet.getProvideIntents())) {
+ //3. The provides intent is more qualified than the required intent
+ if (intentRegistry.isQualifiedIntent(intent)) {
+ addMatching(matchings, policySet);
+ } else {
+ //TODO
+ }
+ }
+
+ //handle PolicySetReference
+ Collection<PolicySetReference> policySetReferences = policySet.getPolicySetReferences();
+ for (PolicySetReference reference : policySetReferences) {
+ PolicySet referencedPolicySet = policySetContainer.getPolicySet(reference.getReference());
+ if (introspectPolicySet(referencedPolicySet, intent, artifactType, matchings)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private void addMatching(Collection<PolicyModel> matching, PolicyContentModel policy) {
+ if (!policy.getWsPolicyAttachments().isEmpty()) {
+ matching.addAll(policy.getWsPolicyAttachments());
+ }
+ if (!policy.getPolicyExtensions().isEmpty()) {
+ matching.addAll(policy.getPolicyExtensions());
+ }
+ }
+
+ private boolean searchIntentMaps(IntentName require,
+ IntentName satisfiedIntent,
+ Collection<PolicyModel> matchings,
+ Collection<IntentMap> intentMaps) {
+ String qualifierName = getQualifierName(require, satisfiedIntent, intentMaps);
+ for (IntentMap intentMap : intentMaps) {
+ if (intentMap.getProvideIntents().contains(qualifierName)) {
+ Collection<Qualifier> qualifiers = intentMap.getQualifiers();
+ for (Qualifier qualifier : qualifiers) {
+ String nextQualifier = getNextQualifier(require, satisfiedIntent, intentMap);
+ if (qualifier.getName().equals(nextQualifier)) {
+ if (intentRegistry
+ .isQualifiedIntent(new IntentName(satisfiedIntent.toString() + "/" + nextQualifier))) {
+ addMatching(matchings, qualifier);
+ return true;
+ } else {
+ require = new IntentName(require.toString() + "/" + intentMap.getDefaultProvideIntent());
+ satisfiedIntent = new IntentName(satisfiedIntent.toString() + "/" + qualifierName);
+ intentMaps = new ArrayList<IntentMap>(0);
+ intentMaps.add(qualifier.getIntentMap());
+ searchIntentMaps(require, satisfiedIntent, matchings, intentMaps);
+ }
+ break;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private String getQualifierName(IntentName require, IntentName satisfiedIntent, Collection<IntentMap> intentMaps) {
+ String[] requrieQualifiers = require.getQualifiedNames();
+ String[] satisfiedQualifiers = satisfiedIntent.getQualifiedNames();
+ if (requrieQualifiers.length == satisfiedQualifiers.length) {
+ return requrieQualifiers[requrieQualifiers.length - 1];
+ } else if (requrieQualifiers.length > satisfiedQualifiers.length) {
+ return satisfiedQualifiers[satisfiedQualifiers.length - 1];
+ }
+ //TODO raise exception
+ return null;
+ }
+
+ private String getNextQualifier(IntentName require, IntentName satisfiedIntent, IntentMap intentMap) {
+ String[] requrieQualifiers = require.getQualifiedNames();
+ String[] satisfiedQualifiers = satisfiedIntent.getQualifiedNames();
+ if (requrieQualifiers.length > satisfiedQualifiers.length) {
+ return requrieQualifiers[satisfiedQualifiers.length];
+ } else {
+ return intentMap.getDefaultProvideIntent();
+ }
+ }
+
+ private IntentName getSatisfiedIntent(IntentName require, Collection<IntentName> provides) {
+ for (IntentName name : provides) {
+ if (PolicyHelper.isQualifiedIntentFor(require, name, true)) {
+ return name;
+ }
+ }
+ //TODO raise exception
+ return null;
+ }
+
+ private boolean provideAbstract(IntentName require, Collection<IntentName> provides) {
+ for (IntentName name : provides) {
+ if (PolicyHelper.isQualifiedIntentFor(require, name, true)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean provideQualifier(IntentName require, Collection<IntentName> provides) {
+ for (IntentName name : provides) {
+ if (PolicyHelper.isQualifiedIntentFor(name, require, true)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private Collection<PolicySet> getExplicitPolicySet(QName[] policySetNames) {
+ Collection<PolicySet> result = new ArrayList<PolicySet>();
+ for (QName policySetName : policySetNames) {
+ PolicySet set = policySetContainer.getPolicySet(policySetName);
+ if (set != null) {
+ result.add(set);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Step C. Calculate the list of explicitly specified policySets that apply to the target element as follows: 1.
+ * Start with the list of policySets specified in the element's policySet attribute. 2. If any of these explicitly
+ * listed policySets has an XPath expression in its appliesTo attribute that does not match the target element
+ * (binding or implementation) then the composite is invalid. It does not match if the XPath returns a result set
+ * that corresponds to XPath false. For example, a policySet could have appliesTo=”binding.ws/soaphttp”. This would
+ * return false if the target element is a <binding.jms…/> element. 3. Include the values of policySet attributes
+ * from ancestor elements. 4. Remove any policySet where the XPath expression in that policySet’s appliesTo
+ * attribute does not match the target element.
+ * <p/>
+ *
+ * @param requires
+ * @param policies
+ * @return intent names was satisfied by this step.
+ */
+ private Collection<IntentName> calculateExplicitPolicySet(Collection<IntentName> requires,
+ Collection<PolicySet> policies,
+ QName artifactType,
+ Collection<PolicyModel> matchings) {
+ Collection<IntentName> satisfied = new ArrayList<IntentName>();
+ for (IntentName intent : requires) {
+ for (PolicySet policySet : policies) {
+ if (introspectPolicySet(policySet, intent, artifactType, matchings)) {
+ satisfied.add(intent);
+ }
+ }
+ }
+ return satisfied;
+ }
+
+ /**
+ * * The remaining required intents, if any, are provided by finding additional matching policySets within the SCA
+ * system. E. Choose the smallest collection of these policySets that match all remaining required intents. A
+ * policySet matches a required intent if any of the following are true: 1. The required intent matches a provides
+ * intent in a policySet exactly. 2. The provides intent is a parent (e.g. prefix) of the required intent (in this
+ * case the policySet must have an intentMap entry for the requested qualifier) 3. The provides intent is more
+ * qualified than the required intent All intents should now be satisfied.
+ *
+ * @param remainings
+ * @param artifactType
+ * @param matchings
+ */
+ private Collection<IntentName> findingAdditionalMatching(final Collection<IntentName> remainings,
+ QName artifactType,
+ Collection<PolicyModel> matchings) {
+ Collection<IntentName> satisfied = new ArrayList<IntentName>();
+ Collection<PolicySet> policies = this.policySetContainer.getAllPolicySet();
+ for (IntentName intent : remainings) {
+ for (PolicySet policySet : policies) {
+ if (introspectPolicySet(policySet, intent, artifactType, matchings)) {
+ satisfied.add(intent);
+ }
+ }
+ }
+ return satisfied;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/policy/PolicyHelper.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/policy/PolicyHelper.java
new file mode 100644
index 0000000000..50c94aaf13
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/policy/PolicyHelper.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.policy;
+
+import org.apache.tuscany.spi.model.IntentName;
+
+/**
+ * Contains utility methods for dealing with policies
+ */
+public final class PolicyHelper {
+
+ private PolicyHelper() {
+ }
+
+ /**
+ * Whether <code>qualified</code> is qualified intent for <code>qualifiable</code>
+ * <p/>
+ * For example: sec.confidentiality/message is direct qualifier for sec.confidentiality.
+ * sec.confidentiality/message/body is qualifier for sec.confidentiality, but not a direct qualifier
+ *
+ * @param qualified qualified intent name
+ * @param qualifiable qualifiable intent name
+ * @param direct indicate whether to expect <code>qualified</code> is direct qualified intent for
+ * <code>qualifiable</code>
+ * @return whether <code>qualified</code> is qualified intent for <code>qualifiable</code>
+ */
+ public static boolean isQualifiedIntentFor(final IntentName qualified,
+ final IntentName qualifiable,
+ boolean direct) {
+ if (qualified.equals(qualifiable) || !qualified.getDomain().equals(qualifiable.getDomain())) {
+ return false;
+ }
+ boolean result = true;
+ String[] shortArray = qualifiable.getQualifiedNames();
+ String[] longArray = qualified.getQualifiedNames();
+ if (longArray.length - shortArray.length < 1 && !direct) {
+ return false;
+ } else if (direct && longArray.length - shortArray.length != 1) {
+ return false;
+ }
+ for (int i = 0; i < shortArray.length; i++) {
+ if (!shortArray[i].equals(longArray[i])) {
+ result = false;
+ break;
+ }
+ }
+ return result;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/property/PropertyHelper.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/property/PropertyHelper.java
new file mode 100644
index 0000000000..36054dc2f6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/property/PropertyHelper.java
@@ -0,0 +1,235 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.property;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.tuscany.core.databinding.xml.InputStream2Node;
+import org.apache.tuscany.spi.databinding.extension.DOMHelper;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.loader.InvalidValueException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.Implementation;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.PropertyValue;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * The property factory backed by the DataBindingframework
+ */
+public final class PropertyHelper {
+
+ private static final XPathFactory FACTORY = XPathFactory.newInstance();
+
+ private PropertyHelper() {
+ }
+
+ public static Document evaluate(NamespaceContext nsContext, Node node, String xPathExpression)
+ throws XPathExpressionException, ParserConfigurationException {
+ XPath path = FACTORY.newXPath();
+ if (nsContext != null) {
+ path.setNamespaceContext(nsContext);
+ } else {
+ path.setNamespaceContext(new DOMNamespeceContext(node));
+ }
+ XPathExpression expression = path.compile(xPathExpression);
+ Node result = (Node)expression.evaluate(node, XPathConstants.NODE);
+ if (result == null) {
+ return null;
+ }
+
+ // TODO: How to wrap the result into a Document?
+ Document document = DOMHelper.newDocument();
+ if (result instanceof Document) {
+ return (Document)result;
+ } else {
+ document.appendChild(document.importNode(result, true));
+ return document;
+ }
+ }
+
+ public static Document loadFromFile(String file, DeploymentContext deploymentContext)
+ throws LoaderException {
+ try {
+ URI uri = URI.create(file);
+ URL url = null;
+ if (!uri.isAbsolute()) {
+ url = deploymentContext.getClassLoader().getResource(file);
+ } else {
+ url = uri.toURL();
+ }
+ InputStream is = url.openStream();
+ try {
+ InputStream2Node transformer = new InputStream2Node();
+ return (Document)transformer.transform(is, null);
+ } finally {
+ is.close();
+ }
+ } catch (Exception e) {
+ throw new LoaderException(e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void processProperties(CompositeComponentType<?, ?, Property<?>> parent,
+ ComponentDefinition<? extends Implementation<?>> componentDefinition,
+ DeploymentContext deploymentContext) throws LoaderException {
+ Map<String, PropertyValue<?>> propertyValues = componentDefinition.getPropertyValues();
+
+ for (PropertyValue propValue : propertyValues.values()) {
+ String source = propValue.getSource();
+ String file = propValue.getFile();
+ if (source != null) {
+ try {
+ // $<name>/...
+ int index = source.indexOf('/');
+ if (index == -1) {
+ // Tolerating $prop
+ source = source + "/";
+ index = source.length() - 1;
+ }
+ if (source.charAt(0) == '$') {
+ String name = source.substring(1, index);
+ Property<?> compositeProp = parent.getProperties().get(name);
+ if (compositeProp == null) {
+ InvalidValueException ex =
+ new InvalidValueException(
+ "The 'source' cannot be resolved to a composite property");
+ ex.addContextName(source);
+ throw ex;
+ }
+
+ boolean prependValue = false;
+ DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ Document compositePropDefValues = builder.newDocument();
+ Node element = null;
+ for (int count = 0 ; count < compositeProp.getDefaultValues().size() ; ++count) {
+ element = compositeProp.getDefaultValues().get(count);
+ prependValue = element.getNodeName().equals("value");
+ element = compositePropDefValues.adoptNode(element);
+ compositePropDefValues.appendChild(element);
+ }
+ // Adding /value because the document root is "value"
+ String path = source.substring(index);
+ String xpath = null;
+ Property<?> componentProperty = (Property<?>)
+ componentDefinition.getImplementation().getComponentType().getProperties().get(propValue.getName());
+ if (prependValue) {
+ if ("/".equals(path)) {
+ // trailing / is not legal for xpath
+ xpath = "/value";
+ } else {
+ xpath = "/value" + path;
+ }
+ } else {
+ xpath = path;
+ }
+
+ // FIXME: How to deal with namespaces?
+ Document node = evaluate(null, compositePropDefValues, xpath);
+ //Document node = evaluate(null, compositeProp.getDefaultValues().get(0).getOwnerDocument(), xpath);
+ if (node != null) {
+ List<Document> values = new ArrayList<Document>();
+ values.add(node);
+ propValue.setValue(values);
+ }
+ } else {
+ InvalidValueException ex =
+ new InvalidValueException("The 'source' has an invalid value");
+ ex.addContextName(source);
+ throw ex;
+ }
+ } catch (Exception e) {
+ throw new LoaderException(e);
+ }
+ } else if (file != null) {
+ Property<?> prop =
+ (Property<?>)componentDefinition.getImplementation().getComponentType().getProperties()
+ .get(propValue.getName());
+ Document document = loadFromFile(propValue.getFile(), deploymentContext);
+ List<Element> values = new ArrayList<Element>();
+ if (prop.isMany()) {
+ //extract the property value elements from the loaded document
+ Element element = document.getDocumentElement();
+ Node childNode = null;
+ for (int count = 0 ; count < element.getChildNodes().getLength() ; ++count) {
+ if (element.getChildNodes().item(count).getNodeType() == Document.ELEMENT_NODE) {
+ values.add((Element)element.getChildNodes().item(count));
+ }
+ }
+ propValue.setValue(values);
+ propValue.setValueFactory(new SimpleMultivaluedPropertyObjectFactory(prop, propValue.getValue()));
+ } else {
+ values.add(document.getDocumentElement());
+ propValue.setValue(values);
+ propValue.setValueFactory(new SimplePropertyObjectFactory(prop, (Element)propValue.getValue().get(0)));
+ }
+ }
+ }
+ }
+
+ private static class DOMNamespeceContext implements NamespaceContext {
+ private Node node;
+
+ /**
+ * @param node
+ */
+ public DOMNamespeceContext(Node node) {
+ super();
+ this.node = node;
+ }
+
+ public String getNamespaceURI(String prefix) {
+ //return "http://foo";
+ return node.lookupNamespaceURI(prefix);
+ }
+
+ public String getPrefix(String namespaceURI) {
+ //return "foo";
+ return node.lookupPrefix(namespaceURI);
+ }
+
+ public Iterator getPrefixes(String namespaceURI) {
+ return null;
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/property/PropertyObjectFactoryImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/property/PropertyObjectFactoryImpl.java
new file mode 100644
index 0000000000..53b4f58b71
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/property/PropertyObjectFactoryImpl.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.property;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.core.databinding.xml.DOMDataBinding;
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.databinding.DataBinding;
+import org.apache.tuscany.spi.databinding.DataBindingRegistry;
+import org.apache.tuscany.spi.databinding.Mediator;
+import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension;
+import org.apache.tuscany.spi.idl.TypeInfo;
+import org.apache.tuscany.spi.idl.XMLType;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.PropertyObjectFactory;
+import org.apache.tuscany.spi.model.DataType;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.PropertyValue;
+import org.osoa.sca.annotations.Constructor;
+import org.osoa.sca.annotations.Scope;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+
+@Service(PropertyObjectFactory.class)
+@Scope("COMPOSITE")
+public class PropertyObjectFactoryImpl implements PropertyObjectFactory {
+ private DataBindingRegistry registry;
+ private Mediator mediator;
+
+ public PropertyObjectFactoryImpl() {
+ }
+
+ @Constructor( {"registry", "mediator"})
+ public PropertyObjectFactoryImpl(@Autowire
+ DataBindingRegistry registry, @Autowire
+ Mediator mediator) {
+ super();
+ this.registry = registry;
+ this.mediator = mediator;
+ }
+
+ public <T> ObjectFactory<T> createObjectFactory(Property<T> property, PropertyValue<T> value) {
+ if (mediator == null) {
+ return new SimplePropertyObjectFactory<T>(property, value.getValue().get(0));
+ }
+ return new ObjectFactoryImpl<T>(property, value);
+ }
+
+ public <T> ObjectFactory<List<T>> createListObjectFactory(Property<T> property, PropertyValue<T> value)
+ throws LoaderException {
+ if (mediator == null) {
+ return new SimpleMultivaluedPropertyObjectFactory<T>(property, value.getValue());
+ }
+ return new ListObjectFactoryImpl<T>(property, value);
+ }
+
+ public class ObjectFactoryImplBase<P> {
+ protected Property<P> property;
+ protected PropertyValue<P> propertyValue;
+ protected DataType<XMLType> sourceDataType;
+ protected DataType<?> targetDataType;
+
+ public ObjectFactoryImplBase(Property<P> property, PropertyValue<P> propertyValue) {
+ this.property = property;
+ this.propertyValue = propertyValue;
+ sourceDataType =
+ new DataType<XMLType>(DOMDataBinding.NAME, Node.class, new XMLType(null, this.property.getXmlType()));
+ TypeInfo typeInfo = null;
+ if (this.property.getXmlType() != null) {
+ if (SimpleTypeMapperExtension.isSimpleXSDType(this.property.getXmlType())) {
+ typeInfo = new TypeInfo(property.getXmlType(), true, null);
+ } else {
+ typeInfo = new TypeInfo(property.getXmlType(), false, null);
+ }
+ } else {
+ typeInfo = new TypeInfo(property.getXmlType(), false, null);
+ }
+
+ XMLType xmlType = new XMLType(typeInfo);
+ /*
+ * ElementInfo elementInfo = new ElementInfo(null, typeInfo);
+ * sourceDataType.setMetadata(ElementInfo.class.getName(),
+ * elementInfo);
+ */
+ Class javaType = this.property.getJavaType();
+ String dataBinding = (String)property.getExtensions().get(DataBinding.class.getName());
+ if (dataBinding != null) {
+ targetDataType = new DataType<XMLType>(dataBinding, javaType, xmlType);
+ } else {
+ targetDataType = new DataType<XMLType>(dataBinding, javaType, xmlType);
+ registry.introspectType(targetDataType, null);
+ }
+ }
+ }
+
+ public class ObjectFactoryImpl<P> extends ObjectFactoryImplBase<P> implements ObjectFactory<P> {
+
+ public ObjectFactoryImpl(Property<P> property, PropertyValue<P> propertyValue) {
+ super(property, propertyValue);
+ }
+
+ @SuppressWarnings("unchecked")
+ public P getInstance() throws ObjectCreationException {
+ return (P)mediator.mediate(propertyValue.getValue().get(0), sourceDataType, targetDataType, null);
+ }
+ }
+
+ public class ListObjectFactoryImpl<P> extends ObjectFactoryImplBase<P> implements ObjectFactory<List<P>> {
+
+ public ListObjectFactoryImpl(Property<P> property, PropertyValue<P> propertyValue) {
+ super(property, propertyValue);
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<P> getInstance() throws ObjectCreationException {
+ List<P> instances = new ArrayList<P>();
+ for (int count = 0; count < propertyValue.getValue().size(); ++count) {
+ instances.add((P)mediator.mediate(propertyValue.getValue().get(count),
+ sourceDataType,
+ targetDataType,
+ null));
+ }
+ return instances;
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/property/SimpleMultivaluedPropertyObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/property/SimpleMultivaluedPropertyObjectFactory.java
new file mode 100644
index 0000000000..85e41381a2
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/property/SimpleMultivaluedPropertyObjectFactory.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.core.property;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension;
+import org.apache.tuscany.spi.idl.TypeInfo;
+import org.apache.tuscany.spi.model.Property;
+import org.w3c.dom.Element;
+
+public class SimpleMultivaluedPropertyObjectFactory<P> implements ObjectFactory<List<P>> {
+ private SimpleTypeMapperExtension typeMapper;
+ private Property<P> property;
+ private List<Element> values;
+ private List<P> instance;
+
+ public SimpleMultivaluedPropertyObjectFactory(Property<P> property, List<Element> value) {
+ super();
+
+ this.property = property;
+ this.values = (value == null) ? property.getDefaultValues() : value;
+ this.typeMapper = new SimpleTypeMapperExtension();
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<P> getInstance() throws ObjectCreationException {
+ if (values == null) {
+ return null;
+ }
+
+ TypeInfo xmlType = null;
+ String text = null;
+
+ if (instance == null) {
+ instance = new ArrayList<P>();
+ for (int count = 0 ; count < values.size() ; ++count) {
+ text = values.get(count).getTextContent();
+
+ if (property.getJavaType() == null) {
+ xmlType = new TypeInfo(property.getXmlType(), true, null);
+ } else {
+ xmlType = typeMapper.getXMLType(property.getJavaType());
+ }
+ if (xmlType == null) {
+ throw new IllegalArgumentException("Complex property is not supported.");
+ }
+ instance.add((P)typeMapper.toJavaObject(xmlType.getQName(), text, null));
+ }
+ }
+ return instance;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/property/SimplePropertyObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/property/SimplePropertyObjectFactory.java
new file mode 100644
index 0000000000..87d8d414e2
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/property/SimplePropertyObjectFactory.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.property;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension;
+import org.apache.tuscany.spi.idl.TypeInfo;
+import org.apache.tuscany.spi.model.Property;
+import org.w3c.dom.Element;
+
+public class SimplePropertyObjectFactory<P> implements ObjectFactory<P> {
+ private SimpleTypeMapperExtension typeMapper;
+ private Property<P> property;
+ private Element value;
+ private P instance;
+
+ public SimplePropertyObjectFactory(Property<P> property, Element value) {
+ super();
+
+ this.property = property;
+ this.value = (value == null) ? property.getDefaultValues().get(0) : value;
+ this.typeMapper = new SimpleTypeMapperExtension();
+ }
+
+ @SuppressWarnings("unchecked")
+ public P getInstance() throws ObjectCreationException {
+ if (value == null) {
+ return null;
+ }
+ if (instance == null) {
+ String text = value.getTextContent();
+ TypeInfo xmlType = null;
+ if (property.getJavaType() == null) {
+ xmlType = new TypeInfo(property.getXmlType(), true, null);
+ } else {
+ xmlType = typeMapper.getXMLType(property.getJavaType());
+ }
+ if (xmlType == null) {
+ throw new IllegalArgumentException("Complex property is not supported.");
+ }
+ instance = (P)typeMapper.toJavaObject(xmlType.getQName(), text, null);
+ }
+ return instance;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/AbstractRuntime.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/AbstractRuntime.java
new file mode 100644
index 0000000000..4dd4e792a2
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/AbstractRuntime.java
@@ -0,0 +1,283 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.runtime;
+
+import java.net.URL;
+import javax.xml.stream.XMLInputFactory;
+
+import org.apache.tuscany.core.bootstrap.Bootstrapper;
+import org.apache.tuscany.core.bootstrap.DefaultBootstrapper;
+import org.apache.tuscany.core.implementation.system.model.SystemCompositeImplementation;
+import org.apache.tuscany.core.monitor.NullMonitorFactory;
+import org.apache.tuscany.host.MonitorFactory;
+import org.apache.tuscany.host.RuntimeInfo;
+import org.apache.tuscany.host.management.ManagementService;
+import org.apache.tuscany.host.runtime.InitializationException;
+import org.apache.tuscany.host.runtime.TuscanyRuntime;
+import org.apache.tuscany.spi.bootstrap.ComponentNames;
+import org.apache.tuscany.spi.bootstrap.RuntimeComponent;
+import org.apache.tuscany.spi.builder.BuilderException;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ComponentException;
+import org.apache.tuscany.spi.component.ComponentRegistrationException;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.deployer.Deployer;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.CompositeImplementation;
+import org.apache.tuscany.spi.services.management.TuscanyManagementService;
+import org.apache.tuscany.spi.wire.WireService;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractRuntime implements TuscanyRuntime {
+ private final XMLInputFactory xmlFactory;
+ private URL systemScdl;
+ private String applicationName;
+ private URL applicationScdl;
+ private ClassLoader hostClassLoader;
+ private ClassLoader applicationClassLoader;
+ private RuntimeInfo runtimeInfo;
+ private MonitorFactory monitorFactory;
+ private ManagementService<?> managementService;
+
+ private RuntimeComponent runtime;
+ private CompositeComponent systemComponent;
+ private CompositeComponent tuscanySystem;
+ private Deployer deployer;
+ private WireService wireService;
+
+ protected AbstractRuntime() {
+ this(new NullMonitorFactory());
+ }
+
+ protected AbstractRuntime(MonitorFactory monitorFactory) {
+ this.monitorFactory = monitorFactory;
+ xmlFactory = XMLInputFactory.newInstance("javax.xml.stream.XMLInputFactory", getClass().getClassLoader());
+ }
+
+ public URL getSystemScdl() {
+ return systemScdl;
+ }
+
+ public void setSystemScdl(URL systemScdl) {
+ this.systemScdl = systemScdl;
+ }
+
+ public String getApplicationName() {
+ return applicationName;
+ }
+
+ public void setApplicationName(String applicationName) {
+ this.applicationName = applicationName;
+ }
+
+ public URL getApplicationScdl() {
+ return applicationScdl;
+ }
+
+ public void setApplicationScdl(URL applicationScdl) {
+ this.applicationScdl = applicationScdl;
+ }
+
+ public ClassLoader getApplicationClassLoader() {
+ return applicationClassLoader;
+ }
+
+ public void setApplicationClassLoader(ClassLoader applicationClassLoader) {
+ this.applicationClassLoader = applicationClassLoader;
+ }
+
+ public ClassLoader getHostClassLoader() {
+ return hostClassLoader;
+ }
+
+ public void setHostClassLoader(ClassLoader hostClassLoader) {
+ this.hostClassLoader = hostClassLoader;
+ }
+
+ public RuntimeInfo getRuntimeInfo() {
+ return runtimeInfo;
+ }
+
+ public void setRuntimeInfo(RuntimeInfo runtimeInfo) {
+ this.runtimeInfo = runtimeInfo;
+ }
+
+ public MonitorFactory getMonitorFactory() {
+ return monitorFactory;
+ }
+
+ public void setMonitorFactory(MonitorFactory monitorFactory) {
+ this.monitorFactory = monitorFactory;
+ }
+
+ public ManagementService<?> getManagementService() {
+ return managementService;
+ }
+
+ public void setManagementService(ManagementService<?> managementService) {
+ this.managementService = managementService;
+ }
+
+ protected XMLInputFactory getXMLFactory() {
+ return xmlFactory;
+ }
+
+ protected RuntimeComponent getRuntime() {
+ return runtime;
+ }
+
+ protected CompositeComponent getSystemComponent() {
+ return systemComponent;
+ }
+
+ protected CompositeComponent getTuscanySystem() {
+ return tuscanySystem;
+ }
+
+ protected Deployer getDeployer() {
+ return deployer;
+ }
+
+ protected WireService getWireService() {
+ return wireService;
+ }
+
+ public void initialize() throws InitializationException {
+ Bootstrapper bootstrapper = createBootstrapper();
+ runtime = bootstrapper.createRuntime();
+ runtime.start();
+
+ systemComponent = runtime.getSystemComponent();
+ registerSystemComponents();
+ systemComponent.start();
+
+ // deploy the system scdl
+ try {
+ tuscanySystem =
+ deploySystemScdl(bootstrapper.createDeployer(),
+ systemComponent,
+ ComponentNames.TUSCANY_SYSTEM,
+ getSystemScdl(),
+ getClass().getClassLoader());
+ } catch (LoaderException e) {
+ throw new InitializationException(e);
+ } catch (BuilderException e) {
+ throw new InitializationException(e);
+ } catch (ComponentException e) {
+ throw new InitializationException(e);
+ }
+ tuscanySystem.start();
+
+ this.deployer = locateDeployer();
+ this.wireService = locateWireService();
+ }
+
+ public void destroy() {
+ this.wireService = null;
+ this.deployer = null;
+ if (tuscanySystem != null) {
+ tuscanySystem.stop();
+ tuscanySystem = null;
+ }
+ if (systemComponent != null) {
+ systemComponent.stop();
+ systemComponent = null;
+ }
+ if (runtime != null) {
+ runtime.stop();
+ runtime = null;
+ }
+ }
+
+ protected Bootstrapper createBootstrapper() {
+ TuscanyManagementService tms = (TuscanyManagementService)getManagementService();
+ return new DefaultBootstrapper(getMonitorFactory(), xmlFactory, tms);
+ }
+
+ protected void registerSystemComponents() throws InitializationException {
+ try {
+ systemComponent.registerJavaObject(RuntimeInfo.COMPONENT_NAME, RuntimeInfo.class, runtimeInfo);
+ systemComponent.registerJavaObject("MonitorFactory", MonitorFactory.class, getMonitorFactory());
+ } catch (ComponentRegistrationException e) {
+ throw new InitializationException(e);
+ }
+ }
+
+ protected Deployer locateDeployer() throws InitializationException {
+ SCAObject deployerComponent = tuscanySystem.getSystemChild(ComponentNames.TUSCANY_DEPLOYER);
+ if (!(deployerComponent instanceof AtomicComponent)) {
+ throw new InitializationException("Deployer must be an atomic component");
+ }
+ try {
+ return (Deployer)((AtomicComponent)deployerComponent).getTargetInstance();
+ } catch (TargetResolutionException e) {
+ throw new InitializationException(e);
+ }
+ }
+
+ protected WireService locateWireService() throws InitializationException {
+ SCAObject wireServiceComponent = tuscanySystem.getSystemChild(ComponentNames.TUSCANY_WIRE_SERVICE);
+ if (!(wireServiceComponent instanceof AtomicComponent)) {
+ throw new InitializationException("WireService must be an atomic component");
+ }
+ try {
+ return (WireService)((AtomicComponent)wireServiceComponent).getTargetInstance();
+ } catch (TargetResolutionException e) {
+ throw new InitializationException(e);
+ }
+ }
+
+ protected CompositeComponent deploySystemScdl(Deployer deployer,
+ CompositeComponent parent,
+ String name,
+ URL systemScdl,
+ ClassLoader systemClassLoader) throws LoaderException,
+ BuilderException, ComponentException {
+
+ SystemCompositeImplementation impl = new SystemCompositeImplementation();
+ impl.setScdlLocation(systemScdl);
+ impl.setClassLoader(systemClassLoader);
+ ComponentDefinition<SystemCompositeImplementation> definition =
+ new ComponentDefinition<SystemCompositeImplementation>(name, impl);
+
+ return (CompositeComponent)deployer.deploy(parent, definition);
+ }
+
+ protected CompositeComponent deployApplicationScdl(Deployer deployer,
+ CompositeComponent parent,
+ String name,
+ URL applicationScdl,
+ ClassLoader applicationClassLoader) throws LoaderException,
+ BuilderException, ComponentException {
+
+ CompositeImplementation impl = new CompositeImplementation();
+ impl.setScdlLocation(applicationScdl);
+ impl.setClassLoader(applicationClassLoader);
+ ComponentDefinition<CompositeImplementation> definition =
+ new ComponentDefinition<CompositeImplementation>(name, impl);
+
+ return (CompositeComponent)deployer.deploy(parent, definition);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/mini/SimpleRuntime.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/mini/SimpleRuntime.java
new file mode 100644
index 0000000000..e192b18e5f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/mini/SimpleRuntime.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.runtime.mini;
+
+import org.apache.tuscany.host.runtime.TuscanyRuntime;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface SimpleRuntime extends TuscanyRuntime {
+ CompositeComponent start() throws Exception;
+ <T> T getSystemService(Class<T> type, String name) throws TargetResolutionException;
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/mini/SimpleRuntimeImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/mini/SimpleRuntimeImpl.java
new file mode 100644
index 0000000000..bb9a32e7e0
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/mini/SimpleRuntimeImpl.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.runtime.mini;
+
+import static org.apache.tuscany.spi.bootstrap.ComponentNames.TUSCANY_ASSEMBLY_SERVICE;
+import static org.apache.tuscany.spi.bootstrap.ComponentNames.TUSCANY_CONTRIBUTION_SERVICE;
+
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.api.annotation.LogLevel;
+import org.apache.tuscany.core.launcher.CompositeContextImpl;
+import org.apache.tuscany.core.monitor.JavaLoggingMonitorFactory;
+import org.apache.tuscany.core.runtime.AbstractRuntime;
+import org.apache.tuscany.core.services.deployment.AssemblyServiceImpl;
+import org.apache.tuscany.host.MonitorFactory;
+import org.apache.tuscany.host.RuntimeInfo;
+import org.apache.tuscany.host.deployment.AssemblyService;
+import org.apache.tuscany.host.deployment.ContributionService;
+import org.apache.tuscany.host.monitor.FormatterRegistry;
+import org.apache.tuscany.host.runtime.InitializationException;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ComponentRegistrationException;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.osoa.sca.CompositeContext;
+import org.osoa.sca.CurrentCompositeContext;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SimpleRuntimeImpl extends AbstractRuntime implements SimpleRuntime {
+ protected JavaLoggingMonitorFactory monitorFactory;
+ protected SimpleMonitor monitor;
+ protected CompositeComponent application;
+
+ public SimpleRuntimeImpl(SimpleRuntimeInfo runtimeInfo) {
+ super();
+ monitorFactory = new JavaLoggingMonitorFactory();
+ setMonitorFactory(monitorFactory);
+ monitor = monitorFactory.getMonitor(SimpleMonitor.class);
+ ClassLoader hostClassLoader = ClassLoader.getSystemClassLoader();
+ setHostClassLoader(hostClassLoader);
+ setSystemScdl(runtimeInfo.getSystemSCDL());
+ setRuntimeInfo(runtimeInfo);
+ }
+
+ public interface SimpleMonitor {
+ @LogLevel("SEVERE")
+ void runError(Exception e);
+ }
+
+ public CompositeComponent start() throws Exception {
+ initialize();
+ ContributionService contributionService =
+ getSystemService(ContributionService.class, TUSCANY_CONTRIBUTION_SERVICE);
+ CompositeComponent composite = getTuscanySystem();
+ // TODO: Make assembly service a pluggable component?
+ AssemblyService assemblyService = new AssemblyServiceImpl(contributionService, composite);
+ composite.registerJavaObject(TUSCANY_ASSEMBLY_SERVICE, AssemblyService.class, assemblyService);
+
+ SimpleRuntimeInfo runtimeInfo = (SimpleRuntimeInfo)getRuntimeInfo();
+ int i = 0;
+ for (URL ext : runtimeInfo.getExtensionSCDLs()) {
+ CompositeComponent extensionComponent =
+ deploySystemScdl(getDeployer(), getTuscanySystem(), "tuscany.extension." + (i++), ext, runtimeInfo
+ .getClassLoader());
+ extensionComponent.start();
+ }
+
+ URI contributionId = runtimeInfo.getContributionURI();
+ contributionService.contribute(contributionId, runtimeInfo.getContributionRoot(), false);
+ URI compositeDefinitionId = contributionId.resolve(runtimeInfo.getCompositePath());
+
+ application =
+ (CompositeComponent)assemblyService.addCompositeToDomain(contributionId, compositeDefinitionId, runtimeInfo
+ .getCompositePath());
+
+ CompositeContext context = new CompositeContextImpl(application, getWireService());
+ CurrentCompositeContext.setContext(context);
+ return application;
+ }
+
+ public <T> T getSystemService(Class<T> type, String name) throws TargetResolutionException {
+ SCAObject child = getTuscanySystem().getSystemChild(name);
+ if (child == null) {
+ return null;
+ }
+ AtomicComponent service = (AtomicComponent)child;
+ return type.cast(service.getTargetInstance());
+ }
+
+ @Override
+ protected void registerSystemComponents() throws InitializationException {
+ try {
+ // initialize the runtime info
+ CompositeComponent parent = getSystemComponent();
+ parent.registerJavaObject("RuntimeInfo", RuntimeInfo.class, getRuntimeInfo());
+
+ // register the monitor factory
+ if (monitorFactory instanceof FormatterRegistry) {
+ List<Class<?>> interfazes = new ArrayList<Class<?>>(2);
+ interfazes.add(MonitorFactory.class);
+ interfazes.add(FormatterRegistry.class);
+ parent.registerJavaObject("MonitorFactory", interfazes, monitorFactory);
+ } else {
+ parent.registerJavaObject("MonitorFactory", MonitorFactory.class, monitorFactory);
+ }
+ } catch (ComponentRegistrationException e) {
+ throw new InitializationException(e);
+ }
+ }
+
+ @Override
+ public void destroy() {
+ CurrentCompositeContext.setContext(null);
+ application.stop();
+ super.destroy();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/mini/SimpleRuntimeInfo.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/mini/SimpleRuntimeInfo.java
new file mode 100644
index 0000000000..10b88d9e47
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/mini/SimpleRuntimeInfo.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.runtime.mini;
+
+import java.net.URI;
+import java.net.URL;
+import java.util.List;
+
+import org.apache.tuscany.host.RuntimeInfo;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface SimpleRuntimeInfo extends RuntimeInfo {
+ String DEFAULT_SYSTEM_SCDL = "META-INF/tuscany/default-system.composite";
+ String SYSTEM_SCDL = "system.composite";
+ String EXTENSION_SCDL = "META-INF/sca/extension.composite";
+ String SERVICE_SCDL = "META-INF/sca/service.composite";
+ String META_APPLICATION_SCDL = "META-INF/sca/application.composite";
+ String APPLICATION_SCDL = "application.composite";
+
+ ClassLoader getClassLoader();
+
+ String getCompositePath();
+
+ URL getSystemSCDL();
+ List<URL> getExtensionSCDLs();
+ URL getContributionRoot();
+ URI getContributionURI();
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/mini/SimpleRuntimeInfoImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/mini/SimpleRuntimeInfoImpl.java
new file mode 100644
index 0000000000..a9e0f2a114
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/runtime/mini/SimpleRuntimeInfoImpl.java
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.runtime.mini;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.apache.tuscany.core.util.FileHelper;
+import org.apache.tuscany.host.AbstractRuntimeInfo;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SimpleRuntimeInfoImpl extends AbstractRuntimeInfo implements SimpleRuntimeInfo {
+ private ClassLoader classLoader;
+ private String compositePath;
+
+ private List<URL> extensions;
+ private URL applicationSCDL;
+ private URL systemSCDL;
+
+ private URL contributionURL;
+ private URI contributionURI;
+
+ /**
+ * @param classLoader
+ * @param compositePath
+ * @param extensions
+ * @param applicationSCDL
+ * @param systemSCDL
+ */
+ public SimpleRuntimeInfoImpl(ClassLoader classLoader,
+ URL systemSCDL,
+ List<URL> extensions,
+ URI contributionURI,
+ URL applicationSCDL,
+ String compositePath) {
+ this(classLoader, compositePath);
+ this.extensions = extensions;
+ this.applicationSCDL = applicationSCDL;
+ this.systemSCDL = systemSCDL;
+ this.contributionURI = contributionURI;
+ }
+
+ public SimpleRuntimeInfoImpl(ClassLoader classLoader, String compositePath) {
+ // super(domain, applicationRootDirectory, baseUrl, online, runtimeId);
+ super(URI.create("sca://domain/local"), null, null, false, "simple");
+ if (classLoader != null) {
+ this.classLoader = classLoader;
+ } else {
+ classLoader = Thread.currentThread().getContextClassLoader();
+ }
+ this.compositePath = compositePath != null ? compositePath : APPLICATION_SCDL;
+ getApplicationSCDL();
+ this.contributionURI = URI.create("/default");
+ }
+
+ public ClassLoader getClassLoader() {
+ return classLoader;
+ }
+
+ public String getCompositePath() {
+ return compositePath;
+ }
+
+ public final URL getApplicationSCDL() {
+ if (applicationSCDL == null) {
+ applicationSCDL = classLoader.getResource(compositePath);
+ if (applicationSCDL == null) {
+ applicationSCDL = classLoader.getResource(APPLICATION_SCDL);
+ if (applicationSCDL == null) {
+ applicationSCDL = classLoader.getResource(META_APPLICATION_SCDL);
+ if (applicationSCDL != null) {
+ compositePath = META_APPLICATION_SCDL;
+ }
+ } else {
+ if (compositePath == null) {
+ compositePath = APPLICATION_SCDL;
+ }
+ }
+ if (applicationSCDL == null) {
+ throw new IllegalArgumentException("application SCDL not found: " + APPLICATION_SCDL);
+ }
+ }
+ }
+ return applicationSCDL;
+ }
+
+ public URL getContributionRoot() {
+ if (contributionURL == null) {
+ contributionURL = getContributionLocation(getApplicationSCDL(), compositePath);
+ }
+ return contributionURL;
+ }
+
+ public List<URL> getExtensionSCDLs() {
+ if (extensions == null) {
+ try {
+ List<URL> extensionURLs = new ArrayList<URL>();
+ Enumeration<URL> urls = classLoader.getResources(SERVICE_SCDL);
+ extensionURLs.addAll(Collections.list(urls));
+ urls = classLoader.getResources(EXTENSION_SCDL);
+ extensionURLs.addAll(Collections.list(urls));
+ if (extensions != null) {
+ for (URL ext : extensions) {
+ if (!extensionURLs.contains(ext)) {
+ extensionURLs.add(ext);
+ }
+ }
+ }
+ extensions = extensionURLs;
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+ return extensions;
+ }
+
+ public URL getSystemSCDL() {
+ if (systemSCDL == null) {
+ systemSCDL = classLoader.getResource(SYSTEM_SCDL);
+ if (systemSCDL == null) {
+ systemSCDL = classLoader.getResource(DEFAULT_SYSTEM_SCDL);
+ }
+ }
+ return systemSCDL;
+ }
+
+ private static URL getContributionLocation(URL applicationSCDL, String compositePath) {
+ URL root = null;
+ // "jar:file://....../something.jar!/a/b/c/app.composite"
+ try {
+ String scdlUrl = applicationSCDL.toExternalForm();
+ String protocol = applicationSCDL.getProtocol();
+ if ("file".equals(protocol)) {
+ // directory contribution
+ if (scdlUrl.endsWith(compositePath)) {
+ String location = scdlUrl.substring(0, scdlUrl.lastIndexOf(compositePath));
+ // workaround from evil url/uri form maven
+ root = FileHelper.toFile(new URL(location)).toURI().toURL();
+ }
+
+ } else if ("jar".equals(protocol)) {
+ // jar contribution
+ String location = scdlUrl.substring(4, scdlUrl.lastIndexOf("!/"));
+ // workaround from evil url/uri form maven
+ root = FileHelper.toFile(new URL(location)).toURI().toURL();
+ }
+ } catch (MalformedURLException mfe) {
+ throw new IllegalArgumentException(mfe);
+ }
+
+ return root;
+ }
+
+ public URI getContributionURI() {
+ return contributionURI;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/artifact/LocalMavenRepository.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/artifact/LocalMavenRepository.java
new file mode 100644
index 0000000000..f50e8544a3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/artifact/LocalMavenRepository.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.artifact;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collection;
+
+import org.osoa.sca.annotations.Property;
+
+import org.apache.tuscany.spi.services.artifact.Artifact;
+import org.apache.tuscany.spi.services.artifact.ArtifactRepository;
+
+/**
+ * An implementation of ArtifactRepository that uses a local Maven2 repository.
+ *
+ * @version $Rev$ $Date$
+ */
+public class LocalMavenRepository implements ArtifactRepository {
+ private File localRepo;
+
+ /**
+ * Constructor specifying the location of the local repo. Relative paths are resolved against the user's home
+ * directory.
+ *
+ * @param repoPath the path to the local repo
+ */
+ public LocalMavenRepository(@Property(name = "repository") String repoPath) {
+ String home = AccessController.doPrivileged(new PrivilegedAction<String>() {
+ public String run() {
+ return System.getProperty("user.home");
+ }
+ });
+ this.localRepo = new File(home, repoPath);
+ }
+
+ public void resolve(Artifact artifact) {
+ if (artifact.getUrl() != null) {
+ return;
+ }
+
+ String path = getPath(artifact);
+ File artifactFile = new File(localRepo, path);
+ if (artifactFile.exists()) {
+ try {
+ artifact.setUrl(artifactFile.toURI().toURL());
+ } catch (MalformedURLException e) {
+ // toURI should have escaped the filename to allow it to be converted to a URL
+ throw new AssertionError();
+ }
+ }
+ }
+
+ /**
+ * Return the path into the repo for an artifact. The path for an artifact is ${group.replace('.',
+ * '/')}/$[name}/${version}/${name}-${version}[-${classifier}].${type}
+ *
+ * @param artifact the artifact to resolve
+ * @return the path into the repo for the artifact
+ */
+ protected String getPath(Artifact artifact) {
+ StringBuilder builder = new StringBuilder();
+ if (artifact.getGroup() != null) {
+ builder.append(artifact.getGroup().replace('.', '/')).append('/');
+ }
+ builder.append(artifact.getName()).append('/');
+ builder.append(artifact.getVersion()).append('/');
+
+ builder.append(artifact.getName()).append('-').append(artifact.getVersion());
+ if (artifact.getClassifier() != null) {
+ builder.append('-').append(artifact.getClassifier());
+ }
+ builder.append('.').append(artifact.getType());
+ return builder.toString();
+ }
+
+ public void resolve(Collection<? extends Artifact> artifacts) {
+ for (Artifact artifact : artifacts) {
+ resolve(artifact);
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ArtifactResolverRegistryImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ArtifactResolverRegistryImpl.java
new file mode 100644
index 0000000000..a8fd3ba737
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ArtifactResolverRegistryImpl.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.services.deployment;
+
+import java.net.URI;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.deployer.ArtifactResolver;
+import org.apache.tuscany.spi.deployer.ArtifactResolverRegistry;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.model.Contribution;
+import org.osoa.sca.annotations.EagerInit;
+
+/**
+ * @version $Rev$ $Date$
+ */
+@EagerInit
+public class ArtifactResolverRegistryImpl implements ArtifactResolverRegistry {
+ private Map<Class, ArtifactResolver> registry = new HashMap<Class, ArtifactResolver>();
+
+ public void registerResolver(Class<?> modelClass, ArtifactResolver resolver) {
+ registry.put(modelClass, resolver);
+ }
+
+ public void unregisterResolver(Class<?> modelClass) {
+ registry.remove(modelClass);
+ }
+
+ public <T> T resolve(Contribution contribution,
+ Class<T> modelClass,
+ String namespace,
+ String name,
+ Map attributes,
+ DeploymentContext context) {
+ ArtifactResolver resolver = registry.get(modelClass);
+ if (resolver == null) {
+ return null;
+ }
+ return resolver.resolve(contribution, modelClass, namespace, name, attributes, context);
+ }
+
+ public URL resolve(Contribution contribution, String targetNamespace, String location, String baseURI) {
+ // FIXME: What's a URI resolver?
+ ArtifactResolver resolver = registry.get(URI.class);
+ if (resolver == null) {
+ return null;
+ }
+ return resolver.resolve(contribution, targetNamespace, location, baseURI);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/AssemblyServiceImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/AssemblyServiceImpl.java
new file mode 100644
index 0000000000..6982a9fa58
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/AssemblyServiceImpl.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.deployment;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.host.deployment.AssemblyService;
+import org.apache.tuscany.host.deployment.ContributionService;
+import org.apache.tuscany.host.deployment.DeploymentException;
+import org.apache.tuscany.host.deployment.UnsupportedContentTypeException;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.bootstrap.ComponentNames;
+import org.apache.tuscany.spi.builder.BuilderException;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.ComponentException;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.deployer.ChangeSetHandler;
+import org.apache.tuscany.spi.deployer.ChangeSetHandlerRegistry;
+import org.apache.tuscany.spi.deployer.Deployer;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.osoa.sca.annotations.Constructor;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class AssemblyServiceImpl implements AssemblyService, ChangeSetHandlerRegistry {
+ private final Map<String, ChangeSetHandler> registry = new HashMap<String, ChangeSetHandler>();
+
+ private final ContributionService contributionService;
+
+ private final CompositeComponent domain;
+
+ @Constructor
+ public AssemblyServiceImpl(@Autowire ContributionService contributionService, CompositeComponent domain) {
+ this.contributionService = contributionService;
+ this.domain = domain;
+ }
+
+ public Object addCompositeToDomain(URI contribution, URI composite, String artifactName)
+ throws DeploymentException {
+
+ /*Contribution contributionMetadata =
+ (Contribution)this.contributionService.getContribution(contribution);
+ DeployedArtifact scdlArtifact = contributionMetadata.getArtifacts().get(composite);
+
+ ComponentDefinition model =
+ (ComponentDefinition)scdlArtifact.getModelObject(CompositeComponentType.class, null);*/
+
+ ComponentDefinition model =
+ (ComponentDefinition) this.contributionService.resolve(contribution, ComponentDefinition.class, null, artifactName);
+
+ Component component = null;
+ Deployer deployer = null;
+
+ SCAObject child = this.domain.getSystemChild(ComponentNames.TUSCANY_DEPLOYER);
+ assert child instanceof AtomicComponent : "Deployer must be an atomic component";
+
+ try {
+
+ deployer = (Deployer)((AtomicComponent)child).getTargetInstance();
+ component = deployer.deployFromContribution(this.domain, model);
+
+ } catch (TargetResolutionException e) {
+ throw new DomainUpdateException(e);
+ } catch (BuilderException e) {
+ throw new DomainUpdateException(e);
+ } catch (ComponentException e) {
+ throw new DomainUpdateException(e);
+ }
+ component.start();
+
+ return component;
+ }
+
+ public void applyChanges(URL changeSet) throws DeploymentException, IOException {
+ if (changeSet == null) {
+ throw new IllegalArgumentException("changeSet is null");
+ }
+
+ URLConnection connection = changeSet.openConnection();
+ String contentType = connection.getContentType();
+ // todo try and figure out content type from the URL
+ if (contentType == null) {
+ throw new UnsupportedContentTypeException(null, changeSet.toString());
+ }
+
+ InputStream is = connection.getInputStream();
+ try {
+ applyChanges(is, contentType);
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+
+ public void applyChanges(InputStream changeSet, String contentType) throws DeploymentException, IOException {
+ if (changeSet == null) {
+ throw new IllegalArgumentException("changeSet is null");
+ }
+ if (contentType == null) {
+ throw new IllegalArgumentException("contentType is null");
+ }
+
+ ChangeSetHandler handler = registry.get(contentType);
+ if (handler == null) {
+ throw new UnsupportedContentTypeException(contentType);
+ }
+
+ handler.applyChanges(changeSet);
+ }
+
+ public void register(ChangeSetHandler handler) {
+ registry.put(handler.getContentType(), handler);
+ }
+
+ public <T> T getDefinition(URI contribution, Class<T> type, String namespace, String name) {
+ return contributionService.resolve(contribution, type, namespace, name);
+ }
+
+ public Object getDomainComposite() {
+ return domain;
+ }
+
+ public void removeCompositeFromDomain(URI contribution, URI composite) throws DeploymentException {
+ // TODO:
+ throw new UnsupportedOperationException("To be implemented");
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContentTypeDescriberImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContentTypeDescriberImpl.java
new file mode 100644
index 0000000000..013d916c1d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContentTypeDescriberImpl.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.services.deployment;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.core.util.FileHelper;
+import org.apache.tuscany.spi.deployer.ContentType;
+import org.apache.tuscany.spi.deployer.ContentTypeDescriber;
+import org.apache.tuscany.spi.model.Contribution;
+import org.osoa.sca.annotations.EagerInit;
+import org.osoa.sca.annotations.Service;
+
+/**
+ * Implementation of the content describer
+ *
+ * @version $Rev$ $Date$
+ */
+@EagerInit
+@Service(ContentTypeDescriber.class)
+public class ContentTypeDescriberImpl implements ContentTypeDescriber {
+ private final Map<String, String> contentTypeRegistry = new HashMap<String, String>();
+
+ public ContentTypeDescriberImpl() {
+ super();
+ init();
+ }
+
+ /**
+ * Initialize contentType registry with know types based on known file
+ * extensions
+ */
+ private void init() {
+ contentTypeRegistry.put("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 url
+ * @param defaultContentType
+ * @return
+ */
+ public String getContentType(URL resourceURL, String defaultContentType) {
+ URLConnection connection = null;
+ String contentType = defaultContentType;
+
+ if (resourceURL.getProtocol().equals("file") && FileHelper.toFile(resourceURL).isDirectory()) {
+ // Special case : contribution is a folder
+ contentType = ContentType.FOLDER;
+ } else if (resourceURL.toExternalForm().endsWith(Contribution.SCA_CONTRIBUTION_META)
+ || resourceURL.toExternalForm().endsWith(Contribution.SCA_CONTRIBUTION_GENERATED_META)) {
+ // Special case : contribution metadata
+ contentType = ContentType.CONTRIBUTION_METADATA;
+ } else {
+ contentType = resolveContentyTypeByExtension(resourceURL);
+ if (contentType == null) {
+ try {
+ connection = resourceURL.openConnection();
+ contentType = connection.getContentType();
+
+ if (contentType == null || contentType.equals("content/unknown")) {
+ // here we couldn't figure out from our registry or from URL and it's not a special file
+ // return defaultContentType if provided
+ contentType = defaultContentType;
+ }
+ } catch (IOException io) {
+ // could not access artifact, just ignore and we will return
+ // null contentType
+ }
+ }
+ }
+ return contentType == null ? defaultContentType : contentType;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionDirectoryWatcher.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionDirectoryWatcher.java
new file mode 100644
index 0000000000..f06010a0ab
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionDirectoryWatcher.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.services.deployment;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tuscany.host.deployment.ContributionService;
+import org.apache.tuscany.host.deployment.DeploymentException;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.osoa.sca.annotations.EagerInit;
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Property;
+
+@EagerInit
+public class ContributionDirectoryWatcher {
+ private final String path;
+
+ private final ContributionService contributionService;
+
+ public ContributionDirectoryWatcher(@Autowire
+ ContributionService contributionService, @Property(name = "path")
+ String path) {
+ this.path = path;
+ this.contributionService = contributionService;
+ }
+
+ @Init
+ public void init() {
+ File extensionDir = new File(path);
+ if (!extensionDir.isDirectory()) {
+ // we don't have an extension directory, there's nothing to do
+ return;
+ }
+
+ File[] files = extensionDir.listFiles();
+ for (File file : files) {
+ try {
+ if (file.isDirectory()) {
+ this.contributionService.contribute(null, file.toURL(), false);
+ } else {
+ this.contributionService.contribute(null, file.toURL(), true);
+ }
+ } catch (DeploymentException de) {
+ // FIXME handle this
+ de.printStackTrace();
+ } catch (IOException ioe) {
+ // FIXME handle this
+ ioe.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionLoader.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionLoader.java
new file mode 100644
index 0000000000..eef4bd30af
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionLoader.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.deployment;
+
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+import static org.osoa.sca.Constants.SCA_NS;
+
+import java.net.URI;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.InvalidValueException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.Contribution;
+import org.apache.tuscany.spi.model.ContributionImport;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.osoa.sca.annotations.Constructor;
+
+/**
+ * Loader that handles &lt;include&gt; elements.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ContributionLoader extends LoaderExtension<Contribution> {
+ private static final QName CONTRIBUTION = new QName(SCA_NS, "contribution");
+ private static final QName DEPLOYABLE = new QName(SCA_NS, "deployable");
+ private static final QName IMPORT = new QName(SCA_NS, "import");
+ private static final QName EXPORT = new QName(SCA_NS, "export");
+
+ @Constructor({"registry"})
+ public ContributionLoader(@Autowire LoaderRegistry registry) {
+ super(registry);
+ }
+
+ public QName getXMLType() {
+ return CONTRIBUTION;
+ }
+
+ public Contribution load(CompositeComponent parent,
+ ModelObject object,
+ XMLStreamReader reader,
+ DeploymentContext deploymentContext) throws XMLStreamException, LoaderException {
+
+ Contribution contribution = new Contribution();
+ while (true) {
+ int event = reader.next();
+ switch (event) {
+ case START_ELEMENT:
+ QName element = reader.getName();
+ 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);
+ String ns = reader.getNamespaceContext().getNamespaceURI(prefix);
+ if (ns == null) {
+ throw new InvalidValueException("Invalid prefix: " + prefix);
+ }
+ compositeName = new QName(ns, localPart, prefix);
+ } else {
+ String prefix = "";
+ String ns = reader.getNamespaceURI();
+ String localPart = name;
+ compositeName = new QName(ns, localPart, prefix);
+ }
+ contribution.getDeployables().add(compositeName);
+ } 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 = new ContributionImport();
+ if (location != null) {
+ contributionImport.setLocation(URI.create(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");
+ }
+ contribution.getExports().add(ns);
+ }
+ break;
+ case XMLStreamConstants.END_ELEMENT:
+ if (CONTRIBUTION.equals(reader.getName())) {
+ return contribution;
+ }
+ break;
+
+ }
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionProcessorRegistryImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionProcessorRegistryImpl.java
new file mode 100644
index 0000000000..47f457d396
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionProcessorRegistryImpl.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.core.services.deployment;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.host.deployment.DeploymentException;
+import org.apache.tuscany.host.deployment.UnsupportedContentTypeException;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.deployer.ContentTypeDescriber;
+import org.apache.tuscany.spi.deployer.ContributionProcessor;
+import org.apache.tuscany.spi.deployer.ContributionProcessorRegistry;
+import org.apache.tuscany.spi.model.Contribution;
+import org.osoa.sca.annotations.EagerInit;
+import org.osoa.sca.annotations.Service;
+
+/**
+ * Default implementation of ContributionProcessorRegistry
+ *
+ * @version $Rev$ $Date$
+ */
+@EagerInit
+@Service(ContributionProcessorRegistry.class)
+public class ContributionProcessorRegistryImpl implements ContributionProcessorRegistry {
+ /**
+ * Processor registry
+ */
+ private Map<String, ContributionProcessor> registry = new HashMap<String, ContributionProcessor>();
+ /**
+ * Helper method to describe contentType for each artifact
+ */
+ private ContentTypeDescriber contentTypeDescriber;
+
+ public ContributionProcessorRegistryImpl(@Autowire ContentTypeDescriber contentTypeDescriber) {
+ if (contentTypeDescriber == null) {
+ this.contentTypeDescriber = new ContentTypeDescriberImpl();
+ } else {
+ this.contentTypeDescriber = contentTypeDescriber;
+ }
+ }
+
+ public void register(String contentType, ContributionProcessor processor) {
+ registry.put(contentType, processor);
+ }
+
+ public void unregister(String contentType) {
+ registry.remove(contentType);
+ }
+
+ public void processContent(Contribution contribution, URI source, InputStream inputStream)
+ throws DeploymentException, IOException {
+
+ URL locationURL = contribution.getArtifact(source).getLocation();
+ String contentType = this.contentTypeDescriber.getContentType(locationURL, null);
+ if (contentType == null) {
+ throw new UnsupportedContentTypeException("Invalid contentType: null");
+ }
+
+ ContributionProcessor processor = this.registry.get(contentType);
+ if (processor == null) {
+ throw new UnsupportedContentTypeException(contentType, locationURL.getPath());
+ }
+ try {
+ processor.processContent(contribution, source, inputStream);
+ } catch ( Exception e ) {
+ e.printStackTrace();
+ }
+
+ }
+
+ public void processModel(Contribution contribution, URI source, Object modelObject) throws DeploymentException,
+ IOException {
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionRepositoryImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionRepositoryImpl.java
new file mode 100644
index 0000000000..b56c7fe263
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionRepositoryImpl.java
@@ -0,0 +1,275 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.services.deployment;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.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.core.util.FileHelper;
+import org.apache.tuscany.core.util.IOHelper;
+import org.apache.tuscany.spi.deployer.ContributionRepository;
+import org.osoa.sca.annotations.Constructor;
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.EagerInit;
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Property;
+
+/**
+ * The default implementation of ContributionRepository
+ *
+ * @version $Rev$ $Date$
+ */
+@EagerInit
+public class ContributionRepositoryImpl implements ContributionRepository {
+ private static final String NS = "http://tuscany.apache.org/xmlns/1.0-SNAPSHOT";
+ private final File rootFile;
+ private Map<URI, String> contributionMap = new HashMap<URI, String>();
+
+ private URI domain;
+ private XMLInputFactory factory;
+
+ /**
+ * Constructor with repository root
+ *
+ * @param repository
+ */
+ @Constructor
+ public ContributionRepositoryImpl(@Property(name = "repository")
+ 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(URI contribution) {
+ // FIXME: Map the contribution URI to a file?
+ return new File(rootFile, "contributions" + File.separator + contribution.getPath());
+ }
+
+ /**
+ * Write a specific source inputstream to a file on disk
+ *
+ * @param source contents of the file to be written to disk
+ * @param target file to be written
+ * @throws IOException
+ */
+ public static void copy(InputStream source, File target) throws IOException {
+ BufferedOutputStream out = null;
+ BufferedInputStream in = null;
+
+ try {
+ out = new BufferedOutputStream(new FileOutputStream(target));
+ in = new BufferedInputStream(source);
+ IOHelper.copy(in, out);
+ } finally {
+ IOHelper.closeQuietly(out);
+ IOHelper.closeQuietly(in);
+ }
+ }
+
+ public URL store(URI contribution, InputStream contributionStream) throws IOException {
+ // where the file should be stored in the repository
+ File location = mapToFile(contribution);
+ 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(URI contribution, URL sourceURL) throws IOException {
+ // where the file should be stored in the repository
+ File location = mapToFile(contribution);
+ File source = FileHelper.toFile(sourceURL);
+ if (source == null || source.isFile()) {
+ InputStream is = sourceURL.openStream();
+ try {
+ return store(contribution, 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(URI 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(URI 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<URI> list() {
+ return new ArrayList<URI>(contributionMap.keySet());
+ }
+
+ @Init
+ 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.create(uri), location);
+ }
+ break;
+ default:
+ break;
+ }
+ reader.next();
+ }
+ } catch (Exception e) {
+ // Ignore
+ } finally {
+ IOHelper.closeQuietly(is);
+ }
+ }
+
+ private void saveMap() {
+ File domainFile = new File(rootFile, "sca-domain.xml");
+ 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<URI, 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);
+ }
+ }
+
+ @Destroy
+ public void destroy() {
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionServiceImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionServiceImpl.java
new file mode 100644
index 0000000000..5d28d5f2ef
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/ContributionServiceImpl.java
@@ -0,0 +1,232 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.deployment;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.core.util.IOHelper;
+import org.apache.tuscany.host.deployment.ContributionService;
+import org.apache.tuscany.host.deployment.DeploymentException;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.deployer.ArtifactResolverRegistry;
+import org.apache.tuscany.spi.deployer.ContributionProcessorRegistry;
+import org.apache.tuscany.spi.deployer.ContributionRepository;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.Contribution;
+import org.apache.tuscany.spi.model.DeployedArtifact;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ContributionServiceImpl implements ContributionService {
+ /**
+ * Repository where contributions are stored. Usually set by injection.
+ */
+ protected ContributionRepository contributionRepository;
+
+ /**
+ * Registry of available processors. Usually set by injection.
+ */
+ protected ContributionProcessorRegistry processorRegistry;
+
+ /**
+ * xml factory used to create reader instance to load contribution metadata
+ */
+ protected XMLInputFactory xmlFactory;
+ /**
+ * contribution metadata loader
+ */
+ protected ContributionLoader contributionLoader;
+
+
+ /**
+ * Contribution registry This is a registry of processed Contributios index
+ * by URI
+ */
+ protected Map<URI, Contribution> contributionRegistry = new HashMap<URI, Contribution>();
+
+ protected ArtifactResolverRegistry resolverRegistry;
+
+ public ContributionServiceImpl(@Autowire
+ ContributionRepository repository, @Autowire
+ ContributionProcessorRegistry processorRegistry, @Autowire
+ ArtifactResolverRegistry resolverRegistry) {
+ super();
+ this.contributionRepository = repository;
+ this.processorRegistry = processorRegistry;
+ this.resolverRegistry = resolverRegistry;
+
+ this.xmlFactory = XMLInputFactory.newInstance("javax.xml.stream.XMLInputFactory", getClass().getClassLoader());
+ this.contributionLoader = new ContributionLoader(null);
+ }
+
+ public void contribute(URI contributionURI, URL sourceURL, boolean storeInRepository) throws DeploymentException,
+ 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");
+ }
+
+ addContribution(contributionURI, sourceURL, null, storeInRepository);
+ }
+
+ public void contribute(URI contributionURI, InputStream input) throws DeploymentException, IOException {
+ addContribution(contributionURI, null, input, true);
+ }
+
+ private Contribution initializeContributionMetadata(URL sourceURL) throws DeploymentException {
+ Contribution contributionMetadata = null;
+ URL contributionMetadataURL;
+ URL generatedContributionMetadataURL;
+ InputStream metadataStream = null;
+
+ URL[] clUrls = {sourceURL};
+ URLClassLoader cl = new URLClassLoader(clUrls, getClass().getClassLoader());
+
+ contributionMetadataURL = cl.getResource(Contribution.SCA_CONTRIBUTION_META);
+ generatedContributionMetadataURL = cl.getResource(Contribution.SCA_CONTRIBUTION_GENERATED_META);
+
+ try {
+ if (contributionMetadataURL == null && generatedContributionMetadataURL == null) {
+ contributionMetadata = new Contribution();
+ } else {
+ URL metadataURL =
+ contributionMetadataURL != null ? contributionMetadataURL : generatedContributionMetadataURL;
+
+ try {
+ metadataStream = metadataURL.openStream();
+ XMLStreamReader xmlReader = this.xmlFactory.createXMLStreamReader(metadataStream);
+ contributionMetadata = this.contributionLoader.load(null, null, xmlReader, null);
+
+ } catch (IOException ioe) {
+ throw new
+ InvalidContributionMetadataException(ioe.getMessage(), metadataURL.toExternalForm(), ioe);
+ } catch (XMLStreamException xmle) {
+ throw new
+ InvalidContributionMetadataException(xmle.getMessage(), metadataURL.toExternalForm(), xmle);
+ } catch (LoaderException le) {
+ throw new
+ InvalidContributionMetadataException(le.getMessage(), metadataURL.toExternalForm(), le);
+ }
+ }
+ } finally {
+ IOHelper.closeQuietly(metadataStream);
+ metadataStream = null;
+ }
+
+ if (contributionMetadata == null) {
+ contributionMetadata = new Contribution();
+ }
+
+ return contributionMetadata;
+
+ }
+
+ /**
+ * Note:
+ * @param contributionURI ContributionID
+ * @param sourceURL contribution location
+ * @param contributionStream contribution content
+ * @param storeInRepository flag if we store the contribution into the repository or not
+ * @throws IOException
+ * @throws DeploymentException
+ */
+ private void addContribution(URI contributionURI, URL sourceURL, InputStream contributionStream, boolean storeInRepository)
+ throws IOException, DeploymentException {
+ 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 (sourceURL != null) {
+ locationURL = contributionRepository.store(contributionURI, sourceURL);
+ } else {
+ locationURL = contributionRepository.store(contributionURI, contributionStream);
+ }
+ }
+
+ Contribution contribution = initializeContributionMetadata(locationURL);
+ contribution.setURI(contributionURI);
+ contribution.setLocation(locationURL);
+
+ if (contributionStream == null) {
+ contributionStream = sourceURL.openStream();
+ try {
+ // process the contribution
+ this.processorRegistry.processContent(contribution, contribution.getUri(), contributionStream);
+ } finally {
+ IOHelper.closeQuietly(contributionStream);
+ contributionStream = null;
+ }
+
+ } else {
+ // process the contribution
+ this.processorRegistry.processContent(contribution, contribution.getUri(), contributionStream);
+ }
+
+
+ // store the contribution on the registry
+ this.contributionRegistry.put(contribution.getUri(), contribution);
+ }
+
+ public Object getContribution(URI id) {
+ return this.contributionRegistry.get(id);
+ }
+
+ public void remove(URI contribution) throws DeploymentException {
+ // remove from repository
+ this.contributionRegistry.remove(contribution);
+ }
+
+ public void addDeploymentComposite(URI contribution, Object composite) {
+ CompositeComponentType model = (CompositeComponentType)composite;
+ URI compositeURI = contribution.resolve(model.getName() + ".composite");
+ DeployedArtifact artifact = new DeployedArtifact(compositeURI);
+ // FIXME: the namespace should be from the CompositeComponentType model
+ artifact.addModelObject(composite.getClass(), null, composite);
+ Contribution contributionObject = (Contribution)getContribution(contribution);
+ contributionObject.addArtifact(artifact);
+ }
+
+ public <T> T resolve(URI contribution, Class<T> definitionType, String namespace, String name) {
+ Contribution contributionObject = (Contribution)getContribution(contribution);
+ return resolverRegistry.resolve(contributionObject, definitionType, namespace, name, null, null);
+ }
+
+ public URL resolve(URI contribution, String namespace, URI uri, URI baseURI) {
+ Contribution contributionObject = (Contribution)getContribution(contribution);
+ return resolverRegistry.resolve(contributionObject, namespace, uri.toString(), baseURI.toString());
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/DomainUpdateException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/DomainUpdateException.java
new file mode 100644
index 0000000000..65df12f35c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/DomainUpdateException.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.services.deployment;
+
+import org.apache.tuscany.host.deployment.DeploymentException;
+
+public class DomainUpdateException extends DeploymentException {
+ public DomainUpdateException() {
+ }
+
+ public DomainUpdateException(String message) {
+ super(message);
+ }
+
+ public DomainUpdateException(String message, String identifier) {
+ super(message, identifier);
+ }
+
+ public DomainUpdateException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public DomainUpdateException(String message, String identifier, Throwable cause) {
+ super(message, identifier, cause);
+ }
+
+ public DomainUpdateException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/InvalidContributionMetadataException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/InvalidContributionMetadataException.java
new file mode 100644
index 0000000000..110633e685
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/InvalidContributionMetadataException.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.deployment;
+
+import org.apache.tuscany.host.deployment.DeploymentException;
+
+/**
+ * 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 DeploymentException {
+
+ protected InvalidContributionMetadataException() {
+ }
+
+ protected InvalidContributionMetadataException(String message) {
+ super(message);
+ }
+
+ protected InvalidContributionMetadataException(String message, String identifier) {
+ super(message, identifier);
+ }
+
+ protected InvalidContributionMetadataException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ protected InvalidContributionMetadataException(String message, String identifier, Throwable cause) {
+ super(message, identifier, cause);
+ }
+
+ protected InvalidContributionMetadataException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/InvalidDocumentException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/InvalidDocumentException.java
new file mode 100644
index 0000000000..c4848a3a08
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/InvalidDocumentException.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.deployment;
+
+import org.apache.tuscany.host.deployment.DeploymentException;
+
+/**
+ * Exception that indicates that the supplied XML Document invalid.
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidDocumentException extends DeploymentException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8872656291809499499L;
+
+ protected InvalidDocumentException(String rootElement) {
+ super(rootElement);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/XMLChangeSetHandler.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/XMLChangeSetHandler.java
new file mode 100644
index 0000000000..87f68340e2
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/XMLChangeSetHandler.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.deployment;
+
+import java.io.IOException;
+import java.io.InputStream;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import static javax.xml.stream.XMLStreamConstants.END_DOCUMENT;
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.bootstrap.RuntimeComponent;
+import org.apache.tuscany.spi.builder.Builder;
+import org.apache.tuscany.spi.builder.BuilderException;
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.ComponentRegistrationException;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.PrepareException;
+import org.apache.tuscany.spi.deployer.ChangeSetHandler;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.loader.Loader;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+
+import org.apache.tuscany.core.deployer.RootDeploymentContext;
+import org.apache.tuscany.host.deployment.ContentTypes;
+import org.apache.tuscany.host.deployment.DeploymentException;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class XMLChangeSetHandler implements ChangeSetHandler {
+ private static final String NS = "http://tuscany.apache.org/xmlns/1.0-SNAPSHOT";
+ private static final QName CHANGESET = new QName(NS, "changeSet");
+ private static final QName CREATECOMPONENT = new QName(NS, "createComponent");
+
+ private final RuntimeComponent runtime;
+ private final Builder builder;
+ private final Loader loader;
+ private final XMLInputFactory xmlFactory;
+
+ public XMLChangeSetHandler(RuntimeComponent runtime, Loader loader, Builder builder) {
+ this.runtime = runtime;
+ this.loader = loader;
+ this.builder = builder;
+ xmlFactory = XMLInputFactory.newInstance("javax.xml.stream.XMLInputFactory", getClass().getClassLoader());
+ }
+
+ public String getContentType() {
+ return ContentTypes.CHANGESET_XML;
+ }
+
+ public void applyChanges(InputStream changeSet) throws DeploymentException, IOException {
+ try {
+ XMLStreamReader xmlReader = xmlFactory.createXMLStreamReader(changeSet);
+ while (true) {
+ switch (xmlReader.next()) {
+ case START_ELEMENT:
+ if (!CHANGESET.equals(xmlReader.getName())) {
+ throw new InvalidDocumentException(xmlReader.getName().toString());
+ }
+ processChanges(xmlReader);
+ break;
+ case END_DOCUMENT:
+ return;
+ }
+ }
+ } catch (XMLStreamException e) {
+ throw (IOException) new IOException(e.getMessage()).initCause(e);
+ }
+ }
+
+ public void processChanges(XMLStreamReader xmlReader) throws XMLStreamException, DeploymentException {
+ while (true) {
+ switch (xmlReader.next()) {
+ case START_ELEMENT:
+ if (CREATECOMPONENT.equals(xmlReader.getName())) {
+ createComponent(xmlReader);
+ } else {
+ // reject unrecognized commands
+ throw new InvalidDocumentException(xmlReader.getName().toString());
+ }
+ break;
+ case END_ELEMENT:
+ return;
+ }
+ }
+ }
+
+ public void createComponent(XMLStreamReader xmlReader) throws XMLStreamException {
+ DeploymentContext deploymentContext = new RootDeploymentContext(null, xmlFactory, null, null);
+ CompositeComponent parent = runtime.getRootComponent();
+ try {
+ ComponentDefinition<?> componentDefinition =
+ (ComponentDefinition<?>) loader.load(parent, null, xmlReader, deploymentContext);
+ Component component = builder.build(parent, componentDefinition, deploymentContext);
+ component.prepare();
+ parent.register(component);
+ } catch (LoaderException e) {
+ // FIXME throw something appropriate
+ throw new AssertionError("FIXME");
+ } catch (BuilderException e) {
+ // FIXME throw something appropriate
+ throw new AssertionError("FIXME");
+ } catch (PrepareException e) {
+ // FIXME throw something appropriate
+ throw new AssertionError("FIXME");
+ } catch (ComponentRegistrationException e) {
+ // FIXME throw something appropriate
+ throw new AssertionError("FIXME");
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/CompositeContributionProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/CompositeContributionProcessor.java
new file mode 100644
index 0000000000..8309273b3f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/CompositeContributionProcessor.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.services.deployment.contribution;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+
+import javax.xml.stream.XMLInputFactory;
+
+import org.apache.tuscany.core.deployer.RootDeploymentContext;
+import org.apache.tuscany.host.deployment.DeploymentException;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.deployer.CompositeClassLoader;
+import org.apache.tuscany.spi.deployer.ContentType;
+import org.apache.tuscany.spi.deployer.ContributionProcessor;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.ContributionProcessorExtension;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.CompositeImplementation;
+import org.apache.tuscany.spi.model.Contribution;
+
+public class CompositeContributionProcessor extends ContributionProcessorExtension implements ContributionProcessor {
+ /**
+ * Content-type that this processor can handle
+ */
+ public static final String CONTENT_TYPE = ContentType.COMPOSITE;
+
+ protected XMLInputFactory xmlFactory;
+ private final LoaderRegistry registry;
+
+ public CompositeContributionProcessor(@Autowire LoaderRegistry registry) {
+ super();
+ this.registry = registry;
+ this.xmlFactory = XMLInputFactory.newInstance("javax.xml.stream.XMLInputFactory", getClass().getClassLoader());
+ }
+
+ @Override
+ public String getContentType() {
+ return CONTENT_TYPE;
+ }
+
+ public void processContent(Contribution contribution, URI artifactURI, InputStream inputStream)
+ throws DeploymentException, IOException {
+ if (artifactURI == null) {
+ throw new IllegalArgumentException("Invalid null source uri.");
+ }
+
+ if (inputStream == null) {
+ throw new IllegalArgumentException("Invalid null source inputstream.");
+ }
+
+ try {
+ CompositeClassLoader cl = new CompositeClassLoader(getClass().getClassLoader());
+ cl.addURL(contribution.getLocation());
+ DeploymentContext deploymentContext = new RootDeploymentContext(cl, this.xmlFactory, null,
+ contribution.getArtifact(artifactURI).getLocation());
+
+ CompositeComponentType componentType = this.registry.load(null, null,
+ contribution.getArtifact(artifactURI).getLocation(),
+ CompositeComponentType.class, deploymentContext);
+
+ CompositeImplementation implementation = new CompositeImplementation();
+ implementation.setComponentType(componentType);
+ ComponentDefinition<CompositeImplementation> componentDefinition =
+ new ComponentDefinition<CompositeImplementation>(implementation);
+
+ componentDefinition.setName(componentType.getName());
+
+ contribution.getArtifact(artifactURI).addModelObject(CompositeComponentType.class, null, componentDefinition);
+
+ } catch (LoaderException le) {
+ throw new InvalidComponentDefinitionlException(contribution.getArtifact(artifactURI).getLocation()
+ .toExternalForm(), le);
+ }
+ }
+
+ public void processModel(Contribution contribution, URI source, Object modelObject) throws DeploymentException,
+ IOException {
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/FolderContributionProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/FolderContributionProcessor.java
new file mode 100644
index 0000000000..3bcfefb1ca
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/FolderContributionProcessor.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.services.deployment.contribution;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.core.services.deployment.ContentTypeDescriberImpl;
+import org.apache.tuscany.core.util.FileHelper;
+import org.apache.tuscany.core.util.IOHelper;
+import org.apache.tuscany.host.deployment.DeploymentException;
+import org.apache.tuscany.spi.deployer.ContentType;
+import org.apache.tuscany.spi.deployer.ContentTypeDescriber;
+import org.apache.tuscany.spi.deployer.ContributionProcessor;
+import org.apache.tuscany.spi.extension.ContributionProcessorExtension;
+import org.apache.tuscany.spi.model.Contribution;
+import org.apache.tuscany.spi.model.DeployedArtifact;
+
+public class FolderContributionProcessor extends ContributionProcessorExtension implements ContributionProcessor {
+ /**
+ * Content-type that this processor can handle
+ */
+ public static final String CONTENT_TYPE = ContentType.FOLDER;
+
+ @Override
+ public String getContentType() {
+ return CONTENT_TYPE;
+ }
+
+ /**
+ * Recursively traverse a root directory
+ *
+ * @param fileList
+ * @param root
+ * @throws IOException
+ */
+ private void traverse(List<URL> fileList, File root) throws IOException {
+ if (root.isFile()) {
+ fileList.add(root.toURL());
+ } else if (root.isDirectory()) {
+ // FIXME: Maybe we should externalize it as a property
+ // Regular expression to exclude .xxx files
+ File[] files = root.listFiles(FileHelper.getFileFilter("[^\u002e].*", true));
+ for (int i = 0; i < files.length; i++) {
+ traverse(fileList, files[i]);
+ }
+ }
+ }
+
+ /**
+ * Get a list of files from the directory
+ *
+ * @return
+ * @throws IOException
+ */
+ protected List<URL> getArtifacts(URL rootURL) throws DeploymentException,
+ IOException {
+ List<URL> artifacts = new ArrayList<URL>();
+
+ // Assume the root is a jar file
+ File rootFolder;
+
+ try {
+ rootFolder = new File(rootURL.toURI());
+ if (rootFolder.isDirectory()) {
+ this.traverse(artifacts, rootFolder);
+ }
+
+ } catch (URISyntaxException e) {
+ throw new InvalidFolderContributionURIException(rootURL.toExternalForm(), e);
+ }
+
+ return artifacts;
+ }
+
+ public void processContent(Contribution contribution, URI source, InputStream inputStream)
+ throws DeploymentException, IOException {
+ if (contribution == null) {
+ throw new IllegalArgumentException("Invalid null contribution.");
+ }
+
+ if (source == null) {
+ throw new IllegalArgumentException("Invalid null source uri.");
+ }
+
+ URL contributionURL = contribution.getArtifact(source).getLocation();
+
+ for (URL artifactURL : getArtifacts(contributionURL)) {
+ String artifactPath = artifactURL.toExternalForm().substring(contributionURL.toExternalForm().length());
+ URI artifactURI = contribution.getUri().resolve(artifactPath);
+ DeployedArtifact artifact = new DeployedArtifact(artifactURI);
+ artifact.setLocation(artifactURL);
+ contribution.addArtifact(artifact);
+
+ ContentTypeDescriber contentTypeDescriber = new ContentTypeDescriberImpl();
+ String contentType = contentTypeDescriber.getContentType(artifactURL, null);
+
+ // just process scdl and contribution metadata for now
+ if (ContentType.COMPOSITE.equals(contentType)) {
+ InputStream is = artifactURL.openStream();
+ try {
+ this.registry.processContent(contribution, artifactURI, is);
+ } finally {
+ IOHelper.closeQuietly(is);
+ is = null;
+ }
+ }
+ }
+ }
+
+ public void processModel(Contribution contribution, URI source, Object modelObject) throws DeploymentException,
+ IOException {
+ // NOOP
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidComponentDefinitionlException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidComponentDefinitionlException.java
new file mode 100644
index 0000000000..c5c7d8cbf9
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidComponentDefinitionlException.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.deployment.contribution;
+
+import org.apache.tuscany.host.deployment.DeploymentException;
+
+/**
+ * Exception that indicates that the supplied XML Document invalid.
+ *
+ */
+public class InvalidComponentDefinitionlException extends DeploymentException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2724173457894813837L;
+
+ protected InvalidComponentDefinitionlException(String componentDefinitionLocatoin) {
+ super(componentDefinitionLocatoin);
+ }
+
+ protected InvalidComponentDefinitionlException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidFolderContributionURIException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidFolderContributionURIException.java
new file mode 100644
index 0000000000..0e6ff6b5e8
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidFolderContributionURIException.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.services.deployment.contribution;
+
+import org.apache.tuscany.host.deployment.DeploymentException;
+
+/**
+ *
+ */
+public class InvalidFolderContributionURIException extends DeploymentException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1564255850052593282L;
+
+ protected InvalidFolderContributionURIException(String componentDefinitionLocatoin) {
+ super(componentDefinitionLocatoin);
+ }
+
+ protected InvalidFolderContributionURIException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidPojoComponentDefinitionlException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidPojoComponentDefinitionlException.java
new file mode 100644
index 0000000000..e2d2f12cb5
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/InvalidPojoComponentDefinitionlException.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.deployment.contribution;
+
+import org.apache.tuscany.host.deployment.DeploymentException;
+
+/**
+ * Exception that indicates that the supplied XML Document invalid.
+ *
+ */
+public class InvalidPojoComponentDefinitionlException extends DeploymentException {
+
+ protected InvalidPojoComponentDefinitionlException(String componentDefinitionLocatoin) {
+ super(componentDefinitionLocatoin);
+ }
+
+ protected InvalidPojoComponentDefinitionlException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/JarContributionProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/JarContributionProcessor.java
new file mode 100644
index 0000000000..819c0ce9e6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/JarContributionProcessor.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.services.deployment.contribution;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+import org.apache.tuscany.core.services.deployment.ContentTypeDescriberImpl;
+import org.apache.tuscany.core.util.IOHelper;
+import org.apache.tuscany.host.deployment.DeploymentException;
+import org.apache.tuscany.spi.deployer.ContentType;
+import org.apache.tuscany.spi.deployer.ContentTypeDescriber;
+import org.apache.tuscany.spi.deployer.ContributionProcessor;
+import org.apache.tuscany.spi.extension.ContributionProcessorExtension;
+import org.apache.tuscany.spi.model.Contribution;
+import org.apache.tuscany.spi.model.DeployedArtifact;
+
+public class JarContributionProcessor extends ContributionProcessorExtension implements ContributionProcessor {
+ /**
+ * Content-type that this processor can handle
+ */
+ public static final String CONTENT_TYPE = ContentType.JAR;
+
+ @Override
+ public String getContentType() {
+ return CONTENT_TYPE;
+ }
+
+ /**
+ * Get a list of resources inside the jar
+ *
+ * @return
+ * @throws IOException
+ */
+ protected List<URL> getArtifacts(URL rootURL, InputStream sourceInputStream) throws IOException {
+ List<URL> artifacts = new ArrayList<URL>();
+
+ // Assume the root is a jar file
+ JarInputStream jar = new JarInputStream(sourceInputStream);
+ try {
+ while (true) {
+ JarEntry entry = jar.getNextJarEntry();
+ if (entry == null) {
+ // EOF
+ break;
+ }
+ if (entry.isDirectory()) {
+ continue;
+ }
+
+ // FIXME: Maybe we should externalize the filter as a property
+ if (!entry.getName().startsWith(".")) {
+ artifacts.add(new URL(rootURL, entry.getName()));
+ }
+ }
+ } finally {
+ jar.close();
+ }
+ return artifacts;
+ }
+
+ private URL forceJarURL(URL sourceURL) throws MalformedURLException {
+ if (sourceURL.toString().startsWith("jar:")) {
+ return sourceURL;
+ } else {
+ return new URL("jar:" + sourceURL.toExternalForm() + "!/");
+ }
+
+ }
+
+ public void processContent(Contribution contribution, URI source, InputStream inputStream)
+ throws DeploymentException, IOException {
+ if (contribution == null) {
+ throw new IllegalArgumentException("Invalid null contribution.");
+ }
+
+ if (source == null) {
+ throw new IllegalArgumentException("Invalid null source uri.");
+ }
+
+ if (inputStream == null) {
+ throw new IllegalArgumentException("Invalid null source inputstream.");
+ }
+
+ URL sourceURL = contribution.getArtifact(source).getLocation();
+
+ sourceURL = forceJarURL(sourceURL);
+
+ for (URL artifactURL : getArtifacts(sourceURL, inputStream)) {
+ URI artifactURI;
+
+ String artifactPath = artifactURL.toExternalForm().substring(sourceURL.toExternalForm().length());
+ artifactURI = contribution.getUri().resolve(artifactPath);
+ DeployedArtifact artifact = new DeployedArtifact(artifactURI);
+ artifact.setLocation(artifactURL);
+ contribution.addArtifact(artifact);
+
+
+ ContentTypeDescriber contentTypeDescriber = new ContentTypeDescriberImpl();
+ String contentType = contentTypeDescriber.getContentType(artifactURL, null);
+
+ // just process scdl for now
+ if (ContentType.COMPOSITE.equals(contentType)) {
+ InputStream is = IOHelper.getInputStream(artifactURL);
+ try {
+ this.registry.processContent(contribution, artifactURI, is);
+ } finally {
+ IOHelper.closeQuietly(is);
+ is = null;
+ }
+ }
+ }
+
+ }
+
+ public void processModel(Contribution contribution, URI source, Object modelObject) throws DeploymentException,
+ IOException {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/JavaContributionProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/JavaContributionProcessor.java
new file mode 100644
index 0000000000..0a95dcc684
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/JavaContributionProcessor.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.services.deployment.contribution;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+
+import org.apache.tuscany.host.deployment.DeploymentException;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.deployer.CompositeClassLoader;
+import org.apache.tuscany.spi.deployer.ContentType;
+import org.apache.tuscany.spi.deployer.ContributionProcessor;
+import org.apache.tuscany.spi.extension.ContributionProcessorExtension;
+import org.apache.tuscany.spi.implementation.java.IntrospectionRegistry;
+import org.apache.tuscany.spi.implementation.java.Introspector;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+import org.apache.tuscany.spi.model.Contribution;
+import org.osoa.sca.annotations.Constructor;
+
+public class JavaContributionProcessor extends ContributionProcessorExtension implements ContributionProcessor {
+ /**
+ * Content-type that this processor can handle
+ */
+ public static final String CONTENT_TYPE = ContentType.JAVA;
+ /**
+ * Pojo introspector
+ */
+ private Introspector introspector;
+
+ @Constructor("introspector")
+ public JavaContributionProcessor(@Autowire IntrospectionRegistry introspector) {
+ this.introspector = introspector;
+ }
+
+ @Override
+ public String getContentType() {
+ return CONTENT_TYPE;
+ }
+
+ private String getClazzName(URL clazzURL) {
+ String clazzName;
+
+ clazzName =
+ clazzURL.toExternalForm().substring(clazzURL.toExternalForm().lastIndexOf("!/") + 2,
+ clazzURL.toExternalForm().length() - ".class".length());
+ clazzName = clazzName.replace("/", ".");
+
+ return clazzName;
+ }
+
+ public void processContent(Contribution contribution, URI artifactURI, InputStream inputStream)
+ throws DeploymentException, IOException {
+ if (artifactURI == null) {
+ throw new IllegalArgumentException("Invalid null source uri.");
+ }
+
+ if (inputStream == null) {
+ throw new IllegalArgumentException("Invalid null source inputstream.");
+ }
+
+ try {
+ CompositeClassLoader cl = new CompositeClassLoader(getClass().getClassLoader());
+ cl.addURL(contribution.getLocation());
+
+ String clazzName = getClazzName(contribution.getArtifact(artifactURI).getLocation());
+
+ Class clazz = cl.loadClass(clazzName);
+
+ PojoComponentType javaInfo = introspector.introspect(null, clazz, null, null);
+
+ contribution.getArtifact(artifactURI).addModelObject(PojoComponentType.class, null, javaInfo);
+
+ } catch (ClassNotFoundException cnfe) {
+ throw new InvalidPojoComponentDefinitionlException(contribution.getArtifact(artifactURI).getLocation()
+ .toExternalForm(), cnfe);
+ } catch (ProcessingException pe) {
+ throw new InvalidPojoComponentDefinitionlException(contribution.getArtifact(artifactURI).getLocation()
+ .toExternalForm(), pe);
+ }
+ }
+
+ public void processModel(Contribution contribution, URI source, Object modelObject) throws DeploymentException,
+ IOException {
+ // NOOP
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/MetadataContributionProcessor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/MetadataContributionProcessor.java
new file mode 100644
index 0000000000..63d8320860
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/contribution/MetadataContributionProcessor.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.services.deployment.contribution;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.core.services.deployment.ContributionLoader;
+import org.apache.tuscany.host.deployment.DeploymentException;
+import org.apache.tuscany.spi.deployer.ContentType;
+import org.apache.tuscany.spi.deployer.ContributionProcessor;
+import org.apache.tuscany.spi.extension.ContributionProcessorExtension;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.model.Contribution;
+
+public class MetadataContributionProcessor extends ContributionProcessorExtension implements ContributionProcessor {
+ /**
+ * Content-type that this processor can handle
+ */
+ public static final String CONTENT_TYPE = ContentType.CONTRIBUTION_METADATA;
+
+ protected XMLInputFactory xmlFactory;
+ protected ContributionLoader contributionLoader;
+
+ public MetadataContributionProcessor() {
+ super();
+ this.xmlFactory = XMLInputFactory.newInstance("javax.xml.stream.XMLInputFactory", getClass().getClassLoader());
+ this.contributionLoader = new ContributionLoader(null);
+ }
+
+ @Override
+ public String getContentType() {
+ return CONTENT_TYPE;
+ }
+
+ public void processContent(Contribution contribution, URI artifactURI, InputStream inputStream)
+ throws DeploymentException, IOException {
+ if (artifactURI == null) {
+ throw new IllegalArgumentException("Invalid null source uri.");
+ }
+
+ if (inputStream == null) {
+ throw new IllegalArgumentException("Invalid null source inputstream.");
+ }
+
+ try {
+ XMLStreamReader xmlReader = this.xmlFactory.createXMLStreamReader(inputStream);
+ Contribution contributionMetadata = this.contributionLoader.load(null, null, xmlReader, null);
+
+ for (QName deployable : contributionMetadata.getDeployables()) {
+ System.out.println("Deployable : " + deployable.toString());
+ }
+
+ } catch (XMLStreamException xmle) {
+ throw new InvalidComponentDefinitionlException(contribution.getArtifact(artifactURI).getLocation()
+ .toExternalForm(), xmle);
+ } catch (LoaderException le){
+ throw new InvalidComponentDefinitionlException(contribution.getArtifact(artifactURI).getLocation()
+ .toExternalForm(), le);
+ }
+ }
+
+ public void processModel(Contribution contribution, URI source, Object modelObject) throws DeploymentException,
+ IOException {
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/resolver/ComponentDefinitionArtifactResolver.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/resolver/ComponentDefinitionArtifactResolver.java
new file mode 100644
index 0000000000..27586a322e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/deployment/resolver/ComponentDefinitionArtifactResolver.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.services.deployment.resolver;
+
+import java.net.URI;
+import java.net.URL;
+import java.util.Map;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.deployer.ArtifactResolver;
+import org.apache.tuscany.spi.deployer.ArtifactResolverRegistry;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.ArtifactResolverExtension;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.Contribution;
+import org.apache.tuscany.spi.model.DeployedArtifact;
+
+public class ComponentDefinitionArtifactResolver extends ArtifactResolverExtension implements ArtifactResolver {
+
+ public ComponentDefinitionArtifactResolver(@Autowire
+ ArtifactResolverRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public Class<?> getType() {
+ return ComponentDefinition.class;
+ }
+
+ public <ComponentDefinition> ComponentDefinition resolve(Contribution contribution,
+ Class<ComponentDefinition> modelClass,
+ String namespace,
+ String name,
+ Map attributes,
+ DeploymentContext context) {
+
+ // generate artifact uri based on it's name
+ URI artifactURI = contribution.getUri().resolve(name);
+ DeployedArtifact artifact = contribution.getArtifact(artifactURI);
+
+ ComponentDefinition componentDefinition =
+ (ComponentDefinition)artifact.getModelObject(CompositeComponentType.class, null);
+ return componentDefinition;
+ }
+
+ public URL resolve(Contribution contribution, String targetNamespace, String location, String baseURI) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/extension/AbstractExtensionDeployer.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/extension/AbstractExtensionDeployer.java
new file mode 100644
index 0000000000..cc3339e2b7
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/extension/AbstractExtensionDeployer.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.extension;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.tuscany.core.implementation.system.model.SystemCompositeImplementation;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ComponentException;
+import org.apache.tuscany.spi.deployer.CompositeClassLoader;
+import org.apache.tuscany.spi.deployer.Deployer;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.builder.BuilderException;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class AbstractExtensionDeployer {
+ protected Deployer deployer;
+ protected CompositeComponent parent;
+
+ @Autowire
+ public void setDeployer(Deployer deployer) {
+ this.deployer = deployer;
+ }
+
+ @Autowire
+ public void setParent(CompositeComponent parent) {
+ this.parent = parent;
+ }
+
+ protected void deployExtension(File file) {
+ // extension name is file name less any extension
+ String name = file.getName();
+ int dot = name.lastIndexOf('.');
+ if (dot > 0) {
+ name = name.substring(0, dot);
+ }
+ URL url;
+ try {
+ url = file.toURI().toURL();
+ } catch (MalformedURLException e) {
+ // toURI should have encoded the URL
+ throw new AssertionError();
+ }
+
+ deployExtension(name, url);
+ }
+
+ protected void deployExtension(String name, URL url) {
+ // FIXME for now, assume this class's ClassLoader is the Tuscany system classloader
+ // FIXME we should really use the one associated with the parent composite
+ CompositeClassLoader extensionCL = new CompositeClassLoader(getClass().getClassLoader());
+
+ // see if the URL points to a composite JAR by looking for a default SCDL file inside it
+ URL scdlLocation;
+ try {
+ scdlLocation = new URL("jar:" + url.toExternalForm() + "!/META-INF/sca/default.scdl");
+ } catch (MalformedURLException e) {
+ // the form of the jar: URL should be correct given url.toExternalForm() worked
+ throw new AssertionError();
+ }
+ try {
+ scdlLocation.openStream().close();
+ // we connected to the SCDL so let's add the JAR file to the classloader
+ extensionCL.addURL(url);
+ } catch (IOException e) {
+ // assume that the URL we were given is not a JAR file so just use the supplied resource
+ scdlLocation = url;
+ }
+
+ // create a ComponentDefinition to represent the component we are going to deploy
+ SystemCompositeImplementation implementation = new SystemCompositeImplementation();
+ implementation.setScdlLocation(scdlLocation);
+ implementation.setClassLoader(extensionCL);
+ ComponentDefinition<SystemCompositeImplementation> definition =
+ new ComponentDefinition<SystemCompositeImplementation>(name, implementation);
+
+ // FIXME: [rfeng] Should we reset the thread context class loader here?
+ // From the debugger with tomcat, the current TCCL is the RealmClassLoader
+ // ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
+ try {
+ // Thread.currentThread().setContextClassLoader(extensionCL);
+ Component component = null;
+ try {
+ component = deployer.deploy(parent, definition);
+ component.start();
+ } catch (BuilderException e) {
+ // FIXME JFM handle the exception
+ e.printStackTrace();
+ } catch (ComponentException e) {
+ // FIXME handle the exception
+ e.printStackTrace();
+ }
+ } catch (LoaderException e) {
+ // FIXME handle the exception
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/host/DelegatingResourceHostRegistry.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/host/DelegatingResourceHostRegistry.java
new file mode 100644
index 0000000000..38ce4d16d2
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/host/DelegatingResourceHostRegistry.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.host;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osoa.sca.annotations.Service;
+
+import org.apache.tuscany.spi.host.ResourceHost;
+import org.apache.tuscany.spi.host.ResourceHostRegistry;
+import org.apache.tuscany.spi.host.ResourceResolutionException;
+
+/**
+ * The default implementation of a <code>ResourceRegisty</code> that resolves resources in the <code>SCA://</code>
+ * namespace against its parent composite and delegates resolution to registered <code>ResourceHost</code>s for other
+ * namespaces. The search order for resources resolved by type starts with the SCA namespace and proceeds to hosts in
+ * the order they were registered.
+ *
+ * @version $Rev$ $Date$
+ */
+@Service(interfaces = {ResourceHost.class, ResourceHostRegistry.class})
+public class DelegatingResourceHostRegistry implements ResourceHost, ResourceHostRegistry {
+ private static final String SCA_PREFIX = "SCA://";
+ private Map<String, ResourceHost> resourceHosts = new HashMap<String, ResourceHost>();
+ private Map<Class<?>, Object> systemResources = new HashMap<Class<?>, Object>();
+ private Map<Key, Object> mappedSystemResources = new HashMap<Key, Object>();
+
+ public DelegatingResourceHostRegistry() {
+ }
+
+ public void registerResourceHost(String uri, ResourceHost host) {
+ resourceHosts.put(uri, host);
+ }
+
+ public void unregisterResourceHost(String uri) {
+ resourceHosts.remove(uri);
+ }
+
+ public void registerResource(Class<?> type, Object resource) {
+ systemResources.put(type, resource);
+ }
+
+ public void registerResource(Class<?> type, String name, Object resource) {
+ mappedSystemResources.put(new Key(type, name), resource);
+ }
+
+ public void unregisterResource(Class<?> type, String name) {
+ mappedSystemResources.remove(new Key(type, name));
+ }
+
+ public void unregisterResource(Class<?> type) {
+ systemResources.remove(type);
+ }
+
+ public <T> T resolveResource(Class<T> type) throws ResourceResolutionException {
+ T instance = type.cast(systemResources.get(type));
+ if (instance == null) {
+ for (ResourceHost host : resourceHosts.values()) {
+ instance = host.resolveResource(type);
+ if (instance != null) {
+ return instance;
+ }
+ }
+ }
+ return instance;
+ }
+
+ public <T> T resolveResource(Class<T> type, String mappedName) throws ResourceResolutionException {
+ if (mappedName.startsWith(SCA_PREFIX)) {
+ String name = mappedName.substring(SCA_PREFIX.length());
+ return type.cast(mappedSystemResources.get(new Key(type, name)));
+ } else {
+ int pos = mappedName.indexOf("://");
+ if (pos == -1) {
+ return type.cast(mappedSystemResources.get(new Key(type, mappedName)));
+ }
+ String uri = mappedName.substring(0, pos + 3);
+ ResourceHost host = resourceHosts.get(uri);
+ if (host == null) {
+ throw new ResourceResolutionException("No resource host for URI", uri);
+ }
+ return host.resolveResource(type, mappedName);
+ }
+ }
+
+ private class Key {
+ private Class<?> clazz;
+ private String name;
+
+ public Key(Class<?> clazz, String name) {
+ this.clazz = clazz;
+ this.name = name;
+ }
+
+ public Key(Class<?> clazz) {
+ this.clazz = clazz;
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ Key key = (Key) o;
+
+ if (clazz != null ? !clazz.equals(key.clazz) : key.clazz != null) {
+ return false;
+ }
+ if (name != null ? !name.equals(key.name) : key.name != null) {
+ return false;
+ }
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = clazz != null ? clazz.hashCode() : 0;
+ result = 31 * result + (name != null ? name.hashCode() : 0);
+ return result;
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/store/memory/MemoryStore.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/store/memory/MemoryStore.java
new file mode 100644
index 0000000000..b1a0b67001
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/store/memory/MemoryStore.java
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.store.memory;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.EagerInit;
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Property;
+import org.osoa.sca.annotations.Service;
+
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.event.AbstractEventPublisher;
+import org.apache.tuscany.spi.services.store.DuplicateRecordException;
+import org.apache.tuscany.spi.services.store.RecoveryListener;
+import org.apache.tuscany.spi.services.store.Store;
+import org.apache.tuscany.spi.services.store.StoreExpirationEvent;
+import org.apache.tuscany.spi.services.store.StoreMonitor;
+import org.apache.tuscany.spi.services.store.StoreWriteException;
+
+import org.apache.tuscany.api.annotation.Monitor;
+
+/**
+ * Implements a non-durable, non-transactional store using a simple in-memory map
+ *
+ * @version $Rev$ $Date$
+ */
+@Service(Store.class)
+@EagerInit
+public class MemoryStore extends AbstractEventPublisher implements Store {
+ private Map<SCAObject, Map<String, Record>> store;
+ // TODO integrate with a core threading scheme
+ private ScheduledExecutorService scheduler;
+ private long reaperInterval = 300000;
+ private StoreMonitor monitor;
+ private long defaultExpirationOffset = 600000; // 10 minutes
+
+ public MemoryStore(@Monitor StoreMonitor monitor) {
+ this.monitor = monitor;
+ this.store = new ConcurrentHashMap<SCAObject, Map<String, Record>>();
+ this.scheduler = Executors.newSingleThreadScheduledExecutor();
+ }
+
+ /**
+ * Returns the maximum default expiration offset for records in the store
+ *
+ * @return the maximum default expiration offset for records in the store
+ */
+ public long getDefaultExpirationOffset() {
+ return defaultExpirationOffset;
+ }
+
+ /**
+ * Sets the maximum default expiration offset for records in the store
+ */
+ @Property
+ public void setDefaultExpirationOffset(long defaultExpirationOffset) {
+ this.defaultExpirationOffset = defaultExpirationOffset;
+ }
+
+ /**
+ * Sets the interval for expired entry scanning to be performed
+ */
+ @Property
+ public void setReaperInterval(long reaperInterval) {
+ this.reaperInterval = reaperInterval;
+ }
+
+ public long getReaperInterval() {
+ return reaperInterval;
+ }
+
+ @Init
+ public void init() {
+ scheduler.scheduleWithFixedDelay(new Reaper(), reaperInterval, reaperInterval, TimeUnit.MILLISECONDS);
+ monitor.start("In-memory store started");
+ }
+
+ @Destroy
+ public void destroy() {
+ scheduler.shutdown();
+ monitor.stop("In-memory store stopped");
+ }
+
+ public void insertRecord(SCAObject owner, String id, Object object, long expiration) throws StoreWriteException {
+ Map<String, Record> map = store.get(owner);
+ if (map == null) {
+ map = new ConcurrentHashMap<String, Record>();
+ store.put(owner, map);
+ }
+ if (map.containsKey(id)) {
+ throw new DuplicateRecordException(owner.getCanonicalName(), id);
+ }
+ map.put(id, new Record(object, expiration));
+ }
+
+ public void updateRecord(SCAObject owner, String id, Object object, long expiration) throws StoreWriteException {
+ Map<String, Record> map = store.get(owner);
+ if (map == null) {
+ throw new StoreWriteException("Record not found", owner.getCanonicalName(), id);
+ }
+ Record record = map.get(id);
+ if (record == null) {
+ throw new StoreWriteException("Record not found", owner.getCanonicalName(), id);
+ }
+ record.data = object;
+ }
+
+ public Object readRecord(SCAObject owner, String id) {
+ Map<String, Record> map = store.get(owner);
+ if (map == null) {
+ return null;
+ }
+ Record record = map.get(id);
+ if (record != null) {
+ return record.data;
+ }
+ return null;
+ }
+
+ public void removeRecords() {
+ store.clear();
+ }
+
+ public void removeRecord(SCAObject owner, String id) throws StoreWriteException {
+ Map<String, Record> map = store.get(owner);
+ if (map == null) {
+ throw new StoreWriteException("Owner not found", owner.getCanonicalName(), id);
+ }
+ if (map.remove(id) == null) {
+ throw new StoreWriteException("Owner not found", owner.getCanonicalName(), id);
+ }
+ }
+
+ public void recover(RecoveryListener listener) {
+ throw new UnsupportedOperationException();
+ }
+
+ private class Record {
+ private Object data;
+ private long expiration = NEVER;
+
+ public Record(Object data, long expiration) {
+ this.data = data;
+ this.expiration = expiration;
+ }
+
+ public Object getData() {
+ return data;
+ }
+
+ public long getExpiration() {
+ return expiration;
+ }
+ }
+
+ private class Reaper implements Runnable {
+
+ public void run() {
+ long now = System.currentTimeMillis();
+ for (Map.Entry<SCAObject, Map<String, Record>> entries : store.entrySet()) {
+ for (Map.Entry<String, Record> entry : entries.getValue().entrySet()) {
+ final long expiration = entry.getValue().expiration;
+ if (expiration != NEVER && now >= expiration) {
+ SCAObject owner = entries.getKey();
+ Object instance = entry.getValue().getData();
+ // notify listeners of the expiration
+ StoreExpirationEvent event = new StoreExpirationEvent(this, owner, instance);
+ publish(event);
+ entries.getValue().remove(entry.getKey());
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jca/JcaWorkScheduler.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jca/JcaWorkScheduler.java
new file mode 100644
index 0000000000..79b7bf4ca1
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jca/JcaWorkScheduler.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.work.jca;
+
+import javax.resource.spi.work.Work;
+import javax.resource.spi.work.WorkEvent;
+import javax.resource.spi.work.WorkException;
+import javax.resource.spi.work.WorkListener;
+import javax.resource.spi.work.WorkManager;
+import javax.resource.spi.work.WorkRejectedException;
+
+import org.apache.tuscany.spi.services.work.NotificationListener;
+import org.apache.tuscany.spi.services.work.WorkScheduler;
+import org.apache.tuscany.spi.services.work.WorkSchedulerException;
+
+/**
+ * A work scheduler implementation based on the JCA SPI work manager.
+ * <p/>
+ * <p/>
+ * This needs a JCA SPI work manager implementation available for scheduling work. Instances can be configured with a
+ * work manager implementation that is injected in. It is the responsibility of the runtime environment to make a work
+ * manager implementaion available. </p>
+ */
+public class JcaWorkScheduler implements WorkScheduler {
+
+ /**
+ * Underlying JCA work manager
+ */
+ private WorkManager jcaWorkManager;
+
+ /**
+ * Initializes the JCA work manager.
+ *
+ * @param jcaWorkManager JCA work manager.
+ */
+ public JcaWorkScheduler(WorkManager jcaWorkManager) {
+
+ if (jcaWorkManager == null) {
+ throw new IllegalArgumentException("Work manager cannot be null");
+ }
+ this.jcaWorkManager = jcaWorkManager;
+
+ }
+
+ /**
+ * Schedules a unit of work for future execution. The notification listener is used to register interest in
+ * callbacks regarding the status of the work.
+ *
+ * @param work The unit of work that needs to be asynchronously executed.
+ */
+ public <T extends Runnable> void scheduleWork(T work) {
+ scheduleWork(work, null);
+ }
+
+ /**
+ * Schedules a unit of work for future execution. The notification listener is used to register interest in
+ * callbacks regarding the status of the work.
+ *
+ * @param work The unit of work that needs to be asynchronously executed.
+ * @param listener Notification listener for callbacks.
+ */
+ public <T extends Runnable> void scheduleWork(T work, NotificationListener<T> listener) {
+
+ if (work == null) {
+ throw new IllegalArgumentException("Work cannot be null");
+ }
+
+ JcaWork<T> jcaWork = new JcaWork<T>(work);
+ try {
+ if (listener == null) {
+ jcaWorkManager.scheduleWork(jcaWork);
+ } else {
+ JcaWorkListener<T> jcaWorkListener = new JcaWorkListener<T>(listener);
+ // TODO Clarify the usage of timeout and execution context
+ jcaWorkManager.scheduleWork(jcaWork, -1, null, jcaWorkListener);
+ }
+ } catch (WorkRejectedException ex) {
+ if (listener != null) {
+ listener.workRejected(work);
+ } else {
+ throw new WorkSchedulerException(ex);
+ }
+ } catch (WorkException ex) {
+ throw new WorkSchedulerException(ex);
+ }
+
+ }
+
+ /*
+ * Worklistener for keeping track of work status callbacks.
+ *
+ */
+ private class JcaWorkListener<T extends Runnable> implements WorkListener {
+
+ // Notification listener
+ private NotificationListener<T> listener;
+
+ /*
+ * Initializes the notification listener.
+ */
+ public JcaWorkListener(NotificationListener<T> listener) {
+ this.listener = listener;
+ }
+
+ /*
+ * Callback when the work is accepted.
+ */
+ public void workAccepted(WorkEvent workEvent) {
+ T work = getWork(workEvent);
+ listener.workAccepted(work);
+ }
+
+ /*
+ * Callback when the work is rejected.
+ */
+ public void workRejected(WorkEvent workEvent) {
+ T work = getWork(workEvent);
+ listener.workRejected(work);
+ }
+
+ /*
+ * Callback when the work is started.
+ */
+ public void workStarted(WorkEvent workEvent) {
+ T work = getWork(workEvent);
+ listener.workStarted(work);
+ }
+
+ /*
+ * Callback when the work is completed.
+ */
+ public void workCompleted(WorkEvent workEvent) {
+ T work = getWork(workEvent);
+ Exception exception = workEvent.getException();
+ if (exception != null) {
+ listener.workFailed(work, exception);
+ } else {
+ listener.workCompleted(work);
+ }
+ }
+
+ /*
+ * Gets the underlying work from the work event.
+ */
+ @SuppressWarnings("unchecked")
+ private T getWork(WorkEvent workEvent) {
+ JcaWork<T> jcaWork = (JcaWork<T>) workEvent.getWork();
+ return jcaWork.getWork();
+ }
+
+ }
+
+ /*
+ * JCA work wrapper.
+ */
+ private class JcaWork<T extends Runnable> implements Work {
+
+ // Work that is being executed.
+ private T work;
+
+ /*
+ * Initializes the work instance.
+ */
+ public JcaWork(T work) {
+ this.work = work;
+ }
+
+ /*
+ * Releases the work.
+ */
+ public void release() {
+ }
+
+ /*
+ * Performs the work.
+ */
+ public void run() {
+ work.run();
+ }
+
+ /*
+ * Returns the completed work.
+ */
+ public T getWork() {
+ return work;
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkScheduler.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkScheduler.java
new file mode 100644
index 0000000000..8fa8000477
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkScheduler.java
@@ -0,0 +1,217 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.work.jsr237;
+
+import org.osoa.sca.annotations.Scope;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.services.work.NotificationListener;
+import org.apache.tuscany.spi.services.work.WorkScheduler;
+import org.apache.tuscany.spi.services.work.WorkSchedulerException;
+
+import commonj.work.Work;
+import commonj.work.WorkEvent;
+import commonj.work.WorkException;
+import commonj.work.WorkListener;
+import commonj.work.WorkManager;
+import commonj.work.WorkRejectedException;
+
+/**
+ * A work scheduler implementation based on a JSR 237 work manager.
+ * <p/>
+ * <p/>
+ * This needs a JSR 237 work manager implementation available for scheduling work. Instances can be configured with a
+ * work manager implementation that is injected in. It is the responsibility of the runtime environment to make a work
+ * manager implementaion available. For example, if the managed environment supports work manager the runtime can use
+ * the appropriate lookup mechanism to inject the work manager implementation. </p>
+ */
+@Scope("COMPOSITE")
+public class Jsr237WorkScheduler implements WorkScheduler {
+
+ /**
+ * Underlying JSR-237 work manager
+ */
+ private WorkManager jsr237WorkManager;
+
+ /**
+ * Initializes the JSR 237 work manager.
+ *
+ * @param jsr237WorkManager JSR 237 work manager.
+ */
+ public Jsr237WorkScheduler(@Autowire WorkManager jsr237WorkManager) {
+ if (jsr237WorkManager == null) {
+ throw new IllegalArgumentException("Work manager cannot be null");
+ }
+ this.jsr237WorkManager = jsr237WorkManager;
+ }
+
+ /**
+ * Schedules a unit of work for future execution. The notification listener is used to register interest in
+ * callbacks regarding the status of the work.
+ *
+ * @param work The unit of work that needs to be asynchronously executed.
+ */
+ public <T extends Runnable> void scheduleWork(T work) {
+ scheduleWork(work, null);
+ }
+
+ /**
+ * Schedules a unit of work for future execution. The notification listener is used to register interest in
+ * callbacks regarding the status of the work.
+ *
+ * @param work The unit of work that needs to be asynchronously executed.
+ * @param listener Notification listener for callbacks.
+ */
+ public <T extends Runnable> void scheduleWork(T work, NotificationListener<T> listener) {
+
+ if (work == null) {
+ throw new IllegalArgumentException("Work cannot be null");
+ }
+
+ Jsr237Work<T> jsr237Work = new Jsr237Work<T>(work);
+ try {
+ if (listener == null) {
+ jsr237WorkManager.schedule(jsr237Work);
+ } else {
+ Jsr237WorkListener<T> jsr237WorkListener = new Jsr237WorkListener<T>(listener, work);
+ jsr237WorkManager.schedule(jsr237Work, jsr237WorkListener);
+ }
+ } catch (WorkRejectedException ex) {
+ if (listener != null) {
+ listener.workRejected(work);
+ } else {
+ throw new WorkSchedulerException(ex);
+ }
+ } catch (WorkException ex) {
+ throw new WorkSchedulerException(ex);
+ }
+
+ }
+
+ /*
+ * Worklistener for keeping track of work status callbacks.
+ *
+ */
+ private class Jsr237WorkListener<T extends Runnable> implements WorkListener {
+
+ // Notification listener
+ private NotificationListener<T> listener;
+
+ // Work
+ private T work;
+
+ /*
+ * Initializes the notification listener.
+ */
+ public Jsr237WorkListener(NotificationListener<T> listener, T work) {
+ this.listener = listener;
+ this.work = work;
+ }
+
+ /*
+ * Callback when the work is accepted.
+ */
+ public void workAccepted(WorkEvent workEvent) {
+ T work = getWork();
+ listener.workAccepted(work);
+ }
+
+ /*
+ * Callback when the work is rejected.
+ */
+ public void workRejected(WorkEvent workEvent) {
+ T work = getWork();
+ listener.workRejected(work);
+ }
+
+ /*
+ * Callback when the work is started.
+ */
+ public void workStarted(WorkEvent workEvent) {
+ T work = getWork();
+ listener.workStarted(work);
+ }
+
+ /*
+ * Callback when the work is completed.
+ */
+ public void workCompleted(WorkEvent workEvent) {
+ T work = getWork();
+ Exception exception = workEvent.getException();
+ if (exception != null) {
+ listener.workFailed(work, exception);
+ } else {
+ listener.workCompleted(work);
+ }
+ }
+
+ /*
+ * Gets the underlying work from the work event.
+ */
+ private T getWork() {
+ return work;
+ }
+
+ }
+
+ /*
+ * JCA work wrapper.
+ */
+ private class Jsr237Work<T extends Runnable> implements Work {
+
+ // Work that is being executed.
+ private T work;
+
+ /*
+ * Initializes the work instance.
+ */
+ public Jsr237Work(T work) {
+ this.work = work;
+ }
+
+ /*
+ * Returns the completed work.
+ */
+ public T getWork() {
+ return work;
+ }
+
+ /*
+ * Release the work.
+ */
+ public void release() {
+ }
+
+ /*
+ * Work attributes are not daemon.
+ */
+ public boolean isDaemon() {
+ return false;
+ }
+
+ /*
+ * Runs the work.
+ */
+ public void run() {
+ work.run();
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/DefaultWorkEvent.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/DefaultWorkEvent.java
new file mode 100644
index 0000000000..c391d0b597
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/DefaultWorkEvent.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.work.jsr237.workmanager;
+
+import commonj.work.WorkEvent;
+import commonj.work.WorkException;
+import commonj.work.WorkItem;
+
+/**
+ * Default immutable implementation of the <code>WorkEvent</code> class.
+ */
+class DefaultWorkEvent implements WorkEvent {
+
+ // Work item for this event
+ private WorkItem workItem;
+
+ // Exception if something has gone wrong
+ private WorkException exception;
+
+ /**
+ * Instantiates the event.
+ *
+ * @param workItem Work item for this event.
+ */
+ public DefaultWorkEvent(final DefaultWorkItem workItem) {
+ this.workItem = workItem;
+ this.exception = workItem.getException();
+ }
+
+ /**
+ * Returns the work type based on whether the work was accepted, started,
+ * rejected or completed.
+ *
+ * @return Work type.
+ */
+ public int getType() {
+ return workItem.getStatus();
+ }
+
+ /**
+ * Returns the work item associated with this work type.
+ *
+ * @return Work item.
+ */
+ public WorkItem getWorkItem() {
+ return workItem;
+ }
+
+ /**
+ * Returns the exception if the work completed with an exception.
+ *
+ * @return Work exception.
+ */
+ public WorkException getException() {
+ return exception;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/DefaultWorkItem.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/DefaultWorkItem.java
new file mode 100644
index 0000000000..0adc005bb0
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/DefaultWorkItem.java
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.work.jsr237.workmanager;
+
+import commonj.work.Work;
+import commonj.work.WorkException;
+import commonj.work.WorkItem;
+
+/**
+ * An identity based immutable implementation of the <code>WorkItem</code>
+ * interface.
+ *
+ */
+class DefaultWorkItem implements WorkItem {
+
+ // Id scoped for the VM
+ private String id;
+
+ // Status
+ private int status = -1;
+
+ // Result
+ private Work result;
+
+ // Original work
+ private Work originalWork;
+
+ // Exception
+ private WorkException exception;
+
+ /**
+ * Instantiates an id for this item.
+ *
+ * @param id of this work event.
+ */
+ protected DefaultWorkItem(final String id, final Work orginalWork) {
+ this.id = id;
+ this.originalWork = orginalWork;
+ }
+
+ /**
+ * Returns the id.
+ *
+ * @return Id of this item.
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Returns the original work.
+ *
+ * @return Original work.
+ */
+ public Work getOriginalWork() {
+ return originalWork;
+ }
+
+ /**
+ * Returns the work result if the work completed.
+ *
+ * @return Work.
+ * @throws WorkException If the work completed with an exception.
+ */
+ public Work getResult() throws WorkException {
+ return result;
+ }
+
+ /**
+ * Sets the result.
+ *
+ * @param result Result.
+ */
+ protected void setResult(final Work result) {
+ this.result = result;
+ }
+
+ /**
+ * Returns the exception if work completed with an exception.
+ *
+ * @return Work exception.
+ */
+ protected WorkException getException() {
+ return exception;
+ }
+
+ /**
+ * Sets the exception.
+ *
+ * @param exception Exception.
+ */
+ protected void setException(final WorkException exception) {
+ this.exception = exception;
+ }
+
+ /**
+ * Returns the work type based on whether the work was accepted, started,
+ * rejected or completed.
+ *
+ * @return Work status.
+ */
+ public int getStatus() {
+ return status;
+ }
+
+ /**
+ * Sets the status.
+ *
+ * @param status Status.
+ */
+ protected void setStatus(final int status) {
+ this.status = status;
+ }
+
+ /**
+ * @see Object#hashCode()
+ */
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+ /**
+ * Indicates whether some other object is "equal to" this one.
+ *
+ * @param obj Object to be compared.
+ * @return true if this object is the same as the obj argument; false
+ * otherwise..
+ */
+ public boolean equals(final Object obj) {
+ return (obj != null) && (obj.getClass() == DefaultWorkItem.class) && ((DefaultWorkItem) obj).id.equals(id);
+ }
+
+ /**
+ * Compares this object with the specified object for order. Returns a
+ * negative integer, zero, or a positive integer as this object is less
+ * than, equal to, or greater than the specified object.
+ *
+ * @param o Object to be compared.
+ * @return A negative integer, zero, or a positive integer as this object
+ * is less than, equal to, or greater than the specified object.
+ * @throws ClassCastException needs better documentation.
+ */
+ public int compareTo(final Object o) {
+ if (o.getClass() != DefaultWorkItem.class) {
+ throw new ClassCastException(o.getClass().getName());
+ } else {
+ return ((DefaultWorkItem) o).getId().compareTo(getId());
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/ThreadPoolWorkManager.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/ThreadPoolWorkManager.java
new file mode 100644
index 0000000000..1a7639b41d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/services/work/jsr237/workmanager/ThreadPoolWorkManager.java
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.work.jsr237.workmanager;
+
+import java.rmi.server.UID;
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.RejectedExecutionException;
+
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.Property;
+
+import commonj.work.Work;
+import commonj.work.WorkEvent;
+import commonj.work.WorkException;
+import commonj.work.WorkItem;
+import commonj.work.WorkListener;
+import commonj.work.WorkManager;
+import commonj.work.WorkRejectedException;
+
+/**
+ * A thread-pool based implementation for the JSR-237 work manager.
+ * <p/>
+ * <p/>
+ * This implementation supports only local work.
+ * <p/>
+ * TODO Elaborate the implementation. </p>
+ */
+public class ThreadPoolWorkManager implements WorkManager {
+
+ // Map of work items currently handled by the work manager
+ private Map<DefaultWorkItem, WorkListener> workItems = new ConcurrentHashMap<DefaultWorkItem, WorkListener>();
+
+ // Thread-pool
+ private ExecutorService executor;
+
+ /**
+ * Initializes the thread-pool.
+ *
+ * @param threadPoolSize Thread-pool size.
+ */
+ public ThreadPoolWorkManager(@Property(name = "poolSize") int threadPoolSize) {
+ executor = Executors.newFixedThreadPool(threadPoolSize);
+ }
+
+ /**
+ * Schedules a unit of work asynchronously.
+ *
+ * @param work Work that needs to be scheduled.
+ * @return Work Work item representing the asynchronous work
+ */
+ public WorkItem schedule(Work work) throws WorkException {
+ return schedule(work, null);
+ }
+
+ /**
+ * Schedules a unit of work asynchronously.
+ *
+ * @param work Work that needs to be scheduled.
+ * @param workListener Work listener for callbacks.
+ * @return Work Work item representing the asynchronous work
+ */
+ public WorkItem schedule(Work work, WorkListener workListener) throws WorkRejectedException {
+
+ DefaultWorkItem workItem = new DefaultWorkItem(new UID().toString(), work);
+ if (workListener != null) {
+ workItems.put(workItem, workListener);
+ }
+ workAccepted(workItem, work);
+ if (scheduleWork(work, workItem)) {
+ return workItem;
+ } else {
+ workItem.setStatus(WorkEvent.WORK_REJECTED);
+ if (workListener != null) {
+ workListener.workRejected(new DefaultWorkEvent(workItem));
+ }
+ throw new WorkRejectedException("Unable to schedule work");
+ }
+ }
+
+ /**
+ * Wait for all the specified units of work to finish.
+ *
+ * @param works Units of the work that need to finish.
+ * @param timeout Timeout for waiting for the units of work to finish.
+ */
+ public boolean waitForAll(Collection works, long timeout) {
+ throw new UnsupportedOperationException("waitForAll not supported");
+ }
+
+ /**
+ * Wait for any of the specified units of work to finish.
+ *
+ * @param works Units of the work that need to finish.
+ * @param timeout Timeout for waiting for the units of work to finish.
+ */
+ public Collection waitForAny(Collection works, long timeout) {
+ throw new UnsupportedOperationException("waitForAny not supported");
+ }
+
+ /**
+ * Method provided for subclasses to indicate a work accptance.
+ *
+ * @param workItem Work item representing the work that was accepted.
+ * @param work Work that was accepted.
+ */
+ private void workAccepted(final DefaultWorkItem workItem, final Work work) {
+ WorkListener listener = workItems.get(workItem);
+ if (listener != null) {
+ workItem.setStatus(WorkEvent.WORK_ACCEPTED);
+ WorkEvent event = new DefaultWorkEvent(workItem);
+ listener.workAccepted(event);
+ }
+ }
+
+ /*
+ * Method to indicate a work start.
+ */
+ private void workStarted(final DefaultWorkItem workItem, final Work work) {
+ WorkListener listener = workItems.get(workItem);
+ if (listener != null) {
+ workItem.setStatus(WorkEvent.WORK_STARTED);
+ WorkEvent event = new DefaultWorkEvent(workItem);
+ listener.workStarted(event);
+ }
+ }
+
+ /*
+ * Method to indicate a work completion.
+ */
+ private void workCompleted(final DefaultWorkItem workItem, final Work work) {
+ workCompleted(workItem, work, null);
+ }
+
+ /*
+ * Method to indicate a work completion.
+ */
+ private void workCompleted(final DefaultWorkItem workItem, final Work work, final WorkException exception) {
+ WorkListener listener = workItems.get(workItem);
+ if (listener != null) {
+ workItem.setStatus(WorkEvent.WORK_COMPLETED);
+ workItem.setResult(work);
+ workItem.setException(exception);
+ WorkEvent event = new DefaultWorkEvent(workItem);
+ listener.workCompleted(event);
+ workItems.remove(workItem);
+ }
+ }
+
+ /*
+ * Schedules the work using the threadpool.
+ */
+ private boolean scheduleWork(final Work work, final DefaultWorkItem workItem) {
+ try {
+ executor.execute(new DecoratingWork(workItem, work));
+ return true;
+ } catch (RejectedExecutionException ex) {
+ return false;
+ }
+ }
+
+ /*
+ * Class that decorates the original worker so that it can get callbacks when work is done.
+ */
+ private final class DecoratingWork implements Runnable {
+
+ // Work item for this work.
+ private DefaultWorkItem workItem;
+
+ // The original work.
+ private Work decoratedWork;
+
+ /*
+ * Initializes the work item and underlying work.
+ */
+ private DecoratingWork(final DefaultWorkItem workItem, final Work decoratedWork) {
+ this.workItem = workItem;
+ this.decoratedWork = decoratedWork;
+ }
+
+ /*
+ * Overrides the run method.
+ */
+ public void run() {
+ workStarted(workItem, decoratedWork);
+ try {
+ decoratedWork.run();
+ workCompleted(workItem, decoratedWork);
+ } catch (Throwable th) {
+ workCompleted(workItem, decoratedWork, new WorkException(th.getMessage(), th));
+ }
+ }
+
+ }
+
+ @Destroy
+ public void destroy() {
+ executor.shutdown();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/test/SCATestCaseRunner.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/test/SCATestCaseRunner.java
new file mode 100644
index 0000000000..191dacdf0d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/test/SCATestCaseRunner.java
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.test;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+/**
+ * A helper class that can be used to run an SCA JUnit test case. The test case will run in an isolated class loader.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SCATestCaseRunner {
+
+ private ClassLoader classLoader;
+ private Class<?> testSuiteClass;
+ private Object testSuite;
+ private Class<?> testResultClass;
+ private Class<?> testCaseClass;
+ private Object testCase;
+
+ private Class<?> beforeAnnotation;
+ private Class<?> beforeClassAnnotation;
+ private Class<?> afterAnnotation;
+ private Class<?> afterClassAnnotation;
+ private Class<?> junit4AdapterClass;
+ private Class<?> junit3TestCaseClass;
+
+ /**
+ * Constructs a new TestCase runner.
+ *
+ * @param testClass
+ */
+ public SCATestCaseRunner(Class testClass) {
+ try {
+ classLoader = (URLClassLoader)testClass.getClassLoader();
+ if (classLoader instanceof URLClassLoader) {
+ URL[] urls = ((URLClassLoader)classLoader).getURLs();
+ classLoader = new URLClassLoader(urls, classLoader.getParent());
+ } else {
+ classLoader = new URLClassLoader(new URL[0], classLoader);
+ }
+
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(classLoader);
+
+ testCaseClass = Class.forName(testClass.getName(), true, classLoader);
+ testCase = testCaseClass.newInstance();
+
+ junit3TestCaseClass = Class.forName("junit.framework.TestCase", true, classLoader);
+
+ testSuiteClass = Class.forName("junit.framework.TestSuite", true, classLoader);
+ Constructor testSuiteConstructor = testSuiteClass.getConstructor(Class.class);
+ testSuite = testSuiteConstructor.newInstance(testCaseClass);
+
+ testResultClass = Class.forName("junit.framework.TestResult", true, classLoader);
+
+ try {
+ beforeAnnotation = Class.forName("org.junit.Before", true, classLoader);
+ afterAnnotation = Class.forName("org.junit.After", true, classLoader);
+ beforeClassAnnotation = Class.forName("org.junit.BeforeClass", true, classLoader);
+ afterClassAnnotation = Class.forName("org.junit.AfterClass", true, classLoader);
+ junit4AdapterClass = Class.forName("junit.framework.JUnit4TestAdapter", true, classLoader);
+ } catch (Exception e) {
+ // Unexpected
+ throw new AssertionError(e);
+ }
+
+ } finally {
+ Thread.currentThread().setContextClassLoader(tccl);
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Run the test case
+ */
+ public void run() {
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(classLoader);
+
+ if (junit3TestCaseClass.isAssignableFrom(testCaseClass)) {
+ Object testResult = testResultClass.newInstance();
+ Method runMethod = testSuiteClass.getMethod("run", testResultClass);
+ runMethod.invoke(testSuite, testResult);
+ } else {
+ Object junit4Adapter = junit4AdapterClass.getConstructor(Class.class).newInstance(testCaseClass);
+ Object testResult = testResultClass.newInstance();
+ Method runMethod = junit4AdapterClass.getMethod("run", testResultClass);
+ runMethod.invoke(junit4Adapter, testResult);
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ Thread.currentThread().setContextClassLoader(tccl);
+ }
+ }
+
+ /**
+ * Invoke the setUp method
+ */
+ public void setUp() {
+ execute("setUp");
+ }
+
+ /**
+ * Invoke the before methods
+ */
+ public void before() {
+ execute(beforeAnnotation);
+ }
+
+ /**
+ * Invoke the beforeClass methods
+ */
+ public void beforeClass() {
+ execute(beforeClassAnnotation);
+ }
+
+ /**
+ * Invoke the tearDown method
+ */
+ public void tearDown() {
+ execute("tearDown");
+ }
+
+ /**
+ * Invoke the after methods
+ */
+ public void after() {
+ execute(afterAnnotation);
+ }
+
+ /**
+ * Invoke the afterClass methods
+ */
+ public void afterClass() {
+ execute(afterClassAnnotation);
+ }
+
+ /**
+ * Invoke the specified test method.
+ */
+ public void run(String methodName) {
+ execute(methodName);
+ }
+
+ /**
+ * Invoke the methods annotated with the specified annotation.
+ */
+ private void execute(Class<?> annotationClass) {
+ if (annotationClass == null) {
+ throw new RuntimeException(new NoSuchMethodException());
+ }
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(classLoader);
+
+ for (Method method : testCaseClass.getDeclaredMethods()) {
+ for (Annotation annotation : method.getAnnotations()) {
+ if (annotation.annotationType() == annotationClass) {
+ method.invoke(testCase);
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ Thread.currentThread().setContextClassLoader(tccl);
+ }
+ }
+
+ /**
+ * Invoke the specified method
+ */
+ private void execute(String methodName) {
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(classLoader);
+ Method setUpMethod = testCaseClass.getDeclaredMethod(methodName);
+ setUpMethod.setAccessible(true);
+ setUpMethod.invoke(testCase);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ Thread.currentThread().setContextClassLoader(tccl);
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/ClassLoaderHelper.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/ClassLoaderHelper.java
new file mode 100644
index 0000000000..a8c57db9d1
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/ClassLoaderHelper.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.util;
+
+import java.io.File;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.net.URLClassLoader;
+
+/**
+ * Functions to create & manipulate classloaders.
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+
+public final class ClassLoaderHelper {
+ /**
+ * Hide constructor
+ */
+ private ClassLoaderHelper() {
+ }
+
+ /**
+ * Create a classloader for the supplied classpath.
+ *
+ * @param path a list of file/directory names separated by the platform path separator
+ * @param parent the parent for the new classloader
+ * @return a classloader that will load classes from the supplied path
+ */
+ public static ClassLoader createClassLoader(ClassLoader parent, String path) {
+ String[] files = path.split(File.pathSeparator);
+ return createClassLoader(parent, files);
+ }
+
+ /**
+ * Create a classloader for a classpath supplied as individual file names.
+ *
+ * @param files a list of file/directory names
+ * @param parent the parent for the new classloader
+ * @return a classloader that will load classes from the supplied path
+ */
+ public static ClassLoader createClassLoader(ClassLoader parent, String[] files) {
+ URL[] urls = new URL[files.length];
+ for (int i = 0; i < files.length; i++) {
+ try {
+ File file = new File(files[i]);
+ urls[i] = file.toURI().toURL();
+ } catch (MalformedURLException e) {
+ // just ignore this value
+ continue;
+ }
+ }
+
+ return new URLClassLoader(urls, parent);
+ }
+
+ /**
+ * Create a classloader for a classpath supplied as a list of files.
+ *
+ * @param files a list of files
+ * @param parent the parent for the new classloader
+ * @return a classloader that will load classes from the supplied path
+ */
+ public static ClassLoader createClassLoader(ClassLoader parent, File[] files) {
+ URL[] urls = new URL[files.length];
+ for (int i = 0; i < files.length; i++) {
+ try {
+ File file = files[i];
+ urls[i] = file.toURI().toURL();
+ } catch (MalformedURLException e) {
+
+ continue;
+ }
+ }
+ return new URLClassLoader(urls, parent);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/FileHelper.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/FileHelper.java
new file mode 100644
index 0000000000..2544c90846
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/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.core.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()) {
+ throw new IOException("Destination '" + destFile + "' directory cannot be created");
+ }
+ }
+ if (!(destFile.exists() && destFile.canWrite())) {
+ throw new IOException("Destination '" + destFile + "' exists but is read-only");
+ }
+ doCopyFile(srcFile, destFile, preserveFileDate);
+ }
+
+ // -----------------------------------------------------------------------
+ /**
+ * Copies a file to a directory preserving the file date.
+ * <p>
+ * This method copies the contents of the specified source file to a file of
+ * the same name in the specified destination directory. The destination
+ * directory is created if it does not exist. If the destination file
+ * exists, then this method will overwrite it.
+ *
+ * @param srcFile an existing file to copy, must not be <code>null</code>
+ * @param destDir the directory to place the copy in, must not be
+ * <code>null</code>
+ * @throws NullPointerException if source or destination is null
+ * @throws IOException if source or destination is invalid
+ * @throws IOException if an IO error occurs during copying
+ * @see #copyFile(File, File, boolean)
+ */
+ public static void copyFileToDirectory(File srcFile, File destDir) throws IOException {
+ copyFileToDirectory(srcFile, destDir, true);
+ }
+
+ /**
+ * Copies a file to a directory optionally preserving the file date.
+ * <p>
+ * This method copies the contents of the specified source file to a file of
+ * the same name in the specified destination directory. The destination
+ * directory is created if it does not exist. If the destination file
+ * exists, then this method will overwrite it.
+ *
+ * @param srcFile an existing file to copy, must not be <code>null</code>
+ * @param destDir the directory to place the copy in, must not be
+ * <code>null</code>
+ * @param preserveFileDate true if the file date of the copy should be the
+ * same as the original
+ * @throws NullPointerException if source or destination is
+ * <code>null</code>
+ * @throws IOException if source or destination is invalid
+ * @throws IOException if an IO error occurs during copying
+ * @see #copyFile(File, File, boolean)
+ * @since Commons IO 1.3
+ */
+ public static void copyFileToDirectory(File srcFile, File destDir, boolean preserveFileDate) throws IOException {
+ if (destDir == null) {
+ throw new NullPointerException("Destination must not be null");
+ }
+ if (!(destDir.exists() && destDir.isDirectory())) {
+ throw new IllegalArgumentException("Destination '" + destDir + "' is not a directory");
+ }
+ copyFile(srcFile, new File(destDir, srcFile.getName()), preserveFileDate);
+ }
+
+ // -----------------------------------------------------------------------
+ /**
+ * Recursively delete a directory.
+ *
+ * @param directory directory to delete
+ * @throws IOException in case deletion is unsuccessful
+ */
+ public static void deleteDirectory(File directory) throws IOException {
+ if (!directory.exists()) {
+ return;
+ }
+
+ cleanDirectory(directory);
+ if (!directory.delete()) {
+ String message = "Unable to delete directory " + directory + ".";
+ throw new IOException(message);
+ }
+ }
+
+ /**
+ * Recursively schedule directory for deletion on JVM exit.
+ *
+ * @param directory directory to delete, must not be <code>null</code>
+ * @throws NullPointerException if the directory is <code>null</code>
+ * @throws IOException in case deletion is unsuccessful
+ */
+ private static void deleteDirectoryOnExit(File directory) throws IOException {
+ if (!directory.exists()) {
+ return;
+ }
+
+ cleanDirectoryOnExit(directory);
+ directory.deleteOnExit();
+ }
+
+ /**
+ * Internal copy directory method.
+ *
+ * @param srcDir the validated source directory, must not be
+ * <code>null</code>
+ * @param destDir the validated destination directory, must not be
+ * <code>null</code>
+ * @param preserveFileDate whether to preserve the file date
+ * @throws IOException if an error occurs
+ * @since Commons IO 1.1
+ */
+ private static void doCopyDirectory(File srcDir, File destDir, boolean preserveFileDate) throws IOException {
+ if (destDir.exists()) {
+ if (!destDir.isDirectory()) {
+ throw new IOException("Destination '" + destDir + "' exists but is not a directory");
+ }
+ } else {
+ if (!destDir.mkdirs()) {
+ throw new IOException("Destination '" + destDir + "' directory cannot be created");
+ }
+ if (preserveFileDate) {
+ destDir.setLastModified(srcDir.lastModified());
+ }
+ }
+ if (!destDir.canWrite()) {
+ throw new IOException("Destination '" + destDir + "' cannot be written to");
+ }
+ // recurse
+ File[] files = srcDir.listFiles();
+ if (files == null) { // null if security restricted
+ throw new IOException("Failed to list contents of " + srcDir);
+ }
+ for (int i = 0; i < files.length; i++) {
+ File copiedFile = new File(destDir, files[i].getName());
+ if (files[i].isDirectory()) {
+ doCopyDirectory(files[i], copiedFile, preserveFileDate);
+ } else {
+ doCopyFile(files[i], copiedFile, preserveFileDate);
+ }
+ }
+ }
+
+ /**
+ * Internal copy file method.
+ *
+ * @param srcFile the validated source file, must not be <code>null</code>
+ * @param destFile the validated destination file, must not be
+ * <code>null</code>
+ * @param preserveFileDate whether to preserve the file date
+ * @throws IOException if an error occurs
+ */
+ private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException {
+ if (destFile.exists() && destFile.isDirectory()) {
+ throw new IOException("Destination '" + destFile + "' exists but is a directory");
+ }
+
+ FileInputStream input = new FileInputStream(srcFile);
+ try {
+ FileOutputStream output = new FileOutputStream(destFile);
+ try {
+ IOHelper.copy(input, output);
+ } finally {
+ IOHelper.closeQuietly(output);
+ }
+ } finally {
+ IOHelper.closeQuietly(input);
+ }
+
+ if (srcFile.length() != destFile.length()) {
+ throw new IOException("Failed to copy full contents from '" + srcFile + "' to '" + destFile + "'");
+ }
+ if (preserveFileDate) {
+ destFile.setLastModified(srcFile.lastModified());
+ }
+ }
+
+ /**
+ * Schedule a file to be deleted when JVM exits. If file is directory delete
+ * it and all sub-directories.
+ *
+ * @param file file or directory to delete, must not be <code>null</code>
+ * @throws NullPointerException if the file is <code>null</code>
+ * @throws IOException in case deletion is unsuccessful
+ */
+ public static void forceDeleteOnExit(File file) throws IOException {
+ if (file.isDirectory()) {
+ deleteDirectoryOnExit(file);
+ } else {
+ file.deleteOnExit();
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/IOHelper.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/IOHelper.java
new file mode 100644
index 0000000000..e3f0ebb5c4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/IOHelper.java
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.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);
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/JavaIntrospectionHelper.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/JavaIntrospectionHelper.java
new file mode 100644
index 0000000000..6b11725481
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/JavaIntrospectionHelper.java
@@ -0,0 +1,439 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Implements various reflection-related operations
+ *
+ * @version $Rev$ $Date$
+ */
+public final class JavaIntrospectionHelper {
+
+ private static final Class[] EMPTY_CLASS_ARRY = new Class[0];
+
+ /**
+ * Hide the constructor
+ */
+ private JavaIntrospectionHelper() {
+ }
+
+
+ /**
+ * Returns a collection of public, and protected fields declared by a class or one of its supertypes
+ */
+ public static Set<Field> getAllPublicAndProtectedFields(Class clazz) {
+ return getAllPublicAndProtectedFields(clazz, new HashSet<Field>());
+ }
+
+ /**
+ * Recursively evaluates the type hierachy to return all fields that are public or protected
+ */
+ private static Set<Field> getAllPublicAndProtectedFields(Class clazz, Set<Field> fields) {
+ if (clazz == null || clazz.isArray() || Object.class.equals(clazz)) {
+ return fields;
+ }
+ fields = getAllPublicAndProtectedFields(clazz.getSuperclass(), fields);
+ Field[] declaredFields = clazz.getDeclaredFields();
+ for (Field field : declaredFields) {
+ int modifiers = field.getModifiers();
+ if ((Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)) && !Modifier.isStatic(modifiers)) {
+ field.setAccessible(true); // ignore Java accessibility
+ fields.add(field);
+ }
+ }
+ return fields;
+ }
+
+ /**
+ * Returns a collection of public and protected methods declared by a class or one of its supertypes. Note that
+ * overriden methods will not be returned in the collection (i.e. only the method override will be). <p/> This
+ * method can potentially be expensive as reflection information is not cached. It is assumed that this method will
+ * be used during a configuration phase.
+ */
+ public static Set<Method> getAllUniquePublicProtectedMethods(Class clazz) {
+ return getAllUniqueMethods(clazz, new HashSet<Method>());
+ }
+
+ /**
+ * Recursively evaluates the type hierarchy to return all unique methods
+ */
+ private static Set<Method> getAllUniqueMethods(Class pClass, Set<Method> methods) {
+ if (pClass == null || pClass.isArray() || Object.class.equals(pClass)) {
+ return methods;
+ }
+ // we first evaluate methods of the subclass and then move to the parent
+ Method[] declaredMethods = pClass.getDeclaredMethods();
+ for (Method declaredMethod : declaredMethods) {
+ int modifiers = declaredMethod.getModifiers();
+ if ((!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers)) || Modifier.isStatic(modifiers)) {
+ continue;
+ }
+ if (methods.size() == 0) {
+ methods.add(declaredMethod);
+ } else {
+ List<Method> temp = new ArrayList<Method>();
+ boolean matched = false;
+ for (Method method : methods) {
+ // only add if not already in the set from a supclass (i.e. the
+ // method is not overrided)
+ if (exactMethodMatch(declaredMethod, method)) {
+ matched = true;
+ break;
+ }
+ }
+ if (!matched) {
+ // TODO ignore Java accessibility
+ declaredMethod.setAccessible(true);
+ temp.add(declaredMethod);
+ }
+ methods.addAll(temp);
+ temp.clear();
+ }
+ }
+ // evaluate class hierarchy - this is done last to track inherited methods
+ methods = getAllUniqueMethods(pClass.getSuperclass(), methods);
+ return methods;
+ }
+
+ /**
+ * Finds the closest matching field with the given name, that is, a field of the exact specified type or,
+ * alternately, of a supertype.
+ *
+ * @param name the name of the field
+ * @param type the field type
+ * @param fields the collection of fields to search
+ * @return the matching field or null if not found
+ */
+ public static Field findClosestMatchingField(String name, Class type, Set<Field> fields) {
+ Field candidate = null;
+ for (Field field : fields) {
+ if (field.getName().equals(name)) {
+ if (field.getType().equals(type)) {
+ return field; // exact match
+ } else if (field.getType().isAssignableFrom(type)
+ || (field.getType().isPrimitive() && primitiveAssignable(field.getType(), type))) {
+ // We could have the situation where a field parameter is a primitive and the demarshalled value is
+ // an object counterpart (e.g. Integer and int)
+ // @spec issue
+ // either an interface or super class, so keep a reference until
+ // we know there are no closer types
+ candidate = field;
+ }
+ }
+ }
+ if (candidate != null) {
+ return candidate;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Finds the closest matching method with the given name, that is, a method taking the exact parameter types or,
+ * alternately, parameter supertypes.
+ *
+ * @param name the name of the method
+ * @param types the method parameter types
+ * @param methods the collection of methods to search
+ * @return the matching method or null if not found
+ */
+ public static Method findClosestMatchingMethod(String name, Class[] types, Set<Method> methods) {
+ if (types == null) {
+ types = EMPTY_CLASS_ARRY;
+ }
+ Method candidate = null;
+ for (Method method : methods) {
+ if (method.getName().equals(name) && method.getParameterTypes().length == types.length) {
+ Class<?>[] params = method.getParameterTypes();
+ boolean disqualify = false;
+ boolean exactMatch = true;
+ for (int i = 0; i < params.length; i++) {
+ if (!params[i].equals(types[i]) && !params[i].isAssignableFrom(types[i])) {
+ // no match
+ disqualify = true;
+ exactMatch = false;
+ break;
+ } else if (!params[i].equals(types[i]) && params[i].isAssignableFrom(types[i])) {
+ // not exact match
+ exactMatch = false;
+ }
+ }
+ if (disqualify) {
+ continue;
+ } else if (exactMatch) {
+ return method;
+ } else {
+ candidate = method;
+ }
+ }
+ }
+ if (candidate != null) {
+ return candidate;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Searches a collection of fields for one that matches by name and has a multiplicity type. i.e. a List or Array of
+ * interfaces
+ *
+ * @return a matching field or null
+ */
+ public static Field findMultiplicityFieldByName(String name, Set<Field> fields) {
+ for (Field candidate : fields) {
+ if (candidate.getName().equals(name)
+ && (List.class.isAssignableFrom(candidate.getType()) || (candidate.getType().isArray()
+ && candidate.getType().getComponentType() != null && candidate.getType().getComponentType()
+ .isInterface()))) {
+ return candidate;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Searches a collection of method for one that matches by name and has single parameter of a multiplicity type.
+ * i.e. a List or Array of interfaces
+ *
+ * @return a matching method or null
+ */
+ public static Method findMultiplicityMethodByName(String name, Set<Method> methods) {
+ for (Method candidate : methods) {
+ if (candidate.getName().equals(name)
+ && candidate.getParameterTypes().length == 1
+ && (List.class.isAssignableFrom(candidate.getParameterTypes()[0])
+ || (candidate.getParameterTypes()[0].isArray()
+ && candidate.getParameterTypes()[0].getComponentType() != null
+ && candidate.getParameterTypes()[0].getComponentType().isInterface()))) {
+ return candidate;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Determines if two methods "match" - that is, they have the same method names and exact parameter types (one is
+ * not a supertype of the other)
+ */
+ public static boolean exactMethodMatch(Method method1, Method method2) {
+ if (!method1.getName().equals(method2.getName())) {
+ return false;
+ }
+ Class[] types1 = method1.getParameterTypes();
+ Class[] types2 = method2.getParameterTypes();
+ if (types1.length == 0 && types2.length == 0) {
+ return true;
+ } else if (types1.length == types2.length) {
+ for (int n = 0; n < types1.length; n++) {
+ if (!types1[n].equals(types2[n])) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public static <T> Constructor<T> getDefaultConstructor(Class<T> clazz) throws NoSuchMethodException {
+ return clazz.getConstructor((Class[]) null);
+ }
+
+ /**
+ * Loads a class corresponding to the class name using the current context class loader.
+ *
+ * @throws ClassNotFoundException if the class was not found on the classpath
+ */
+ public static Class loadClass(String pName) throws ClassNotFoundException {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ return Class.forName(pName, true, loader);
+ }
+
+ /**
+ * Returns the simple name of a class - i.e. the class name devoid of its package qualifier
+ *
+ * @param implClass the implmentation class
+ */
+ public static String getBaseName(Class<?> implClass) {
+ String baseName = implClass.getName();
+ int lastDot = baseName.lastIndexOf('.');
+ if (lastDot != -1) {
+ baseName = baseName.substring(lastDot + 1);
+ }
+ return baseName;
+ }
+
+ public static boolean isImmutable(Class clazz) {
+ return String.class == clazz
+ || clazz.isPrimitive()
+ || Number.class.isAssignableFrom(clazz)
+ || Boolean.class.isAssignableFrom(clazz)
+ || Character.class.isAssignableFrom(clazz)
+ || Byte.class.isAssignableFrom(clazz);
+ }
+
+ /**
+ * Takes a property name and converts it to a getter method name according to JavaBean conventions. For example,
+ * property <code>foo<code> is returned as <code>getFoo</code>
+ */
+ public static String toGetter(String name) {
+ return "get" + name.toUpperCase().substring(0, 1) + name.substring(1);
+ }
+
+ /**
+ * Takes a setter or getter method name and converts it to a property name according to JavaBean conventions. For
+ * example, <code>setFoo(var)</code> is returned as property <code>foo<code>
+ */
+ public static String toPropertyName(String name) {
+ if (!name.startsWith("set")) {
+ return name;
+ }
+ return Character.toLowerCase(name.charAt(3)) + name.substring(4);
+ }
+
+ /**
+ * Takes a property name and converts it to a setter method name according to JavaBean conventions. For example, the
+ * property <code>foo<code> is returned as <code>setFoo(var)</code>
+ */
+ public static String toSetter(String name) {
+ return "set" + name.toUpperCase().substring(0, 1) + name.substring(1);
+ }
+
+ /**
+ * Compares a two types, assuming one is a primitive, to determine if the other is its object counterpart
+ */
+ private static boolean primitiveAssignable(Class memberType, Class param) {
+ if (memberType == Integer.class) {
+ return param == Integer.TYPE;
+ } else if (memberType == Double.class) {
+ return param == Double.TYPE;
+ } else if (memberType == Float.class) {
+ return param == Float.TYPE;
+ } else if (memberType == Short.class) {
+ return param == Short.TYPE;
+ } else if (memberType == Character.class) {
+ return param == Character.TYPE;
+ } else if (memberType == Boolean.class) {
+ return param == Boolean.TYPE;
+ } else if (memberType == Byte.class) {
+ return param == Byte.TYPE;
+ } else if (param == Integer.class) {
+ return memberType == Integer.TYPE;
+ } else if (param == Double.class) {
+ return memberType == Double.TYPE;
+ } else if (param == Float.class) {
+ return memberType == Float.TYPE;
+ } else if (param == Short.class) {
+ return memberType == Short.TYPE;
+ } else if (param == Character.class) {
+ return memberType == Character.TYPE;
+ } else if (param == Boolean.class) {
+ return memberType == Boolean.TYPE;
+ } else if (param == Byte.class) {
+ return memberType == Byte.TYPE;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the generic types represented in the given type. Usage as follows: <code>
+ * JavaIntrospectionHelper.getGenerics(field.getGenericType());
+ * <p/>
+ * JavaIntrospectionHelper.getGenerics(m.getGenericParameterTypes()[0];); </code>
+ *
+ * @return the generic types in order of declaration or an empty array if the type is not genericized
+ */
+ public static List<? extends Type> getGenerics(Type genericType) {
+ List<Type> classes = new ArrayList<Type>();
+ if (genericType instanceof ParameterizedType) {
+ ParameterizedType ptype = (ParameterizedType) genericType;
+ // get the type arguments
+ Type[] targs = ptype.getActualTypeArguments();
+ for (Type targ : targs) {
+ classes.add(targ);
+ }
+ }
+ return classes;
+ }
+
+ /**
+ * Returns the generic type specified by the class at the given position as in:
+ * <p/>
+ * <code> public class Foo<Bar,Baz>{ //.. }
+ * <p/>
+ * JavaIntrospectionHelper.introspectGeneric(Foo.class,1); <code>
+ * <p/>
+ * will return Baz.
+ */
+ public static Class introspectGeneric(Class<?> clazz, int pos) {
+ assert clazz != null : "No class specified";
+ Type type = clazz.getGenericSuperclass();
+ if (type instanceof ParameterizedType) {
+ Type[] args = ((ParameterizedType) type).getActualTypeArguments();
+ if (args.length <= pos) {
+ throw new IllegalArgumentException("Invalid index value for generic class " + clazz.getName());
+ }
+ return (Class) ((ParameterizedType) type).getActualTypeArguments()[pos];
+ } else {
+ Type[] interfaces = clazz.getGenericInterfaces();
+ for (Type itype : interfaces) {
+ if (!(itype instanceof ParameterizedType)) {
+ continue;
+ }
+ ParameterizedType interfaceType = (ParameterizedType) itype;
+ return (Class) interfaceType.getActualTypeArguments()[0];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the set of interfaces implemented by the given class and its ancestors or a blank set if none
+ */
+ public static Set<Class> getAllInterfaces(Class clazz) {
+ Set<Class> implemented = new HashSet<Class>();
+ getAllInterfaces(clazz, implemented);
+ return implemented;
+ }
+
+ private static void getAllInterfaces(Class clazz, Set<Class> implemented) {
+ Class[] interfaces = clazz.getInterfaces();
+ for (Class interfaze : interfaces) {
+ implemented.add(interfaze);
+ }
+ Class<?> superClass = clazz.getSuperclass();
+ // Object has no superclass so check for null
+ if (superClass != null && !superClass.equals(Object.class)) {
+ getAllInterfaces(superClass, implemented);
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/ReferenceLoaderHelper.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/ReferenceLoaderHelper.java
new file mode 100644
index 0000000000..dad586dd18
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/util/ReferenceLoaderHelper.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.util;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.apache.tuscany.spi.loader.IncompatibleOverridingServiceContractException;
+import org.apache.tuscany.spi.loader.InvalidReferenceException;
+import org.apache.tuscany.spi.model.CompositeReferenceDefinition;
+import org.apache.tuscany.spi.model.Multiplicity;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceContract;
+
+/**
+ * Functions to help in loading of references
+ */
+
+public final class ReferenceLoaderHelper {
+ /**
+ * Hide constructor
+ */
+ private ReferenceLoaderHelper() {
+ }
+
+ public static void populateRefTargets(AbstractReferenceDefinition refDefn, String concatenatedTargets) throws InvalidReferenceException {
+ StringTokenizer st = new StringTokenizer(concatenatedTargets);
+ while (st.hasMoreTokens()) {
+ try {
+ refDefn.addTarget(new URI(st.nextToken()));
+ } catch (URISyntaxException e) {
+ throw new InvalidReferenceException(e);
+ }
+ }
+ }
+
+ public static void populatePromotedRefs(CompositeReferenceDefinition refDefn, String concatenatedUris) throws InvalidReferenceException {
+ StringTokenizer st = new StringTokenizer(concatenatedUris);
+ while (st.hasMoreTokens()) {
+ try {
+ refDefn.addPromotedReference(new URI(st.nextToken()));
+ } catch (URISyntaxException e) {
+ throw new InvalidReferenceException(e);
+ }
+ }
+ }
+
+ public static boolean isCompatibleMultiplicity(Multiplicity definedMul, Multiplicity overridenMul) {
+ return ((definedMul == overridenMul) ||
+ (definedMul == Multiplicity.ZERO_ONE && overridenMul == Multiplicity.ZERO_N) ||
+ (definedMul == Multiplicity.ZERO_N && overridenMul == Multiplicity.ZERO_ONE) ||
+ (definedMul == Multiplicity.ONE_ONE && overridenMul == Multiplicity.ONE_N) ||
+ (definedMul == Multiplicity.ONE_N && overridenMul == Multiplicity.ONE_ONE));
+ }
+
+ public static boolean isValidMultiplicityOverride(Multiplicity definedMul, Multiplicity overridenMul) {
+ if (definedMul != overridenMul) {
+ switch (definedMul) {
+ case ZERO_N:
+ return overridenMul == Multiplicity.ZERO_ONE;
+ case ONE_N:
+ return overridenMul == Multiplicity.ONE_ONE;
+ default:
+ return false;
+ }
+ } else {
+ return true;
+ }
+ }
+
+ public static boolean validateMultiplicityAndTargets(Multiplicity multiplicity,
+ List<URI> targets) {
+ int count = targets.size();
+ switch (multiplicity) {
+ case ZERO_N:
+ break;
+ case ZERO_ONE:
+ if (count > 1) {
+ return false;
+ }
+ break;
+ case ONE_ONE:
+ if (count != 1) {
+ return false;
+ }
+ break;
+ case ONE_N:
+ if (count < 1) {
+ return false;
+ }
+ break;
+ }
+ return true;
+ }
+
+ public static void checkInterfaceCompatibility(ServiceContract<?> source,
+ ServiceContract<?> target,
+ boolean ignoreCallback) throws IncompatibleOverridingServiceContractException {
+ if (source == target) {
+ // Shortcut for performance
+ return;
+ }
+
+ //FIXME: we don't go into operations comparison for now since the service contract thta the
+ //interace loader loads does not have operation details as the intropection 'has not been deep'
+ //The JavaInterfaceLoader has set the 'deep' introspection to false....will fix this after
+ //sorting that out.
+
+ if (source.getInteractionScope() != target.getInteractionScope()) {
+ throw new IncompatibleOverridingServiceContractException(
+ "Interaction scopes settings do not match",
+ source, target);
+ }
+
+ for (Operation<?> operation : source.getOperations().values()) {
+ Operation<?> targetOperation = target.getOperation(operation.getName());
+ if (targetOperation == null) {
+ throw new IncompatibleOverridingServiceContractException("Operation not found on target",
+ source, target);
+ }
+ if (!targetOperation.equals(operation)) {
+ throw new IncompatibleOverridingServiceContractException(
+ "Target operations are not compatible",
+ source, target);
+ }
+ }
+
+ if (ignoreCallback) {
+ return;
+ }
+
+ for (Operation<?> operation : source.getCallbackOperations().values()) {
+ Operation<?> targetOperation = target.getCallbackOperations().get(operation.getName());
+ if (targetOperation == null) {
+ throw new IncompatibleOverridingServiceContractException(
+ "Callback operation not found on target",
+ source, target, null,
+ targetOperation);
+ }
+ if (!operation.equals(targetOperation)) {
+ throw new IncompatibleOverridingServiceContractException(
+ "Target callback operation is not compatible",
+ source, target, operation,
+ targetOperation);
+ }
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/BridgingInterceptor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/BridgingInterceptor.java
new file mode 100644
index 0000000000..c1766fbb6f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/BridgingInterceptor.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import org.apache.tuscany.spi.wire.Interceptor;
+
+/**
+ * Responsible for bridging an outbound to an inbound invocation chain associated with a source and target respectively
+ *
+ * @version $Rev$ $Date$
+ */
+public interface BridgingInterceptor extends Interceptor {
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/CallbackInterfaceInterceptor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/CallbackInterfaceInterceptor.java
new file mode 100644
index 0000000000..06f0e62f70
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/CallbackInterfaceInterceptor.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import org.osoa.sca.NoRegisteredCallbackException;
+
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+
+/**
+ * An interceptor applied to the outbound side of a wire that ensures the callback target implements the required
+ * service contract. This is required as callback targets may be set dynamically by service implementations.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CallbackInterfaceInterceptor implements Interceptor {
+ private boolean invokingServiceImplements;
+ private Interceptor next;
+
+ public CallbackInterfaceInterceptor(boolean invokingServiceImplements) {
+ this.invokingServiceImplements = invokingServiceImplements;
+ }
+
+ public Message invoke(Message msg) {
+ // TODO check in the context if a callback object is set, if so invoke next since the setCallback will
+ // perform the check
+ if (!invokingServiceImplements) {
+ throw new NoRegisteredCallbackException("Callback target does not implement the callback interface");
+ }
+ return next.invoke(msg);
+ }
+
+ public void setNext(Interceptor next) {
+ this.next = next;
+ }
+
+ public Interceptor getNext() {
+ return next;
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/InboundInvocationChainImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/InboundInvocationChainImpl.java
new file mode 100644
index 0000000000..45b580d419
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/InboundInvocationChainImpl.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+
+/**
+ * Contains a target-side invocation chain
+ *
+ * @version $Rev$ $Date$
+ */
+public class InboundInvocationChainImpl extends InvocationChainImpl implements InboundInvocationChain {
+
+ /**
+ * Creates an new target-side chain for the given operation
+ */
+ public InboundInvocationChainImpl(Operation operation) {
+ super(operation);
+ }
+
+ public void prepare() {
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/InboundWireImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/InboundWireImpl.java
new file mode 100644
index 0000000000..b529cafbb6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/InboundWireImpl.java
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+/**
+ * Default implementation of an inbound wire
+ *
+ * @version $Rev$ $Date$
+ */
+public class InboundWireImpl implements InboundWire {
+ private QName bindingType = LOCAL_BINDING;
+ private String serviceName;
+ private ServiceContract serviceContract;
+ private OutboundWire targetWire;
+ private String callbackReferenceName;
+ private Map<Operation<?>, InboundInvocationChain> chains = new HashMap<Operation<?>, InboundInvocationChain>();
+ private Map<Object, Map<Operation<?>, OutboundInvocationChain>> callbackSourceChainMaps =
+ new HashMap<Object, Map<Operation<?>, OutboundInvocationChain>>();
+ private SCAObject container;
+ private AtomicComponent targetComponent;
+ private boolean optimizable;
+
+
+ /**
+ * Creates a local inbound wire
+ */
+ public InboundWireImpl() {
+ }
+
+
+ /**
+ * Creates an inbound wire for the given binding type
+ *
+ * @param bindingType the binding type
+ */
+ public InboundWireImpl(QName bindingType) {
+ this.bindingType = bindingType;
+ }
+
+ public QName getBindingType() {
+ return bindingType;
+ }
+
+ public Object getTargetService() throws TargetResolutionException {
+ // JFM fixme hack
+ if (targetWire == null && targetComponent != null) {
+ return targetComponent.getTargetInstance();
+ }
+ assert targetWire != null;
+ // optimized, no interceptors or handlers on either end
+ return targetWire.getTargetService();
+ }
+
+ public ServiceContract getServiceContract() {
+ return serviceContract;
+ }
+
+ public void setServiceContract(ServiceContract serviceContract) {
+ this.serviceContract = serviceContract;
+ }
+
+ public void addInterface(Class claz) {
+ throw new UnsupportedOperationException("Additional proxy interfaces not yet supported");
+ }
+
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ public void setServiceName(String serviceName) {
+ this.serviceName = serviceName;
+ }
+
+ public Map<Operation<?>, InboundInvocationChain> getInvocationChains() {
+ return chains;
+ }
+
+ public void addInvocationChains(Map<Operation<?>, InboundInvocationChain> chains) {
+ this.chains.putAll(chains);
+ }
+
+ public void addInvocationChain(Operation<?> operation, InboundInvocationChain chain) {
+ chains.put(operation, chain);
+ }
+
+ public Map<Operation<?>, OutboundInvocationChain> getSourceCallbackInvocationChains(Object targetAddr) {
+ return callbackSourceChainMaps.get(targetAddr);
+ }
+
+ public void addSourceCallbackInvocationChains(Object targetAddr,
+ Map<Operation<?>, OutboundInvocationChain> chains) {
+ callbackSourceChainMaps.put(targetAddr, chains);
+ }
+
+ public void addSourceCallbackInvocationChain(Object targetAddr,
+ Operation operation,
+ OutboundInvocationChain chain) {
+ Map<Operation<?>, OutboundInvocationChain> chains = callbackSourceChainMaps.get(targetAddr);
+ if (chains == null) {
+ chains = new HashMap<Operation<?>, OutboundInvocationChain>();
+ callbackSourceChainMaps.put(targetAddr, chains);
+ }
+ chains.put(operation, chain);
+ }
+
+ public void setTargetWire(OutboundWire wire) {
+ targetWire = wire;
+ }
+
+ public String getCallbackReferenceName() {
+ return callbackReferenceName;
+ }
+
+ public void setCallbackReferenceName(String callbackReferenceName) {
+ this.callbackReferenceName = callbackReferenceName;
+ }
+
+ public boolean isOptimizable() {
+ return optimizable;
+ }
+
+ public void setOptimizable(boolean optimizable) {
+ this.optimizable = optimizable;
+ }
+
+ public SCAObject getContainer() {
+ return container;
+ }
+
+ public void setContainer(SCAObject container) {
+ if (container instanceof AtomicComponent) {
+ targetComponent = (AtomicComponent) container;
+ }
+ this.container = container;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/IncompatibleServiceContractExceptionFormatter.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/IncompatibleServiceContractExceptionFormatter.java
new file mode 100644
index 0000000000..92da622d11
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/IncompatibleServiceContractExceptionFormatter.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.io.PrintWriter;
+
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.EagerInit;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.IncompatibleServiceContractException;
+
+import org.apache.tuscany.host.monitor.ExceptionFormatter;
+import org.apache.tuscany.host.monitor.FormatterRegistry;
+
+/**
+ * Formats {@link org.apache.tuscany.spi.wire.IncompatibleServiceContractException} for JDK logging
+ *
+ * @version $Rev$ $Date$
+ */
+@EagerInit
+public class IncompatibleServiceContractExceptionFormatter implements ExceptionFormatter {
+ private FormatterRegistry factory;
+
+ public IncompatibleServiceContractExceptionFormatter(@Autowire FormatterRegistry factory) {
+ this.factory = factory;
+ factory.register(this);
+ }
+
+ public boolean canFormat(Class<?> type) {
+ return IncompatibleServiceContractException.class.isAssignableFrom(type);
+ }
+
+ @Destroy
+ public void destroy() {
+ factory.unregister(this);
+ }
+
+ public PrintWriter write(PrintWriter writer, Throwable exception) {
+ assert exception instanceof IncompatibleServiceContractException;
+ IncompatibleServiceContractException e = (IncompatibleServiceContractException) exception;
+ e.appendBaseMessage(writer);
+ ServiceContract<?> source = e.getSource();
+ String sourceContractName = null;
+ if (source != null) {
+ sourceContractName = source.getInterfaceName();
+ }
+ Operation<?> sourceOperation = e.getSourceOperation();
+ String sourceOpName = null;
+ if (sourceOperation != null) {
+ sourceOpName = sourceOperation.getName();
+ }
+ if (sourceOpName == null) {
+ writer.write("\nSource Contract: " + sourceContractName);
+ } else {
+ writer.write("\nSource Contract: " + sourceContractName + "/" + sourceOpName);
+ }
+ ServiceContract<?> target = e.getTarget();
+ String targetContractName = null;
+ if (target != null) {
+ targetContractName = target.getInterfaceName();
+ }
+ Operation<?> targetOperation = e.getTargetOperation();
+ String targetOpName = null;
+ if (targetOperation != null) {
+ targetOpName = targetOperation.getName();
+ }
+ if (targetOpName == null) {
+ writer.write("\nTarget Contract: " + targetContractName + "\n");
+ } else {
+ writer.write("\nTarget Contract: " + targetContractName + "/" + targetOpName + "\n");
+
+ }
+ e.appendContextStack(writer);
+ return writer;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/InvocationChainImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/InvocationChainImpl.java
new file mode 100644
index 0000000000..d93426af4c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/InvocationChainImpl.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.InvocationChain;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+/**
+ * Contains functionality common to source- and target- side invocation chains
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class InvocationChainImpl implements InvocationChain {
+ protected Operation operation;
+ protected TargetInvoker targetInvoker;
+ protected Interceptor interceptorChainHead;
+ protected Interceptor interceptorChainTail;
+
+
+ // the pointer to a bridged target head interceptor or null if the target has no interceptors
+ protected Interceptor targetInterceptorChainHead;
+
+ public InvocationChainImpl(Operation operation) {
+ assert operation != null : "No operation type specified";
+ this.operation = operation;
+ }
+
+ public Operation getOperation() {
+ return operation;
+ }
+
+ public void setTargetInvoker(TargetInvoker invoker) {
+ this.targetInvoker = invoker;
+ }
+
+ public TargetInvoker getTargetInvoker() {
+ return targetInvoker;
+ }
+
+ public void addInterceptor(Interceptor interceptor) {
+ if (interceptorChainHead == null) {
+ interceptorChainHead = interceptor;
+ } else {
+ interceptorChainTail.setNext(interceptor);
+ }
+ interceptorChainTail = interceptor;
+ }
+
+ public void addInterceptor(int index, Interceptor interceptor) {
+ int i = 0;
+ Interceptor next = interceptorChainHead;
+ Interceptor prev = null;
+ while (next != null && i < index) {
+ prev = next;
+ next = next.getNext();
+ i++;
+ }
+ if (i == index) {
+ if (prev != null) {
+ prev.setNext(interceptor);
+ } else {
+ interceptorChainHead = interceptor;
+ }
+ interceptor.setNext(next);
+ if (next == null) {
+ interceptorChainTail = interceptor;
+ }
+ } else {
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
+ }
+
+ public Interceptor getHeadInterceptor() {
+ return interceptorChainHead;
+ }
+
+ public Interceptor getTailInterceptor() {
+ return interceptorChainTail;
+ }
+
+ public void setTargetInterceptor(Interceptor interceptor) {
+ targetInterceptorChainHead = interceptor;
+ }
+
+ public Interceptor getTargetInterceptor() {
+ return targetInterceptorChainHead;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/InvokerInterceptor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/InvokerInterceptor.java
new file mode 100644
index 0000000000..90b17a930c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/InvokerInterceptor.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+/**
+ * Serves as a tail interceptor on a target wire chain. This implementation dispatches to the target invoker passed
+ * inside the wire message. Target invokers are passed from the source in order to allow for caching of target
+ * instances.
+ *
+ * @version $Rev$ $Date$
+ * @see org.apache.tuscany.spi.wire.TargetInvoker
+ */
+public class InvokerInterceptor implements Interceptor {
+
+ public InvokerInterceptor() {
+ }
+
+ public Message invoke(Message msg) throws InvocationRuntimeException {
+ TargetInvoker invoker = msg.getTargetInvoker();
+ if (invoker == null) {
+ throw new InvocationRuntimeException("No target invoker specified on message");
+ }
+ return invoker.invoke(msg);
+ }
+
+ public void setNext(Interceptor next) {
+ throw new IllegalStateException("This interceptor must be the last one in an target interceptor chain");
+ }
+
+ public Interceptor getNext() {
+ return null;
+ }
+
+ public boolean isOptimizable() {
+ return true;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/LoopBackWire.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/LoopBackWire.java
new file mode 100644
index 0000000000..a2cd71cafe
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/LoopBackWire.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import org.apache.tuscany.spi.component.TargetResolutionException;
+
+/**
+ * A specialized wire that points back to its target container. Used to autowire to parent composites
+ *
+ * @version $Rev$ $Date$
+ */
+public class LoopBackWire extends InboundWireImpl {
+
+ public Object getTargetService() throws TargetResolutionException {
+ return getContainer();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/NoMethodForOperationException.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/NoMethodForOperationException.java
new file mode 100644
index 0000000000..aec281d190
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/NoMethodForOperationException.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import org.apache.tuscany.spi.wire.ProxyCreationException;
+
+/**
+ * Thrown when an {@link org.apache.tuscany.spi.model.Operation} cannot be mapped to a method on an interface
+ * @version $Rev$ $Date$
+ */
+public class NoMethodForOperationException extends ProxyCreationException {
+ public NoMethodForOperationException() {
+ }
+
+ public NoMethodForOperationException(String message) {
+ super(message);
+ }
+
+ public NoMethodForOperationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public NoMethodForOperationException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/NonBlockingBridgingInterceptor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/NonBlockingBridgingInterceptor.java
new file mode 100644
index 0000000000..a2e6b0379f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/NonBlockingBridgingInterceptor.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.util.LinkedList;
+
+import org.osoa.sca.ServiceRuntimeException;
+
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.services.work.WorkScheduler;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.apache.tuscany.spi.model.Scope;
+
+/**
+ * Bridges interceptors in a non-blocking fashion between an {@link org.apache.tuscany.spi.wire.InboundInvocationChain}
+ * and an {@link org.apache.tuscany.spi.wire.OutboundInvocationChain} by using a {@link
+ * org.apache.tuscany.spi.component.WorkContext}.
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class NonBlockingBridgingInterceptor implements BridgingInterceptor {
+
+ private static final Message RESPONSE = new ImmutableMessage();
+
+ private WorkScheduler workScheduler;
+ private WorkContext workContext;
+ private Interceptor next;
+
+ public NonBlockingBridgingInterceptor(WorkScheduler workScheduler, WorkContext workContext) {
+ this.workScheduler = workScheduler;
+ this.workContext = workContext;
+ }
+
+ public NonBlockingBridgingInterceptor(WorkScheduler workScheduler, WorkContext workContext, Interceptor next) {
+ this.workScheduler = workScheduler;
+ this.workContext = workContext;
+ this.next = next;
+ }
+
+ public Message invoke(final Message msg) {
+ // Retrieve conversation id to transfer to new thread
+ // Notice that we cannot clear the conversation id from the current thread
+ final Object conversationID = workContext.getIdentifier(Scope.CONVERSATION);
+ // Schedule the invocation of the next interceptor in a new Work instance
+ try {
+ workScheduler.scheduleWork(new Runnable() {
+ public void run() {
+ workContext.setCurrentCorrelationId(null);
+ // if we got a conversation id, transfer it to new thread
+ if (conversationID != null) {
+ workContext.setIdentifier(Scope.CONVERSATION, conversationID);
+ }
+ next.invoke(msg);
+ }
+ });
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ return RESPONSE;
+ }
+
+ public Interceptor getNext() {
+ return next;
+ }
+
+ public void setNext(Interceptor next) {
+ this.next = next;
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+
+ /**
+ * A dummy message passed back on an invocation
+ */
+ private static class ImmutableMessage implements Message {
+
+ public Object getBody() {
+ return null;
+ }
+
+ public void setBody(Object body) {
+ if (body != null) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public void setTargetInvoker(TargetInvoker invoker) {
+ throw new UnsupportedOperationException();
+ }
+
+ public TargetInvoker getTargetInvoker() {
+ return null;
+ }
+
+ public Message getRelatedCallbackMessage() {
+ return null;
+ }
+
+ public Object getFromAddress() {
+ return null;
+ }
+
+ public void setFromAddress(Object fromAddress) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object popFromAddress() {
+ return null;
+ }
+
+ public void pushFromAddress(Object fromAddress) {
+ throw new UnsupportedOperationException();
+ }
+
+ public LinkedList<Object> getCallbackRoutingChain() {
+ return null;
+ }
+
+ public void setCallbackRoutingChain(LinkedList<Object> fromAddresses) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getMessageId() {
+ return null;
+ }
+
+ public void setMessageId(Object messageId) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getCorrelationId() {
+ return null;
+ }
+
+ public void setCorrelationId(Object correlationId) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isFault() {
+ return false;
+ }
+
+ public void setBodyWithFault(Object fault) {
+ throw new UnsupportedOperationException();
+ }
+
+ public short getConversationSequence() {
+ return TargetInvoker.NONE;
+ }
+
+ public void setConversationSequence(short sequence) {
+
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/OptimizedWireObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/OptimizedWireObjectFactory.java
new file mode 100644
index 0000000000..4a4b268201
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/OptimizedWireObjectFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+/**
+ * Returns a target instance directly from a wire
+ *
+ * @version $Rev$ $Date$
+ */
+public class OptimizedWireObjectFactory implements ObjectFactory {
+
+ private OutboundWire wire;
+
+ public OptimizedWireObjectFactory(OutboundWire factory) {
+ this.wire = factory;
+ }
+
+ public Object getInstance() throws ObjectCreationException {
+ try {
+ return wire.getTargetService();
+ } catch (TargetResolutionException e) {
+ throw new ObjectCreationException(e);
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/OutboundInvocationChainImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/OutboundInvocationChainImpl.java
new file mode 100644
index 0000000000..a9d83cb7a0
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/OutboundInvocationChainImpl.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+
+/**
+ * Contains a outgoing invocation pipeline for a service operation.
+ *
+ * @version $Rev$ $Date$
+ */
+public class OutboundInvocationChainImpl extends InvocationChainImpl implements OutboundInvocationChain {
+
+ /**
+ * Creates an new outbound chain
+ */
+ public OutboundInvocationChainImpl(Operation operation) {
+ super(operation);
+ }
+
+ public void prepare() {
+ if (interceptorChainHead != null) {
+ if (targetInterceptorChainHead != null) {
+ // Connect source interceptor chain directly to target interceptor chain
+ interceptorChainTail.setNext(targetInterceptorChainHead);
+ }
+ } else {
+ // no source interceptor chain or source handlers, connect to target interceptor chain or channel
+ if (targetInterceptorChainHead != null) {
+ interceptorChainHead = targetInterceptorChainHead;
+ interceptorChainTail = targetInterceptorChainHead;
+ }
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/OutboundWireImpl.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/OutboundWireImpl.java
new file mode 100644
index 0000000000..bad92ffe1e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/OutboundWireImpl.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+/**
+ * Default implementation of an outbound wire
+ *
+ * @version $Rev$ $Date$
+ */
+public class OutboundWireImpl implements OutboundWire {
+ private QName bindingType = LOCAL_BINDING;
+ private ServiceContract serviceContract;
+ private Class<?>[] callbackInterfaces;
+ private Map<Operation<?>, OutboundInvocationChain> chains = new HashMap<Operation<?>, OutboundInvocationChain>();
+ private Map<Operation<?>, InboundInvocationChain> callbackTargetChains =
+ new HashMap<Operation<?>, InboundInvocationChain>();
+ private String referenceName;
+ private QualifiedName targetName;
+ private InboundWire targetWire;
+ private SCAObject container;
+ private boolean autowire;
+ private boolean optimizable;
+
+ /**
+ * Creates a local outbound wire
+ */
+ public OutboundWireImpl() {
+ }
+
+ /**
+ * Creates an outbound wire for the given binding type
+ *
+ * @param bindingType the binding type
+ */
+ public OutboundWireImpl(QName bindingType) {
+ this.bindingType = bindingType;
+ }
+
+ public void setOptimizable(boolean optimizable) {
+ this.optimizable = optimizable;
+ }
+
+ public QName getBindingType() {
+ return bindingType;
+ }
+
+ public Object getTargetService() throws TargetResolutionException {
+ if (targetWire == null) {
+ return null;
+ }
+ // optimized, no interceptors or handlers on either end
+ return targetWire.getTargetService();
+ }
+
+ public ServiceContract getServiceContract() {
+ return serviceContract;
+ }
+
+ public void setServiceContract(ServiceContract serviceContract) {
+ this.serviceContract = serviceContract;
+ }
+
+ public void addInterface(Class<?> claz) {
+ throw new UnsupportedOperationException("Additional proxy interfaces not yet supported");
+ }
+
+ public void setCallbackInterface(Class<?> interfaze) {
+ callbackInterfaces = new Class[]{interfaze};
+ }
+
+ public Class<?> getCallbackInterface() {
+ return callbackInterfaces[0];
+ }
+
+ public void addCallbackInterface(Class<?> claz) {
+ throw new UnsupportedOperationException("Additional callback interfaces not yet supported");
+ }
+
+ public Class[] getImplementedCallbackInterfaces() {
+ return callbackInterfaces;
+ }
+
+ public void setTargetWire(InboundWire wire) {
+ this.targetWire = wire;
+ }
+
+ public Map<Operation<?>, OutboundInvocationChain> getInvocationChains() {
+ return chains;
+ }
+
+ public void addInvocationChains(Map<Operation<?>, OutboundInvocationChain> chains) {
+ this.chains.putAll(chains);
+ }
+
+ public void addInvocationChain(Operation<?> operation, OutboundInvocationChain chain) {
+ chains.put(operation, chain);
+ }
+
+ public Map<Operation<?>, InboundInvocationChain> getTargetCallbackInvocationChains() {
+ return callbackTargetChains;
+ }
+
+ public void addTargetCallbackInvocationChains(Map<Operation<?>, InboundInvocationChain> chains) {
+ callbackTargetChains.putAll(chains);
+ }
+
+ public void addTargetCallbackInvocationChain(Operation operation, InboundInvocationChain chain) {
+ callbackTargetChains.put(operation, chain);
+ }
+
+ public String getReferenceName() {
+ return referenceName;
+ }
+
+ public void setReferenceName(String referenceName) {
+ this.referenceName = referenceName;
+ }
+
+ public QualifiedName getTargetName() {
+ return targetName;
+ }
+
+ public void setTargetName(QualifiedName targetName) {
+ this.targetName = targetName;
+ }
+
+ public boolean isAutowire() {
+ return autowire;
+ }
+
+ public void setAutowire(boolean autowire) {
+ this.autowire = autowire;
+ }
+
+ public boolean isOptimizable() {
+ return optimizable;
+ }
+
+ public SCAObject getContainer() {
+ return container;
+ }
+
+ public void setContainer(SCAObject container) {
+ this.container = container;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/SynchronousBridgingInterceptor.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/SynchronousBridgingInterceptor.java
new file mode 100644
index 0000000000..f09bda400a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/SynchronousBridgingInterceptor.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+
+/**
+ * Synchronously bridges interceptors between an {@link org.apache.tuscany.spi.wire.InboundInvocationChain} and an
+ * {@link org.apache.tuscany.spi.wire.OutboundInvocationChain}.
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class SynchronousBridgingInterceptor implements BridgingInterceptor {
+ private Interceptor next;
+
+ public SynchronousBridgingInterceptor() {
+ }
+
+ public SynchronousBridgingInterceptor(Interceptor next) {
+ this.next = next;
+ }
+
+ public Message invoke(Message msg) {
+ return next.invoke(msg);
+ }
+
+ public Interceptor getNext() {
+ return next;
+ }
+
+ public void setNext(Interceptor next) {
+ this.next = next;
+ }
+
+ public boolean isOptimizable() {
+ return true;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/WireObjectFactory.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/WireObjectFactory.java
new file mode 100644
index 0000000000..c04869e8f5
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/WireObjectFactory.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.wire.OutboundChainHolder;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.WireService;
+
+/**
+ * Uses a wire to return an object instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class WireObjectFactory<T> implements ObjectFactory<T> {
+ private Class<T> interfaze;
+ private OutboundWire wire;
+ private WireService wireService;
+ // the cache of proxy interface method to operation mappings
+ private Map<Method, OutboundChainHolder> mappings;
+ private boolean optimizable;
+
+ /**
+ * Constructor.
+ *
+ * @param interfaze the interface to inject on the client
+ * @param wire the backing wire
+ * @param wireService the wire service to create the proxy
+ * @throws NoMethodForOperationException
+ */
+ public WireObjectFactory(Class<T> interfaze, OutboundWire wire, WireService wireService)
+ throws NoMethodForOperationException {
+ this.interfaze = interfaze;
+ this.wire = wire;
+ this.wireService = wireService;
+ this.mappings = WireUtils.createInterfaceToWireMapping(interfaze, wire);
+ }
+
+ public T getInstance() throws ObjectCreationException {
+ // note optimization must be done lazily as wire object factories are created during the build phase prior
+ // to the outbound and inbound wires being connected
+ if ((optimizable
+ || wire.isOptimizable())
+ && wire.getServiceContract().getInterfaceClass() != null
+ && interfaze.isAssignableFrom(wire.getServiceContract().getInterfaceClass())) {
+ optimizable = true;
+ try {
+ return interfaze.cast(wire.getTargetService());
+ } catch (TargetResolutionException e) {
+ throw new ObjectCreationException(e);
+ }
+ }
+ // clone the cached mappings
+ Map<Method, OutboundChainHolder> newChains = new HashMap<Method, OutboundChainHolder>(mappings.size());
+ for (Map.Entry<Method, OutboundChainHolder> entry : mappings.entrySet()) {
+ newChains.put(entry.getKey(), entry.getValue().clone());
+ }
+ return interfaze.cast(wireService.createProxy(interfaze, wire, newChains));
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/WireServiceExtension.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/WireServiceExtension.java
new file mode 100644
index 0000000000..80ab5b361a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/WireServiceExtension.java
@@ -0,0 +1,323 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.core.binding.local.LocalReferenceBinding;
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.ComponentReferenceDefinition;
+import org.apache.tuscany.spi.model.ComponentType;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.Implementation;
+import org.apache.tuscany.spi.model.Multiplicity;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ReferenceTarget;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.apache.tuscany.spi.policy.PolicyBuilderRegistry;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.IncompatibleServiceContractException;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.WireService;
+
+/**
+ * Base class for wire service extensions
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class WireServiceExtension implements WireService {
+ protected PolicyBuilderRegistry policyRegistry;
+ protected WorkContext context;
+
+ protected WireServiceExtension(WorkContext context, PolicyBuilderRegistry policyRegistry) {
+ this.policyRegistry = policyRegistry;
+ this.context = context;
+ }
+
+ public OutboundInvocationChain createOutboundChain(Operation<?> operation) {
+ return new OutboundInvocationChainImpl(operation);
+ }
+
+ public InboundInvocationChain createInboundChain(Operation<?> operation) {
+ return new InboundInvocationChainImpl(operation);
+ }
+
+ public InboundWire createWire(ServiceDefinition service) {
+ InboundWire wire = new InboundWireImpl();
+ ServiceContract<?> contract = service.getServiceContract();
+ wire.setServiceContract(contract);
+ wire.setServiceName(service.getName());
+ for (Operation<?> operation : contract.getOperations().values()) {
+ InboundInvocationChain chain = createInboundChain(operation);
+ // TODO handle policy
+ chain.addInterceptor(new InvokerInterceptor());
+ wire.addInvocationChain(operation, chain);
+ }
+ if (contract.getCallbackName() != null) {
+ wire.setCallbackReferenceName(service.getCallbackReferenceName());
+ }
+ return wire;
+ }
+
+ public void createWires(AtomicComponent component, ComponentDefinition<?> definition) {
+ Implementation<?> implementation = definition.getImplementation();
+ ComponentType<?, ?, ?> componentType = implementation.getComponentType();
+ // create incoming service wires
+ for (ServiceDefinition service : componentType.getServices().values()) {
+ InboundWire wire = createWire(service);
+ wire.setContainer(component);
+ component.addInboundWire(wire);
+ }
+ // create outgoing reference wires
+ for (ComponentReferenceDefinition refDefn : definition.getReferences().values()) {
+ if (!refDefn.isWiredByImpl()) {
+ List<OutboundWire> wires = createWire(refDefn.getTargets(), refDefn);
+ Multiplicity multiplicity = refDefn.getMultiplicity();
+ if (multiplicity == Multiplicity.ZERO_ONE || multiplicity == Multiplicity.ONE_ONE) {
+ // 0..1 or 1..1
+ for (OutboundWire wire : wires) {
+ wire.setContainer(component);
+ component.addOutboundWire(wire);
+ }
+ } else {
+ // 0..N or 1..N
+ for (OutboundWire wire : wires) {
+ wire.setContainer(component);
+ }
+ component.addOutboundWires(wires);
+ }
+ }
+ }
+ }
+
+ public void createWires(ReferenceBinding referenceBinding, ServiceContract<?> contract, QualifiedName targetName) {
+ InboundWire inboundWire = new InboundWireImpl(referenceBinding.getBindingType());
+ inboundWire.setServiceContract(contract);
+ inboundWire.setContainer(referenceBinding);
+ for (Operation<?> operation : contract.getOperations().values()) {
+ InboundInvocationChain chain = createInboundChain(operation);
+ inboundWire.addInvocationChain(operation, chain);
+ }
+ OutboundWire outboundWire = new OutboundWireImpl(referenceBinding.getBindingType());
+ outboundWire.setTargetName(targetName);
+
+ // [rfeng] Check if the Reference has the binding contract
+ ServiceContract<?> bindingContract = referenceBinding.getBindingServiceContract();
+ if (bindingContract == null) {
+ bindingContract = contract;
+ }
+ outboundWire.setServiceContract(bindingContract);
+ outboundWire.setContainer(referenceBinding);
+ for (Operation<?> operation : bindingContract.getOperations().values()) {
+ OutboundInvocationChain chain = createOutboundChain(operation);
+ if (referenceBinding instanceof LocalReferenceBinding) {
+ // Not ideal but the local binding case is special as its inbound and outbound wires are connected
+ // before the outbound wire is connected to the reference target. This requires the binding outbound
+ // chain to have an interceptor to connect to from the binding inbound chain. This outbound
+ // interceptor will then be bridged to the head target interceptor
+ chain.addInterceptor(new SynchronousBridgingInterceptor());
+ } else {
+ chain.addInterceptor(new InvokerInterceptor());
+ }
+ outboundWire.addInvocationChain(operation, chain);
+ }
+ // Add target callback chain to outbound wire
+ if (contract.getCallbackName() != null) {
+ outboundWire.setCallbackInterface(contract.getCallbackClass());
+ for (Operation<?> operation : contract.getCallbackOperations().values()) {
+ InboundInvocationChain callbackTargetChain = createInboundChain(operation);
+ // TODO handle policy
+ callbackTargetChain.addInterceptor(new InvokerInterceptor());
+ outboundWire.addTargetCallbackInvocationChain(operation, callbackTargetChain);
+ }
+ }
+ referenceBinding.setInboundWire(inboundWire);
+ referenceBinding.setOutboundWire(outboundWire);
+ }
+
+ public void createWires(ServiceBinding serviceBinding, ServiceContract<?> contract, String targetName) {
+ InboundWire inboundWire = new InboundWireImpl(serviceBinding.getBindingType());
+ // [rfeng] Check if the Reference has the serviceBinding contract
+ ServiceContract<?> bindingContract = serviceBinding.getBindingServiceContract();
+ if (bindingContract == null) {
+ bindingContract = contract;
+ }
+ inboundWire.setServiceContract(bindingContract);
+ inboundWire.setContainer(serviceBinding);
+ for (Operation<?> operation : bindingContract.getOperations().values()) {
+ InboundInvocationChain inboundChain = createInboundChain(operation);
+ inboundChain.addInterceptor(new SynchronousBridgingInterceptor());
+ inboundWire.addInvocationChain(operation, inboundChain);
+ }
+
+ OutboundWire outboundWire = new OutboundWireImpl(serviceBinding.getBindingType());
+ outboundWire.setServiceContract(contract);
+ outboundWire.setTargetName(new QualifiedName(targetName));
+ outboundWire.setContainer(serviceBinding);
+
+ for (Operation<?> operation : contract.getOperations().values()) {
+ OutboundInvocationChain outboundChain = createOutboundChain(operation);
+ outboundWire.addInvocationChain(operation, outboundChain);
+ }
+
+ // Add target callback chain to outbound wire
+ if (contract.getCallbackName() != null) {
+ outboundWire.setCallbackInterface(contract.getCallbackClass());
+ for (Operation<?> operation : contract.getCallbackOperations().values()) {
+ InboundInvocationChain callbackTargetChain = createInboundChain(operation);
+ // TODO handle policy
+ callbackTargetChain.addInterceptor(new InvokerInterceptor());
+ outboundWire.addTargetCallbackInvocationChain(operation, callbackTargetChain);
+ }
+ }
+ serviceBinding.setInboundWire(inboundWire);
+ serviceBinding.setOutboundWire(outboundWire);
+ }
+
+ /**
+ * Compares two operations for wiring compatibility as defined by the SCA assembly specification, namely: <p/> <ol>
+ * <li>compatibility for the individual method is defined as compatibility of the signature, that is method name,
+ * input types, and output types MUST BE the same. <li>the order of the input and output types also MUST BE the
+ * same. <li>the set of Faults and Exceptions expected by the source MUST BE the same or be a superset of those
+ * specified by the service. </ol>
+ *
+ * @param source the source contract to compare
+ * @param target the target contract to compare
+ * @throws org.apache.tuscany.spi.wire.IncompatibleServiceContractException
+ * if the two contracts don't match
+ */
+ public void checkCompatibility(ServiceContract<?> source, ServiceContract<?> target, boolean ignoreCallback)
+ throws IncompatibleServiceContractException {
+ if (source == target) {
+ // Shortcut for performance
+ return;
+ }
+// TODO: TUSCANY-1111, this test fails when wiring java to wsdl
+// if (source.isRemotable() != target.isRemotable()) {
+// throw new IncompatibleServiceContractException("Remotable settings do not match", source, target);
+// }
+ if (source.getInteractionScope() != target.getInteractionScope()) {
+ throw new IncompatibleServiceContractException("Interaction scopes settings do not match", source, target);
+ }
+
+ for (Operation<?> operation : source.getOperations().values()) {
+ Operation<?> targetOperation = target.getOperation(operation.getName());
+ if (targetOperation == null) {
+ throw new IncompatibleServiceContractException("Operation not found on target", source, target);
+ }
+ if (!targetOperation.equals(operation)) {
+ throw new IncompatibleServiceContractException("Target operations are not compatible", source, target);
+ }
+ }
+
+ if (ignoreCallback) {
+ return;
+ }
+
+ for (Operation<?> operation : source.getCallbackOperations().values()) {
+ Operation<?> targetOperation = target.getCallbackOperations().get(operation.getName());
+ if (targetOperation == null) {
+ throw new IncompatibleServiceContractException("Callback operation not found on target",
+ source,
+ target,
+ null,
+ targetOperation);
+ }
+ if (!operation.equals(targetOperation)) {
+ throw new IncompatibleServiceContractException("Target callback operation is not compatible",
+ source,
+ target,
+ operation,
+ targetOperation);
+ }
+ }
+ }
+
+
+ /**
+ * Creates a wire for flowing outbound invocations from a reference
+ *
+ * @param target the reference definition
+ * @param definition the reference target configuration
+ * @return the wire the outbound wire
+ */
+ protected List<OutboundWire> createWire(List<URI> targetUris, ComponentReferenceDefinition definition) {
+ ServiceContract<?> contract = definition.getServiceContract();
+ List<OutboundWire> outboundWires = new ArrayList<OutboundWire>();
+ if (definition.getAssociatedCompTypeRefDefn().isAutowire() || definition.isAutowire()) {
+ OutboundWire wire = new OutboundWireImpl();
+ wire.setAutowire(true);
+ wire.setServiceContract(contract);
+ wire.setReferenceName(definition.getName());
+ for (Operation<?> operation : contract.getOperations().values()) {
+ // TODO handle policy
+ OutboundInvocationChain chain = createOutboundChain(operation);
+ wire.addInvocationChain(operation, chain);
+ }
+ if (contract.getCallbackName() != null) {
+ wire.setCallbackInterface(contract.getCallbackClass());
+ for (Operation<?> operation : contract.getCallbackOperations().values()) {
+ InboundInvocationChain callbackTargetChain = createInboundChain(operation);
+ // TODO handle policy
+ callbackTargetChain.addInterceptor(new InvokerInterceptor());
+ wire.addTargetCallbackInvocationChain(operation, callbackTargetChain);
+ }
+ }
+ outboundWires.add(wire);
+ } else {
+ for (URI uri : targetUris) {
+ OutboundWire wire = new OutboundWireImpl();
+ QualifiedName qName = new QualifiedName(uri.toString());
+ wire.setTargetName(qName);
+ wire.setServiceContract(contract);
+ wire.setReferenceName(definition.getName());
+ for (Operation<?> operation : contract.getOperations().values()) {
+ // TODO handle policy
+ OutboundInvocationChain chain = createOutboundChain(operation);
+ wire.addInvocationChain(operation, chain);
+
+ }
+ if (contract.getCallbackName() != null) {
+ wire.setCallbackInterface(contract.getCallbackClass());
+ for (Operation<?> operation : contract.getCallbackOperations().values()) {
+ InboundInvocationChain callbackTargetChain = createInboundChain(operation);
+ // TODO handle policy
+ callbackTargetChain.addInterceptor(new InvokerInterceptor());
+ wire.addTargetCallbackInvocationChain(operation, callbackTargetChain);
+ }
+ }
+ outboundWires.add(wire);
+ }
+ }
+ return outboundWires;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/WireUtils.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/WireUtils.java
new file mode 100644
index 0000000000..73aa34e6bb
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/WireUtils.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.SCAObject;
+import static org.apache.tuscany.spi.idl.java.JavaIDLUtils.findMethod;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.OutboundChainHolder;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+/**
+ * Utilities for operating on wires
+ *
+ * @version $Rev$ $Date$
+ */
+public final class WireUtils {
+
+ private WireUtils() {
+ }
+
+ /**
+ * Maps invocation chains on a wire to corresponding methods
+ *
+ * @param wire the wire containing the invocation chains to map
+ * @param methods the methods to map to
+ * @return a collection containing the method to invocation chain mapping
+ * @throws NoMethodForOperationException
+ */
+ public static Map<Method, InboundInvocationChain> createInboundMapping(InboundWire wire, Method[] methods)
+ throws NoMethodForOperationException {
+ Map<Method, InboundInvocationChain> chains = new HashMap<Method, InboundInvocationChain>();
+ for (Map.Entry<Operation<?>, InboundInvocationChain> entry : wire.getInvocationChains().entrySet()) {
+ Operation<?> operation = entry.getKey();
+ InboundInvocationChain chain = entry.getValue();
+ Method method = findMethod(operation, methods);
+ if (method == null) {
+ throw new NoMethodForOperationException(operation.getName());
+ }
+ chains.put(method, chain);
+ }
+ return chains;
+ }
+
+
+ /**
+ * Maps methods on an interface to operations on a wire
+ *
+ * @param interfaze the interface to map from
+ * @param wire the wire to map to
+ * @return a collection of method to operation mappings
+ * @throws NoMethodForOperationException
+ */
+ public static Map<Method, OutboundChainHolder> createInterfaceToWireMapping(Class<?> interfaze, OutboundWire wire)
+ throws NoMethodForOperationException {
+ Map<Operation<?>, OutboundInvocationChain> invocationChains = wire.getInvocationChains();
+ Map<Method, OutboundChainHolder> chains = new HashMap<Method, OutboundChainHolder>(invocationChains.size());
+ Method[] methods = interfaze.getMethods();
+ for (Map.Entry<Operation<?>, OutboundInvocationChain> entry : invocationChains.entrySet()) {
+ Operation operation = entry.getKey();
+ Method method = findMethod(operation, methods);
+ if (method == null) {
+ throw new NoMethodForOperationException(operation.getName());
+ }
+ chains.put(method, new OutboundChainHolder(entry.getValue()));
+ }
+ return chains;
+ }
+
+ /**
+ * Determines if the given wire is optimizable, i.e. its invocation chains may be bypassed during an invocation.
+ * This is typically calculated during the connect phase to optimize away invocation chains.
+ *
+ * @param wire the wire
+ * @return true if the wire is optimizable
+ */
+ public static boolean isOptimizable(OutboundWire wire) {
+ for (OutboundInvocationChain chain : wire.getInvocationChains().values()) {
+ if (chain.getHeadInterceptor() != null) {
+ Interceptor current = chain.getHeadInterceptor();
+ if (current == null) {
+ break;
+ }
+ while (current != null) {
+ if (!current.isOptimizable()) {
+ return false;
+ }
+ current = current.getNext();
+ }
+ }
+ }
+ // if there is a callback, the wire is never optimizable since the callback target needs to be disambiguated
+ return wire.getTargetCallbackInvocationChains().isEmpty();
+ }
+
+ /**
+ * Determines if the given wire is optimizable, i.e. its invocation chains may be bypassed during an invocation.
+ * This is typically calculated during the connect phase to optimize away invocation chains.
+ *
+ * @param wire the wire
+ * @return true if the wire is optimizable
+ */
+ public static boolean isOptimizable(InboundWire wire) {
+ SCAObject container = wire.getContainer();
+ if (!(container instanceof Component) || !((Component) container).isOptimizable()) {
+ return false;
+ }
+ for (InboundInvocationChain chain : wire.getInvocationChains().values()) {
+ if (chain.getHeadInterceptor() != null) {
+ Interceptor current = chain.getHeadInterceptor();
+ while (current != null) {
+ if (!current.isOptimizable()) {
+ return false;
+ }
+ current = current.getNext();
+ }
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandler.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandler.java
new file mode 100644
index 0000000000..741ef21794
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandler.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire.jdk;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.osoa.sca.NoRegisteredCallbackException;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ReactivationException;
+import org.apache.tuscany.spi.component.SCAExternalizable;
+import org.apache.tuscany.spi.component.WorkContext;
+import static org.apache.tuscany.spi.idl.java.JavaIDLUtils.findOperation;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.AbstractOutboundInvocationHandler;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.apache.tuscany.spi.wire.WireInvocationHandler;
+
+
+/**
+ * Responsible for invoking on an outbound wire associated with a callback. The handler retrieves the correct outbound
+ * callback wire from the work context.
+ * <p/>
+ * TODO cache target invoker
+ *
+ * @version $Rev$ $Date$
+ */
+public class JDKCallbackInvocationHandler extends AbstractOutboundInvocationHandler
+ implements WireInvocationHandler, InvocationHandler, Externalizable, SCAExternalizable {
+ private transient WorkContext context;
+ private transient InboundWire wire;
+ private String serviceName;
+
+ /**
+ * Constructor used for deserialization only
+ */
+ public JDKCallbackInvocationHandler() {
+ }
+
+ public JDKCallbackInvocationHandler(InboundWire wire, WorkContext context) {
+ this.context = context;
+ this.wire = wire;
+ this.serviceName = wire.getServiceName();
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if (method.getParameterTypes().length == 0 && "toString".equals(method.getName())) {
+ return "[Proxy - " + Integer.toHexString(hashCode()) + "]";
+ } else if (method.getDeclaringClass().equals(Object.class)
+ && "equals".equals(method.getName())) {
+ // TODO implement
+ throw new UnsupportedOperationException();
+ } else if (Object.class.equals(method.getDeclaringClass())
+ && "hashCode".equals(method.getName())) {
+ return hashCode();
+ // TODO beter hash algorithm
+ }
+ Object correlationId = context.getCurrentCorrelationId();
+ context.setCurrentCorrelationId(null);
+ LinkedList<Object> callbackRoutingChain = (LinkedList<Object>) context.getCurrentCallbackRoutingChain().clone();
+ if (callbackRoutingChain == null) {
+ throw new AssertionError("Missing stack of from addresses");
+ }
+ Object targetAddress = callbackRoutingChain.removeFirst();
+ if (targetAddress == null) {
+ throw new AssertionError("Popped a null from address from stack");
+ }
+ //TODO optimize as this is slow in local invocations
+ Map<Operation<?>, OutboundInvocationChain> sourceCallbackInvocationChains =
+ wire.getSourceCallbackInvocationChains(targetAddress);
+ Operation operation = findOperation(method, sourceCallbackInvocationChains.keySet());
+ OutboundInvocationChain chain = sourceCallbackInvocationChains.get(operation);
+ TargetInvoker invoker = chain.getTargetInvoker();
+
+ try {
+ return invoke(chain, invoker, args, correlationId, callbackRoutingChain);
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getCause();
+ if (t instanceof NoRegisteredCallbackException) {
+ throw t;
+ }
+ throw e;
+ }
+ }
+
+
+ public Object invoke(Method method, Object[] args) throws Throwable {
+ return invoke(null, method, args);
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeObject(serviceName);
+ }
+
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ serviceName = (String) in.readObject();
+ }
+
+ public void setWorkContext(WorkContext context) {
+ this.context = context;
+ }
+
+ public void reactivate() throws ReactivationException {
+ AtomicComponent owner = context.getCurrentAtomicComponent();
+ if (owner == null) {
+ throw new ReactivationException("Current atomic component not set on work context");
+ }
+ wire = owner.getInboundWire(serviceName);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKInboundInvocationHandler.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKInboundInvocationHandler.java
new file mode 100644
index 0000000000..d0d82484e3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKInboundInvocationHandler.java
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire.jdk;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ReactivationException;
+import org.apache.tuscany.spi.component.SCAExternalizable;
+import org.apache.tuscany.spi.component.TargetInvocationException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.wire.AbstractInboundInvocationHandler;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.apache.tuscany.spi.wire.WireInvocationHandler;
+
+import org.apache.tuscany.core.wire.WireUtils;
+
+
+/**
+ * Receives a request from a proxy and performs an invocation on an {@link org.apache.tuscany.spi.wire.InboundWire} via
+ * an {@link InboundInvocationChain}
+ *
+ * @version $Rev$ $Date$
+ */
+public final class JDKInboundInvocationHandler extends AbstractInboundInvocationHandler
+ implements WireInvocationHandler, InvocationHandler, Externalizable, SCAExternalizable {
+ private static final long serialVersionUID = -307902641125881043L;
+
+ /*
+ * an association of an operation to chain holder. The holder contains the invocation chain
+ * and a local clone of the master TargetInvoker. TargetInvokers will be cloned by the handler and placed in the
+ * holder if they are cacheable. This allows optimizations such as avoiding target resolution when a source refers
+ * to a target of greater scope since the target reference can be maintained by the invoker. When a target invoker
+ * is not cacheable, the master associated with the wire chains will be used.
+ */
+ private transient Map<Method, ChainHolder> chains;
+ private transient WorkContext context;
+ private String serviceName;
+ private Class<?> interfaze;
+
+ /**
+ * Constructor used for deserialization only
+ */
+ public JDKInboundInvocationHandler() {
+ }
+
+ public JDKInboundInvocationHandler(Class<?> interfaze, InboundWire wire, WorkContext context) {
+ this.context = context;
+ this.serviceName = wire.getServiceName();
+ this.interfaze = interfaze;
+ init(interfaze, wire);
+ }
+
+ public void setWorkContext(WorkContext context) {
+ this.context = context;
+ }
+
+ /**
+ * Dispatches a client request made on a proxy
+ */
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ ChainHolder holder = chains.get(method);
+ if (holder == null) {
+ if (method.getParameterTypes().length == 0 && "toString".equals(method.getName())) {
+ return "[Proxy - " + Integer.toHexString(hashCode()) + "]";
+ } else if (method.getDeclaringClass().equals(Object.class)
+ && "equals".equals(method.getName())) {
+ // TODO implement
+ throw new UnsupportedOperationException();
+ } else if (Object.class.equals(method.getDeclaringClass())
+ && "hashCode".equals(method.getName())) {
+ return hashCode();
+ // TODO beter hash algorithm
+ }
+ throw new TargetInvocationException("Operation not configured", method.getName());
+ }
+ InboundInvocationChain chain = holder.chain;
+ TargetInvoker invoker;
+ if (holder.cachedInvoker == null) {
+ assert chain != null;
+ if (chain.getTargetInvoker() == null) {
+ String name = chain.getOperation().getName();
+ throw new TargetInvocationException("No target invoker configured for operation", name);
+ }
+ if (chain.getTargetInvoker().isCacheable()) {
+ // clone and store the invoker locally
+ holder.cachedInvoker = (TargetInvoker) chain.getTargetInvoker().clone();
+ invoker = holder.cachedInvoker;
+ } else {
+ invoker = chain.getTargetInvoker();
+ }
+ } else {
+ assert chain != null;
+ invoker = chain.getTargetInvoker();
+ }
+ context.setCurrentCorrelationId(null);
+ return invoke(chain, invoker, args);
+ }
+
+
+ public Object invoke(Method method, Object[] args) throws Throwable {
+ return invoke(null, method, args);
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeObject(serviceName);
+ out.writeObject(interfaze);
+ }
+
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ serviceName = (String) in.readObject();
+ interfaze = (Class<?>) in.readObject();
+ }
+
+ public void reactivate() throws ReactivationException {
+ // TODO this method will be extremely slow - look to optimize
+ AtomicComponent owner = context.getCurrentAtomicComponent();
+ if (owner == null) {
+ throw new ReactivationException("Current atomic component not set on work context");
+ }
+ InboundWire wire = owner.getInboundWire(serviceName);
+ init(interfaze, wire);
+ }
+
+ private void init(Class<?> interfaze, InboundWire wire) {
+ this.chains = new HashMap<Method, ChainHolder>();
+ Method[] methods = interfaze.getMethods();
+ Map<Method, InboundInvocationChain> invocationChains = WireUtils.createInboundMapping(wire, methods);
+ for (Map.Entry<Method, InboundInvocationChain> entry : invocationChains.entrySet()) {
+ this.chains.put(entry.getKey(), new ChainHolder(entry.getValue()));
+ }
+ }
+
+ /**
+ * A holder used to associate an wire chain with a local copy of a target invoker that was previously cloned from
+ * the chain master
+ */
+ private class ChainHolder {
+ InboundInvocationChain chain;
+ TargetInvoker cachedInvoker;
+
+ public ChainHolder(InboundInvocationChain config) {
+ this.chain = config;
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKOutboundInvocationHandler.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKOutboundInvocationHandler.java
new file mode 100644
index 0000000000..99cfb3c627
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKOutboundInvocationHandler.java
@@ -0,0 +1,249 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire.jdk;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.osoa.sca.NoRegisteredCallbackException;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ReactivationException;
+import org.apache.tuscany.spi.component.SCAExternalizable;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.TargetInvocationException;
+import org.apache.tuscany.spi.component.WorkContext;
+import static org.apache.tuscany.spi.model.InteractionScope.CONVERSATIONAL;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.AbstractOutboundInvocationHandler;
+import org.apache.tuscany.spi.wire.OutboundChainHolder;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.apache.tuscany.spi.wire.WireInvocationHandler;
+
+import org.apache.tuscany.core.implementation.PojoAtomicComponent;
+import org.apache.tuscany.core.wire.NoMethodForOperationException;
+import org.apache.tuscany.core.wire.WireUtils;
+
+
+/**
+ * Receives a request from a proxy and performs an invocation on an {@link org.apache.tuscany.spi.wire.OutboundWire} via
+ * an {@link org.apache.tuscany.spi.wire.OutboundInvocationChain}
+ *
+ * @version $Rev$ $Date$
+ */
+public final class JDKOutboundInvocationHandler extends AbstractOutboundInvocationHandler
+ implements WireInvocationHandler, InvocationHandler, Externalizable, SCAExternalizable {
+ private static final long serialVersionUID = -6155278451964527325L;
+
+ /*
+ * an association of an operation to chain holder. The holder contains an invocation chain
+ * and a local clone of the master TargetInvoker. TargetInvokers will be cloned by the handler and placed in the
+ * holder if they are cacheable. This allows optimizations such as avoiding target resolution when a source refers
+ * to a target of greater scope since the target reference can be maintained by the invoker. When a target invoker
+ * is not cacheable, the master associated with the wire chains will be used.
+ */
+ private transient Map<Method, OutboundChainHolder> chains;
+ private transient WorkContext workContext;
+ private transient Object fromAddress;
+ private transient boolean wireContainerIsAtomicComponent;
+ private transient boolean contractHasCallback;
+ private transient boolean callbackIsImplemented;
+ private transient String callbackClassName;
+ private transient boolean contractIsRemotable;
+ private transient boolean contractIsConversational;
+ private transient String convIdForRemotableTarget;
+ private transient String convIdFromThread;
+ private String referenceName;
+ private Class<?> interfaze;
+
+ /**
+ * Constructor used for deserialization only
+ */
+ public JDKOutboundInvocationHandler() {
+ }
+
+ public JDKOutboundInvocationHandler(Class<?> interfaze, OutboundWire wire, WorkContext workContext)
+ throws NoMethodForOperationException {
+ this.workContext = workContext;
+ this.interfaze = interfaze;
+ init(interfaze, wire, null);
+ }
+
+ public JDKOutboundInvocationHandler(Class<?> interfaze,
+ OutboundWire wire,
+ Map<Method, OutboundChainHolder> mapping,
+ WorkContext workContext)
+ throws NoMethodForOperationException {
+ this.workContext = workContext;
+ this.interfaze = interfaze;
+ init(interfaze, wire, mapping);
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ OutboundChainHolder holder = chains.get(method);
+ if (holder == null) {
+ if (method.getParameterTypes().length == 0 && "toString".equals(method.getName())) {
+ return "[Proxy - " + Integer.toHexString(hashCode()) + "]";
+ } else if (method.getDeclaringClass().equals(Object.class)
+ && "equals".equals(method.getName())) {
+ // TODO implement
+ throw new UnsupportedOperationException();
+ } else if (Object.class.equals(method.getDeclaringClass())
+ && "hashCode".equals(method.getName())) {
+ return hashCode();
+ // TODO beter hash algorithm
+ }
+ throw new TargetInvocationException("Operation not configured", method.getName());
+ }
+ OutboundInvocationChain chain = holder.getChain();
+ TargetInvoker invoker;
+
+ if (holder.getCachedInvoker() == null) {
+ assert chain != null;
+ if (chain.getTargetInvoker() == null) {
+ String name = chain.getOperation().getName();
+ throw new TargetInvocationException("No target invoker configured for operation", name);
+ }
+ if (chain.getTargetInvoker().isCacheable()) {
+ // clone and store the invoker locally
+ holder.setCachedInvoker((TargetInvoker) chain.getTargetInvoker().clone());
+ invoker = holder.getCachedInvoker();
+ } else {
+ invoker = chain.getTargetInvoker();
+ }
+ } else {
+ assert chain != null;
+ invoker = chain.getTargetInvoker();
+ }
+
+ if (wireContainerIsAtomicComponent && contractHasCallback && !callbackIsImplemented) {
+ throw new NoRegisteredCallbackException("Instance is does not implement callback: "
+ + callbackClassName);
+ }
+
+ if (contractIsConversational) {
+ assert workContext != null : "Work context cannot be null for conversational invocation";
+ // Check for a conv id on thread and remember it
+ convIdFromThread = (String) workContext.getIdentifier(Scope.CONVERSATION);
+ if (contractIsRemotable) {
+ if (convIdForRemotableTarget == null) {
+ convIdForRemotableTarget = createConversationID();
+ }
+ // Always use the conv id for this target
+ workContext.setIdentifier(Scope.CONVERSATION, convIdForRemotableTarget);
+ } else if (convIdFromThread == null) {
+ String newConvId = createConversationID();
+ workContext.setIdentifier(Scope.CONVERSATION, newConvId);
+ }
+ }
+
+ Object result = invoke(chain, invoker, args, null, null);
+ if (contractIsConversational && contractIsRemotable) {
+ // Make sure we restore the remembered conv id to continue propagating
+ workContext.setIdentifier(Scope.CONVERSATION, convIdFromThread);
+ }
+ return result;
+ }
+
+ public Object invoke(Method method, Object[] args) throws Throwable {
+ return invoke(null, method, args);
+ }
+
+ protected Object getFromAddress() {
+ return contractHasCallback ? fromAddress : null;
+ }
+
+ public void setWorkContext(WorkContext context) {
+ workContext = context;
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeObject(referenceName);
+ out.writeObject(interfaze);
+ }
+
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ referenceName = (String) in.readObject();
+ interfaze = (Class<?>) in.readObject();
+ }
+
+ public void reactivate() throws ReactivationException {
+ AtomicComponent owner = workContext.getCurrentAtomicComponent();
+ if (owner == null) {
+ throw new ReactivationException("Current atomic component not set on work context");
+ }
+ List<OutboundWire> wires = owner.getOutboundWires().get(referenceName);
+ if (wires == null) {
+ throw new ReactivationException("Reference wire not found", referenceName, owner.getName());
+ }
+ // TODO handle multiplicity
+ OutboundWire wire = wires.get(0);
+ try {
+ init(interfaze, wire, null);
+ } catch (NoMethodForOperationException e) {
+ throw new ReactivationException(e);
+ }
+ }
+
+ private void init(Class<?> interfaze, OutboundWire wire, Map<Method, OutboundChainHolder> mapping)
+ throws NoMethodForOperationException {
+ ServiceContract contract = wire.getServiceContract();
+ this.referenceName = wire.getReferenceName();
+ SCAObject wireContainer = wire.getContainer();
+ this.fromAddress = (wireContainer == null) ? null : wireContainer.getName();
+ this.contractIsConversational = contract.getInteractionScope().equals(CONVERSATIONAL);
+ this.contractIsRemotable = contract.isRemotable();
+ this.contractHasCallback = contract.getCallbackClass() != null;
+ if (contractHasCallback) {
+ this.callbackClassName = contract.getCallbackClass().getName();
+ } else {
+ this.callbackClassName = null;
+ }
+ // FIXME JFM this should be done during the callback and not be dependent on PojoAtomicComponent
+ this.wireContainerIsAtomicComponent = wireContainer instanceof PojoAtomicComponent;
+ if (wireContainerIsAtomicComponent && contractHasCallback) {
+ this.callbackIsImplemented =
+ ((PojoAtomicComponent) wireContainer).implementsCallback(contract.getCallbackClass());
+ } else {
+ this.callbackIsImplemented = false;
+ }
+ if (mapping == null) {
+ chains = WireUtils.createInterfaceToWireMapping(interfaze, wire);
+ } else {
+ chains = mapping;
+ }
+ }
+
+ // TODO Temporary fix to return a string with a UUID
+ private String createConversationID() {
+ return UUID.randomUUID().toString();
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKWireService.java b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKWireService.java
new file mode 100644
index 0000000000..e15b851351
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKWireService.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire.jdk;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Map;
+
+import org.osoa.sca.annotations.Constructor;
+import org.osoa.sca.annotations.EagerInit;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.policy.PolicyBuilderRegistry;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundChainHolder;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.ProxyCreationException;
+import org.apache.tuscany.spi.wire.Wire;
+import org.apache.tuscany.spi.wire.WireInvocationHandler;
+
+import org.apache.tuscany.core.wire.WireServiceExtension;
+
+/**
+ * the default implementation of a wire service that uses JDK dynamic proxies
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+@EagerInit
+public class JDKWireService extends WireServiceExtension {
+
+ public JDKWireService() {
+ super(null, null);
+ }
+
+ @Constructor
+ public JDKWireService(@Autowire WorkContext context, @Autowire PolicyBuilderRegistry policyRegistry) {
+ super(context, policyRegistry);
+ }
+
+ public <T> T createProxy(Class<T> interfaze, Wire wire) throws ProxyCreationException {
+ assert interfaze != null;
+ assert wire != null;
+ if (wire instanceof InboundWire) {
+ InboundWire inbound = (InboundWire) wire;
+ JDKInboundInvocationHandler handler = new JDKInboundInvocationHandler(interfaze, inbound, context);
+ ClassLoader cl = interfaze.getClassLoader();
+ return interfaze.cast(Proxy.newProxyInstance(cl, new Class[]{interfaze}, handler));
+ } else if (wire instanceof OutboundWire) {
+ OutboundWire outbound = (OutboundWire) wire;
+ JDKOutboundInvocationHandler handler = new JDKOutboundInvocationHandler(interfaze, outbound, context);
+ ClassLoader cl = interfaze.getClassLoader();
+ return interfaze.cast(Proxy.newProxyInstance(cl, new Class[]{interfaze}, handler));
+ } else {
+ throw new ProxyCreationException("Invalid wire type", wire.getClass().getName());
+ }
+ }
+
+ public <T> T createProxy(Class<T> interfaze, Wire wire, Map<Method, OutboundChainHolder> mapping)
+ throws ProxyCreationException {
+ assert interfaze != null;
+ assert wire != null;
+ assert mapping != null;
+ if (wire instanceof InboundWire) {
+ InboundWire inbound = (InboundWire) wire;
+ JDKInboundInvocationHandler handler = new JDKInboundInvocationHandler(interfaze, inbound, context);
+ ClassLoader cl = interfaze.getClassLoader();
+ return interfaze.cast(Proxy.newProxyInstance(cl, new Class[]{interfaze}, handler));
+ } else if (wire instanceof OutboundWire) {
+ OutboundWire outbound = (OutboundWire) wire;
+ JDKOutboundInvocationHandler handler = new JDKOutboundInvocationHandler(interfaze, outbound, context);
+ ClassLoader cl = interfaze.getClassLoader();
+ return interfaze.cast(Proxy.newProxyInstance(cl, new Class[]{interfaze}, handler));
+ } else {
+ throw new ProxyCreationException("Invalid wire type", wire.getClass().getName());
+ }
+ }
+
+ public Object createCallbackProxy(Class<?> interfaze, InboundWire wire) throws ProxyCreationException {
+ ClassLoader cl = interfaze.getClassLoader();
+ JDKCallbackInvocationHandler handler = new JDKCallbackInvocationHandler(wire, context);
+ return interfaze.cast(Proxy.newProxyInstance(cl, new Class[]{interfaze}, handler));
+ }
+
+ public WireInvocationHandler createHandler(Class<?> interfaze, Wire wire) {
+ assert wire != null;
+ if (wire instanceof InboundWire) {
+ InboundWire inbound = (InboundWire) wire;
+ return new JDKInboundInvocationHandler(interfaze, inbound, context);
+ } else if (wire instanceof OutboundWire) {
+ OutboundWire outbound = (OutboundWire) wire;
+ return new JDKOutboundInvocationHandler(interfaze, outbound, context);
+ } else {
+ throw new ProxyCreationException("Invalid wire type", wire.getClass().getName());
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/resources/META-INF/tuscany/default-system.composite b/branches/sca-java-integration/sca/kernel/core/src/main/resources/META-INF/tuscany/default-system.composite
new file mode 100644
index 0000000000..e77a4fcb06
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/resources/META-INF/tuscany/default-system.composite
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<!--
+ Default system configuration for the launcher environment.
+
+ $Rev$ $Date$
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="default-system">
+
+ <!-- Component that provides the Deployer service -->
+ <component name="deployer">
+ <system:implementation.system class="org.apache.tuscany.core.deployer.DeployerImpl" />
+ </component>
+
+ <!-- Work management -->
+ <component name="workContext">
+ <system:implementation.system class="org.apache.tuscany.core.component.WorkContextImpl" />
+ </component>
+
+ <!-- Wire service -->
+ <component name="wireService">
+ <system:implementation.system class="org.apache.tuscany.core.wire.jdk.JDKWireService" />
+ </component>
+
+ <!-- Scope infrastructure -->
+ <component name="scopeRegistry">
+ <system:implementation.system class="org.apache.tuscany.core.component.scope.ScopeRegistryImpl" />
+ </component>
+
+ <!-- Store infrastructure -->
+ <component name="store">
+ <system:implementation.system class="org.apache.tuscany.core.services.store.memory.MemoryStore" />
+ </component>
+
+ <!-- Builder and BuilderRegistry -->
+ <component name="builder">
+ <system:implementation.system class="org.apache.tuscany.core.builder.BuilderRegistryImpl" />
+ </component>
+
+ <!-- Loader and LoaderRegistry -->
+ <component name="loader">
+ <system:implementation.system class="org.apache.tuscany.core.loader.LoaderRegistryImpl" />
+ </component>
+
+ <!-- Introspector and IntrospectionRegistry -->
+ <component name="interfaceProcessorRegistry">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.IntrospectionRegistryImpl" />
+ </component>
+
+ <!-- Resource host registry -->
+ <component name="resourceHostRegistry">
+ <system:implementation.system class="org.apache.tuscany.core.services.host.DelegatingResourceHostRegistry" />
+ </component>
+
+ <!-- Connector infrastructure -->
+ <component name="connector">
+ <system:implementation.system class="org.apache.tuscany.core.builder.ConnectorImpl" />
+ </component>
+
+ <component name="wirePostProcessorRegistry">
+ <system:implementation.system class="org.apache.tuscany.core.builder.WirePostProcessorRegistryImpl" />
+ </component>
+
+ <!-- Default scopes -->
+ <component name="scope.module">
+ <system:implementation.system class="org.apache.tuscany.core.component.scope.CompositeScopeObjectFactory" />
+ </component>
+ <component name="scope.stateless">
+ <system:implementation.system class="org.apache.tuscany.core.component.scope.StatelessScopeObjectFactory" />
+ </component>
+ <component name="scope.request">
+ <system:implementation.system class="org.apache.tuscany.core.component.scope.RequestScopeObjectFactory" />
+ </component>
+
+ <component name="scope.conversational">
+ <system:implementation.system class="org.apache.tuscany.core.component.scope.ConversationalScopeObjectFactory" />
+ </component>
+
+ <!-- service for resolving artifacts against the user's local Maven repository -->
+ <component name="artifactRepository">
+ <system:implementation.system class="org.apache.tuscany.core.services.artifact.LocalMavenRepository" />
+ <property name="repository">.m2/repository</property>
+ </component>
+
+ <!-- WorkScheduler service -->
+ <component name="workManager">
+ <system:implementation.system class="org.apache.tuscany.core.services.work.jsr237.workmanager.ThreadPoolWorkManager" />
+ <property name="poolSize">10</property>
+ </component>
+
+ <component name="workScheduler">
+ <system:implementation.system class="org.apache.tuscany.core.services.work.jsr237.Jsr237WorkScheduler" />
+ </component>
+
+ <component name="policyBuilderRegistry">
+ <system:implementation.system class="org.apache.tuscany.core.policy.PolicyBuilderRegistryImpl" />
+ </component>
+
+ <component name="propertyFactory">
+ <system:implementation.system class="org.apache.tuscany.core.property.PropertyObjectFactoryImpl" />
+ </component>
+
+ <component name="wireLoader">
+ <system:implementation.system class="org.apache.tuscany.core.loader.WireLoader" />
+ </component>
+
+ <!-- include loader configuration -->
+ <include name="org.apache.tuscany.launcher.Loader" scdlResource="org/apache/tuscany/core/loader.scdl" />
+
+ <!-- include implementation processor configuration -->
+ <include name="org.apache.tuscany.launcher.Implementation" scdlResource="org/apache/tuscany/core/implementation.scdl" />
+
+ <!-- Java interface definition language -->
+ <include name="org.apache.tuscany.launcher.InterfaceJava" scdlResource="org/apache/tuscany/core/interfaceJava.scdl" />
+
+ <!-- include omposite implementation type -->
+ <include name="org.apache.tuscany.launcher.Composite" scdlResource="org/apache/tuscany/core/composite.scdl" />
+
+ <!-- System implementation type -->
+ <include name="org.apache.tuscany.launcher.SystemImplementation"
+ scdlResource="org/apache/tuscany/core/systemImplementation.scdl" />
+
+ <!-- Java implementation type -->
+ <include name="org.apache.tuscany.launcher.JavaImplementation"
+ scdlResource="org/apache/tuscany/core/javaImplementation.scdl" />
+
+ <!-- Data Binding -->
+ <include name="org.apache.tuscany.launcher.DataBinding" scdlResource="org/apache/tuscany/core/databinding.scdl" />
+
+ <!-- Logging formatters -->
+ <include name="org.apache.tuscany.launcher.Formatters" scdlResource="org/apache/tuscany/core/formatters.scdl" />
+
+ <!-- Deployment -->
+ <include name="org.apache.tuscany.launcher.Deployment" scdlResource="org/apache/tuscany/core/deployment.scdl" />
+
+ <!-- the local binding -->
+ <component name="localBindingLoader">
+ <system:implementation.system class="org.apache.tuscany.core.binding.local.LocalBindingLoader" />
+ </component>
+
+ <component name="localBindingBuilder">
+ <system:implementation.system class="org.apache.tuscany.core.binding.local.LocalBindingBuilder" />
+ </component>
+
+</composite>
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/composite.scdl b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/composite.scdl
new file mode 100644
index 0000000000..b51c9e4f68
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/composite.scdl
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<!--
+ Default system configuration for the launcher environment.
+
+ $Rev$ $Date$
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="org.apache.tuscany.core.Composite">
+
+ <!-- Composite implementation type -->
+ <component name="composite.loader">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.composite.CompositeLoader"/>
+ </component>
+ <component name="composite.implementationLoader">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.composite.ImplementationCompositeLoader"/>
+ </component>
+ <component name="composite.dependencyLoader">
+ <system:implementation.system class="org.apache.tuscany.core.loader.DependencyLoader"/>
+ </component>
+ <component name="composite.componentTypeLoader">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.composite.CompositeComponentTypeLoader"/>
+ </component>
+ <component name="composite.builder">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.composite.CompositeBuilder"/>
+ </component>
+</composite>
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/databinding.scdl b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/databinding.scdl
new file mode 100644
index 0000000000..b2b0173191
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/databinding.scdl
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="org.apache.tuscany.core.DataBinding">
+
+ <component name="databinding.wirePostProcessor" initLevel="50">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.DataBindingWirePostProcessor" />
+ </component>
+
+ <component name="databinding.javaInterfaceProcessor">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.DataBindingJavaInterfaceProcessor" />
+ </component>
+
+ <!-- [rfeng] HACK: Make sure the passByValue interceptor is added before the databinding interceptor -->
+ <component name="databinding.passByValueWirePostProcessor" initLevel="80">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.PassByValueWirePostProcessor" />
+ </component>
+
+ <!-- DataBinding registry -->
+ <component name="databinding.registry">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.DataBindingRegistryImpl" />
+ </component>
+
+ <!-- DataBinding registry -->
+ <component name="databinding.mediator">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.MediatorImpl" />
+ </component>
+
+ <!-- Transformer registry -->
+ <component name="databinding.transformerRegistry" initLevel="90">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.TransformerRegistryImpl" />
+ </component>
+
+ <component name="dataType.loader">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.DataTypeLoader" />
+ </component>
+
+ <component name="databinding.dom">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.DOMDataBinding" />
+ </component>
+
+ <component name="databinding.xmlString">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.XMLStringDataBinding" />
+ </component>
+
+ <!-- Group databindings -->
+ <component name="databinding.group.xml">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.XMLGroupDataBinding" />
+ </component>
+
+<!-- Comment out the stax databinding as it's covered in the databinding.group.xml -->
+<!--
+ <component name="databinding.stax">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.StAXDataBinding" />
+ </component>
+-->
+ <component name="databinding.javabeans">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.javabeans.JavaBeansDataBinding" />
+ </component>
+
+ <!-- Transformers -->
+
+ <component name="transformer.Input2InputTransformer">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.Input2InputTransformer" />
+ </component>
+
+ <component name="transformer.Exception2ExceptionTransformer">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.Exception2ExceptionTransformer" />
+ </component>
+
+ <component name="transformer.Output2OutputTransformer">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.Output2OutputTransformer" />
+ </component>
+
+ <component name="transformer.Group2GroupTransformer">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.Group2GroupTransformer" />
+ </component>
+
+ <component name="transformer.InputSource2Node">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.InputSource2Node" />
+ </component>
+
+ <component name="transformer.InputSource2SAX">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.InputSource2SAX" />
+ </component>
+
+ <component name="transformer.InputStream2Node">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.InputStream2Node" />
+ </component>
+
+ <component name="transformer.InputStream2SAX">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.InputStream2SAX" />
+ </component>
+
+ <component name="transformer.DOMNode2JavaBean">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.javabeans.DOMNode2JavaBeanTransformer" />
+ </component>
+
+ <component name="transformer.Node2OutputStream">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.Node2OutputStream" />
+ </component>
+
+ <component name="transformer.Node2String">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.Node2String" />
+ </component>
+
+ <component name="transformer.Node2Writer">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.Node2Writer" />
+ </component>
+
+ <component name="transformer.Node2XMLStreamReader">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.Node2XMLStreamReader" />
+ </component>
+
+ <component name="transformer.JavaBean2DOMNode">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.javabeans.JavaBean2DOMNodeTransformer" />
+ </component>
+
+ <component name="transformer.Reader2Node">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.Reader2Node" />
+ </component>
+
+ <component name="transformer.Reader2SAX">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.Reader2SAX" />
+ </component>
+
+ <component name="transformer.SAX2DOMPipe">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.SAX2DOMPipe" />
+ </component>
+
+ <component name="transformer.Source2ResultTransformer">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.Source2ResultTransformer" />
+ </component>
+
+ <component name="transformer.StreamDataPipe">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.StreamDataPipe" />
+ </component>
+
+ <component name="transformer.String2Node">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.String2Node" />
+ </component>
+
+ <component name="transformer.String2SAX">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.String2SAX" />
+ </component>
+
+ <component name="transformer.String2XMLStreamReader">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.String2XMLStreamReader" />
+ </component>
+
+ <component name="transformer.Writer2ReaderDataPipe">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.Writer2ReaderDataPipe" />
+ </component>
+
+ <component name="transformer.XMLStreamReader2Node">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.XMLStreamReader2Node" />
+ </component>
+
+ <component name="transformer.XMLStreamReader2SAX">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.XMLStreamReader2SAX" />
+ </component>
+
+ <component name="transformer.XMLStreamReader2String">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.xml.XMLStreamReader2String" />
+ </component>
+</composite> \ No newline at end of file
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/deployment.scdl b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/deployment.scdl
new file mode 100644
index 0000000000..64f40ac566
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/deployment.scdl
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<!--
+ Deployment-related system components
+
+ $Rev$ $Date$
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="org.apache.tuscany.core.Deployment">
+
+ <!-- Contribution Service -->
+ <component name="contributionDirectoryWatcher" initLevel="100">
+ <system:implementation.system class="org.apache.tuscany.core.services.deployment.ContributionDirectoryWatcher" />
+ <property name="path">target/deployables</property>
+ </component>
+ <component name="contributionService" initLevel="90">
+ <system:implementation.system class="org.apache.tuscany.core.services.deployment.ContributionServiceImpl" />
+ </component>
+ <component name="contributionRepository" initLevel="40">
+ <system:implementation.system class="org.apache.tuscany.core.services.deployment.ContributionRepositoryImpl" />
+ </component>
+
+ <!-- contribution processor registry and processors -->
+ <component name="contributionProcessorRegistry" initLevel="35">
+ <system:implementation.system class="org.apache.tuscany.core.services.deployment.ContributionProcessorRegistryImpl" />
+ </component>
+
+ <component name="contentTypeDescriber" initLevel="30">
+ <system:implementation.system class="org.apache.tuscany.core.services.deployment.ContentTypeDescriberImpl" />
+ </component>
+ <component name="JarContributionProcessor" initLevel="30">
+ <system:implementation.system class="org.apache.tuscany.core.services.deployment.contribution.JarContributionProcessor" />
+ </component>
+ <component name="FolderContributionProcessor" initLevel="30">
+ <system:implementation.system class="org.apache.tuscany.core.services.deployment.contribution.FolderContributionProcessor" />
+ </component>
+ <component name="JavaContributionProcessor" initLevel="30">
+ <system:implementation.system class="org.apache.tuscany.core.services.deployment.contribution.JavaContributionProcessor" />
+ </component>
+ <component name="CompositeContributionProcessor" initLevel="30">
+ <system:implementation.system class="org.apache.tuscany.core.services.deployment.contribution.CompositeContributionProcessor" />
+ </component>
+
+ <!-- contribution resolver registry and resolvers -->
+ <component name="artifactResolverRegistry" initLevel="35">
+ <system:implementation.system class="org.apache.tuscany.core.services.deployment.ArtifactResolverRegistryImpl" />
+ </component>
+
+ <component name="ComponentDefinitionArtifactResolver" initLevel="30">
+ <system:implementation.system class="org.apache.tuscany.core.services.deployment.resolver.ComponentDefinitionArtifactResolver" />
+ </component>
+
+</composite>
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/formatters.scdl b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/formatters.scdl
new file mode 100644
index 0000000000..194bdd27fd
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/formatters.scdl
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<!--
+ Formatter configurations for JDK logging.
+
+ $Rev: 476250 $ $Date: 2006-11-17 10:56:22 -0800 (Fri, 17 Nov 2006) $
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="org.apache.tuscany.core.Formatters">
+
+ <component name="LoaderExceptionFormatter">
+ <system:implementation.system class="org.apache.tuscany.core.loader.LoaderExceptionFormatter"/>
+ </component>
+
+ <component name="IncompatibleServiceContractExceptionFormatter">
+ <system:implementation.system
+ class="org.apache.tuscany.core.wire.IncompatibleServiceContractExceptionFormatter"/>
+ </component>
+
+ <component name="WireExceptionExceptionFormatter">
+ <system:implementation.system
+ class="org.apache.tuscany.core.builder.WiringExceptionFormatter"/>
+ </component>
+
+</composite>
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/implementation.scdl b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/implementation.scdl
new file mode 100644
index 0000000000..9d4a3dbeda
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/implementation.scdl
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<!--
+ Default system configuration for the launcher environment.
+
+ $Rev$ $Date$
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="org.apache.tuscany.core.Implementation">
+
+ <!-- Foundation implementation processors -->
+ <component name="implementation.ImplementationProcessorService">
+ <system:implementation.system
+ class="org.apache.tuscany.core.implementation.processor.ImplementationProcessorServiceImpl"/>
+ </component>
+ <component name="implementation.Constructor">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.processor.ConstructorProcessor"/>
+ </component>
+ <component name="implementation.Destroy">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.processor.DestroyProcessor"/>
+ </component>
+ <component name="implementation.Init">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.processor.InitProcessor"/>
+ </component>
+ <component name="implementation.EagerInit">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.processor.EagerInitProcessor"/>
+ </component>
+ <component name="implementation.Scope">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.processor.ScopeProcessor"/>
+ </component>
+ <component name="implementation.AllowsPassByReference">
+ <system:implementation.system
+ class="org.apache.tuscany.core.implementation.processor.AllowsPassByReferenceProcessor"/>
+ </component>
+ <component name="implementation.Property">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.processor.PropertyProcessor"/>
+ </component>
+ <component name="implementation.Reference">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.processor.ReferenceProcessor"/>
+ </component>
+ <component name="implementation.Service">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.processor.ServiceProcessor"/>
+ </component>
+ <component name="implementation.HeuristicPojo">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.processor.HeuristicPojoProcessor"/>
+ </component>
+ <component name="implementation.Monitor">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.processor.MonitorProcessor"/>
+ </component>
+ <component name="implementation.Resource">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.processor.ResourceProcessor"/>
+ </component>
+ <component name="implementation.Conversation">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.processor.ConversationProcessor"/>
+ </component>
+ <component name="implementation.ContextProcessor">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.processor.ContextProcessor"/>
+ </component>
+
+</composite>
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/interfaceJava.scdl b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/interfaceJava.scdl
new file mode 100644
index 0000000000..40e5070e69
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/interfaceJava.scdl
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<!--
+ Configuration for Java IDL support.
+
+ $Rev$ $Date$
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="org.apache.tuscany.core.InterfaceJava">
+
+ <component name="interfaceJava.interfaceProcessorRegistry">
+ <system:implementation.system class="org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl"/>
+ </component>
+ <component name="interfaceJava.loader">
+ <system:implementation.system class="org.apache.tuscany.core.idl.java.InterfaceJavaLoader"/>
+ </component>
+</composite>
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/javaImplementation.scdl b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/javaImplementation.scdl
new file mode 100644
index 0000000000..b53b01480f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/javaImplementation.scdl
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<!--
+ Default system configuration for the launcher environment.
+
+ $Rev$ $Date$
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="org.apache.tuscany.core.JavaImplementation">
+
+ <!-- Java implementation type -->
+ <component name="java.implementationLoader">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.java.JavaImplementationLoader"/>
+ </component>
+ <component name="java.componentTypeLoader">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.java.JavaComponentTypeLoader"/>
+ </component>
+ <component name="java.componentBuilder">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.java.JavaComponentBuilder"/>
+ </component>
+</composite>
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/loader.scdl b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/loader.scdl
new file mode 100644
index 0000000000..cfc0382895
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/loader.scdl
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<!--
+ Default loader configuration for the launcher environment.
+
+ $Rev$ $Date$
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="org.apache.tuscany.core.Loader">
+
+ <!-- Foundation element loader implementations -->
+ <component name="elementLoader.component">
+ <system:implementation.system class="org.apache.tuscany.core.loader.ComponentLoader"/>
+ </component>
+ <component name="elementLoader.componentType">
+ <system:implementation.system class="org.apache.tuscany.core.loader.ComponentTypeElementLoader"/>
+ </component>
+ <component name="elementLoader.include">
+ <system:implementation.system class="org.apache.tuscany.core.loader.IncludeLoader"/>
+ </component>
+ <component name="elementLoader.property">
+ <system:implementation.system class="org.apache.tuscany.core.loader.PropertyLoader"/>
+ </component>
+ <component name="elementLoader.reference">
+ <system:implementation.system class="org.apache.tuscany.core.loader.ReferenceLoader"/>
+ </component>
+ <component name="elementLoader.service">
+ <system:implementation.system class="org.apache.tuscany.core.loader.ServiceLoader"/>
+ </component>
+ <component name="elementLoader.wire">
+ <system:implementation.system class="org.apache.tuscany.core.loader.WireLoader"/>
+ </component>
+
+</composite>
diff --git a/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/systemImplementation.scdl b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/systemImplementation.scdl
new file mode 100644
index 0000000000..f4c2c456ba
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/main/resources/org/apache/tuscany/core/systemImplementation.scdl
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<!--
+ Default system configuration for the launcher environment.
+
+ $Rev$ $Date$
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="org.apache.tuscany.core.SystemImplementation">
+
+ <!-- System implementation type -->
+ <component name="system.componentTypeLoader">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.system.loader.SystemComponentTypeLoader"/>
+ </component>
+
+ <component name="system.compositeComponentTypeLoader">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.system.loader.SystemCompositeComponentTypeLoader"/>
+ </component>
+ <component name="system.implementationLoader">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.system.loader.SystemImplementationLoader"/>
+ </component>
+ <component name="system.componentBuilder">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.system.builder.SystemComponentBuilder"/>
+ </component>
+ <component name="system.compositeBuilder">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.composite.SystemCompositeBuilder"/>
+ </component>
+</composite>
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/AbstractLocalTargetInvokerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/AbstractLocalTargetInvokerTestCase.java
new file mode 100644
index 0000000000..8dc0023332
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/AbstractLocalTargetInvokerTestCase.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.binding.local;
+
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.mock.wire.MockTargetInvoker;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class AbstractLocalTargetInvokerTestCase extends TestCase {
+
+ public void testInvokerWithInterceptor() throws Throwable {
+ AbstractLocalTargetInvoker invoker = new MockTargetInvoker();
+ Interceptor interceptor = EasyMock.createMock(Interceptor.class);
+ interceptor.invoke(EasyMock.isA(Message.class));
+ EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ Message msg = (Message) EasyMock.getCurrentArguments()[0];
+ if (msg.getTargetInvoker() == null) {
+ fail("Target invoker not set");
+ }
+ return null;
+ }
+ });
+ EasyMock.replay(interceptor);
+ OutboundInvocationChain chain = EasyMock.createMock(OutboundInvocationChain.class);
+ EasyMock.expect(chain.getHeadInterceptor()).andReturn(interceptor);
+ EasyMock.replay(chain);
+ invoker.invoke(chain, EasyMock.createNiceMock(TargetInvoker.class), new MessageImpl());
+ EasyMock.verify(chain);
+ EasyMock.verify(interceptor);
+ }
+
+ public void testShortCircuitInvoke() throws Throwable {
+ AbstractLocalTargetInvoker invoker = new MockTargetInvoker();
+ TargetInvoker targetInvoker = EasyMock.createMock(TargetInvoker.class);
+ EasyMock.expect(targetInvoker.invoke(EasyMock.isA(Message.class))).andReturn(new MessageImpl());
+ EasyMock.replay(targetInvoker);
+ OutboundInvocationChain chain = EasyMock.createMock(OutboundInvocationChain.class);
+ EasyMock.expect(chain.getHeadInterceptor()).andReturn(null);
+ EasyMock.replay(chain);
+ invoker.invoke(chain, targetInvoker, new MessageImpl());
+ EasyMock.verify(chain);
+ EasyMock.verify(targetInvoker);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalBindingBuilderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalBindingBuilderTestCase.java
new file mode 100644
index 0000000000..90f02e80a6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalBindingBuilderTestCase.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.binding.local;
+
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class LocalBindingBuilderTestCase extends TestCase {
+
+ public void testBuild() throws Exception {
+ LocalBindingBuilder builder = new LocalBindingBuilder();
+ ServiceDefinition def = new ServiceDefinition();
+ def.setName("foo");
+ ServiceBinding binding = builder.build(null, def, null, null);
+ assertEquals(LocalServiceBinding.class, binding.getClass());
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalBindingLoaderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalBindingLoaderTestCase.java
new file mode 100644
index 0000000000..1633d5f8ea
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalBindingLoaderTestCase.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.binding.local;
+
+import java.net.URI;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.loader.LoaderException;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class LocalBindingLoaderTestCase extends TestCase {
+ private LocalBindingLoader loader;
+
+ public void testParse() throws Exception {
+ XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class);
+ EasyMock.expect(reader.getAttributeValue(null, "uri")).andReturn("foo");
+ EasyMock.replay(reader);
+ LocalBindingDefinition definition = loader.load(null, null, reader, null);
+ assertEquals(new URI("foo"), definition.getTargetUri());
+ EasyMock.verify(reader);
+ }
+
+ public void testNoUri() throws Exception {
+ XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class);
+ EasyMock.expect(reader.getAttributeValue(null, "uri")).andReturn(null);
+ EasyMock.replay(reader);
+ LocalBindingDefinition definition = loader.load(null, null, reader, null);
+ assertNull(definition.getTargetUri());
+ EasyMock.verify(reader);
+ }
+
+ public void testBadUri() throws Exception {
+ XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class);
+ EasyMock.expect(reader.getAttributeValue(null, "uri")).andReturn("foo foo");
+ EasyMock.replay(reader);
+ try {
+ loader.load(null, null, reader, null);
+ fail();
+ } catch (LoaderException e) {
+ // expected
+ }
+ EasyMock.verify(reader);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ loader = new LocalBindingLoader(null);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerInvocationExceptionTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerInvocationExceptionTestCase.java
new file mode 100644
index 0000000000..1976170f54
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerInvocationExceptionTestCase.java
@@ -0,0 +1,86 @@
+package org.apache.tuscany.core.binding.local;
+
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class LocalCallbackTargetInvokerInvocationExceptionTestCase extends TestCase {
+ private InboundWire wire;
+ private Message message;
+ private OutboundInvocationChain chain;
+ private LocalCallbackTargetInvoker invoker;
+
+ /**
+ * Verfies an InvocationTargetException thrown when invoking the target is propagated to the client correctly and
+ * the originating error is unwrapped
+ */
+ public void testThrowableTargetInvocation() throws Exception {
+ Message response = invoker.invoke(message);
+ assertTrue(response.isFault());
+ Object body = response.getBody();
+ assertTrue(SomeException.class.equals(body.getClass()));
+ EasyMock.verify(wire);
+ EasyMock.verify(chain);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ Object targetAddress = new Object();
+ message = new MessageImpl();
+ message.pushFromAddress(targetAddress);
+ message.setBody("foo");
+ Message response = new MessageImpl();
+ response.setBody("response");
+ Operation<Type> operation = new Operation<Type>("echo", null, null, null);
+ Interceptor head = new ErrorInterceptor();
+ chain = EasyMock.createMock(OutboundInvocationChain.class);
+ EasyMock.expect(chain.getTargetInvoker()).andReturn(null);
+ EasyMock.expect(chain.getHeadInterceptor()).andReturn(head);
+ EasyMock.replay(chain);
+ Map<Operation<?>, OutboundInvocationChain> chains = new HashMap<Operation<?>, OutboundInvocationChain>();
+ chains.put(operation, chain);
+ wire = EasyMock.createMock(InboundWire.class);
+ EasyMock.expect(wire.getSourceCallbackInvocationChains(targetAddress)).andReturn(chains);
+ EasyMock.replay(wire);
+ invoker = new LocalCallbackTargetInvoker(operation, wire);
+ }
+
+ private class SomeException extends Exception {
+
+ }
+
+ private class ErrorInterceptor implements Interceptor {
+
+ public Message invoke(Message msg) {
+ msg.setBodyWithFault(new SomeException());
+ return msg;
+ }
+
+ public void setNext(Interceptor next) {
+
+ }
+
+ public Interceptor getNext() {
+ return null;
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerTestCase.java
new file mode 100644
index 0000000000..123f32d66a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerTestCase.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.binding.local;
+
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class LocalCallbackTargetInvokerTestCase extends TestCase {
+ private InboundWire wire;
+ private Message message;
+ private OutboundInvocationChain chain;
+ private Interceptor head;
+ private LocalCallbackTargetInvoker invoker;
+
+ /**
+ * Verfies the normal execution path through a callback
+ */
+ public void testNormalPathMessageInvocation() throws Exception {
+ Message response = invoker.invoke(message);
+ assertEquals("response", response.getBody());
+ EasyMock.verify(wire);
+ EasyMock.verify(chain);
+ EasyMock.verify(head);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ Object targetAddress = new Object();
+ message = new MessageImpl();
+ message.pushFromAddress(targetAddress);
+ message.setBody("foo");
+ Message response = new MessageImpl();
+ response.setBody("response");
+ Operation<Type> operation = new Operation<Type>("echo", null, null, null);
+ head = EasyMock.createMock(Interceptor.class);
+ EasyMock.expect(head.invoke(EasyMock.isA(Message.class))).andReturn(response);
+ EasyMock.replay(head);
+ chain = EasyMock.createMock(OutboundInvocationChain.class);
+ EasyMock.expect(chain.getTargetInvoker()).andReturn(null);
+ EasyMock.expect(chain.getHeadInterceptor()).andReturn(head);
+ EasyMock.replay(chain);
+ Map<Operation<?>, OutboundInvocationChain> chains = new HashMap<Operation<?>, OutboundInvocationChain>();
+ chains.put(operation, chain);
+ wire = EasyMock.createMock(InboundWire.class);
+ EasyMock.expect(wire.getSourceCallbackInvocationChains(targetAddress)).andReturn(chains);
+ EasyMock.replay(wire);
+
+ invoker = new LocalCallbackTargetInvoker(operation, wire);
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerThrowableTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerThrowableTestCase.java
new file mode 100644
index 0000000000..9c1bbc616e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalCallbackTargetInvokerThrowableTestCase.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.binding.local;
+
+import java.lang.reflect.Type;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class LocalCallbackTargetInvokerThrowableTestCase extends TestCase {
+ private InboundWire wire;
+ private Message message;
+ private OutboundInvocationChain chain;
+ private Interceptor head;
+ private LocalCallbackTargetInvoker invoker;
+
+ /**
+ * Verfies an exception thrown in the target is propagated to the client correctly
+ */
+ public void testThrowableTargetInvocation() throws Exception {
+ Message response = invoker.invoke(message);
+ assertTrue(response.isFault());
+ Object body = response.getBody();
+ if (!(body instanceof UndeclaredThrowableException)) {
+ fail(); // EasyMock wraps the Throwable in an UndeclaredThrowableException
+ }
+ UndeclaredThrowableException e = (UndeclaredThrowableException) body;
+ assertTrue(InsidiousException.class.equals(e.getUndeclaredThrowable().getClass()));
+ EasyMock.verify(wire);
+ EasyMock.verify(chain);
+ EasyMock.verify(head);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void setUp() throws Exception {
+ super.setUp();
+ Object targetAddress = new Object();
+ message = new MessageImpl();
+ message.pushFromAddress(targetAddress);
+ message.setBody("foo");
+ Message response = new MessageImpl();
+ response.setBody("response");
+ Operation<Type> operation = new Operation<Type>("echo", null, null, null);
+ head = EasyMock.createMock(Interceptor.class);
+ EasyMock.expect(head.invoke(EasyMock.isA(Message.class))).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ throw new InsidiousException(); // andThrow() does not seem to work here
+ }
+ });
+ EasyMock.replay(head);
+ chain = EasyMock.createMock(OutboundInvocationChain.class);
+ EasyMock.expect(chain.getTargetInvoker()).andReturn(null);
+ EasyMock.expect(chain.getHeadInterceptor()).andReturn(head);
+ EasyMock.replay(chain);
+ Map<Operation<?>, OutboundInvocationChain> chains = new HashMap<Operation<?>, OutboundInvocationChain>();
+ chains.put(operation, chain);
+ wire = EasyMock.createMock(InboundWire.class);
+ EasyMock.expect(wire.getSourceCallbackInvocationChains(targetAddress)).andReturn(chains);
+ EasyMock.replay(wire);
+ invoker = new LocalCallbackTargetInvoker(operation, wire);
+ }
+
+ private class InsidiousException extends Throwable {
+
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalTargetInvokerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalTargetInvokerTestCase.java
new file mode 100644
index 0000000000..a313d341ed
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/binding/local/LocalTargetInvokerTestCase.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.binding.local;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class LocalTargetInvokerTestCase extends TestCase {
+ private ServiceContract<Object> serviceContract;
+ private Operation<Object> operation;
+
+ public void testInvoke() {
+ TargetInvoker targetInvoker = EasyMock.createMock(TargetInvoker.class);
+ EasyMock.expect(targetInvoker.invoke(EasyMock.isA(Message.class))).andReturn(new MessageImpl());
+ EasyMock.replay(targetInvoker);
+ OutboundInvocationChain chain = EasyMock.createNiceMock(OutboundInvocationChain.class);
+ EasyMock.expect(chain.getTargetInvoker()).andReturn(targetInvoker);
+ EasyMock.replay(chain);
+ Map<Operation<?>, OutboundInvocationChain> chains = new HashMap<Operation<?>, OutboundInvocationChain>();
+ chains.put(operation, chain);
+ OutboundWire wire = EasyMock.createNiceMock(OutboundWire.class);
+ wire.getInvocationChains();
+ EasyMock.expectLastCall().andReturn(chains);
+ EasyMock.expect(wire.getServiceContract()).andReturn(serviceContract);
+ EasyMock.replay(wire);
+ TargetInvoker invoker = new LocalTargetInvoker(operation, wire);
+ Message msg = invoker.invoke(new MessageImpl());
+ assertFalse(msg.isFault());
+ EasyMock.verify(targetInvoker);
+ }
+
+ public void testCallbackSetInvoke() {
+ ServiceContract<?> contract = new ServiceContract<Object>() {
+
+ };
+ contract.setCallbackClass(Object.class);
+ TargetInvoker targetInvoker = EasyMock.createMock(TargetInvoker.class);
+ EasyMock.expect(targetInvoker.invoke(EasyMock.isA(Message.class))).andReturn(new MessageImpl());
+ EasyMock.replay(targetInvoker);
+ OutboundInvocationChain chain = EasyMock.createNiceMock(OutboundInvocationChain.class);
+ EasyMock.expect(chain.getTargetInvoker()).andReturn(targetInvoker);
+ EasyMock.replay(chain);
+ Map<Operation<?>, OutboundInvocationChain> chains = new HashMap<Operation<?>, OutboundInvocationChain>();
+ chains.put(operation, chain);
+ SCAObject container = EasyMock.createMock(SCAObject.class);
+ EasyMock.expect(container.getName()).andReturn("foo").atLeastOnce();
+ EasyMock.replay(container);
+ OutboundWire wire = EasyMock.createNiceMock(OutboundWire.class);
+ EasyMock.expect(wire.getContainer()).andReturn(container).atLeastOnce();
+ wire.getInvocationChains();
+ EasyMock.expectLastCall().andReturn(chains);
+ EasyMock.expect(wire.getServiceContract()).andReturn(contract);
+ EasyMock.replay(wire);
+ TargetInvoker invoker = new LocalTargetInvoker(operation, wire);
+ Message msg = EasyMock.createMock(Message.class);
+ msg.pushFromAddress(EasyMock.eq("foo"));
+ EasyMock.replay(msg);
+ invoker.invoke(msg);
+ EasyMock.verify(msg);
+ EasyMock.verify(targetInvoker);
+ }
+
+ public void testFaultInvoke() {
+ TargetInvoker targetInvoker = EasyMock.createMock(TargetInvoker.class);
+ EasyMock.expect(targetInvoker.invoke(EasyMock.isA(Message.class))).andThrow(new TestException());
+ EasyMock.replay(targetInvoker);
+ OutboundInvocationChain chain = EasyMock.createNiceMock(OutboundInvocationChain.class);
+ EasyMock.expect(chain.getTargetInvoker()).andReturn(targetInvoker);
+ EasyMock.replay(chain);
+ Map<Operation<?>, OutboundInvocationChain> chains = new HashMap<Operation<?>, OutboundInvocationChain>();
+ chains.put(operation, chain);
+ OutboundWire wire = EasyMock.createNiceMock(OutboundWire.class);
+ wire.getInvocationChains();
+ EasyMock.expectLastCall().andReturn(chains);
+ EasyMock.expect(wire.getServiceContract()).andReturn(serviceContract);
+ EasyMock.replay(wire);
+ TargetInvoker invoker = new LocalTargetInvoker(operation, wire);
+ Message msg = invoker.invoke(new MessageImpl());
+ assertTrue(msg.isFault());
+ assertTrue(msg.getBody() instanceof TestException);
+ EasyMock.verify(targetInvoker);
+ }
+
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ serviceContract = new ServiceContract<Object>() {
+ };
+ operation = new Operation<Object>("foo", null, null, null);
+ }
+
+
+ private class TestException extends RuntimeException {
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/bootstrap/BootstrapperTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/bootstrap/BootstrapperTestCase.java
new file mode 100644
index 0000000000..728902e82b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/bootstrap/BootstrapperTestCase.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.bootstrap;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.deployer.DeployerImpl;
+import org.apache.tuscany.core.monitor.NullMonitorFactory;
+
+/**
+ * Verifies the default bootstrapper can be instantiated
+ *
+ * @version $Rev$ $Date$
+ */
+public class BootstrapperTestCase extends TestCase {
+ private Bootstrapper bootstrapper;
+
+ public void testDeployerBootstrap() {
+ DeployerImpl deployer = (DeployerImpl) bootstrapper.createDeployer();
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ bootstrapper = new DefaultBootstrapper(new NullMonitorFactory(), null, null);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/AbstractConnectorImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/AbstractConnectorImplTestCase.java
new file mode 100644
index 0000000000..b828262d6e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/AbstractConnectorImplTestCase.java
@@ -0,0 +1,306 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.Service;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.component.TargetInvokerCreationException;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.apache.tuscany.spi.wire.WireService;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.binding.local.LocalReferenceBinding;
+import org.apache.tuscany.core.binding.local.LocalServiceBinding;
+import org.apache.tuscany.core.implementation.composite.ServiceImpl;
+import org.apache.tuscany.core.mock.binding.MockServiceBinding;
+import org.apache.tuscany.core.wire.InboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.InboundWireImpl;
+import org.apache.tuscany.core.wire.InvokerInterceptor;
+import org.apache.tuscany.core.wire.OutboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.OutboundWireImpl;
+import org.apache.tuscany.core.wire.SynchronousBridgingInterceptor;
+import org.apache.tuscany.core.wire.jdk.JDKWireService;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractConnectorImplTestCase extends TestCase {
+ protected static final String TARGET = "target";
+ protected static final QualifiedName TARGET_NAME = new QualifiedName(TARGET);
+ protected static final String TARGET_SERVICE = "FooService";
+ protected static final QualifiedName TARGET_SERVICE_NAME = new QualifiedName("target/FooService");
+ protected static final String RESPONSE = "response";
+
+ protected ConnectorImpl connector;
+ protected ServiceContract contract;
+ protected Operation<Type> operation;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ WireService wireService = new JDKWireService(null, null);
+ connector = new ConnectorImpl(wireService, null, null, null);
+ contract = new JavaServiceContract(Foo.class);
+ operation = new Operation<Type>("bar", null, null, null);
+ }
+
+ protected AtomicComponent createAtomicTarget() throws Exception {
+ InboundInvocationChain chain = new InboundInvocationChainImpl(operation);
+ chain.addInterceptor(new InvokerInterceptor());
+ InboundWire targetWire = new InboundWireImpl();
+ targetWire.setServiceContract(contract);
+ targetWire.addInvocationChain(operation, chain);
+
+ MockInvoker mockInvoker = new MockInvoker();
+
+ // create the target
+ AtomicComponent target = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(target.getName()).andReturn(TARGET).anyTimes();
+ EasyMock.expect(target.isOptimizable()).andReturn(false).anyTimes();
+ EasyMock.expect(target.getScope()).andReturn(Scope.COMPOSITE).atLeastOnce();
+ EasyMock.expect(target.isSystem()).andReturn(false).atLeastOnce();
+ target.getInboundWire(EasyMock.eq(TARGET_SERVICE));
+ EasyMock.expectLastCall().andReturn(targetWire).atLeastOnce();
+ target.createTargetInvoker(EasyMock.eq(TARGET_SERVICE), EasyMock.eq(operation), EasyMock.eq(targetWire));
+ EasyMock.expectLastCall().andReturn(mockInvoker);
+ EasyMock.replay(target);
+ targetWire.setContainer(target);
+ return target;
+ }
+
+ protected AtomicComponent createAtomicSource(CompositeComponent parent) throws Exception {
+ // create the outbound wire and chain from the source component
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+
+ OutboundWire outboundWire = new OutboundWireImpl();
+ outboundWire.setTargetName(TARGET_SERVICE_NAME);
+ outboundWire.setServiceContract(contract);
+ outboundWire.addInvocationChain(operation, outboundChain);
+
+ Map<String, List<OutboundWire>> outboundWires = new HashMap<String, List<OutboundWire>>();
+ List<OutboundWire> list = new ArrayList<OutboundWire>();
+ list.add(outboundWire);
+ outboundWires.put(TARGET_SERVICE, list);
+
+ // create the source
+ AtomicComponent source = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(source.isSystem()).andReturn(false).atLeastOnce();
+ EasyMock.expect(source.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.expect(source.getParent()).andReturn(parent).atLeastOnce();
+ EasyMock.expect(source.getOutboundWires()).andReturn(outboundWires).atLeastOnce();
+ EasyMock.expect(source.getName()).andReturn("source").atLeastOnce();
+ source.getInboundWires();
+ EasyMock.expectLastCall().andReturn(Collections.emptyList());
+ EasyMock.replay(source);
+
+ outboundWire.setContainer(source);
+ return source;
+ }
+
+
+ protected Service createServiceNonLocalBinding() throws WireConnectException {
+ QName qName = new QName("foo", "bar");
+ ServiceBinding serviceBinding = new MockServiceBinding();
+ InboundInvocationChain targetInboundChain = new InboundInvocationChainImpl(operation);
+ targetInboundChain.addInterceptor(new SynchronousBridgingInterceptor());
+ InboundWire serviceInboundWire = new InboundWireImpl(qName);
+ serviceInboundWire.setServiceContract(contract);
+ serviceInboundWire.addInvocationChain(operation, targetInboundChain);
+ serviceInboundWire.setContainer(serviceBinding);
+
+ OutboundInvocationChain targetOutboundChain = new OutboundInvocationChainImpl(operation);
+ // place an invoker interceptor on the end
+ targetOutboundChain.addInterceptor(new InvokerInterceptor());
+ OutboundWire targetOutboundWire = new OutboundWireImpl(qName);
+ targetOutboundWire.setServiceContract(contract);
+ targetOutboundWire.addInvocationChain(operation, targetOutboundChain);
+ targetOutboundWire.setContainer(serviceBinding);
+
+ serviceBinding.setInboundWire(serviceInboundWire);
+ serviceBinding.setOutboundWire(targetOutboundWire);
+ // manually connect the service chains
+ connector.connect(targetInboundChain, targetOutboundChain);
+ Service service = new ServiceImpl(TARGET, null, contract);
+ service.addServiceBinding(serviceBinding);
+ return service;
+ }
+
+ /**
+ * Creates a service configured with the local binding and places an invoker interceptor on the end of each outbound
+ * chain for invocation testing without needing to wire the service to a target
+ *
+ * @throws org.apache.tuscany.core.builder.WireConnectException
+ *
+ */
+ protected Service createLocalService(CompositeComponent parent) throws WireConnectException {
+ LocalServiceBinding serviceBinding = new LocalServiceBinding(TARGET, parent);
+ InboundInvocationChain targetInboundChain = new InboundInvocationChainImpl(operation);
+ targetInboundChain.addInterceptor(new SynchronousBridgingInterceptor());
+ InboundWire localServiceInboundWire = new InboundWireImpl();
+ localServiceInboundWire.setServiceContract(contract);
+ localServiceInboundWire.addInvocationChain(operation, targetInboundChain);
+ localServiceInboundWire.setContainer(serviceBinding);
+
+ OutboundInvocationChain targetOutboundChain = new OutboundInvocationChainImpl(operation);
+ // place an invoker interceptor on the end
+ targetOutboundChain.addInterceptor(new InvokerInterceptor());
+ OutboundWire targetOutboundWire = new OutboundWireImpl();
+ targetOutboundWire.setServiceContract(contract);
+ targetOutboundWire.addInvocationChain(operation, targetOutboundChain);
+ targetOutboundWire.setContainer(serviceBinding);
+
+ serviceBinding.setInboundWire(localServiceInboundWire);
+ serviceBinding.setOutboundWire(targetOutboundWire);
+ // manually connect the service chains
+ connector.connect(targetInboundChain, targetOutboundChain);
+ Service service = new ServiceImpl(TARGET, null, contract);
+ service.addServiceBinding(serviceBinding);
+ return service;
+ }
+
+ protected ReferenceBinding createLocalReferenceBinding(QualifiedName target)
+ throws TargetInvokerCreationException {
+ ReferenceBinding referenceBinding = new LocalReferenceBinding("local", null);
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ InboundWire referenceInboundWire = new InboundWireImpl();
+ referenceInboundWire.setServiceContract(contract);
+ referenceInboundWire.setContainer(referenceBinding);
+ referenceInboundWire.addInvocationChain(operation, inboundChain);
+
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ // Outbound chains always contains at least one interceptor
+ outboundChain.addInterceptor(new SynchronousBridgingInterceptor());
+ OutboundWire outboundWire = new OutboundWireImpl();
+ outboundWire.setServiceContract(contract);
+ outboundWire.setTargetName(target);
+ outboundWire.addInvocationChain(operation, outboundChain);
+ outboundWire.setContainer(referenceBinding);
+
+ referenceBinding.setInboundWire(referenceInboundWire);
+ referenceBinding.setOutboundWire(outboundWire);
+
+ return referenceBinding;
+ }
+
+ protected InboundWire createLocalInboundWire(CompositeComponent parent) throws WireConnectException {
+ InboundInvocationChain chain = new InboundInvocationChainImpl(operation);
+ chain.addInterceptor(new SynchronousBridgingInterceptor());
+ InboundWire wire = new InboundWireImpl();
+ wire.setServiceContract(contract);
+ LocalReferenceBinding referenceBinding = new LocalReferenceBinding("", parent);
+ wire.setContainer(referenceBinding);
+ wire.addInvocationChain(operation, chain);
+
+ OutboundInvocationChain targetOutboundChain = new OutboundInvocationChainImpl(operation);
+ // place an invoker interceptor on the end
+ targetOutboundChain.addInterceptor(new InvokerInterceptor());
+ OutboundWire targetOutboundWire = new OutboundWireImpl();
+ targetOutboundWire.setServiceContract(contract);
+ targetOutboundWire.addInvocationChain(operation, targetOutboundChain);
+ referenceBinding.setInboundWire(wire);
+ referenceBinding.setOutboundWire(targetOutboundWire);
+ // manually connect the service chains
+ connector.connect(chain, targetOutboundChain);
+ return wire;
+ }
+
+ protected static class MockInvoker implements TargetInvoker {
+ public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException {
+ return null;
+ }
+
+ public Message invoke(Message msg) throws InvocationRuntimeException {
+ Message resp = new MessageImpl();
+ resp.setBody(RESPONSE);
+ return resp;
+ }
+
+ public boolean isCacheable() {
+ return false;
+ }
+
+ public void setCacheable(boolean cacheable) {
+
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+ }
+
+ protected static class MockInterceptor implements Interceptor {
+ private Interceptor next;
+ private boolean invoked;
+
+ public Message invoke(Message msg) {
+ invoked = true;
+ return next.invoke(msg);
+ }
+
+ public void setNext(Interceptor next) {
+ this.next = next;
+ }
+
+ public Interceptor getNext() {
+ return next;
+ }
+
+ public boolean isInvoked() {
+ return invoked;
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+ }
+
+ protected interface Foo {
+ String echo();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/AtomicConnectorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/AtomicConnectorTestCase.java
new file mode 100644
index 0000000000..f89ba7ea8d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/AtomicConnectorTestCase.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.Service;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import org.apache.tuscany.core.implementation.composite.ServiceImpl;
+import org.apache.tuscany.core.wire.InboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.InboundWireImpl;
+import org.apache.tuscany.core.wire.OutboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.OutboundWireImpl;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class AtomicConnectorTestCase extends AbstractConnectorImplTestCase {
+
+ public void testConnectSynchronousServiceWiresToAtomicTarget() throws Exception {
+ AtomicComponent target = createAtomicTarget();
+
+ // create the parent composite
+ CompositeComponent parent = EasyMock.createMock(CompositeComponent.class);
+ EasyMock.expect(parent.getChild("target")).andReturn(target);
+ EasyMock.replay(parent);
+
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.addInvocationChain(operation, inboundChain);
+ inboundWire.setServiceContract(contract);
+
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ OutboundWire outboundWire = new OutboundWireImpl();
+ outboundWire.setTargetName(TARGET_SERVICE_NAME);
+ outboundWire.addInvocationChain(operation, outboundChain);
+ outboundWire.setServiceContract(contract);
+
+ // create the binding
+ ServiceBinding binding = EasyMock.createMock(ServiceBinding.class);
+ EasyMock.expect(binding.getName()).andReturn("source");
+ binding.setService(EasyMock.isA(Service.class));
+ EasyMock.expect(binding.isSystem()).andReturn(false).atLeastOnce();
+ EasyMock.expect(binding.getInboundWire()).andReturn(inboundWire).atLeastOnce();
+ EasyMock.expect(binding.getOutboundWire()).andReturn(outboundWire);
+ EasyMock.expect(binding.getScope()).andReturn(Scope.SYSTEM);
+ EasyMock.replay(binding);
+
+ outboundWire.setContainer(binding);
+ inboundWire.setContainer(binding);
+
+ Service service = new ServiceImpl("foo", parent, null);
+ service.addServiceBinding(binding);
+
+ connector.connect(service);
+ MessageImpl msg = new MessageImpl();
+ msg.setTargetInvoker(inboundChain.getTargetInvoker());
+ Message resp = inboundChain.getHeadInterceptor().invoke(msg);
+ assertEquals(RESPONSE, resp.getBody());
+ EasyMock.verify(binding);
+ }
+
+ public void testConnectNonBlockingServiceWiresToAtomicTarget() throws Exception {
+ // JFM FIXME
+ }
+
+ public void testConnectCallbackServiceWiresToAtomicTarget() throws Exception {
+ // JFM FIXME
+ }
+
+ /**
+ * Verifies connecting a wire from an atomic component to a target atomic component with one synchronous operation
+ */
+ public void testConnectAtomicComponentToAtomicComponentSyncWire() throws Exception {
+
+ AtomicComponent target = createAtomicTarget();
+ // create the parent composite
+ CompositeComponent parent = EasyMock.createMock(CompositeComponent.class);
+ EasyMock.expect(parent.getChild("target")).andReturn(target);
+ EasyMock.replay(parent);
+ AtomicComponent source = createAtomicSource(parent);
+ connector.connect(source);
+
+ MessageImpl msg = new MessageImpl();
+ Map<String, List<OutboundWire>> wires = source.getOutboundWires();
+ OutboundWire wire = wires.get(TARGET_SERVICE).get(0);
+ OutboundInvocationChain chain = wire.getInvocationChains().get(operation);
+ msg.setTargetInvoker(chain.getTargetInvoker());
+ Message resp = chain.getHeadInterceptor().invoke(msg);
+ assertEquals(RESPONSE, resp.getBody());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/BuilderRegistryNoBindingsTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/BuilderRegistryNoBindingsTestCase.java
new file mode 100644
index 0000000000..16f2846921
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/BuilderRegistryNoBindingsTestCase.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import java.net.URI;
+
+import org.apache.tuscany.spi.builder.BuilderRegistry;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.Reference;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.Service;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.Multiplicity;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.binding.local.LocalBindingBuilder;
+import org.apache.tuscany.core.binding.local.LocalBindingDefinition;
+import org.apache.tuscany.core.binding.local.LocalReferenceBinding;
+import org.apache.tuscany.core.binding.local.LocalServiceBinding;
+import org.apache.tuscany.core.deployer.RootDeploymentContext;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class BuilderRegistryNoBindingsTestCase extends TestCase {
+ private DeploymentContext deploymentContext;
+ private CompositeComponent parent;
+ private BuilderRegistry registry;
+
+ public void testNoServiceBindings() throws Exception {
+ ServiceBinding binding = EasyMock.createNiceMock(ServiceBinding.class);
+ EasyMock.replay(binding);
+ ServiceDefinition definition = new ServiceDefinition("foo", null, false);
+ definition.setTarget(new URI("foo"));
+ Service service = registry.build(parent, definition, deploymentContext);
+ assertEquals(1, service.getServiceBindings().size());
+ assertTrue(service.getServiceBindings().get(0) instanceof LocalServiceBinding);
+ }
+
+ public void testReferenceBindingBuilderDispatch() throws Exception {
+ ReferenceBinding binding = EasyMock.createNiceMock(ReferenceBinding.class);
+ EasyMock.replay(binding);
+ AbstractReferenceDefinition definition = new ComponentTypeReferenceDefinition("foo", null, Multiplicity.ONE_ONE);
+ Reference reference = registry.build(parent, definition, deploymentContext);
+ assertEquals(1, reference.getReferenceBindings().size());
+ assertTrue(reference.getReferenceBindings().get(0) instanceof LocalReferenceBinding);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ deploymentContext = new RootDeploymentContext(null, null, null, null);
+ parent = EasyMock.createNiceMock(CompositeComponent.class);
+ EasyMock.replay(parent);
+ registry = new BuilderRegistryImpl(null, null);
+ registry.register(LocalBindingDefinition.class, new LocalBindingBuilder());
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/BuilderRegistryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/BuilderRegistryTestCase.java
new file mode 100644
index 0000000000..572babf817
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/BuilderRegistryTestCase.java
@@ -0,0 +1,219 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import java.net.URI;
+
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.builder.BindingBuilder;
+import org.apache.tuscany.spi.builder.BuilderConfigException;
+import org.apache.tuscany.spi.builder.BuilderRegistry;
+import org.apache.tuscany.spi.builder.ComponentBuilder;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.Reference;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.component.Service;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.model.BindingDefinition;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.ComponentType;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.CompositeImplementation;
+import org.apache.tuscany.spi.model.Implementation;
+import static org.apache.tuscany.spi.model.Multiplicity.ONE_ONE;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.apache.tuscany.spi.wire.WireService;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.deployer.RootDeploymentContext;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class BuilderRegistryTestCase extends TestCase {
+ private DeploymentContext deploymentContext;
+ //private BuilderRegistryImpl registry;
+ private CompositeComponent parent;
+
+ public void testRegistration() throws Exception {
+ MockBuilder builder = new MockBuilder();
+ BuilderRegistry registry = new BuilderRegistryImpl(null, null);
+ registry.register(CompositeImplementation.class, builder);
+ CompositeImplementation implementation = new CompositeImplementation();
+ ComponentDefinition<CompositeImplementation> componentDefinition =
+ new ComponentDefinition<CompositeImplementation>(implementation);
+ componentDefinition.getImplementation().setComponentType(new CompositeComponentType());
+ registry.build(parent, componentDefinition, deploymentContext);
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public void testServiceBindingBuilderDispatch() throws Exception {
+ WireService wireService = EasyMock.createMock(WireService.class);
+ wireService.createWires(EasyMock.isA(ServiceBinding.class),
+ (ServiceContract) EasyMock.isNull(), EasyMock.isA(String.class)
+ );
+ EasyMock.expectLastCall().times(2);
+ EasyMock.replay(wireService);
+ BuilderRegistry registry = new BuilderRegistryImpl(null, wireService);
+ ServiceBinding binding = EasyMock.createNiceMock(ServiceBinding.class);
+ EasyMock.replay(binding);
+ BindingBuilder<MockBindingDefinition> builder = EasyMock.createMock(BindingBuilder.class);
+ EasyMock.expect(builder.build(EasyMock.isA(CompositeComponent.class),
+ EasyMock.isA(ServiceDefinition.class),
+ EasyMock.isA(MockBindingDefinition.class),
+ EasyMock.isA(DeploymentContext.class))).andReturn(binding).times(2);
+ EasyMock.replay(builder);
+ registry.register(MockBindingDefinition.class, builder);
+ ServiceDefinition definition = new ServiceDefinition("foo", null, false);
+ definition.addBinding(new MockBindingDefinition());
+ definition.addBinding(new MockBindingDefinition());
+ definition.setTarget(new URI("foo"));
+ Service service = registry.build(parent, definition, deploymentContext);
+ assertEquals(2, service.getServiceBindings().size());
+ EasyMock.verify(wireService);
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public void testReferenceBindingBuilderDispatch() throws Exception {
+ WireService wireService = EasyMock.createMock(WireService.class);
+ wireService.createWires(EasyMock.isA(ReferenceBinding.class),
+ (ServiceContract) EasyMock.isNull(), (QualifiedName) EasyMock.isNull()
+ );
+ EasyMock.expectLastCall().times(2);
+ EasyMock.replay(wireService);
+ BuilderRegistry registry = new BuilderRegistryImpl(null, wireService);
+ ReferenceBinding binding = EasyMock.createNiceMock(ReferenceBinding.class);
+ EasyMock.replay(binding);
+ BindingBuilder<MockBindingDefinition> builder = EasyMock.createMock(BindingBuilder.class);
+ EasyMock.expect(builder.build(EasyMock.isA(CompositeComponent.class),
+ EasyMock.isA(AbstractReferenceDefinition.class),
+ EasyMock.isA(MockBindingDefinition.class),
+ EasyMock.isA(DeploymentContext.class))).andReturn(binding).times(2);
+ EasyMock.replay(builder);
+ registry.register(MockBindingDefinition.class, builder);
+ AbstractReferenceDefinition definition = new ComponentTypeReferenceDefinition("foo", null, ONE_ONE);
+ definition.addBinding(new MockBindingDefinition());
+ definition.addBinding(new MockBindingDefinition());
+ Reference reference = registry.build(parent, definition, deploymentContext);
+ assertEquals(2, reference.getReferenceBindings().size());
+ EasyMock.verify(wireService);
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public void testComponentImplementationDispatch() throws Exception {
+ ScopeRegistry scopeRegistry = EasyMock.createMock(ScopeRegistry.class);
+ ScopeContainer scopeContainer = EasyMock.createNiceMock(ScopeContainer.class);
+ EasyMock.expect(scopeRegistry.getScopeContainer(EasyMock.isA(Scope.class))).andReturn(scopeContainer);
+ EasyMock.replay(scopeRegistry);
+ WireService wireService = EasyMock.createMock(WireService.class);
+ wireService.createWires(EasyMock.isA(AtomicComponent.class),
+ EasyMock.isA(ComponentDefinition.class));
+ EasyMock.replay(wireService);
+ BuilderRegistry registry = new BuilderRegistryImpl(scopeRegistry, wireService);
+
+ AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class);
+ EasyMock.replay(component);
+ ComponentBuilder<FooImplementation> builder = EasyMock.createMock(ComponentBuilder.class);
+ EasyMock.expect(builder.build(EasyMock.isA(CompositeComponent.class),
+ EasyMock.isA(ComponentDefinition.class),
+ EasyMock.isA(DeploymentContext.class))).andReturn(component);
+ EasyMock.replay(builder);
+ registry.register(FooImplementation.class, builder);
+
+ FooImplementation impl = new FooImplementation();
+ impl.setComponentType(new ComponentType());
+ ComponentDefinition<FooImplementation> definition = new ComponentDefinition<FooImplementation>("foo", impl);
+ Component ret = registry.build(parent, definition, deploymentContext);
+ assertNotNull(ret);
+ EasyMock.verify(wireService);
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public void testNoConversationalContract() throws Exception {
+ ScopeRegistry scopeRegistry = EasyMock.createMock(ScopeRegistry.class);
+ ScopeContainer scopeContainer = EasyMock.createNiceMock(ScopeContainer.class);
+ EasyMock.expect(scopeRegistry.getScopeContainer(EasyMock.isA(Scope.class))).andReturn(scopeContainer);
+ EasyMock.replay(scopeRegistry);
+ WireService wireService = EasyMock.createMock(WireService.class);
+ wireService.createWires(EasyMock.isA(AtomicComponent.class),
+ EasyMock.isA(ComponentDefinition.class));
+ EasyMock.replay(wireService);
+ BuilderRegistry registry = new BuilderRegistryImpl(scopeRegistry, wireService);
+
+ AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class);
+ EasyMock.replay(component);
+ ComponentBuilder<FooImplementation> builder = EasyMock.createMock(ComponentBuilder.class);
+ EasyMock.expect(builder.build(EasyMock.isA(CompositeComponent.class),
+ EasyMock.isA(ComponentDefinition.class),
+ EasyMock.isA(DeploymentContext.class))).andReturn(component);
+ EasyMock.replay(builder);
+ registry.register(FooImplementation.class, builder);
+
+ FooImplementation impl = new FooImplementation();
+ ComponentType componentType = new ComponentType();
+ componentType.setImplementationScope(Scope.CONVERSATION);
+ impl.setComponentType(componentType);
+ ComponentDefinition<FooImplementation> definition = new ComponentDefinition<FooImplementation>("foo", impl);
+ try {
+ registry.build(parent, definition, deploymentContext);
+ fail("Should throw NoConversationalContractException");
+ } catch (NoConversationalContractException e) {
+ // expected
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ deploymentContext = new RootDeploymentContext(null, null, null, null);
+ parent = EasyMock.createNiceMock(CompositeComponent.class);
+ EasyMock.replay(parent);
+ }
+
+ private class MockBuilder implements ComponentBuilder<CompositeImplementation> {
+ public Component build(CompositeComponent parent,
+ ComponentDefinition componentDefinition,
+ DeploymentContext deploymentContext) throws BuilderConfigException {
+ return null;
+ }
+ }
+
+ private class MockBindingDefinition extends BindingDefinition {
+ public Object clone() {
+ MockBindingDefinition mockClone = new MockBindingDefinition();
+ mockClone.setTargetUri(URI.create(this.getTargetUri().toString()));
+ return mockClone;
+ }
+ }
+
+ private class FooImplementation extends Implementation<ComponentType> {
+
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/ConnectorImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/ConnectorImplTestCase.java
new file mode 100644
index 0000000000..fc5daa6b12
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/ConnectorImplTestCase.java
@@ -0,0 +1,322 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import java.lang.reflect.Type;
+import java.util.Collections;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import org.apache.tuscany.core.wire.InboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.InboundWireImpl;
+import org.apache.tuscany.core.wire.InvokerInterceptor;
+import org.apache.tuscany.core.wire.OutboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.OutboundWireImpl;
+import org.apache.tuscany.core.wire.SynchronousBridgingInterceptor;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ConnectorImplTestCase extends AbstractConnectorImplTestCase {
+
+ public void testConnectTargetNotFound() throws Exception {
+ CompositeComponent parent = EasyMock.createMock(CompositeComponent.class);
+ EasyMock.expect(parent.getName()).andReturn("parent");
+ parent.getChild(EasyMock.isA(String.class));
+ EasyMock.expectLastCall().andReturn(null);
+ EasyMock.replay(parent);
+ try {
+ AtomicComponent source = createAtomicSource(parent);
+ connector.connect(source);
+ fail();
+ } catch (TargetServiceNotFoundException e) {
+ // expected
+ }
+ }
+
+ public void testOutboundToInboundOptimization() throws Exception {
+ AtomicComponent container = EasyMock.createNiceMock(AtomicComponent.class);
+ EasyMock.expect(container.isSystem()).andReturn(true);
+ EasyMock.replay(container);
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.setContainer(container);
+ OutboundWire outboundWire = EasyMock.createMock(OutboundWire.class);
+ outboundWire.setTargetWire(EasyMock.eq(inboundWire));
+ EasyMock.expect(outboundWire.getContainer()).andReturn(container).atLeastOnce();
+ EasyMock.replay(outboundWire);
+
+ connector.connect(outboundWire, inboundWire, true);
+ EasyMock.verify(outboundWire);
+ }
+
+ /**
+ * Verifies that stateless targets with a destructor are not optimized as the destructor callback event must be
+ * issued by the TargetInvoker after it dispatches to the target
+ */
+ public void testOutboundToInboundNoOptimizationBecauseStatelessDestructor() throws Exception {
+ AtomicComponent container = EasyMock.createNiceMock(AtomicComponent.class);
+ EasyMock.expect(container.isSystem()).andReturn(false);
+ EasyMock.expect(container.getScope()).andReturn(Scope.STATELESS);
+ EasyMock.expect(container.isDestroyable()).andReturn(true);
+ EasyMock.replay(container);
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.setContainer(container);
+ OutboundWire outboundWire = EasyMock.createMock(OutboundWire.class);
+ outboundWire.getInvocationChains();
+ EasyMock.expectLastCall().andReturn(Collections.emptyMap()).atLeastOnce();
+ outboundWire.getTargetCallbackInvocationChains();
+ EasyMock.expectLastCall().andReturn(Collections.emptyMap()).atLeastOnce();
+ EasyMock.expect(outboundWire.getContainer()).andReturn(container).atLeastOnce();
+ EasyMock.replay(outboundWire);
+
+ connector.connect(outboundWire, inboundWire, true);
+ EasyMock.verify(outboundWire);
+ }
+
+ public void testOutboundToInboundNoOptimizationAtomic() throws Exception {
+ AtomicComponent container = EasyMock.createNiceMock(AtomicComponent.class);
+ EasyMock.expect(container.isSystem()).andReturn(false);
+ EasyMock.expect(container.getScope()).andReturn(Scope.STATELESS);
+ EasyMock.expect(container.isOptimizable()).andReturn(false);
+ EasyMock.replay(container);
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.setContainer(container);
+ OutboundWire outboundWire = EasyMock.createMock(OutboundWire.class);
+ EasyMock.expect(outboundWire.getContainer()).andReturn(container).atLeastOnce();
+ outboundWire.getInvocationChains();
+ EasyMock.expectLastCall().andReturn(Collections.emptyMap()).atLeastOnce();
+ outboundWire.getTargetCallbackInvocationChains();
+ EasyMock.expectLastCall().andReturn(Collections.emptyMap()).atLeastOnce();
+ EasyMock.replay(outboundWire);
+
+ connector.connect(outboundWire, inboundWire, true);
+ EasyMock.verify(outboundWire);
+ }
+
+ public void testOutboundToInboundNoOptimizationNonAtomicTarget() throws Exception {
+ ReferenceBinding container = EasyMock.createNiceMock(ReferenceBinding.class);
+ EasyMock.expect(container.isSystem()).andReturn(false);
+ EasyMock.replay(container);
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.setContainer(container);
+ OutboundWire outboundWire = EasyMock.createMock(OutboundWire.class);
+ outboundWire.getInvocationChains();
+ EasyMock.expectLastCall().andReturn(Collections.emptyMap()).atLeastOnce();
+ outboundWire.getTargetCallbackInvocationChains();
+ EasyMock.expectLastCall().andReturn(Collections.emptyMap()).atLeastOnce();
+ EasyMock.expect(outboundWire.getContainer()).andReturn(container).atLeastOnce();
+ EasyMock.replay(outboundWire);
+
+ connector.connect(outboundWire, inboundWire, true);
+ EasyMock.verify(outboundWire);
+ }
+
+ public void testOutboundToInboundChainConnect() throws Exception {
+ TargetInvoker invoker = new MockInvoker();
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ inboundChain.addInterceptor(new InvokerInterceptor());
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ connector.connect(outboundChain, inboundChain, invoker, false);
+ Interceptor interceptor = outboundChain.getHeadInterceptor();
+ assertTrue(interceptor instanceof SynchronousBridgingInterceptor);
+ MessageImpl msg = new MessageImpl();
+ msg.setTargetInvoker(new MockInvoker());
+ Message resp = interceptor.invoke(msg);
+ assertEquals(RESPONSE, resp.getBody());
+ }
+
+ public void testOutboundToInboundChainConnectNoInboundInterceptor() {
+ TargetInvoker invoker = new MockInvoker();
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ try {
+ connector.connect(outboundChain, inboundChain, invoker, false);
+ fail();
+ } catch (WireConnectException e) {
+ // expected
+ }
+ }
+
+ public void testInboundToOutboundChainConnect() throws Exception {
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ outboundChain.addInterceptor(new InvokerInterceptor());
+ connector.connect(inboundChain, outboundChain);
+ Interceptor interceptor = inboundChain.getHeadInterceptor();
+ assertTrue(interceptor instanceof SynchronousBridgingInterceptor);
+ MessageImpl msg = new MessageImpl();
+ msg.setTargetInvoker(new MockInvoker());
+ Message resp = interceptor.invoke(msg);
+ assertEquals(RESPONSE, resp.getBody());
+ }
+
+ public void testInboundToOutboundChainConnectNoOutboundInterceptors() throws Exception {
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ try {
+ connector.connect(inboundChain, outboundChain);
+ fail();
+ } catch (WireConnectException e) {
+ // expected
+ }
+ }
+
+ public void testInboundOutboundSystemWireOptimization() throws Exception {
+ SCAObject container = EasyMock.createMock(SCAObject.class);
+ EasyMock.expect(container.isSystem()).andReturn(true);
+ EasyMock.replay(container);
+ InboundWire inboundWire = EasyMock.createMock(InboundWire.class);
+ inboundWire.setTargetWire(EasyMock.isA(OutboundWire.class));
+ EasyMock.expect(inboundWire.getContainer()).andReturn(container).atLeastOnce();
+ EasyMock.replay(inboundWire);
+ OutboundWire outboundWire = new OutboundWireImpl();
+ outboundWire.setContainer(container);
+ connector.connect(inboundWire, outboundWire, true);
+ EasyMock.verify(inboundWire);
+ EasyMock.verify(container);
+ }
+
+ public void testOutboundInboundSystemWireOptimization() throws Exception {
+ SCAObject container = EasyMock.createMock(SCAObject.class);
+ EasyMock.expect(container.isSystem()).andReturn(true);
+ EasyMock.replay(container);
+ OutboundWire outboundWire = EasyMock.createMock(OutboundWire.class);
+ outboundWire.setTargetWire(EasyMock.isA(InboundWire.class));
+ EasyMock.expect(outboundWire.getContainer()).andReturn(container).atLeastOnce();
+ EasyMock.replay(outboundWire);
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.setContainer(container);
+ connector.connect(outboundWire, inboundWire, true);
+ EasyMock.verify(outboundWire);
+ EasyMock.verify(container);
+ }
+
+ public void testIncompatibleInboundOutboundWiresConnect() throws Exception {
+ Operation<Type> operation = new Operation<Type>("bar", null, null, null);
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.addInvocationChain(operation, new InboundInvocationChainImpl(operation));
+ OutboundWire outboundWire = new OutboundWireImpl();
+ try {
+ connector.connect(inboundWire, outboundWire, false);
+ fail();
+ } catch (IncompatibleInterfacesException e) {
+ // expected
+ }
+
+ }
+
+ public void testIncompatibleOutboundInboundWiresConnect() throws Exception {
+ SCAObject container = EasyMock.createNiceMock(SCAObject.class);
+ EasyMock.expect(container.isSystem()).andReturn(false);
+ EasyMock.replay(container);
+ Operation<Type> operation = new Operation<Type>("bar", null, null, null);
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.setContainer(container);
+ OutboundWire outboundWire = new OutboundWireImpl();
+ outboundWire.setContainer(container);
+ outboundWire.addInvocationChain(operation, new OutboundInvocationChainImpl(operation));
+ try {
+ connector.connect(outboundWire, inboundWire, false);
+ fail();
+ } catch (IncompatibleInterfacesException e) {
+ // expected
+ }
+
+ }
+
+ public void testIsOptimizable() {
+ assertTrue(connector.isOptimizable(Scope.STATELESS, Scope.STATELESS));
+ assertTrue(connector.isOptimizable(Scope.STATELESS, Scope.COMPOSITE));
+ assertFalse(connector.isOptimizable(Scope.STATELESS, Scope.CONVERSATION));
+ assertTrue(connector.isOptimizable(Scope.STATELESS, Scope.REQUEST));
+ assertTrue(connector.isOptimizable(Scope.STATELESS, Scope.SESSION));
+ assertTrue(connector.isOptimizable(Scope.STATELESS, Scope.SYSTEM));
+
+ assertTrue(connector.isOptimizable(Scope.COMPOSITE, Scope.COMPOSITE));
+ assertFalse(connector.isOptimizable(Scope.COMPOSITE, Scope.CONVERSATION));
+ assertFalse(connector.isOptimizable(Scope.COMPOSITE, Scope.REQUEST));
+ assertFalse(connector.isOptimizable(Scope.COMPOSITE, Scope.SESSION));
+ assertFalse(connector.isOptimizable(Scope.COMPOSITE, Scope.STATELESS));
+ assertTrue(connector.isOptimizable(Scope.COMPOSITE, Scope.SYSTEM));
+
+ assertFalse(connector.isOptimizable(Scope.CONVERSATION, Scope.COMPOSITE));
+ assertFalse(connector.isOptimizable(Scope.CONVERSATION, Scope.CONVERSATION));
+ assertFalse(connector.isOptimizable(Scope.CONVERSATION, Scope.REQUEST));
+ assertFalse(connector.isOptimizable(Scope.CONVERSATION, Scope.SESSION));
+ assertFalse(connector.isOptimizable(Scope.CONVERSATION, Scope.STATELESS));
+ assertFalse(connector.isOptimizable(Scope.CONVERSATION, Scope.SYSTEM));
+
+ assertTrue(connector.isOptimizable(Scope.REQUEST, Scope.COMPOSITE));
+ assertFalse(connector.isOptimizable(Scope.REQUEST, Scope.CONVERSATION));
+ assertTrue(connector.isOptimizable(Scope.REQUEST, Scope.REQUEST));
+ assertTrue(connector.isOptimizable(Scope.REQUEST, Scope.SESSION));
+ assertFalse(connector.isOptimizable(Scope.REQUEST, Scope.STATELESS));
+ assertTrue(connector.isOptimizable(Scope.REQUEST, Scope.SYSTEM));
+
+ assertTrue(connector.isOptimizable(Scope.SESSION, Scope.COMPOSITE));
+ assertFalse(connector.isOptimizable(Scope.SESSION, Scope.CONVERSATION));
+ assertFalse(connector.isOptimizable(Scope.SESSION, Scope.REQUEST));
+ assertTrue(connector.isOptimizable(Scope.SESSION, Scope.SESSION));
+ assertFalse(connector.isOptimizable(Scope.SESSION, Scope.STATELESS));
+ assertTrue(connector.isOptimizable(Scope.SESSION, Scope.SYSTEM));
+
+ assertTrue(connector.isOptimizable(Scope.SYSTEM, Scope.COMPOSITE));
+ assertFalse(connector.isOptimizable(Scope.SYSTEM, Scope.CONVERSATION));
+ assertFalse(connector.isOptimizable(Scope.SYSTEM, Scope.REQUEST));
+ assertFalse(connector.isOptimizable(Scope.SYSTEM, Scope.SESSION));
+ assertFalse(connector.isOptimizable(Scope.SYSTEM, Scope.STATELESS));
+ assertTrue(connector.isOptimizable(Scope.SYSTEM, Scope.SYSTEM));
+
+ assertFalse(connector.isOptimizable(Scope.UNDEFINED, Scope.COMPOSITE));
+ assertFalse(connector.isOptimizable(Scope.UNDEFINED, Scope.CONVERSATION));
+ assertFalse(connector.isOptimizable(Scope.UNDEFINED, Scope.REQUEST));
+ assertFalse(connector.isOptimizable(Scope.UNDEFINED, Scope.SESSION));
+ assertFalse(connector.isOptimizable(Scope.UNDEFINED, Scope.STATELESS));
+ assertFalse(connector.isOptimizable(Scope.UNDEFINED, Scope.SYSTEM));
+
+ }
+
+ public void testInvalidConnectObject() throws Exception {
+ try {
+ connector.connect(EasyMock.createNiceMock(SCAObject.class));
+ fail();
+ } catch (AssertionError e) {
+ // expected
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/ConnectorPostProcessTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/ConnectorPostProcessTestCase.java
new file mode 100644
index 0000000000..857b17eff5
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/ConnectorPostProcessTestCase.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.WirePostProcessorRegistry;
+import org.apache.tuscany.spi.wire.WireService;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ConnectorPostProcessTestCase extends TestCase {
+
+ public void testInboundToOutboundPostProcessCalled() throws Exception {
+ OutboundWire owire = createNiceMock(OutboundWire.class);
+ replay(owire);
+ InboundWire iwire = createNiceMock(InboundWire.class);
+ Map<Operation<?>, InboundInvocationChain> chains = new HashMap<Operation<?>, InboundInvocationChain>();
+ expect(iwire.getInvocationChains()).andReturn(chains);
+ replay(iwire);
+ WirePostProcessorRegistry registry = createMock(WirePostProcessorRegistry.class);
+ registry.process(EasyMock.eq(iwire), EasyMock.eq(owire));
+ replay(registry);
+ WireService wireService = createMock(WireService.class);
+ wireService.checkCompatibility((ServiceContract<?>) EasyMock.anyObject(),
+ (ServiceContract<?>) EasyMock.anyObject(), EasyMock.eq(false));
+ expectLastCall().anyTimes();
+ replay(wireService);
+ ConnectorImpl connector = new ConnectorImpl(wireService, registry, null, null);
+ connector.connect(iwire, owire, false);
+ verify(registry);
+ }
+
+ public void testOutboundToInboundPostProcessCalled() throws Exception {
+ AtomicComponent source = createNiceMock(AtomicComponent.class);
+ expect(source.getName()).andReturn("Component");
+ replay(source);
+
+ AtomicComponent target = createNiceMock(AtomicComponent.class);
+ expect(target.getName()).andReturn("Component");
+ replay(target);
+
+ OutboundWire owire = createNiceMock(OutboundWire.class);
+ EasyMock.expect(owire.getContainer()).andReturn(source);
+
+ Map<Operation<?>, OutboundInvocationChain> chains = new HashMap<Operation<?>, OutboundInvocationChain>();
+ expect(owire.getInvocationChains()).andReturn(chains);
+ Map<Operation<?>, InboundInvocationChain> ichains = new HashMap<Operation<?>, InboundInvocationChain>();
+ expect(owire.getTargetCallbackInvocationChains()).andReturn(ichains);
+ replay(owire);
+ InboundWire iwire = createNiceMock(InboundWire.class);
+ expect(iwire.getSourceCallbackInvocationChains("Component")).andReturn(chains);
+ EasyMock.expect(iwire.getContainer()).andReturn(target);
+ replay(iwire);
+ WirePostProcessorRegistry registry = createMock(WirePostProcessorRegistry.class);
+ registry.process(EasyMock.eq(owire), EasyMock.eq(iwire));
+ replay(registry);
+ WireService wireService = createMock(WireService.class);
+ wireService.checkCompatibility((ServiceContract<?>) EasyMock.anyObject(),
+ (ServiceContract<?>) EasyMock.anyObject(), EasyMock.eq(false));
+ expectLastCall().anyTimes();
+ replay(wireService);
+ ConnectorImpl connector = new ConnectorImpl(wireService, registry, null, null);
+
+ connector.connect(owire, iwire, false);
+ verify(registry);
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/IllegalCallbackExceptionTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/IllegalCallbackExceptionTestCase.java
new file mode 100644
index 0000000000..40ddc837c7
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/IllegalCallbackExceptionTestCase.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class IllegalCallbackExceptionTestCase extends TestCase {
+
+ public void testInstantiation() throws Exception {
+ IllegalCallbackException e = new IllegalCallbackException("message",
+ "identifier",
+ "source name",
+ "ref name",
+ "target name",
+ "service name");
+ assertEquals("message", e.getMessage());
+ assertEquals("identifier", e.getIdentifier());
+ assertEquals("source name", e.getSourceName());
+ assertEquals("ref name", e.getReferenceName());
+ assertEquals("target name", e.getTargetName());
+ assertEquals("service name", e.getTargetServiceName());
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/InboundtoOutboundConnectTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/InboundtoOutboundConnectTestCase.java
new file mode 100644
index 0000000000..4676dbb7cc
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/InboundtoOutboundConnectTestCase.java
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.mock.component.SimpleTarget;
+import org.apache.tuscany.core.mock.wire.MockSyncInterceptor;
+import org.apache.tuscany.core.wire.InboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.InvokerInterceptor;
+import org.apache.tuscany.core.wire.OutboundInvocationChainImpl;
+import org.easymock.EasyMock;
+
+/**
+ * Verifies connection strategies between {@link org.apache.tuscany.spi.wire.OutboundInvocationChain}s and {@link
+ * org.apache.tuscany.spi.wire.InboundInvocationChain}s
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class InboundtoOutboundConnectTestCase extends TestCase {
+ private Operation operation;
+ private ConnectorImpl connector;
+
+ public void testNoInterceptors() throws Exception {
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ outboundChain.addInterceptor(new InvokerInterceptor());
+ TargetInvoker invoker = EasyMock.createNiceMock(TargetInvoker.class);
+ EasyMock.expect(invoker.invoke(EasyMock.isA(Message.class))).andReturn(new MessageImpl());
+ EasyMock.replay(invoker);
+ connector.connect(inboundChain, outboundChain);
+ inboundChain.setTargetInvoker(invoker);
+ inboundChain.prepare();
+ Message msg = new MessageImpl();
+ msg.setTargetInvoker(invoker);
+ inboundChain.getHeadInterceptor().invoke(msg);
+ EasyMock.verify(invoker);
+ }
+
+
+ /**
+ * Verifies an invocation with a single source interceptor
+ */
+ public void testSourceInterceptor() throws Exception {
+ MockSyncInterceptor interceptor = new MockSyncInterceptor();
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ inboundChain.addInterceptor(interceptor);
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ outboundChain.addInterceptor(new InvokerInterceptor());
+ Message msg = new MessageImpl();
+ TargetInvoker invoker = EasyMock.createNiceMock(TargetInvoker.class);
+ EasyMock.expect(invoker.invoke(EasyMock.eq(msg))).andReturn(msg);
+ EasyMock.replay(invoker);
+ assertEquals(0, interceptor.getCount());
+ connector.connect(inboundChain, outboundChain);
+ inboundChain.setTargetInvoker(invoker);
+ inboundChain.prepare();
+ msg.setTargetInvoker(inboundChain.getTargetInvoker());
+ assertEquals(msg, inboundChain.getHeadInterceptor().invoke(msg));
+ assertEquals(1, interceptor.getCount());
+ EasyMock.verify(invoker);
+ }
+
+ /**
+ * Verifies an invocation with a single target interceptor
+ */
+ public void testTargetInterceptor() throws Exception {
+ MockSyncInterceptor interceptor = new MockSyncInterceptor();
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ inboundChain.addInterceptor(interceptor);
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ outboundChain.addInterceptor(new InvokerInterceptor());
+ Message msg = new MessageImpl();
+ TargetInvoker invoker = EasyMock.createNiceMock(TargetInvoker.class);
+ EasyMock.expect(invoker.invoke(EasyMock.eq(msg))).andReturn(msg);
+ EasyMock.replay(invoker);
+ assertEquals(0, interceptor.getCount());
+ connector.connect(inboundChain, outboundChain);
+ inboundChain.setTargetInvoker(invoker);
+ inboundChain.prepare();
+ msg.setTargetInvoker(inboundChain.getTargetInvoker());
+ assertEquals(msg, inboundChain.getHeadInterceptor().invoke(msg));
+ assertEquals(1, interceptor.getCount());
+ EasyMock.verify(invoker);
+ }
+
+ /**
+ * Verifies an invocation with a source and target interceptor
+ */
+ public void testSourceTargetInterceptor() throws Exception {
+ MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor();
+ MockSyncInterceptor targetInterceptor = new MockSyncInterceptor();
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ outboundChain.addInterceptor(sourceInterceptor);
+ outboundChain.addInterceptor(new InvokerInterceptor());
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ inboundChain.addInterceptor(targetInterceptor);
+ Message msg = new MessageImpl();
+ TargetInvoker invoker = EasyMock.createNiceMock(TargetInvoker.class);
+ EasyMock.expect(invoker.invoke(EasyMock.eq(msg))).andReturn(msg);
+ EasyMock.replay(invoker);
+ assertEquals(0, sourceInterceptor.getCount());
+ assertEquals(0, targetInterceptor.getCount());
+ connector.connect(inboundChain, outboundChain);
+ inboundChain.setTargetInvoker(invoker);
+ inboundChain.prepare();
+ msg.setTargetInvoker(inboundChain.getTargetInvoker());
+ assertEquals(msg, inboundChain.getHeadInterceptor().invoke(msg));
+ assertEquals(1, sourceInterceptor.getCount());
+ assertEquals(1, targetInterceptor.getCount());
+ EasyMock.verify(invoker);
+ }
+
+ public void testOptimizeSet() throws Exception {
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ outboundChain.addInterceptor(new InvokerInterceptor());
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ Message msg = new MessageImpl();
+ TargetInvoker invoker = EasyMock.createNiceMock(TargetInvoker.class);
+ EasyMock.expect(invoker.invoke(EasyMock.eq(msg))).andReturn(msg);
+ EasyMock.replay(invoker);
+ connector.connect(inboundChain, outboundChain);
+ inboundChain.setTargetInvoker(invoker);
+ inboundChain.prepare();
+ msg.setTargetInvoker(inboundChain.getTargetInvoker());
+ assertEquals(msg, inboundChain.getHeadInterceptor().invoke(msg));
+ EasyMock.verify(invoker);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ connector = new ConnectorImpl();
+ JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ ServiceContract<?> contract;
+ try {
+ contract = registry.introspect(SimpleTarget.class);
+ } catch (InvalidServiceContractException e) {
+ throw new AssertionError();
+ }
+ operation = contract.getOperations().get("echo");
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/IncompatibleInterfacesExceptionTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/IncompatibleInterfacesExceptionTestCase.java
new file mode 100644
index 0000000000..7fa6633258
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/IncompatibleInterfacesExceptionTestCase.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class IncompatibleInterfacesExceptionTestCase extends TestCase {
+
+ public void testInstantiation() throws Exception {
+ IncompatibleInterfacesException e = new IncompatibleInterfacesException("message",
+ "source name",
+ "ref name",
+ "target name",
+ "service name");
+ assertEquals("message", e.getMessage());
+ assertEquals("source name", e.getSourceName());
+ assertEquals("ref name", e.getReferenceName());
+ assertEquals("target name", e.getTargetName());
+ assertEquals("service name", e.getTargetServiceName());
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/InvalidTargetTypeExceptionTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/InvalidTargetTypeExceptionTestCase.java
new file mode 100644
index 0000000000..c34be84745
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/InvalidTargetTypeExceptionTestCase.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class InvalidTargetTypeExceptionTestCase extends TestCase {
+
+ public void testInstantiation() throws Exception {
+ InvalidTargetTypeException e = new InvalidTargetTypeException("message",
+ "source name",
+ "ref name",
+ "target name",
+ "service name");
+ assertEquals("message", e.getMessage());
+ assertEquals("source name", e.getSourceName());
+ assertEquals("ref name", e.getReferenceName());
+ assertEquals("target name", e.getTargetName());
+ assertEquals("service name", e.getTargetServiceName());
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/LocalReferenceWiringTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/LocalReferenceWiringTestCase.java
new file mode 100644
index 0000000000..0806708056
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/LocalReferenceWiringTestCase.java
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import java.util.Collections;
+
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.Reference;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.Service;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+
+import org.apache.tuscany.core.implementation.composite.CompositeComponentImpl;
+import org.apache.tuscany.core.implementation.composite.ReferenceImpl;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+
+/**
+ * Verifies various wiring "scenarios" or paths through the connector
+ *
+ * @version $Rev$ $Date$
+ */
+public class LocalReferenceWiringTestCase extends AbstractConnectorImplTestCase {
+ protected ReferenceBinding referenceBinding;
+ private Reference reference;
+
+ /**
+ * Verifies the case where the outbound reference wire is connected to a target atomic component that is a sibling
+ * to the reference's parent composite. This wiring scenario occurs when a reference is configured with the local
+ * binding.
+ */
+ public void testConnectLocalReferenceBindingToAtomicComponentService() throws Exception {
+ final AtomicComponent atomicComponent = createAtomicTarget();
+ CompositeComponent topComposite = EasyMock.createMock(CompositeComponent.class);
+ topComposite.getChild(TARGET);
+ EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ return atomicComponent;
+ }
+ });
+ EasyMock.replay(topComposite);
+ CompositeComponent parent = new CompositeComponentImpl("parent", topComposite, connector, null);
+ reference = createLocalReference(parent, TARGET_SERVICE_NAME);
+ parent.register(reference);
+ // connect to the target
+ connector.connect(parent);
+ // connect the internal reference chains
+ connector.connect(reference);
+ InboundInvocationChain chain = referenceBinding.getInboundWire().getInvocationChains().get(operation);
+ Interceptor interceptor = chain.getHeadInterceptor();
+ MessageImpl msg = new MessageImpl();
+ msg.setTargetInvoker(new MockInvoker());
+ Message resp = interceptor.invoke(msg);
+ assertEquals(RESPONSE, resp.getBody());
+ }
+
+ /**
+ * Verifies the case where the outbound reference wire is connected to a target composite service that is a sibling
+ * to the reference's parent composite. This wiring scenario occurs when a reference is configured with the local
+ * binding.
+ */
+ public void testConnectLocalReferenceBindingToCompositeService() throws Exception {
+ final CompositeComponent topComposite = EasyMock.createMock(CompositeComponent.class);
+
+ topComposite.getInboundWire(TARGET);
+ EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ return createLocalInboundWire(topComposite);
+ }
+ });
+ final Service service = createLocalService(topComposite);
+ topComposite.getChild(TARGET);
+ EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ return service;
+ }
+ });
+ EasyMock.replay(topComposite);
+
+ CompositeComponent parent = new CompositeComponentImpl("parent", topComposite, connector, null);
+ reference = createLocalReference(parent, TARGET_NAME);
+ parent.register(reference);
+ connector.connect(parent);
+ connector.connect(reference);
+ InboundInvocationChain chain = referenceBinding.getInboundWire().getInvocationChains().get(operation);
+ Interceptor interceptor = chain.getHeadInterceptor();
+ MessageImpl msg = new MessageImpl();
+ msg.setTargetInvoker(new MockInvoker());
+ Message resp = interceptor.invoke(msg);
+ assertEquals(RESPONSE, resp.getBody());
+ }
+
+ /**
+ * Verfies an exception if the target composite service (a sibling to the reference's parent) does not have a local
+ * binding
+ */
+ public void testConnectLocalReferenceBindingToCompositeServiceNoMatchingBinding() throws Exception {
+ final Service service = createServiceNonLocalBinding();
+ CompositeComponent topComposite = EasyMock.createMock(CompositeComponent.class);
+ EasyMock.expect(topComposite.getName()).andReturn("foo");
+ topComposite.getChild(TARGET);
+ EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ return service;
+ }
+ });
+ EasyMock.replay(topComposite);
+
+ CompositeComponent parent = new CompositeComponentImpl("parent", topComposite, connector, null);
+ reference = createLocalReference(parent, TARGET_NAME);
+ parent.register(reference);
+ try {
+ connector.connect(parent);
+ fail();
+ } catch (NoCompatibleBindingsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * Verifies a connection to a service offered by a sibling composite of the reference's parent
+ *
+ * @throws Exception
+ */
+ public void testConnectLocalReferenceBindingToSiblingCompositeService() throws Exception {
+ final CompositeComponent sibling = EasyMock.createMock(CompositeComponent.class);
+ final InboundWire localServiceInboundWire = createLocalInboundWire(sibling);
+ EasyMock.expect(sibling.getName()).andReturn("sibling").atLeastOnce();
+ sibling.getInboundWires();
+ EasyMock.expectLastCall().andReturn(Collections.emptyList()).atLeastOnce();
+ EasyMock.expect(sibling.isSystem()).andReturn(false).atLeastOnce();
+ sibling.getInboundWire(TARGET_SERVICE);
+ EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ return localServiceInboundWire;
+ }
+ });
+ EasyMock.expect(sibling.getScope()).andReturn(Scope.SYSTEM).anyTimes();
+ EasyMock.replay(sibling);
+
+ CompositeComponent topComposite = EasyMock.createMock(CompositeComponent.class);
+ EasyMock.expect(topComposite.getName()).andReturn("foo").atLeastOnce();
+ topComposite.getChild(TARGET);
+ EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ return sibling;
+ }
+ });
+ EasyMock.replay(topComposite);
+
+ CompositeComponent parent = new CompositeComponentImpl("parent", topComposite, connector, null);
+ reference = createLocalReference(parent, TARGET_SERVICE_NAME);
+ parent.register(reference);
+ parent.register(sibling);
+ connector.connect(parent);
+ connector.connect(reference);
+ InboundInvocationChain chain = referenceBinding.getInboundWire().getInvocationChains().get(operation);
+ Interceptor interceptor = chain.getHeadInterceptor();
+ MessageImpl msg = new MessageImpl();
+ msg.setTargetInvoker(new MockInvoker());
+ Message resp = interceptor.invoke(msg);
+ assertEquals(RESPONSE, resp.getBody());
+ }
+
+ public void testConnectLocalReferenceBindingToSiblingCompositeServiceNoMatchingBinding() throws Exception {
+ try {
+ final CompositeComponent sibling = EasyMock.createMock(CompositeComponent.class);
+ sibling.getInboundWire(TARGET_SERVICE);
+ EasyMock.expectLastCall().andReturn(null);
+ EasyMock.expect(sibling.getName()).andReturn("sibling").atLeastOnce();
+ EasyMock.expect(sibling.getScope()).andReturn(Scope.SYSTEM).atLeastOnce();
+ EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ return null;
+ }
+ });
+ EasyMock.replay(sibling);
+
+ CompositeComponent topComposite = EasyMock.createMock(CompositeComponent.class);
+ topComposite.getChild(TARGET);
+ EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ return sibling;
+ }
+ });
+ EasyMock.expect(topComposite.getName()).andReturn("top").atLeastOnce();
+ EasyMock.replay(topComposite);
+
+ CompositeComponent parent = new CompositeComponentImpl("parent", topComposite, connector, null);
+
+ reference = createLocalReference(parent, TARGET_SERVICE_NAME);
+ parent.register(reference);
+ connector.connect(parent);
+ fail();
+ } catch (TargetServiceNotFoundException e) {
+ // expected
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+
+ private Reference createLocalReference(CompositeComponent parent, QualifiedName target) throws Exception {
+ referenceBinding = createLocalReferenceBinding(target);
+ Reference reference = new ReferenceImpl("foo", parent, contract);
+ reference.addReferenceBinding(referenceBinding);
+ return reference;
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/NonBlockingForwardNonBlockingCallbackConnectionTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/NonBlockingForwardNonBlockingCallbackConnectionTestCase.java
new file mode 100644
index 0000000000..896a98b773
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/NonBlockingForwardNonBlockingCallbackConnectionTestCase.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.services.work.NotificationListener;
+import org.apache.tuscany.spi.services.work.WorkScheduler;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.apache.tuscany.spi.wire.WireService;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.wire.InboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.InboundWireImpl;
+import org.apache.tuscany.core.wire.OutboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.OutboundWireImpl;
+import org.apache.tuscany.core.wire.jdk.JDKWireService;
+import org.easymock.EasyMock;
+
+/**
+ * Verifies connections with non-blocking forward and callback invocations
+ *
+ * @version $Rev$ $Date$
+ */
+public class NonBlockingForwardNonBlockingCallbackConnectionTestCase extends TestCase {
+ private Operation<Type> operation;
+ private Operation<Type> callbackOperation;
+ private ServiceContract<Type> contract;
+ private ConnectorImpl connector;
+
+ public void testNonBlockingForwardAndNonBlockingCallbackAtomicToAtomic() throws Exception {
+ AtomicComponent target = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(target.isSystem()).andReturn(false).anyTimes();
+ EasyMock.expect(target.getName()).andReturn("target").anyTimes();
+ EasyMock.expect(target.createTargetInvoker(EasyMock.eq("service"),
+ EasyMock.isA(Operation.class),
+ EasyMock.isA(InboundWire.class))).andReturn(EasyMock.createNiceMock(TargetInvoker.class));
+ EasyMock.replay(target);
+
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.setContainer(target);
+ inboundWire.setServiceContract(contract);
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ inboundChain.addInterceptor(new NonBlockingForwardNonBlockingCallbackConnectionTestCase.MockInterceptor());
+ inboundWire.addInvocationChain(operation, inboundChain);
+
+ AtomicComponent source = createSource();
+ OutboundWire outboundWire = new OutboundWireImpl();
+ outboundWire.setContainer(source);
+ outboundWire.setServiceContract(contract);
+ outboundWire.setTargetName(new QualifiedName("target/service"));
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ outboundWire.addInvocationChain(operation, outboundChain);
+
+ InboundInvocationChain callbackInboundChain = new InboundInvocationChainImpl(callbackOperation);
+ callbackInboundChain
+ .addInterceptor(new NonBlockingForwardNonBlockingCallbackConnectionTestCase.MockInterceptor());
+ Map<Operation<?>, InboundInvocationChain> chains = new HashMap<Operation<?>, InboundInvocationChain>();
+ chains.put(callbackOperation, callbackInboundChain);
+ outboundWire.addTargetCallbackInvocationChains(chains);
+
+ connector.connect(outboundWire, inboundWire, true);
+
+ // test the forward request
+ Message msg = new MessageImpl();
+ msg.setBody("foo");
+ Message ret = outboundChain.getHeadInterceptor().invoke(msg);
+ assertEquals(null, ret.getBody());
+
+ // test the callback
+ msg = new MessageImpl();
+ msg.setBody("callback");
+ Map<Operation<?>, OutboundInvocationChain> callbackChains =
+ inboundWire.getSourceCallbackInvocationChains("source");
+ OutboundInvocationChain callbackInvocationChain = callbackChains.get(callbackOperation);
+ ret = callbackInvocationChain.getHeadInterceptor().invoke(msg);
+ assertEquals(null, ret.getBody());
+
+ EasyMock.verify(source);
+ EasyMock.verify(target);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ WorkContext context = new WorkContextImpl();
+ WireService wireService = new JDKWireService(null, null);
+ WorkScheduler scheduler = new MockWorkScheduler();
+ connector = new ConnectorImpl(wireService, null, scheduler, context);
+ operation = new Operation<Type>("bar", null, null, null);
+ operation.setNonBlocking(true);
+ callbackOperation = new Operation<Type>("callback", null, null, null);
+ callbackOperation.setNonBlocking(true);
+ contract = new JavaServiceContract();
+ Map<String, Operation<Type>> ops = new HashMap<String, Operation<Type>>();
+ ops.put("callback", callbackOperation);
+ contract.setCallbackOperations(ops);
+ }
+
+ private AtomicComponent createSource() throws Exception {
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("source").atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(false).anyTimes();
+ EasyMock.expect(component.createTargetInvoker(EasyMock.eq("callback"),
+ EasyMock.isA(Operation.class),
+ (InboundWire) EasyMock.isNull())).andReturn(EasyMock.createNiceMock(TargetInvoker.class));
+ EasyMock.replay(component);
+ return component;
+ }
+
+ private class MockInterceptor implements Interceptor {
+
+ public Message invoke(Message msg) {
+ return msg;
+ }
+
+ public void setNext(Interceptor next) {
+
+ }
+
+ public Interceptor getNext() {
+ return null;
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+ }
+
+ private class MockWorkScheduler implements WorkScheduler {
+
+ public <T extends Runnable> void scheduleWork(T work, NotificationListener<T> listener) {
+ throw new UnsupportedOperationException();
+ }
+
+ public <T extends Runnable> void scheduleWork(T work) {
+ work.run();
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/NonBlockingForwardSyncCallbackConnectionTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/NonBlockingForwardSyncCallbackConnectionTestCase.java
new file mode 100644
index 0000000000..0e425b73bf
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/NonBlockingForwardSyncCallbackConnectionTestCase.java
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+import java.util.HashMap;
+
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.WireService;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.services.work.WorkScheduler;
+import org.apache.tuscany.spi.services.work.NotificationListener;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+import org.apache.tuscany.core.wire.InboundWireImpl;
+import org.apache.tuscany.core.wire.InboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.OutboundWireImpl;
+import org.apache.tuscany.core.wire.OutboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.jdk.JDKWireService;
+import org.apache.tuscany.core.component.WorkContextImpl;
+
+/**
+ * Verifies connections with non-blocking forward and synchronous callback invocations
+ *
+ * @version $Rev$ $Date$
+ */
+public class NonBlockingForwardSyncCallbackConnectionTestCase extends TestCase {
+ private Operation<Type> operation;
+ private Operation<Type> callbackOperation;
+ private ServiceContract<Type> contract;
+ private ConnectorImpl connector;
+
+ public void testNonBlockingForwardAndSyncCallbackAtomicToAtomic() throws Exception {
+ AtomicComponent target = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(target.isSystem()).andReturn(false).anyTimes();
+ EasyMock.expect(target.getName()).andReturn("target").anyTimes();
+ EasyMock.expect(target.createTargetInvoker(EasyMock.eq("service"),
+ EasyMock.isA(Operation.class),
+ EasyMock.isA(InboundWire.class))).andReturn(EasyMock.createNiceMock(TargetInvoker.class));
+ EasyMock.replay(target);
+
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.setContainer(target);
+ inboundWire.setServiceContract(contract);
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ inboundChain.addInterceptor(new NonBlockingForwardSyncCallbackConnectionTestCase.MockInterceptor());
+ inboundWire.addInvocationChain(operation, inboundChain);
+
+ AtomicComponent source = createSource();
+ OutboundWire outboundWire = new OutboundWireImpl();
+ outboundWire.setContainer(source);
+ outboundWire.setServiceContract(contract);
+ outboundWire.setTargetName(new QualifiedName("target/service"));
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ outboundWire.addInvocationChain(operation, outboundChain);
+
+ InboundInvocationChain callbackInboundChain = new InboundInvocationChainImpl(callbackOperation);
+ callbackInboundChain.addInterceptor(new NonBlockingForwardSyncCallbackConnectionTestCase.MockInterceptor());
+ Map<Operation<?>, InboundInvocationChain> chains = new HashMap<Operation<?>, InboundInvocationChain>();
+ chains.put(callbackOperation, callbackInboundChain);
+ outboundWire.addTargetCallbackInvocationChains(chains);
+
+ connector.connect(outboundWire, inboundWire, true);
+
+ // test the forward request
+ Message msg = new MessageImpl();
+ msg.setBody("foo");
+ Message ret = outboundChain.getHeadInterceptor().invoke(msg);
+ assertEquals(null, ret.getBody());
+
+ // test the callback
+ msg = new MessageImpl();
+ msg.setBody("callback");
+ Map<Operation<?>, OutboundInvocationChain> callbackChains =
+ inboundWire.getSourceCallbackInvocationChains("source");
+ OutboundInvocationChain callbackInvocationChain = callbackChains.get(callbackOperation);
+ ret = callbackInvocationChain.getHeadInterceptor().invoke(msg);
+ assertEquals("callback", ret.getBody());
+
+ EasyMock.verify(source);
+ EasyMock.verify(target);
+ }
+
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ WorkContext context = new WorkContextImpl();
+ WireService wireService = new JDKWireService(null, null);
+ WorkScheduler scheduler = new NonBlockingForwardSyncCallbackConnectionTestCase.MockWorkScheduler();
+ connector = new ConnectorImpl(wireService, null, scheduler, context);
+ operation = new Operation<Type>("bar", null, null, null);
+ operation.setNonBlocking(true);
+ callbackOperation = new Operation<Type>("callback", null, null, null);
+ contract = new JavaServiceContract();
+ Map<String, Operation<Type>> ops = new HashMap<String, Operation<Type>>();
+ ops.put("callback", callbackOperation);
+ contract.setCallbackOperations(ops);
+ }
+
+ private AtomicComponent createSource() throws Exception {
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("source").atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(false).anyTimes();
+ EasyMock.expect(component.createTargetInvoker(EasyMock.eq("callback"),
+ EasyMock.isA(Operation.class),
+ (InboundWire) EasyMock.isNull())).andReturn(EasyMock.createNiceMock(TargetInvoker.class));
+ EasyMock.replay(component);
+ return component;
+ }
+
+ private class MockInterceptor implements Interceptor {
+
+ public Message invoke(Message msg) {
+ return msg;
+ }
+
+ public void setNext(Interceptor next) {
+
+ }
+
+ public Interceptor getNext() {
+ return null;
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+ }
+
+ private class MockWorkScheduler implements WorkScheduler {
+
+ public <T extends Runnable> void scheduleWork(T work, NotificationListener<T> listener) {
+ throw new UnsupportedOperationException();
+ }
+
+ public <T extends Runnable> void scheduleWork(T work) {
+ work.run();
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/OutboundToInboundConnectTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/OutboundToInboundConnectTestCase.java
new file mode 100644
index 0000000000..2c8e2c3fa8
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/OutboundToInboundConnectTestCase.java
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import static org.apache.tuscany.spi.wire.TargetInvoker.NONE;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.mock.component.SimpleTarget;
+import org.apache.tuscany.core.mock.wire.MockSyncInterceptor;
+import org.apache.tuscany.core.wire.InboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.InvokerInterceptor;
+import org.apache.tuscany.core.wire.OutboundInvocationChainImpl;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * Verifies connection strategies between {@link org.apache.tuscany.spi.wire.OutboundInvocationChain}s and {@link
+ * org.apache.tuscany.spi.wire.InboundInvocationChain}s
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class OutboundToInboundConnectTestCase extends TestCase {
+
+ public void testNoInterceptorsNoHandlers() throws Exception {
+ ConnectorImpl connector = new ConnectorImpl();
+ InboundInvocationChain inboundChain = setupTarget(null);
+ OutboundInvocationChain outboundChain = setupSource(null);
+ String[] val = new String[]{"foo"};
+ TargetInvoker invoker = createNiceMock(TargetInvoker.class);
+ expect(invoker.invokeTarget(EasyMock.eq(val), EasyMock.eq(NONE))).andReturn(val);
+ replay(invoker);
+ connector.connect(outboundChain, inboundChain, invoker, false);
+ inboundChain.prepare();
+ assertEquals(val, outboundChain.getTargetInvoker().invokeTarget(val, NONE));
+ verify(invoker);
+ }
+
+
+ /**
+ * Verifies an invocation with a single source interceptor
+ */
+ public void testSourceInterceptor() throws Exception {
+ ConnectorImpl connector = new ConnectorImpl();
+ MockSyncInterceptor interceptor = new MockSyncInterceptor();
+ List<Interceptor> interceptors = new ArrayList<Interceptor>();
+ interceptors.add(interceptor);
+ OutboundInvocationChain outboundChain = setupSource(interceptors);
+ InboundInvocationChain inboundChain = setupTarget(null);
+ Message msg = new MessageImpl();
+ TargetInvoker invoker = createNiceMock(TargetInvoker.class);
+ expect(invoker.invoke(EasyMock.eq(msg))).andReturn(msg);
+ replay(invoker);
+ assertEquals(0, interceptor.getCount());
+ connector.connect(outboundChain, inboundChain, invoker, false);
+ inboundChain.prepare();
+ msg.setTargetInvoker(outboundChain.getTargetInvoker());
+ assertEquals(msg, outboundChain.getHeadInterceptor().invoke(msg));
+ assertEquals(1, interceptor.getCount());
+ verify(invoker);
+ }
+
+ /**
+ * Verifies an invocation with a single target interceptor
+ */
+ public void testTargetInterceptor() throws Exception {
+ ConnectorImpl connector = new ConnectorImpl();
+ MockSyncInterceptor interceptor = new MockSyncInterceptor();
+ List<Interceptor> interceptors = new ArrayList<Interceptor>();
+ interceptors.add(interceptor);
+ OutboundInvocationChain outboundChain = setupSource(null);
+ InboundInvocationChain inboundChain = setupTarget(interceptors);
+ Message msg = new MessageImpl();
+ TargetInvoker invoker = createNiceMock(TargetInvoker.class);
+ expect(invoker.invoke(EasyMock.eq(msg))).andReturn(msg);
+ replay(invoker);
+ assertEquals(0, interceptor.getCount());
+ connector.connect(outboundChain, inboundChain, invoker, false);
+ inboundChain.prepare();
+ msg.setTargetInvoker(outboundChain.getTargetInvoker());
+ assertEquals(msg, outboundChain.getHeadInterceptor().invoke(msg));
+ assertEquals(1, interceptor.getCount());
+ verify(invoker);
+ }
+
+ /**
+ * Verifies an invocation with a source and target interceptor
+ */
+ public void testSourceTargetInterceptor() throws Exception {
+ ConnectorImpl connector = new ConnectorImpl();
+ MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor();
+ List<Interceptor> sourceInterceptors = new ArrayList<Interceptor>();
+ sourceInterceptors.add(sourceInterceptor);
+ MockSyncInterceptor targetInterceptor = new MockSyncInterceptor();
+ List<Interceptor> targetInterceptors = new ArrayList<Interceptor>();
+ targetInterceptors.add(targetInterceptor);
+ OutboundInvocationChain outboundChain = setupSource(sourceInterceptors);
+ InboundInvocationChain inboundChain = setupTarget(targetInterceptors);
+ Message msg = new MessageImpl();
+ TargetInvoker invoker = createNiceMock(TargetInvoker.class);
+ expect(invoker.invoke(EasyMock.eq(msg))).andReturn(msg);
+ replay(invoker);
+ assertEquals(0, sourceInterceptor.getCount());
+ assertEquals(0, targetInterceptor.getCount());
+ connector.connect(outboundChain, inboundChain, invoker, false);
+ inboundChain.prepare();
+ msg.setTargetInvoker(outboundChain.getTargetInvoker());
+ assertEquals(msg, outboundChain.getHeadInterceptor().invoke(msg));
+ assertEquals(1, sourceInterceptor.getCount());
+ assertEquals(1, targetInterceptor.getCount());
+ verify(invoker);
+ }
+
+
+ public InboundInvocationChain setupTarget(List<Interceptor> interceptors) {
+ JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ ServiceContract<?> contract;
+ try {
+ contract = registry.introspect(SimpleTarget.class);
+ } catch (InvalidServiceContractException e) {
+ throw new AssertionError();
+ }
+ Operation operation = contract.getOperations().get("echo");
+ InboundInvocationChainImpl chain = new InboundInvocationChainImpl(operation);
+ if (interceptors != null) {
+ for (Interceptor interceptor : interceptors) {
+ chain.addInterceptor(interceptor);
+ }
+ }
+ chain.addInterceptor(new InvokerInterceptor()); // add tail interceptor
+ return chain;
+ }
+
+ public OutboundInvocationChain setupSource(List<Interceptor> interceptors) {
+ JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ ServiceContract<?> contract;
+ try {
+ contract = registry.introspect(SimpleTarget.class);
+ } catch (InvalidServiceContractException e) {
+ throw new AssertionError();
+ }
+ Operation operation = contract.getOperations().get("echo");
+ OutboundInvocationChainImpl chain = new OutboundInvocationChainImpl(operation);
+ if (interceptors != null) {
+ for (Interceptor interceptor : interceptors) {
+ chain.addInterceptor(interceptor);
+ }
+ }
+ return chain;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/ReferenceConnectorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/ReferenceConnectorTestCase.java
new file mode 100644
index 0000000000..d3e7263045
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/ReferenceConnectorTestCase.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.Reference;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import org.apache.tuscany.core.implementation.composite.ReferenceImpl;
+import org.apache.tuscany.core.wire.InboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.InboundWireImpl;
+import org.apache.tuscany.core.wire.InvokerInterceptor;
+import org.apache.tuscany.core.wire.OutboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.OutboundWireImpl;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ReferenceConnectorTestCase extends AbstractConnectorImplTestCase {
+ private AtomicComponent source;
+ private CompositeComponent parent;
+
+ public void testConnectReferenceWiresNoInboundInterceptors() throws Exception {
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.setServiceContract(contract);
+ inboundWire.addInvocationChain(operation, inboundChain);
+
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ // Outbound chains always contains at least one interceptor
+ outboundChain.addInterceptor(new InvokerInterceptor());
+ OutboundWire outboundWire = new OutboundWireImpl();
+ outboundWire.setServiceContract(contract);
+ outboundWire.setTargetName(TARGET_SERVICE_NAME);
+ outboundWire.addInvocationChain(operation, outboundChain);
+
+ ReferenceBinding referenceBinding = EasyMock.createMock(ReferenceBinding.class);
+ referenceBinding.setReference(EasyMock.isA(Reference.class));
+ EasyMock.expect(referenceBinding.createTargetInvoker(contract, operation)).andReturn(null);
+ EasyMock.expect(referenceBinding.getInboundWire()).andReturn(inboundWire);
+ EasyMock.expect(referenceBinding.getOutboundWire()).andReturn(outboundWire);
+ EasyMock.expect(referenceBinding.isSystem()).andReturn(false).atLeastOnce();
+ EasyMock.replay(referenceBinding);
+ inboundWire.setContainer(referenceBinding);
+ outboundWire.setContainer(referenceBinding);
+
+ Reference reference = new ReferenceImpl("foo", parent, contract);
+ reference.addReferenceBinding(referenceBinding);
+
+ connector.connect(reference);
+
+ EasyMock.verify(referenceBinding);
+ Interceptor interceptor = inboundChain.getHeadInterceptor();
+ MessageImpl msg = new MessageImpl();
+ msg.setTargetInvoker(new MockInvoker());
+ Message resp = interceptor.invoke(msg);
+ assertEquals(RESPONSE, resp.getBody());
+ }
+
+ public void testConnectReferenceWiresWithInboundInterceptors() throws Exception {
+ MockInterceptor inboundInterceptor = new MockInterceptor();
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ inboundChain.addInterceptor(inboundInterceptor);
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.setServiceContract(contract);
+ inboundWire.addInvocationChain(operation, inboundChain);
+
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ // Outbound always contains at lease one interceptor
+ outboundChain.addInterceptor(new InvokerInterceptor());
+ OutboundWire outboundWire = new OutboundWireImpl();
+ outboundWire.setServiceContract(contract);
+ outboundWire.setTargetName(TARGET_SERVICE_NAME);
+ outboundWire.addInvocationChain(operation, outboundChain);
+
+ ReferenceBinding referenceBinding = EasyMock.createMock(ReferenceBinding.class);
+ referenceBinding.setReference(EasyMock.isA(Reference.class));
+ EasyMock.expect(referenceBinding.createTargetInvoker(contract, operation)).andReturn(null);
+ EasyMock.expect(referenceBinding.getInboundWire()).andReturn(inboundWire);
+ EasyMock.expect(referenceBinding.getOutboundWire()).andReturn(outboundWire);
+ EasyMock.expect(referenceBinding.isSystem()).andReturn(false);
+ EasyMock.replay(referenceBinding);
+ inboundWire.setContainer(referenceBinding);
+ outboundWire.setContainer(referenceBinding);
+
+ Reference reference = new ReferenceImpl("foo", parent, contract);
+ reference.addReferenceBinding(referenceBinding);
+
+ connector.connect(reference);
+
+ EasyMock.verify(referenceBinding);
+ Interceptor interceptor = inboundChain.getHeadInterceptor();
+ MessageImpl msg = new MessageImpl();
+ msg.setTargetInvoker(new MockInvoker());
+ Message resp = interceptor.invoke(msg);
+ assertEquals(RESPONSE, resp.getBody());
+ assertTrue(inboundInterceptor.isInvoked());
+ }
+
+ public void testOutboundWireToInboundReferenceTarget() throws Exception {
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("foo");
+ EasyMock.replay(component);
+
+ ReferenceBinding target = EasyMock.createMock(ReferenceBinding.class);
+ EasyMock.expect(target.isSystem()).andReturn(false);
+ EasyMock.expect(target.createTargetInvoker(EasyMock.isA(ServiceContract.class), EasyMock.isA(Operation.class)))
+ .andReturn(new MockInvoker());
+ EasyMock.replay(target);
+
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ inboundChain.addInterceptor(new InvokerInterceptor());
+ InboundWire targetWire = new InboundWireImpl();
+ targetWire.setServiceContract(contract);
+ targetWire.addInvocationChain(operation, inboundChain);
+ targetWire.setContainer(target);
+
+ // create the outbound wire and chain from the source component
+ OutboundInvocationChain sourceChain = new OutboundInvocationChainImpl(operation);
+ OutboundWire sourceWire = new OutboundWireImpl();
+ sourceWire.setServiceContract(contract);
+ sourceWire.setTargetName(TARGET_SERVICE_NAME);
+ sourceWire.addInvocationChain(operation, sourceChain);
+ sourceWire.setContainer(component);
+ sourceWire.setContainer(source);
+
+ connector.connect(sourceWire, targetWire, false);
+ Interceptor interceptor = sourceChain.getHeadInterceptor();
+ MessageImpl msg = new MessageImpl();
+ msg.setTargetInvoker(new MockInvoker());
+ Message resp = interceptor.invoke(msg);
+ assertEquals(RESPONSE, resp.getBody());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ parent = EasyMock.createNiceMock(CompositeComponent.class);
+ source = EasyMock.createNiceMock(AtomicComponent.class);
+ EasyMock.replay(source);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/ServiceConnectorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/ServiceConnectorTestCase.java
new file mode 100644
index 0000000000..0ccab5bfea
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/ServiceConnectorTestCase.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.Reference;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.Service;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import org.apache.tuscany.core.implementation.composite.ReferenceImpl;
+import org.apache.tuscany.core.implementation.composite.ServiceImpl;
+import org.apache.tuscany.core.mock.binding.MockServiceBinding;
+import org.apache.tuscany.core.wire.InboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.InboundWireImpl;
+import org.apache.tuscany.core.wire.InvokerInterceptor;
+import org.apache.tuscany.core.wire.OutboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.OutboundWireImpl;
+import org.apache.tuscany.core.wire.SynchronousBridgingInterceptor;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ServiceConnectorTestCase extends AbstractConnectorImplTestCase {
+ private CompositeComponent parent;
+ private InboundInvocationChain inboundChain;
+ private ServiceBinding sourceServiceBinding;
+
+ public void testConnectServiceToAtomicComponent() throws Exception {
+ configureAtomicTarget();
+ Service sourceService = new ServiceImpl("foo", parent, contract);
+ sourceService.addServiceBinding(sourceServiceBinding);
+ connector.connect(sourceService);
+ Interceptor interceptor = inboundChain.getHeadInterceptor();
+ MessageImpl msg = new MessageImpl();
+ msg.setTargetInvoker(new MockInvoker());
+ Message resp = interceptor.invoke(msg);
+ assertEquals(RESPONSE, resp.getBody());
+ }
+
+ public void testConnectServiceToChildCompositeService() throws Exception {
+ configureChildCompositeServiceTarget();
+ Service sourceService = new ServiceImpl("foo", parent, contract);
+ sourceService.addServiceBinding(sourceServiceBinding);
+ connector.connect(sourceService);
+ Interceptor interceptor = inboundChain.getHeadInterceptor();
+ MessageImpl msg = new MessageImpl();
+ msg.setTargetInvoker(new MockInvoker());
+ Message resp = interceptor.invoke(msg);
+ assertEquals(RESPONSE, resp.getBody());
+ }
+
+ public void testConnectServiceToReference() throws Exception {
+ configureReferenceTarget();
+ Service sourceService = new ServiceImpl("foo", parent, contract);
+ sourceService.addServiceBinding(sourceServiceBinding);
+ connector.connect(sourceService);
+ Interceptor interceptor = inboundChain.getHeadInterceptor();
+ MessageImpl msg = new MessageImpl();
+ msg.setTargetInvoker(new MockInvoker());
+ Message resp = interceptor.invoke(msg);
+ assertEquals(RESPONSE, resp.getBody());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ inboundChain = new InboundInvocationChainImpl(operation);
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.setServiceContract(contract);
+ inboundWire.addInvocationChain(operation, inboundChain);
+
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ // Outbound chains always contains at least one interceptor
+ outboundChain.addInterceptor(new SynchronousBridgingInterceptor());
+ OutboundWire outboundWire = new OutboundWireImpl();
+ outboundWire.setServiceContract(contract);
+ outboundWire.setTargetName(TARGET_SERVICE_NAME);
+ outboundWire.addInvocationChain(operation, outboundChain);
+
+ sourceServiceBinding = new MockServiceBinding();
+ sourceServiceBinding.setInboundWire(inboundWire);
+ sourceServiceBinding.setOutboundWire(outboundWire);
+ inboundWire.setContainer(sourceServiceBinding);
+ outboundWire.setContainer(sourceServiceBinding);
+
+ }
+
+ private void configureAtomicTarget() throws Exception {
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ inboundChain.addInterceptor(new InvokerInterceptor());
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.setServiceContract(contract);
+ inboundWire.addInvocationChain(operation, inboundChain);
+
+ AtomicComponent atomicTarget = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(atomicTarget.getInboundWire(EasyMock.isA(String.class))).andReturn(inboundWire).atLeastOnce();
+ EasyMock.expect(atomicTarget.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.expect(atomicTarget.isSystem()).andReturn(false);
+ EasyMock.expect(atomicTarget.createTargetInvoker(EasyMock.isA(String.class),
+ EasyMock.isA(Operation.class),
+ EasyMock.isA(InboundWire.class))).andReturn(new MockInvoker());
+ EasyMock.replay(atomicTarget);
+
+ inboundWire.setContainer(atomicTarget);
+
+ parent = EasyMock.createNiceMock(CompositeComponent.class);
+ EasyMock.expect(parent.getChild(TARGET)).andReturn(atomicTarget);
+ EasyMock.replay(parent);
+ }
+
+ private void configureChildCompositeServiceTarget() throws Exception {
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ inboundChain.addInterceptor(new InvokerInterceptor());
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.setServiceContract(contract);
+ inboundWire.addInvocationChain(operation, inboundChain);
+
+ CompositeComponent compositeTarget = EasyMock.createMock(CompositeComponent.class);
+ Service service = createLocalService(compositeTarget);
+ ServiceBinding binding = service.getServiceBindings().get(0);
+ EasyMock.expect(compositeTarget.getInboundWire(TARGET_SERVICE)).andReturn(binding.getInboundWire());
+ EasyMock.expect(compositeTarget.getScope()).andReturn(Scope.SYSTEM).anyTimes();
+ EasyMock.replay(compositeTarget);
+
+ inboundWire.setContainer(compositeTarget);
+
+ parent = EasyMock.createNiceMock(CompositeComponent.class);
+ EasyMock.expect(parent.getChild(TARGET)).andReturn(compositeTarget);
+ EasyMock.replay(parent);
+ }
+
+
+ private void configureReferenceTarget() throws Exception {
+ ReferenceBinding binding = createLocalReferenceBinding(TARGET_NAME);
+ Reference referenceTarget = new ReferenceImpl(TARGET, parent, contract);
+ referenceTarget.addReferenceBinding(binding);
+ // put a terminating interceptor on the outbound wire of the reference for testing an invocation
+ binding.getOutboundWire().getInvocationChains().get(operation).addInterceptor(new InvokerInterceptor());
+ connector.connect(binding.getInboundWire(), binding.getOutboundWire(), true);
+ parent = EasyMock.createNiceMock(CompositeComponent.class);
+ EasyMock.expect(parent.getChild(TARGET)).andReturn(referenceTarget);
+ EasyMock.replay(parent);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/SynchronousForwardCallbackConnectionTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/SynchronousForwardCallbackConnectionTestCase.java
new file mode 100644
index 0000000000..9beca64444
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/SynchronousForwardCallbackConnectionTestCase.java
@@ -0,0 +1,256 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.apache.tuscany.spi.wire.WireService;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.wire.InboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.InboundWireImpl;
+import org.apache.tuscany.core.wire.OutboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.OutboundWireImpl;
+import org.apache.tuscany.core.wire.jdk.JDKWireService;
+import org.easymock.EasyMock;
+
+/**
+ * Verifies connections with synchronous forward and callback invocations
+ *
+ * @version $Rev$ $Date$
+ */
+public class SynchronousForwardCallbackConnectionTestCase extends TestCase {
+ private Operation<Type> operation;
+ private Operation<Type> callbackOperation;
+ private ServiceContract<Type> contract;
+ private ConnectorImpl connector;
+
+ public void testSyncForwardAndCallbackAtomicToAtomic() throws Exception {
+ AtomicComponent target = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(target.isSystem()).andReturn(false).anyTimes();
+ EasyMock.expect(target.getName()).andReturn("target").anyTimes();
+ EasyMock.expect(target.createTargetInvoker(EasyMock.eq("service"),
+ EasyMock.isA(Operation.class),
+ EasyMock.isA(InboundWire.class))).andReturn(EasyMock.createNiceMock(TargetInvoker.class));
+ EasyMock.replay(target);
+
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.setContainer(target);
+ inboundWire.setServiceContract(contract);
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ inboundChain.addInterceptor(new MockInterceptor());
+ inboundWire.addInvocationChain(operation, inboundChain);
+
+ AtomicComponent source = createSource();
+ OutboundWire outboundWire = new OutboundWireImpl();
+ outboundWire.setContainer(source);
+ outboundWire.setServiceContract(contract);
+ outboundWire.setTargetName(new QualifiedName("target/service"));
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ outboundWire.addInvocationChain(operation, outboundChain);
+
+ InboundInvocationChain callbackInboundChain = new InboundInvocationChainImpl(callbackOperation);
+ callbackInboundChain.addInterceptor(new MockInterceptor());
+ Map<Operation<?>, InboundInvocationChain> chains = new HashMap<Operation<?>, InboundInvocationChain>();
+ chains.put(callbackOperation, callbackInboundChain);
+ outboundWire.addTargetCallbackInvocationChains(chains);
+
+ connector.connect(outboundWire, inboundWire, true);
+
+ // test the forward request
+ Message msg = new MessageImpl();
+ msg.setBody("foo");
+ Message ret = outboundChain.getHeadInterceptor().invoke(msg);
+ assertEquals("foo", ret.getBody());
+
+ // test the callback
+ msg = new MessageImpl();
+ msg.setBody("callback");
+ Map<Operation<?>, OutboundInvocationChain> callbackChains =
+ inboundWire.getSourceCallbackInvocationChains("source");
+ OutboundInvocationChain callbackInvocationChain = callbackChains.get(callbackOperation);
+ ret = callbackInvocationChain.getHeadInterceptor().invoke(msg);
+ assertEquals("callback", ret.getBody());
+
+ EasyMock.verify(source);
+ EasyMock.verify(target);
+ }
+
+ public void testSyncForwardAndCallbackAtomicToReferenceBinding() throws Exception {
+ ReferenceBinding target = EasyMock.createMock(ReferenceBinding.class);
+ EasyMock.expect(target.isSystem()).andReturn(false).anyTimes();
+ EasyMock.expect(target.createTargetInvoker(EasyMock.isA(ServiceContract.class),
+ EasyMock.isA(Operation.class))).andReturn(EasyMock.createNiceMock(TargetInvoker.class));
+ EasyMock.replay(target);
+
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.setContainer(target);
+ inboundWire.setServiceContract(contract);
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ inboundChain.addInterceptor(new MockInterceptor());
+ inboundWire.addInvocationChain(operation, inboundChain);
+
+ AtomicComponent source = createSource();
+ OutboundWire outboundWire = new OutboundWireImpl();
+ outboundWire.setContainer(source);
+ outboundWire.setServiceContract(contract);
+ outboundWire.setTargetName(new QualifiedName("target/service"));
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ outboundWire.addInvocationChain(operation, outboundChain);
+
+ InboundInvocationChain callbackInboundChain = new InboundInvocationChainImpl(callbackOperation);
+ callbackInboundChain.addInterceptor(new MockInterceptor());
+ Map<Operation<?>, InboundInvocationChain> chains = new HashMap<Operation<?>, InboundInvocationChain>();
+ chains.put(callbackOperation, callbackInboundChain);
+ outboundWire.addTargetCallbackInvocationChains(chains);
+
+ connector.connect(outboundWire, inboundWire, true);
+ // test the forward request
+ Message msg = new MessageImpl();
+ msg.setBody("foo");
+ Message ret = outboundChain.getHeadInterceptor().invoke(msg);
+ assertEquals("foo", ret.getBody());
+
+ // test the callback
+ msg = new MessageImpl();
+ msg.setBody("callback");
+ Map<Operation<?>, OutboundInvocationChain> callbackChains =
+ inboundWire.getSourceCallbackInvocationChains("source");
+ OutboundInvocationChain callbackInvocationChain = callbackChains.get(callbackOperation);
+ ret = callbackInvocationChain.getHeadInterceptor().invoke(msg);
+ assertEquals("callback", ret.getBody());
+
+ EasyMock.verify(target);
+ EasyMock.verify(source);
+ }
+
+ public void testSyncForwardAndCallbackReferenceBindingToServiceBinding() throws Exception {
+ ReferenceBinding source = EasyMock.createMock(ReferenceBinding.class);
+ EasyMock.expect(source.isSystem()).andReturn(false).anyTimes();
+ EasyMock.expect(source.getName()).andReturn("source").atLeastOnce();
+ EasyMock.expect(source.createTargetInvoker(EasyMock.isA(ServiceContract.class),
+ EasyMock.isA(Operation.class))).andReturn(EasyMock.createNiceMock(TargetInvoker.class));
+ EasyMock.replay(source);
+
+ ServiceBinding target = EasyMock.createMock(ServiceBinding.class);
+ EasyMock.expect(target.isSystem()).andReturn(false).anyTimes();
+ EasyMock.expect(target.createTargetInvoker(EasyMock.isA(ServiceContract.class),
+ EasyMock.isA(Operation.class))).andReturn(EasyMock.createNiceMock(TargetInvoker.class));
+ EasyMock.replay(target);
+
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.setContainer(target);
+ inboundWire.setServiceContract(contract);
+ InboundInvocationChain inboundChain = new InboundInvocationChainImpl(operation);
+ inboundChain.addInterceptor(new MockInterceptor());
+ inboundWire.addInvocationChain(operation, inboundChain);
+
+ OutboundWire outboundWire = new OutboundWireImpl();
+ outboundWire.setContainer(source);
+ outboundWire.setServiceContract(contract);
+ outboundWire.setTargetName(new QualifiedName("target/service"));
+ OutboundInvocationChain outboundChain = new OutboundInvocationChainImpl(operation);
+ outboundWire.addInvocationChain(operation, outboundChain);
+
+ InboundInvocationChain callbackInboundChain = new InboundInvocationChainImpl(callbackOperation);
+ callbackInboundChain.addInterceptor(new MockInterceptor());
+ Map<Operation<?>, InboundInvocationChain> chains = new HashMap<Operation<?>, InboundInvocationChain>();
+ chains.put(callbackOperation, callbackInboundChain);
+ outboundWire.addTargetCallbackInvocationChains(chains);
+
+ connector.connect(outboundWire, inboundWire, true);
+ // test the forward request
+ Message msg = new MessageImpl();
+ msg.setBody("foo");
+ Message ret = outboundChain.getHeadInterceptor().invoke(msg);
+ assertEquals("foo", ret.getBody());
+
+ // test the callback
+ msg = new MessageImpl();
+ msg.setBody("callback");
+ Map<Operation<?>, OutboundInvocationChain> callbackChains =
+ inboundWire.getSourceCallbackInvocationChains("source");
+ OutboundInvocationChain callbackInvocationChain = callbackChains.get(callbackOperation);
+ ret = callbackInvocationChain.getHeadInterceptor().invoke(msg);
+ assertEquals("callback", ret.getBody());
+
+ EasyMock.verify(source);
+ EasyMock.verify(target);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ WireService wireService = new JDKWireService(null, null);
+ connector = new ConnectorImpl(wireService, null, null, null);
+ operation = new Operation<Type>("bar", null, null, null);
+ callbackOperation = new Operation<Type>("callback", null, null, null);
+ contract = new JavaServiceContract();
+ Map<String, Operation<Type>> ops = new HashMap<String, Operation<Type>>();
+ ops.put("callback", callbackOperation);
+ contract.setCallbackOperations(ops);
+ }
+
+ private AtomicComponent createSource() throws Exception {
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("source").atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(false).anyTimes();
+ EasyMock.expect(component.createTargetInvoker(EasyMock.eq("callback"),
+ EasyMock.isA(Operation.class),
+ (InboundWire) EasyMock.isNull())).andReturn(EasyMock.createNiceMock(TargetInvoker.class));
+ EasyMock.replay(component);
+ return component;
+ }
+
+ private class MockInterceptor implements Interceptor {
+
+ public Message invoke(Message msg) {
+ return msg;
+ }
+
+ public void setNext(Interceptor next) {
+
+ }
+
+ public Interceptor getNext() {
+ return null;
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/TargetServiceNotFoundExceptionTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/TargetServiceNotFoundExceptionTestCase.java
new file mode 100644
index 0000000000..b6ecd952e3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/TargetServiceNotFoundExceptionTestCase.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class TargetServiceNotFoundExceptionTestCase extends TestCase {
+
+ public void testInstantiation() throws Exception {
+ TargetServiceNotFoundException e = new TargetServiceNotFoundException("message",
+ "source name",
+ "ref name",
+ "target name",
+ "service name");
+ assertEquals("message", e.getMessage());
+ assertEquals("source name", e.getSourceName());
+ assertEquals("ref name", e.getReferenceName());
+ assertEquals("target name", e.getTargetName());
+ assertEquals("service name", e.getTargetServiceName());
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/WirePostProcessorRegistryImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/WirePostProcessorRegistryImplTestCase.java
new file mode 100644
index 0000000000..359733a4fc
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/WirePostProcessorRegistryImplTestCase.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import org.apache.tuscany.spi.wire.WirePostProcessor;
+import org.apache.tuscany.spi.wire.WirePostProcessorRegistry;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WirePostProcessorRegistryImplTestCase extends TestCase {
+
+ public void testRegisterUnregister() throws Exception {
+ WirePostProcessorRegistry registry = new WirePostProcessorRegistryImpl();
+ OutboundWire owire = EasyMock.createMock(OutboundWire.class);
+ InboundWire iwire = EasyMock.createMock(InboundWire.class);
+ WirePostProcessor processor = createMock(WirePostProcessor.class);
+ processor.process(EasyMock.eq(owire), EasyMock.eq(iwire));
+ EasyMock.replay(processor);
+ registry.register(processor);
+ registry.process(owire, iwire);
+ registry.unregister(processor);
+ registry.process(owire, iwire);
+ verify(processor);
+ }
+
+ public void testProcessInboundToOutbound() throws Exception {
+ WirePostProcessorRegistry registry = new WirePostProcessorRegistryImpl();
+ OutboundWire owire = EasyMock.createMock(OutboundWire.class);
+ InboundWire iwire = EasyMock.createMock(InboundWire.class);
+ WirePostProcessor processor = createMock(WirePostProcessor.class);
+ processor.process(EasyMock.eq(iwire), EasyMock.eq(owire));
+ EasyMock.replay(processor);
+ registry.register(processor);
+ registry.process(iwire, owire);
+ verify(processor);
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/WiringExceptionFormatterTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/WiringExceptionFormatterTestCase.java
new file mode 100644
index 0000000000..0269fd07e1
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/builder/WiringExceptionFormatterTestCase.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.builder;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.apache.tuscany.spi.builder.WiringException;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.host.monitor.FormatterRegistry;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WiringExceptionFormatterTestCase extends TestCase {
+ WiringExceptionFormatter formatter = new WiringExceptionFormatter(EasyMock.createNiceMock(FormatterRegistry.class));
+
+ public void testFormat() throws Exception {
+ WiringException e = new MockWiringException("message",
+ "identifier",
+ "source name",
+ "ref name",
+ "target name",
+ "service name");
+ StringWriter writer = new StringWriter();
+ PrintWriter pw = new PrintWriter(writer);
+ formatter.write(pw, e);
+ String buffer = writer.toString();
+ assertTrue(buffer.indexOf("message") >= 0);
+ assertTrue(buffer.indexOf("identifier") >= 0);
+ assertTrue(buffer.indexOf("source name") >= 0);
+ assertTrue(buffer.indexOf("ref name") >= 0);
+ assertTrue(buffer.indexOf("target name") >= 0);
+ assertTrue(buffer.indexOf("service name") >= 0);
+ }
+
+
+ public void testFormatNulls() throws Exception {
+ WiringException e = new MockWiringException("message",
+ "identifier",
+ "source name",
+ null,
+ "target name",
+ null);
+ StringWriter writer = new StringWriter();
+ PrintWriter pw = new PrintWriter(writer);
+ formatter.write(pw, e);
+ String buffer = writer.toString();
+ assertTrue(buffer.indexOf("message") >= 0);
+ assertTrue(buffer.indexOf("identifier") >= 0);
+ assertTrue(buffer.indexOf("source name") >= 0);
+ assertTrue(buffer.indexOf("target name") >= 0);
+ }
+
+ private class MockWiringException extends WiringException {
+
+ public MockWiringException(String message, String
+ identifier,
+ String sourceName,
+ String referenceName,
+ String targetName,
+ String serviceName) {
+ super(message, identifier);
+ setSourceName(sourceName);
+ setReferenceName(referenceName);
+ setTargetName(targetName);
+ setTargetServiceName(serviceName);
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/WorkContextImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/WorkContextImplTestCase.java
new file mode 100644
index 0000000000..aee910ddaf
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/WorkContextImplTestCase.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component;
+
+import org.apache.tuscany.spi.component.WorkContext;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WorkContextImplTestCase extends TestCase {
+
+ public void testPushPopServiceNames() throws Exception {
+ WorkContext context = new WorkContextImpl();
+ context.pushServiceName("foo");
+ context.pushServiceName("bar");
+ assertEquals("bar", context.getCurrentServiceName());
+ assertEquals("bar", context.popServiceName());
+ assertEquals("foo", context.getCurrentServiceName());
+ assertEquals("foo", context.popServiceName());
+ assertNull(context.getCurrentServiceName());
+ }
+
+ public void testGetCurrentServiceNamesNull() throws Exception {
+ WorkContext context = new WorkContextImpl();
+ assertNull(context.getCurrentServiceName());
+ }
+
+ public void testPopCurrentServiceNamesNull() throws Exception {
+ WorkContext context = new WorkContextImpl();
+ assertNull(context.popServiceName());
+ }
+
+ public void testClearServiceNames() throws Exception {
+ WorkContext context = new WorkContextImpl();
+ context.pushServiceName("foo");
+ context.pushServiceName("bar");
+ context.clearServiceNames();
+ assertNull(context.getCurrentServiceName());
+ }
+
+ public void testClearServiceNamesNull() throws Exception {
+ WorkContext context = new WorkContextImpl();
+ context.clearServiceNames();
+ assertNull(context.getCurrentServiceName());
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/event/EventTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/event/EventTestCase.java
new file mode 100644
index 0000000000..79b9757c2c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/event/EventTestCase.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.event;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class EventTestCase extends TestCase {
+
+ private CompositeComponent component;
+
+ public void testCompositeStart() {
+ CompositeStart event = new CompositeStart(this, component);
+ assertEquals(component, event.getComposite());
+ }
+
+ public void testCompositeStop() {
+ CompositeStop event = new CompositeStop(this, component);
+ assertEquals(component, event.getComposite());
+ }
+
+ public void testHttpSessionStart() {
+ Object id = new Object();
+ HttpSessionEvent event = new HttpSessionStart(this, id);
+ assertEquals(this, event.getSource());
+ assertEquals(id, event.getId());
+ }
+
+ public void testHttpSessionEnd() {
+ Object id = new Object();
+ HttpSessionEvent event = new HttpSessionEnd(this, id);
+ assertEquals(this, event.getSource());
+ assertEquals(id, event.getId());
+ }
+
+ public void testRequestStart() {
+ RequestStart event = new RequestStart(this);
+ assertEquals(this, event.getSource());
+ }
+
+ public void testReequestEnd() {
+ RequestEnd event = new RequestEnd(this);
+ assertEquals(this, event.getSource());
+ }
+
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ component = EasyMock.createNiceMock(CompositeComponent.class);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/AbstractScopeContainerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/AbstractScopeContainerTestCase.java
new file mode 100644
index 0000000000..f8f8dd5f60
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/AbstractScopeContainerTestCase.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.event.EventFilter;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+import org.apache.tuscany.spi.event.TrueFilter;
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class AbstractScopeContainerTestCase extends TestCase {
+
+ public void testFireListener() {
+ TestContainer container = new TestContainer("foo");
+ RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class);
+ Event event = new TestEvent();
+ listener.onEvent(EasyMock.eq(event));
+ EasyMock.replay(listener);
+ container.addListener(listener);
+ container.publish(event);
+ EasyMock.verify(listener);
+ }
+
+ public void testRemoveListener() {
+ TestContainer container = new TestContainer("foo");
+ RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class);
+ EasyMock.replay(listener);
+ Event event = new TestEvent();
+ container.addListener(listener);
+ container.removeListener(listener);
+ container.publish(event);
+ EasyMock.verify(listener);
+ }
+
+ public void testFalseFilterListener() {
+ TestContainer container = new TestContainer("foo");
+ RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class);
+ Event event = new TestEvent();
+ EasyMock.replay(listener);
+ container.addListener(new FalseFilter(), listener);
+ container.publish(event);
+ EasyMock.verify(listener);
+ }
+
+ public void testTrueFilterListener() {
+ TestContainer container = new TestContainer("foo");
+ RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class);
+ Event event = new TestEvent();
+ listener.onEvent(EasyMock.eq(event));
+ EasyMock.replay(listener);
+ container.addListener(new TrueFilter(), listener);
+ container.publish(event);
+ EasyMock.verify(listener);
+ }
+
+ public void testToString() {
+ TestContainer container = new TestContainer("foo");
+ assertNotNull(container.toString());
+ }
+
+ private class TestContainer extends AbstractScopeContainer {
+
+ public TestContainer(String name) {
+ super(null, null);
+ }
+
+ protected InstanceWrapper getInstanceWrapper(AtomicComponent component, boolean create) {
+ return null;
+ }
+
+ public Scope getScope() {
+ return null;
+ }
+
+ public void register(AtomicComponent component) {
+
+ }
+
+ public void onEvent(Event event) {
+
+ }
+
+ public WorkContext getWorkContext() {
+ return super.getWorkContext();
+ }
+ }
+
+ private class TestEvent implements Event {
+ public Object getSource() {
+ return null;
+ }
+ }
+
+ private class FalseFilter implements EventFilter {
+
+ public boolean match(Event event) {
+ return false;
+ }
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicCompositeScopeTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicCompositeScopeTestCase.java
new file mode 100644
index 0000000000..cd68b46541
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicCompositeScopeTestCase.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.TargetNotFoundException;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.event.CompositeStop;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl;
+import org.apache.tuscany.core.injection.EventInvoker;
+import org.apache.tuscany.core.injection.MethodEventInvoker;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.mock.component.CompositeScopeInitDestroyComponent;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public class BasicCompositeScopeTestCase extends TestCase {
+
+ private EventInvoker<Object> initInvoker;
+ private EventInvoker<Object> destroyInvoker;
+ private PojoObjectFactory<?> factory;
+
+ public void testLifecycleManagement() throws Exception {
+ CompositeScopeContainer scopeContext = new CompositeScopeContainer(null);
+ scopeContext.start();
+ AtomicComponent component = createComponent(scopeContext);
+ // start the request
+ CompositeScopeInitDestroyComponent o1 =
+ (CompositeScopeInitDestroyComponent) scopeContext.getInstance(component);
+ assertTrue(o1.isInitialized());
+ assertFalse(o1.isDestroyed());
+ CompositeScopeInitDestroyComponent o2 =
+ (CompositeScopeInitDestroyComponent) scopeContext.getInstance(component);
+ assertEquals(o1, o2);
+ scopeContext.onEvent(new CompositeStop(this, null));
+ assertTrue(o1.isDestroyed());
+ scopeContext.stop();
+ }
+
+
+ public void testGetAssociatedInstance() throws Exception {
+ CompositeScopeContainer scopeContext = new CompositeScopeContainer(null);
+ scopeContext.start();
+ AtomicComponent component = createComponent(scopeContext);
+ // start the request
+ scopeContext.getInstance(component);
+ scopeContext.getAssociatedInstance(component);
+ }
+
+ public void testGetAssociatedInstanceNonExistent() throws Exception {
+ CompositeScopeContainer scopeContext = new CompositeScopeContainer(null);
+ scopeContext.start();
+ AtomicComponent component = createComponent(scopeContext);
+ // start the request
+ try {
+ scopeContext.getAssociatedInstance(component);
+ fail();
+ } catch (TargetNotFoundException e) {
+ // expected
+ }
+ }
+
+ public void testCompositeIsolation() throws Exception {
+ CompositeScopeContainer scopeContext = new CompositeScopeContainer(null);
+ scopeContext.start();
+
+ AtomicComponent component = createComponent(scopeContext);
+
+ CompositeScopeInitDestroyComponent o1 =
+ (CompositeScopeInitDestroyComponent) scopeContext.getInstance(component);
+ assertTrue(o1.isInitialized());
+ assertFalse(o1.isDestroyed());
+
+ CompositeScopeInitDestroyComponent o2 =
+ (CompositeScopeInitDestroyComponent) scopeContext.getInstance(component);
+ assertSame(o1, o2);
+ scopeContext.onEvent(new CompositeStop(this, null));
+ assertTrue(o1.isDestroyed());
+ scopeContext.stop();
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ factory = new PojoObjectFactory<CompositeScopeInitDestroyComponent>(
+ CompositeScopeInitDestroyComponent.class.getConstructor((Class[]) null));
+ initInvoker = new MethodEventInvoker<Object>(CompositeScopeInitDestroyComponent.class.getMethod(
+ "init", (Class[]) null));
+ destroyInvoker = new MethodEventInvoker<Object>(CompositeScopeInitDestroyComponent.class.getMethod(
+ "destroy", (Class[]) null));
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ private AtomicComponent createComponent(ScopeContainer scopeContainer) {
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInstanceFactory(factory);
+ configuration.setInitInvoker(initInvoker);
+ configuration.setDestroyInvoker(destroyInvoker);
+ configuration.setName("foo");
+ SystemAtomicComponentImpl component = new SystemAtomicComponentImpl(configuration);
+ component.setScopeContainer(scopeContainer);
+ component.start();
+ return component;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicConversationalScopeTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicConversationalScopeTestCase.java
new file mode 100644
index 0000000000..c97f3cb96f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicConversationalScopeTestCase.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.services.store.StoreMonitor;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.component.event.ConversationEnd;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl;
+import org.apache.tuscany.core.injection.EventInvoker;
+import org.apache.tuscany.core.injection.MethodEventInvoker;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.mock.component.ConversationalScopeInitDestroyComponent;
+import org.apache.tuscany.core.services.store.memory.MemoryStore;
+import org.easymock.EasyMock;
+
+/**
+ * @version $$Rev: 471111 $$ $$Date: 2006-11-03 23:06:48 -0500 (Fri, 03 Nov 2006) $$
+ */
+public class BasicConversationalScopeTestCase extends TestCase {
+
+ private EventInvoker<Object> initInvoker;
+ private EventInvoker<Object> destroyInvoker;
+ private PojoObjectFactory<?> factory;
+
+ public void testLifecycleManagement() throws Exception {
+ StoreMonitor monitor = EasyMock.createMock(StoreMonitor.class);
+ monitor.start(EasyMock.isA(String.class));
+ monitor.stop(EasyMock.isA(String.class));
+ MemoryStore store = new MemoryStore(monitor);
+ WorkContext workContext = new WorkContextImpl();
+ ConversationalScopeContainer scopeContext = new ConversationalScopeContainer(store, workContext, null);
+ scopeContext.start();
+ AtomicComponent atomicContext = createContext(scopeContext);
+ // start the request
+ String conversation = "conv";
+ workContext.setIdentifier(Scope.CONVERSATION, conversation);
+ ConversationalScopeInitDestroyComponent o1 =
+ (ConversationalScopeInitDestroyComponent) scopeContext.getInstance(atomicContext);
+ //assertTrue(o1.isInitialized());
+ assertFalse(o1.isDestroyed());
+ ConversationalScopeInitDestroyComponent o2 =
+ (ConversationalScopeInitDestroyComponent) scopeContext.getInstance(atomicContext);
+ assertSame(o1, o2);
+ scopeContext.onEvent(new ConversationEnd(this, conversation));
+ //assertTrue(o1.isDestroyed());
+ scopeContext.stop();
+ }
+
+ public void testCompositeIsolation() throws Exception {
+ StoreMonitor monitor = EasyMock.createMock(StoreMonitor.class);
+ monitor.start(EasyMock.isA(String.class));
+ monitor.stop(EasyMock.isA(String.class));
+ MemoryStore store = new MemoryStore(monitor);
+ WorkContext workContext = new WorkContextImpl();
+ ConversationalScopeContainer scopeContext = new ConversationalScopeContainer(store, workContext, null);
+ scopeContext.start();
+
+ AtomicComponent atomicContext = createContext(scopeContext);
+
+ String conversation1 = "conv";
+ workContext.setIdentifier(Scope.CONVERSATION, conversation1);
+ ConversationalScopeInitDestroyComponent o1 =
+ (ConversationalScopeInitDestroyComponent) scopeContext.getInstance(atomicContext);
+ //assertTrue(o1.isInitialized());
+ assertFalse(o1.isDestroyed());
+
+ String conversation2 = "conv2";
+ workContext.setIdentifier(Scope.CONVERSATION, conversation2);
+ ConversationalScopeInitDestroyComponent o2 =
+ (ConversationalScopeInitDestroyComponent) scopeContext.getInstance(atomicContext);
+ assertNotSame(o1, o2);
+
+ scopeContext.onEvent(new ConversationEnd(this, conversation1));
+ //assertTrue(o1.isDestroyed());
+ assertFalse(o2.isDestroyed());
+ scopeContext.onEvent(new ConversationEnd(this, conversation2));
+ //assertTrue(o2.isDestroyed());
+ scopeContext.stop();
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ factory = new PojoObjectFactory<ConversationalScopeInitDestroyComponent>(
+ ConversationalScopeInitDestroyComponent.class.getConstructor((Class[]) null));
+ initInvoker = new MethodEventInvoker<Object>(
+ ConversationalScopeInitDestroyComponent.class.getMethod("init", (Class[]) null));
+ destroyInvoker = new MethodEventInvoker<Object>(
+ ConversationalScopeInitDestroyComponent.class.getMethod("destroy", (Class[]) null));
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ private AtomicComponent createContext(ScopeContainer scopeContainer) {
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInstanceFactory(factory);
+ configuration.setInitInvoker(initInvoker);
+ configuration.setDestroyInvoker(destroyInvoker);
+ configuration.setName("foo");
+ SystemAtomicComponentImpl component = new SystemAtomicComponentImpl(configuration);
+ component.setScopeContainer(scopeContainer);
+ component.start();
+ return component;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicHttpSessionScopeTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicHttpSessionScopeTestCase.java
new file mode 100644
index 0000000000..44e9bbc1d6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicHttpSessionScopeTestCase.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.TargetNotFoundException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.component.event.HttpSessionEnd;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl;
+import org.apache.tuscany.core.injection.EventInvoker;
+import org.apache.tuscany.core.injection.MethodEventInvoker;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.mock.component.SessionScopeInitDestroyComponent;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public class BasicHttpSessionScopeTestCase extends TestCase {
+ private EventInvoker<Object> initInvoker;
+ private EventInvoker<Object> destroyInvoker;
+ private PojoObjectFactory<?> factory;
+
+ public void testLifecycleManagement() throws Exception {
+ WorkContext workContext = new WorkContextImpl();
+ HttpSessionScopeContainer scopeContext = new HttpSessionScopeContainer(workContext, null);
+ scopeContext.start();
+ AtomicComponent component = createComponent(scopeContext);
+ // start the request
+ Object session = new Object();
+ workContext.setIdentifier(Scope.SESSION, session);
+ SessionScopeInitDestroyComponent o1 =
+ (SessionScopeInitDestroyComponent) scopeContext.getInstance(component);
+ assertTrue(o1.isInitialized());
+ assertFalse(o1.isDestroyed());
+ SessionScopeInitDestroyComponent o2 =
+ (SessionScopeInitDestroyComponent) scopeContext.getInstance(component);
+ assertSame(o1, o2);
+ scopeContext.onEvent(new HttpSessionEnd(this, session));
+ assertTrue(o1.isDestroyed());
+ scopeContext.stop();
+ }
+
+ public void testGetAssociatedInstance() throws Exception {
+ WorkContext workContext = new WorkContextImpl();
+ HttpSessionScopeContainer scopeContext = new HttpSessionScopeContainer(workContext, null);
+ scopeContext.start();
+ AtomicComponent component = createComponent(scopeContext);
+ // start the request
+ Object session = new Object();
+ workContext.setIdentifier(Scope.SESSION, session);
+ scopeContext.getInstance(component);
+ scopeContext.getAssociatedInstance(component);
+ }
+
+ public void testGetAssociatedInstanceNonExistent() throws Exception {
+ WorkContext workContext = new WorkContextImpl();
+ HttpSessionScopeContainer scopeContext = new HttpSessionScopeContainer(workContext, null);
+ scopeContext.start();
+ AtomicComponent component = createComponent(scopeContext);
+ // start the request
+ Object session = new Object();
+ workContext.setIdentifier(Scope.SESSION, session);
+ try {
+ scopeContext.getAssociatedInstance(component);
+ fail();
+ } catch (TargetNotFoundException e) {
+ // expected
+ }
+ }
+
+ public void testSessionIsolation() throws Exception {
+ WorkContext workContext = new WorkContextImpl();
+ HttpSessionScopeContainer scopeContext = new HttpSessionScopeContainer(workContext, null);
+ scopeContext.start();
+
+ AtomicComponent component = createComponent(scopeContext);
+
+ Object session1 = new Object();
+ workContext.setIdentifier(Scope.SESSION, session1);
+ SessionScopeInitDestroyComponent o1 =
+ (SessionScopeInitDestroyComponent) scopeContext.getInstance(component);
+ assertTrue(o1.isInitialized());
+
+ Object session2 = new Object();
+ workContext.setIdentifier(Scope.SESSION, session2);
+ SessionScopeInitDestroyComponent o2 =
+ (SessionScopeInitDestroyComponent) scopeContext.getInstance(component);
+ assertNotSame(o1, o2);
+
+ scopeContext.onEvent(new HttpSessionEnd(this, session1));
+ assertTrue(o1.isDestroyed());
+ assertFalse(o2.isDestroyed());
+ scopeContext.onEvent(new HttpSessionEnd(this, session2));
+ assertTrue(o2.isDestroyed());
+ scopeContext.stop();
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ factory = new PojoObjectFactory<SessionScopeInitDestroyComponent>(
+ SessionScopeInitDestroyComponent.class.getConstructor((Class[]) null));
+ initInvoker = new MethodEventInvoker<Object>(
+ SessionScopeInitDestroyComponent.class.getMethod("init", (Class[]) null));
+ destroyInvoker = new MethodEventInvoker<Object>(
+ SessionScopeInitDestroyComponent.class.getMethod("destroy", (Class[]) null));
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ private AtomicComponent createComponent(ScopeContainer scopeContainer) {
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInstanceFactory(factory);
+ configuration.setInitInvoker(initInvoker);
+ configuration.setDestroyInvoker(destroyInvoker);
+ configuration.setName("foo");
+ SystemAtomicComponentImpl component = new SystemAtomicComponentImpl(configuration);
+ component.setScopeContainer(scopeContainer);
+ component.start();
+ return component;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicRequestScopeTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicRequestScopeTestCase.java
new file mode 100644
index 0000000000..435e7d29b7
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicRequestScopeTestCase.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.TargetNotFoundException;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.event.RequestEnd;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl;
+import org.apache.tuscany.core.injection.EventInvoker;
+import org.apache.tuscany.core.injection.MethodEventInvoker;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.mock.component.RequestScopeInitDestroyComponent;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public class BasicRequestScopeTestCase extends TestCase {
+ private EventInvoker<Object> initInvoker;
+ private EventInvoker<Object> destroyInvoker;
+ private PojoObjectFactory<?> factory;
+
+ public void testLifecycleManagement() throws Exception {
+ RequestScopeContainer scopeContainer = new RequestScopeContainer(null, null);
+ scopeContainer.start();
+ AtomicComponent component = createComponent(scopeContainer);
+ // start the request
+ RequestScopeInitDestroyComponent o1 =
+ (RequestScopeInitDestroyComponent) scopeContainer.getInstance(component);
+ assertTrue(o1.isInitialized());
+ assertFalse(o1.isDestroyed());
+ RequestScopeInitDestroyComponent o2 =
+ (RequestScopeInitDestroyComponent) scopeContainer.getInstance(component);
+ assertSame(o1, o2);
+ scopeContainer.onEvent(new RequestEnd(this));
+ assertTrue(o1.isDestroyed());
+ scopeContainer.stop();
+ }
+
+ public void testGetAssociatedInstance() throws Exception {
+ RequestScopeContainer scopeContainer = new RequestScopeContainer(null, null);
+ scopeContainer.start();
+ AtomicComponent component = createComponent(scopeContainer);
+ // start the request
+ scopeContainer.getInstance(component);
+ scopeContainer.getAssociatedInstance(component);
+ scopeContainer.stop();
+ }
+
+ public void testGetAssociatedInstanceNonExistent() throws Exception {
+ RequestScopeContainer scopeContainer = new RequestScopeContainer(null, null);
+ scopeContainer.start();
+ AtomicComponent component = createComponent(scopeContainer);
+ // start the request
+ try {
+ scopeContainer.getAssociatedInstance(component);
+ fail();
+ } catch (TargetNotFoundException e) {
+ // expected
+ }
+ scopeContainer.stop();
+ }
+
+ public void testRequestIsolation() throws Exception {
+ RequestScopeContainer scopeContainer = new RequestScopeContainer(null, null);
+ scopeContainer.start();
+
+ AtomicComponent component = createComponent(scopeContainer);
+
+ RequestScopeInitDestroyComponent o1 =
+ (RequestScopeInitDestroyComponent) scopeContainer.getInstance(component);
+ assertTrue(o1.isInitialized());
+ scopeContainer.onEvent(new RequestEnd(this));
+ assertTrue(o1.isDestroyed());
+
+ RequestScopeInitDestroyComponent o2 =
+ (RequestScopeInitDestroyComponent) scopeContainer.getInstance(component);
+ assertNotSame(o1, o2);
+ scopeContainer.onEvent(new RequestEnd(this));
+ assertTrue(o2.isDestroyed());
+ scopeContainer.stop();
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ factory = new PojoObjectFactory<RequestScopeInitDestroyComponent>(
+ RequestScopeInitDestroyComponent.class.getConstructor((Class[]) null));
+ initInvoker = new MethodEventInvoker<Object>(
+ RequestScopeInitDestroyComponent.class.getMethod("init", (Class[]) null));
+ destroyInvoker = new MethodEventInvoker<Object>(
+ RequestScopeInitDestroyComponent.class.getMethod("destroy", (Class[]) null));
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ private AtomicComponent createComponent(ScopeContainer scopeContainer) {
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInstanceFactory(factory);
+ configuration.setInitInvoker(initInvoker);
+ configuration.setDestroyInvoker(destroyInvoker);
+ configuration.setName("foo");
+ SystemAtomicComponentImpl component = new SystemAtomicComponentImpl(configuration);
+ component.setScopeContainer(scopeContainer);
+ component.start();
+ return component;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicStatelessScopeTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicStatelessScopeTestCase.java
new file mode 100644
index 0000000000..9ca9230e5b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/BasicStatelessScopeTestCase.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.TargetNotFoundException;
+import org.apache.tuscany.spi.component.WorkContext;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.mock.component.StatelessComponent;
+import org.apache.tuscany.core.mock.component.StatelessComponentImpl;
+
+/**
+ * Unit tests for the composite scope container
+ *
+ * @version $Rev$ $Date$
+ */
+public class BasicStatelessScopeTestCase extends TestCase {
+ private PojoObjectFactory<StatelessComponentImpl> factory;
+
+ /**
+ * Verfies instance identity is properly maintained
+ */
+ public void testInstanceManagement() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ StatelessScopeContainer scope = new StatelessScopeContainer(ctx, null);
+ scope.start();
+ AtomicComponent component1 = createComponent(scope);
+ scope.register(component1);
+ AtomicComponent component2 = createComponent(scope);
+ scope.register(component2);
+ StatelessComponentImpl comp1 = (StatelessComponentImpl) scope.getInstance(component1);
+ Assert.assertNotNull(comp1);
+ StatelessComponentImpl comp2 = (StatelessComponentImpl) scope.getInstance(component2);
+ Assert.assertNotNull(comp2);
+ Assert.assertNotSame(comp1, comp2);
+ scope.stop();
+ }
+
+ public void testGetAssociatedInstance() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ StatelessScopeContainer scope = new StatelessScopeContainer(ctx, null);
+ scope.start();
+ AtomicComponent component1 = createComponent(scope);
+ scope.register(component1);
+ try {
+ // always throws an exception, which is the semantic for stateless implementations
+ scope.getAssociatedInstance(component1);
+ fail();
+ } catch (TargetNotFoundException e) {
+ // expected
+ }
+ scope.stop();
+ }
+
+ public void testRegisterContextAfterRequest() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ StatelessScopeContainer scope = new StatelessScopeContainer(ctx, null);
+
+ scope.start();
+ AtomicComponent component1 = createComponent(scope);
+ scope.register(component1);
+ StatelessComponent comp1 = (StatelessComponentImpl) scope.getInstance(component1);
+ Assert.assertNotNull(comp1);
+ AtomicComponent component2 = createComponent(scope);
+ scope.register(component2);
+ StatelessComponentImpl comp2 = (StatelessComponentImpl) scope.getInstance(component2);
+ Assert.assertNotNull(comp2);
+ scope.stop();
+ }
+
+
+ /**
+ * Tests setting no components in the scope
+ */
+ public void testSetNullComponents() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ StatelessScopeContainer scope = new StatelessScopeContainer(ctx, null);
+ scope.start();
+ scope.stop();
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ factory =
+ new PojoObjectFactory<StatelessComponentImpl>(StatelessComponentImpl.class.getConstructor((Class[]) null));
+
+ }
+
+ private AtomicComponent createComponent(ScopeContainer scopeContainer) {
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInstanceFactory(factory);
+ configuration.setName("foo");
+ AtomicComponent component = new SystemAtomicComponentImpl(configuration);
+ component.setScopeContainer(scopeContainer);
+ return component;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeInitDestroyErrorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeInitDestroyErrorTestCase.java
new file mode 100644
index 0000000000..8ac4ce46a4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeInitDestroyErrorTestCase.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.TargetDestructionException;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.event.CompositeStart;
+import org.apache.tuscany.core.component.event.CompositeStop;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class CompositeScopeInitDestroyErrorTestCase extends TestCase {
+
+ public void testInitializeErrorMonitor() throws Exception {
+ ScopeContainerMonitor monitor;
+ monitor = EasyMock.createMock(ScopeContainerMonitor.class);
+ monitor.eagerInitializationError(EasyMock.isA(ObjectCreationException.class));
+ EasyMock.replay(monitor);
+ CompositeScopeContainer scope = new CompositeScopeContainer(monitor);
+ scope.start();
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("foo").atLeastOnce();
+ EasyMock.expect(component.createInstance()).andThrow(new ObjectCreationException(""));
+ EasyMock.expect(component.getInitLevel()).andReturn(1);
+ EasyMock.replay(component);
+ scope.register(component);
+ scope.onEvent(new CompositeStart(this, null));
+ EasyMock.verify(monitor);
+ }
+
+ public void testDestroyErrorMonitor() throws Exception {
+ ScopeContainerMonitor monitor;
+ monitor = EasyMock.createMock(ScopeContainerMonitor.class);
+ monitor.destructionError(EasyMock.isA(TargetDestructionException.class));
+ EasyMock.replay(monitor);
+ CompositeScopeContainer scope = new CompositeScopeContainer(monitor);
+ scope.start();
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("foo").atLeastOnce();
+ EasyMock.expect(component.createInstance()).andReturn(new Object());
+ EasyMock.expect(component.getInitLevel()).andReturn(1);
+ component.init(EasyMock.isA(Object.class));
+ component.destroy(EasyMock.isA(Object.class));
+ EasyMock.expectLastCall().andThrow(new TargetDestructionException("", ""));
+ EasyMock.replay(component);
+ scope.register(component);
+ scope.onEvent(new CompositeStart(this, null));
+ scope.onEvent(new CompositeStop(this, null));
+ EasyMock.verify(monitor);
+ }
+
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeInstanceLifecycleTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeInstanceLifecycleTestCase.java
new file mode 100644
index 0000000000..0d70bcf252
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeInstanceLifecycleTestCase.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.TargetException;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.event.CompositeStart;
+import org.apache.tuscany.core.component.event.CompositeStop;
+import org.apache.tuscany.core.mock.component.OrderedInitPojo;
+import org.apache.tuscany.core.mock.component.OrderedInitPojoImpl;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+
+/**
+ * Lifecycle unit tests for the composite scope container
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompositeScopeInstanceLifecycleTestCase extends TestCase {
+
+ /**
+ * Verify init and stop by scope container on an atomic component
+ *
+ * @throws Exception
+ */
+ public void testInitDestroy() throws Exception {
+ CompositeScopeContainer scope = new CompositeScopeContainer(null);
+ scope.start();
+ Foo comp = new Foo();
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.createInstance()).andReturn(comp);
+ EasyMock.expect(component.getInitLevel()).andReturn(1).atLeastOnce();
+ component.init(EasyMock.eq(comp));
+ component.destroy(EasyMock.eq(comp));
+ EasyMock.replay(component);
+ scope.register(component);
+ scope.onEvent(new CompositeStart(this, null));
+ assertNotNull(scope.getInstance(component));
+ // expire composite
+ scope.onEvent(new CompositeStop(this, null));
+ scope.stop();
+ EasyMock.verify(component);
+ }
+
+ /**
+ * Verify init and stop by scope container on an atomic component when set to eager initialize
+ *
+ * @throws Exception
+ */
+ public void testEagerInitDestroy() throws Exception {
+ CompositeScopeContainer scope = new CompositeScopeContainer(null);
+ scope.start();
+ Foo comp = new Foo();
+ AtomicComponent initDestroyComponent = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(initDestroyComponent.createInstance()).andReturn(comp);
+ EasyMock.expect(initDestroyComponent.getInitLevel()).andReturn(1).atLeastOnce();
+ initDestroyComponent.init(EasyMock.eq(comp));
+ initDestroyComponent.destroy(EasyMock.eq(comp));
+ EasyMock.replay(initDestroyComponent);
+ scope.register(initDestroyComponent);
+ scope.onEvent(new CompositeStart(this, null));
+ // expire composite
+ scope.onEvent(new CompositeStop(this, null));
+ scope.stop();
+ EasyMock.verify(initDestroyComponent);
+ }
+
+
+ public void testDestroyOrder() throws Exception {
+ CompositeScopeContainer scope = new CompositeScopeContainer(null);
+ scope.start();
+
+ AtomicComponent oneComponent = createComponent(0);
+ scope.register(oneComponent);
+ AtomicComponent twoComponent = createComponent(0);
+ scope.register(twoComponent);
+ AtomicComponent threeComponent = createComponent(0);
+ scope.register(threeComponent);
+
+ scope.onEvent(new CompositeStart(this, null));
+ OrderedInitPojo one = (OrderedInitPojo) scope.getInstance(oneComponent);
+ assertNotNull(one);
+ assertEquals(1, one.getNumberInstantiated());
+ assertEquals(1, one.getInitOrder());
+
+ OrderedInitPojo two = (OrderedInitPojo) scope.getInstance(twoComponent);
+ assertNotNull(two);
+ assertEquals(2, two.getNumberInstantiated());
+ assertEquals(2, two.getInitOrder());
+
+ OrderedInitPojo three = (OrderedInitPojo) scope.getInstance(threeComponent);
+ assertNotNull(three);
+ assertEquals(3, three.getNumberInstantiated());
+ assertEquals(3, three.getInitOrder());
+
+ // expire composite
+ scope.onEvent(new CompositeStop(this, null));
+ assertEquals(0, one.getNumberInstantiated());
+ scope.stop();
+ EasyMock.verify(oneComponent);
+ EasyMock.verify(twoComponent);
+ EasyMock.verify(threeComponent);
+ }
+
+ public void testEagerInitDestroyOrder() throws Exception {
+ CompositeScopeContainer scope = new CompositeScopeContainer(null);
+ scope.start();
+
+ AtomicComponent oneComponent = createComponent(1);
+ scope.register(oneComponent);
+ AtomicComponent twoComponent = createComponent(1);
+ scope.register(twoComponent);
+ AtomicComponent threeComponent = createComponent(1);
+ scope.register(threeComponent);
+
+ scope.onEvent(new CompositeStart(this, null));
+ OrderedInitPojo one = (OrderedInitPojo) scope.getInstance(oneComponent);
+ assertNotNull(one);
+
+ OrderedInitPojo two = (OrderedInitPojo) scope.getInstance(twoComponent);
+ assertNotNull(two);
+
+ OrderedInitPojo three = (OrderedInitPojo) scope.getInstance(threeComponent);
+ assertNotNull(three);
+
+ // expire composite
+ scope.onEvent(new CompositeStop(this, null));
+ assertEquals(0, one.getNumberInstantiated());
+ scope.stop();
+ EasyMock.verify(oneComponent);
+ EasyMock.verify(twoComponent);
+ EasyMock.verify(threeComponent);
+ }
+
+ @SuppressWarnings("unchecked")
+ private AtomicComponent createComponent(int init) throws TargetException {
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.createInstance()).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return new OrderedInitPojoImpl();
+ }
+ });
+ EasyMock.expect(component.getInitLevel()).andReturn(init).atLeastOnce();
+ component.init(EasyMock.isA(OrderedInitPojoImpl.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ OrderedInitPojoImpl pojo = (OrderedInitPojoImpl) EasyMock.getCurrentArguments()[0];
+ pojo.init();
+ return null;
+ }
+ });
+ component.destroy(EasyMock.isA(OrderedInitPojoImpl.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ OrderedInitPojoImpl pojo = (OrderedInitPojoImpl) EasyMock.getCurrentArguments()[0];
+ pojo.destroy();
+ return null;
+ }
+ });
+ EasyMock.replay(component);
+ return component;
+ }
+
+ private class Foo {
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactoryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactoryTestCase.java
new file mode 100644
index 0000000000..611fbfc13f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeObjectFactoryTestCase.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class CompositeScopeObjectFactoryTestCase extends TestCase {
+
+ public void testCreation() {
+ ScopeRegistry registry = EasyMock.createMock(ScopeRegistry.class);
+ registry.registerFactory(EasyMock.isA(Scope.class), EasyMock.isA(CompositeScopeObjectFactory.class));
+
+ assertNotNull(new CompositeScopeObjectFactory(registry, null).getInstance());
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeRestartTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeRestartTestCase.java
new file mode 100644
index 0000000000..1fdaeed48c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/CompositeScopeRestartTestCase.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import java.lang.reflect.Constructor;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.event.CompositeStart;
+import org.apache.tuscany.core.component.event.CompositeStop;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl;
+import org.apache.tuscany.core.injection.MethodEventInvoker;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+
+/**
+ * Verifies the scope container properly disposes resources and canbe restarted
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class CompositeScopeRestartTestCase extends TestCase {
+
+ public void testRestart() throws Exception {
+ CompositeScopeContainer scope = new CompositeScopeContainer(null);
+ scope.start();
+ MethodEventInvoker<Object> initInvoker =
+ new MethodEventInvoker<Object>(InitDestroyOnce.class.getMethod("init"));
+ MethodEventInvoker<Object> destroyInvoker =
+ new MethodEventInvoker<Object>(InitDestroyOnce.class.getMethod("destroy"));
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInitInvoker(initInvoker);
+ configuration.setDestroyInvoker(destroyInvoker);
+ Constructor<InitDestroyOnce> ctr = InitDestroyOnce.class.getConstructor((Class<?>[]) null);
+ configuration.setInstanceFactory(new PojoObjectFactory<InitDestroyOnce>(ctr));
+ configuration.setName("InitDestroy");
+ AtomicComponent component = new SystemAtomicComponentImpl(configuration);
+ component.setScopeContainer(scope);
+ component.start();
+
+ scope.onEvent(new CompositeStart(this, null));
+ Object instance = component.getTargetInstance();
+ assertSame(instance, component.getTargetInstance());
+
+ scope.onEvent(new CompositeStop(this, null));
+ scope.stop();
+ component.stop();
+
+ scope.start();
+ scope.onEvent(new CompositeStart(this, null));
+ component.start();
+ assertNotSame(instance, component.getTargetInstance());
+ scope.onEvent(new CompositeStop(this, null));
+ scope.stop();
+ component.stop();
+ }
+
+ public static class InitDestroyOnce {
+
+ private boolean initialized;
+ private boolean destroyed;
+
+ public InitDestroyOnce() {
+ }
+
+ public void init() {
+ if (!initialized) {
+ initialized = true;
+ } else {
+ fail("Scope did not clean up properly - Init called more than once");
+ }
+ }
+
+ public void destroy() {
+ if (!destroyed) {
+ destroyed = true;
+ } else {
+ fail("Scope did not clean up properly - Destroyed called more than once");
+ }
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerDestroyOnExpirationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerDestroyOnExpirationTestCase.java
new file mode 100644
index 0000000000..a1a3616d0a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerDestroyOnExpirationTestCase.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.event.EventFilter;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+import org.apache.tuscany.spi.services.store.RecoveryListener;
+import org.apache.tuscany.spi.services.store.Store;
+import org.apache.tuscany.spi.services.store.StoreExpirationEvent;
+import org.apache.tuscany.spi.services.store.StoreReadException;
+import org.apache.tuscany.spi.services.store.StoreWriteException;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ConversationalScopeContainerDestroyOnExpirationTestCase extends TestCase {
+ private ScopeContainer container;
+ private TestStore store;
+ private AtomicComponent component;
+
+ /**
+ * Verifies the scope container registers a callback listener for component instance destroy events when a
+ * conversational instance expires
+ */
+ public void testDestroyNotification() throws Exception {
+ store.getListener().onEvent(new StoreExpirationEvent(this, component, new Object()));
+ EasyMock.verify(component);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ component = EasyMock.createMock(AtomicComponent.class);
+ component.destroy(EasyMock.isA(Object.class));
+ EasyMock.replay(component);
+ store = new TestStore();
+ WorkContext context = new WorkContextImpl();
+ container = new ConversationalScopeContainer(store, context, null);
+ container.start();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ container.stop();
+ }
+
+ private class TestStore implements Store {
+ private RuntimeEventListener listener;
+
+ public RuntimeEventListener getListener() {
+ return listener;
+ }
+
+ public void insertRecord(SCAObject owner, String id, Object object, long expiration)
+ throws StoreWriteException {
+
+ }
+
+ public void updateRecord(SCAObject owner, String id, Object object, long expiration)
+ throws StoreWriteException {
+
+ }
+
+ public Object readRecord(SCAObject owner, String id) throws StoreReadException {
+ return null;
+ }
+
+ public void removeRecord(SCAObject owner, String id) throws StoreWriteException {
+
+ }
+
+ public void removeRecords() throws StoreWriteException {
+
+ }
+
+ public void recover(RecoveryListener listener) throws StoreReadException {
+
+ }
+
+ public void publish(Event object) {
+
+ }
+
+ public void addListener(RuntimeEventListener listener) {
+ this.listener = listener;
+ }
+
+ public void addListener(EventFilter filter, RuntimeEventListener listener) {
+
+ }
+
+ public void removeListener(RuntimeEventListener listener) {
+
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerMaxAgeTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerMaxAgeTestCase.java
new file mode 100644
index 0000000000..79ea057652
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerMaxAgeTestCase.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.services.store.Store;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ConversationalScopeContainerMaxAgeTestCase extends TestCase {
+
+ private ScopeContainer container;
+ private WorkContext context;
+ private Store store;
+ private AtomicComponent component;
+
+ public void testMaxAgeUpdate() throws Exception {
+ context.setIdentifier(Scope.CONVERSATION, "12345");
+ container.getInstance(component);
+ EasyMock.verify(store);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ ConversationalScopeContainerMaxAgeTestCase.Foo foo = new ConversationalScopeContainerMaxAgeTestCase.Foo();
+ context = new WorkContextImpl();
+ component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("foo").atLeastOnce();
+ EasyMock.expect(component.getMaxIdleTime()).andReturn(-1L).atLeastOnce();
+ EasyMock.expect(component.getMaxAge()).andReturn(600000L).atLeastOnce();
+ EasyMock.replay(component);
+ store = EasyMock.createMock(Store.class);
+ EasyMock.expect(store.readRecord(EasyMock.isA(SCAObject.class), EasyMock.isA(String.class))).andReturn(foo);
+ store.addListener(EasyMock.isA(RuntimeEventListener.class));
+ EasyMock.replay(store);
+ container = new ConversationalScopeContainer(store, context, null);
+ container.start();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ context.clearIdentifier(Scope.CONVERSATION);
+ container.stop();
+ }
+
+ private class Foo {
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerMaxIdleTimeTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerMaxIdleTimeTestCase.java
new file mode 100644
index 0000000000..2ba152d223
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerMaxIdleTimeTestCase.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.services.store.Store;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ConversationalScopeContainerMaxIdleTimeTestCase extends TestCase {
+
+ private ScopeContainer container;
+ private WorkContext context;
+ private Store store;
+ private AtomicComponent component;
+
+ public void testMaxIdleTimeUpdate() throws Exception {
+ context.setIdentifier(Scope.CONVERSATION, "12345");
+ container.getInstance(component);
+ EasyMock.verify(store);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ Foo foo = new Foo();
+ context = new WorkContextImpl();
+ component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("foo").atLeastOnce();
+ EasyMock.expect(component.getMaxIdleTime()).andReturn(600000L).atLeastOnce();
+ EasyMock.replay(component);
+ store = EasyMock.createMock(Store.class);
+ EasyMock.expect(store.readRecord(EasyMock.isA(SCAObject.class), EasyMock.isA(String.class))).andReturn(foo);
+ store.addListener(EasyMock.isA(RuntimeEventListener.class));
+ store.updateRecord(EasyMock.isA(SCAObject.class),
+ EasyMock.isA(String.class),
+ EasyMock.eq(foo),
+ EasyMock.anyLong());
+ EasyMock.replay(store);
+ container = new ConversationalScopeContainer(store, context, null);
+ container.start();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ context.clearIdentifier(Scope.CONVERSATION);
+ container.stop();
+ }
+
+ private class Foo {
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerPersistenceTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerPersistenceTestCase.java
new file mode 100644
index 0000000000..ae7e91a59a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeContainerPersistenceTestCase.java
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import java.util.UUID;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.TargetNotFoundException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.services.store.Store;
+import org.apache.tuscany.spi.services.store.StoreMonitor;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.services.store.memory.MemoryStore;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ConversationalScopeContainerPersistenceTestCase extends TestCase {
+ private ScopeContainer container;
+ private WorkContext context;
+
+ /**
+ * Verifies the scope container properly creates an instance
+ */
+ public void testNotYetPersistedInMemory() throws Exception {
+ String id = UUID.randomUUID().toString();
+ context.setIdentifier(Scope.CONVERSATION, id);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ component.addListener(EasyMock.eq(container));
+ EasyMock.expect(component.createInstance()).andReturn(new Foo());
+ EasyMock.expect(component.getMaxAge()).andReturn(600000L).atLeastOnce();
+ component.init(EasyMock.isA(Object.class));
+ EasyMock.replay(component);
+ container.register(component);
+ assertTrue(container.getInstance(component) instanceof Foo);
+ EasyMock.verify(component);
+ }
+
+ public void testPersistNewInMemory() throws Exception {
+ String id = UUID.randomUUID().toString();
+ String id2 = UUID.randomUUID().toString();
+ context.setIdentifier(Scope.CONVERSATION, id);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ component.addListener(EasyMock.eq(container));
+ EasyMock.expect(component.getMaxIdleTime()).andReturn(-1L).atLeastOnce();
+ EasyMock.replay(component);
+ container.register(component);
+ Foo foo = new Foo();
+ Foo foo2 = new Foo();
+ container.persistNew(component, id, foo, System.currentTimeMillis() + 100000);
+ assertEquals(foo, container.getInstance(component));
+ container.persistNew(component, id2, foo2, System.currentTimeMillis() + 100000);
+ context.setIdentifier(Scope.CONVERSATION, id2);
+ assertEquals(foo2, container.getInstance(component));
+ EasyMock.verify(component);
+ }
+
+ public void testPersistInMemory() throws Exception {
+ String id = UUID.randomUUID().toString();
+ context.setIdentifier(Scope.CONVERSATION, id);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ component.addListener(EasyMock.eq(container));
+ EasyMock.expect(component.getMaxIdleTime()).andReturn(-1L).atLeastOnce();
+ EasyMock.replay(component);
+ container.register(component);
+ Foo foo = new Foo();
+ container.persistNew(component, id, foo, System.currentTimeMillis() + 100000);
+ assertEquals(foo, container.getInstance(component));
+ container.persist(component, id, foo, System.currentTimeMillis() + 100000);
+ assertEquals(foo, container.getInstance(component));
+ EasyMock.verify(component);
+ }
+
+ public void testRemoveInMemory() throws Exception {
+ String id = UUID.randomUUID().toString();
+ context.setIdentifier(Scope.CONVERSATION, id);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ component.addListener(EasyMock.eq(container));
+ EasyMock.expect(component.getMaxIdleTime()).andReturn(-1L).atLeastOnce();
+ EasyMock.expect(component.getName()).andReturn("foo").atLeastOnce();
+ EasyMock.replay(component);
+ container.register(component);
+ Foo foo = new Foo();
+ container.persistNew(component, id, foo, System.currentTimeMillis() + 100000);
+ assertEquals(foo, container.getInstance(component));
+ container.remove(component);
+ try {
+ container.getAssociatedInstance(component);
+ fail();
+ } catch (TargetNotFoundException e) {
+ //expected
+ }
+ EasyMock.verify(component);
+ }
+
+ public void testRecreateAfterRemoveInMemory() throws Exception {
+ String id = UUID.randomUUID().toString();
+ context.setIdentifier(Scope.CONVERSATION, id);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ component.addListener(EasyMock.eq(container));
+ EasyMock.expect(component.getMaxAge()).andReturn(600000L).atLeastOnce();
+ component.init(EasyMock.isA(Object.class));
+ EasyMock.expect(component.getMaxIdleTime()).andReturn(-1L).atLeastOnce();
+ EasyMock.expect(component.createInstance()).andReturn(new Foo());
+ EasyMock.replay(component);
+ container.register(component);
+ Foo foo = new Foo();
+ container.persistNew(component, id, foo, System.currentTimeMillis() + 100000);
+ assertEquals(foo, container.getInstance(component));
+ container.remove(component);
+ Foo foo2 = (Foo) container.getInstance(component);
+ assertNotNull(foo2);
+ assertNotSame(foo, foo2);
+ EasyMock.verify(component);
+ }
+
+ public void testGetPersistedInstance() throws Exception {
+ String id = UUID.randomUUID().toString();
+ String id2 = UUID.randomUUID().toString();
+ context.setIdentifier(Scope.CONVERSATION, id);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("foo").atLeastOnce();
+ EasyMock.expect(component.getMaxIdleTime()).andReturn(-1L).atLeastOnce();
+ component.addListener(EasyMock.eq(container));
+ EasyMock.replay(component);
+ container.register(component);
+ Foo foo = new Foo();
+ container.persistNew(component, id, foo, System.currentTimeMillis() + 100000);
+ assertEquals(foo, container.getAssociatedInstance(component));
+ assertEquals(foo, container.getAssociatedInstance(component));
+ context.setIdentifier(Scope.CONVERSATION, id2);
+ try {
+ container.getAssociatedInstance(component);
+ fail();
+ } catch (TargetNotFoundException e) {
+ //expected
+ }
+ EasyMock.verify(component);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ context = new WorkContextImpl();
+ StoreMonitor mock = EasyMock.createNiceMock(StoreMonitor.class);
+ EasyMock.replay(mock);
+ Store store = new MemoryStore(mock);
+ container = new ConversationalScopeContainer(store, context, null);
+ container.start();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ context.clearIdentifier(Scope.CONVERSATION);
+ container.stop();
+ }
+
+ private class Foo {
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeInstanceLifecycleTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeInstanceLifecycleTestCase.java
new file mode 100644
index 0000000000..782b175b47
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeInstanceLifecycleTestCase.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.services.store.StoreMonitor;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.services.store.memory.MemoryStore;
+import org.easymock.EasyMock;
+
+/**
+ * Lifecycle unit tests for the conversational scope container
+ *
+ * @version $Rev: 451895 $ $Date: 2006-10-02 02:58:18 -0400 (Mon, 02 Oct 2006) $
+ */
+public class ConversationalScopeInstanceLifecycleTestCase extends TestCase {
+
+ public void testInitRemove() throws Exception {
+ StoreMonitor monitor = EasyMock.createMock(StoreMonitor.class);
+ monitor.start(EasyMock.isA(String.class));
+ monitor.stop(EasyMock.isA(String.class));
+ MemoryStore store = new MemoryStore(monitor);
+ WorkContext ctx = new WorkContextImpl();
+ ConversationalScopeContainer scope = new ConversationalScopeContainer(store, ctx, null);
+ scope.start();
+
+ Foo comp = new Foo();
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.createInstance()).andReturn(comp);
+ component.init(EasyMock.eq(comp));
+ EasyMock.expect(component.getMaxAge()).andReturn(1L).anyTimes();
+ component.addListener(EasyMock.isA(RuntimeEventListener.class));
+ EasyMock.replay(component);
+ scope.register(component);
+ String convID = "ConvID";
+ ctx.setIdentifier(Scope.CONVERSATION, convID);
+ assertNotNull(scope.getInstance(component));
+ // expire
+ scope.remove(component);
+ scope.stop();
+ EasyMock.verify(component);
+ scope.stop();
+ }
+
+ private class Foo {
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeRestartTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeRestartTestCase.java
new file mode 100644
index 0000000000..bc5ddc7c2c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ConversationalScopeRestartTestCase.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import java.lang.reflect.Constructor;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.services.store.StoreMonitor;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.component.event.ConversationEnd;
+import org.apache.tuscany.core.component.event.ConversationStart;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl;
+import org.apache.tuscany.core.injection.MethodEventInvoker;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.services.store.memory.MemoryStore;
+import org.easymock.EasyMock;
+
+/**
+ * Verifies the scope container properly disposes resources and can be restarted
+ *
+ * @version $$Rev: 471111 $$ $$Date: 2006-11-03 23:06:48 -0500 (Fri, 03 Nov 2006) $$
+ */
+public class ConversationalScopeRestartTestCase extends TestCase {
+
+ public void testRestart() throws Exception {
+ StoreMonitor monitor = EasyMock.createMock(StoreMonitor.class);
+ monitor.start(EasyMock.isA(String.class));
+ monitor.stop(EasyMock.isA(String.class));
+ MemoryStore store = new MemoryStore(monitor);
+ WorkContext ctx = new WorkContextImpl();
+ ConversationalScopeContainer scope = new ConversationalScopeContainer(store, ctx, null);
+ scope.start();
+ MethodEventInvoker<Object> initInvoker = new MethodEventInvoker<Object>(
+ ConversationalScopeRestartTestCase.InitDestroyOnce.class.getMethod("init"));
+ MethodEventInvoker<Object> destroyInvoker =
+ new MethodEventInvoker<Object>(InitDestroyOnce.class.getMethod("destroy"));
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInitInvoker(initInvoker);
+ configuration.setDestroyInvoker(destroyInvoker);
+ Constructor<InitDestroyOnce> ctr = InitDestroyOnce.class.getConstructor((Class<?>[]) null);
+ configuration.setInstanceFactory(new PojoObjectFactory<InitDestroyOnce>(ctr));
+ configuration.setName("InitDestroy");
+ AtomicComponent component = new SystemAtomicComponentImpl(configuration);
+ component.setScopeContainer(scope);
+ component.start();
+
+ String conversation = "conv";
+ ctx.setIdentifier(Scope.CONVERSATION, conversation);
+ scope.onEvent(new ConversationStart(this, conversation));
+ Object instance = component.getTargetInstance();
+ assertSame(instance, component.getTargetInstance());
+
+ scope.onEvent(new ConversationEnd(this, conversation));
+ scope.stop();
+ component.stop();
+
+ scope.start();
+ scope.onEvent(new ConversationStart(this, conversation));
+ component.start();
+ //assertNotSame(instance, context.getServiceInstance());
+ scope.onEvent(new ConversationEnd(this, conversation));
+ scope.stop();
+ component.stop();
+ }
+
+ public static class InitDestroyOnce {
+
+ private boolean initialized;
+ private boolean destroyed;
+
+ public InitDestroyOnce() {
+ }
+
+ public void init() {
+ if (!initialized) {
+ initialized = true;
+ } else {
+ fail("Scope did not clean up properly - Init called more than once");
+ }
+ }
+
+ public void destroy() {
+ if (!destroyed) {
+ destroyed = true;
+ } else {
+ fail("Scope did not clean up properly - Destroyed called more than once");
+ }
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/DependencyLifecycleTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/DependencyLifecycleTestCase.java
new file mode 100644
index 0000000000..4a2497a725
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/DependencyLifecycleTestCase.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.component.event.CompositeStart;
+import org.apache.tuscany.core.component.event.CompositeStop;
+import org.apache.tuscany.core.component.event.HttpSessionEnd;
+import org.apache.tuscany.core.component.event.RequestEnd;
+import org.apache.tuscany.core.component.event.RequestStart;
+import org.apache.tuscany.core.mock.component.OrderedDependentPojo;
+import org.apache.tuscany.core.mock.component.OrderedDependentPojoImpl;
+import org.apache.tuscany.core.mock.component.OrderedInitPojo;
+import org.apache.tuscany.core.mock.component.OrderedInitPojoImpl;
+
+/**
+ * Tests dependencies are initalized and destroyed in the proper order (i.e. LIFO)
+ *
+ * @version $Rev$ $Date$
+ */
+public class DependencyLifecycleTestCase extends TestCase {
+
+ public void testInitDestroyOrderCompositeScope() throws Exception {
+ CompositeScopeContainer scopeCtx = new CompositeScopeContainer(null);
+ scopeCtx.start();
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source",
+ OrderedDependentPojoImpl.class,
+ scopeCtx,
+ "target",
+ OrderedInitPojoImpl.class,
+ scopeCtx);
+ for (AtomicComponent component : contexts.values()) {
+ scopeCtx.register(component);
+ }
+ AtomicComponent sourceComponent = contexts.get("source");
+ AtomicComponent targetComponent = contexts.get("target");
+ scopeCtx.register(sourceComponent);
+ scopeCtx.register(targetComponent);
+ scopeCtx.onEvent(new CompositeStart(this, null));
+ OrderedDependentPojo source = (OrderedDependentPojo) scopeCtx.getInstance(sourceComponent);
+ OrderedInitPojo target = (OrderedInitPojo) scopeCtx.getInstance(targetComponent);
+ assertNotNull(source.getPojo());
+ assertNotNull(target);
+ assertEquals(2, source.getNumberInstantiated());
+ scopeCtx.onEvent(new CompositeStop(this, null));
+ assertEquals(0, source.getNumberInstantiated());
+ scopeCtx.stop();
+ }
+
+ public void testInitDestroyOrderAfterStartCompositeScope() throws Exception {
+ CompositeScopeContainer scopeCtx = new CompositeScopeContainer(null);
+ scopeCtx.start();
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source",
+ OrderedDependentPojoImpl.class,
+ scopeCtx,
+ "target",
+ OrderedInitPojoImpl.class,
+ scopeCtx);
+ AtomicComponent sourceComponent = contexts.get("source");
+ AtomicComponent targetComponent = contexts.get("target");
+ scopeCtx.onEvent(new CompositeStart(this, null));
+ scopeCtx.register(sourceComponent);
+ scopeCtx.register(targetComponent);
+ OrderedDependentPojo source = (OrderedDependentPojo) scopeCtx.getInstance(sourceComponent);
+ OrderedInitPojo target = (OrderedInitPojo) scopeCtx.getInstance(targetComponent);
+ assertNotNull(source.getPojo());
+ assertNotNull(target);
+ assertEquals(2, source.getNumberInstantiated());
+ scopeCtx.onEvent(new CompositeStop(this, null));
+ assertEquals(0, source.getNumberInstantiated());
+ scopeCtx.stop();
+ }
+
+
+ public void testInitDestroyOrderSessionScope() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ HttpSessionScopeContainer scopeCtx = new HttpSessionScopeContainer(ctx, null);
+ scopeCtx.start();
+ Object session = new Object();
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source",
+ OrderedDependentPojoImpl.class,
+ scopeCtx,
+ "target",
+ OrderedInitPojoImpl.class,
+ scopeCtx);
+ AtomicComponent sourceComponent = contexts.get("source");
+ AtomicComponent targetComponent = contexts.get("target");
+ scopeCtx.register(sourceComponent);
+ scopeCtx.register(targetComponent);
+ ctx.setIdentifier(Scope.SESSION, session);
+ OrderedDependentPojo source = (OrderedDependentPojo) scopeCtx.getInstance(sourceComponent);
+ assertNotNull(source.getPojo());
+ assertEquals(2, source.getNumberInstantiated());
+ scopeCtx.onEvent(new HttpSessionEnd(this, session));
+ assertEquals(0, source.getNumberInstantiated());
+ scopeCtx.stop();
+ }
+
+
+ public void testInitDestroyOrderAfterStartSessionScope() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ HttpSessionScopeContainer scopeCtx = new HttpSessionScopeContainer(ctx, null);
+ scopeCtx.start();
+ Object session = new Object();
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source",
+ OrderedDependentPojoImpl.class,
+ scopeCtx,
+ "target",
+ OrderedInitPojoImpl.class,
+ scopeCtx);
+ AtomicComponent sourceComponent = contexts.get("source");
+ AtomicComponent targetComponent = contexts.get("target");
+ ctx.setIdentifier(Scope.SESSION, session);
+ scopeCtx.register(sourceComponent);
+ scopeCtx.register(targetComponent);
+ OrderedDependentPojo source = (OrderedDependentPojo) scopeCtx.getInstance(sourceComponent);
+ assertNotNull(source.getPojo());
+ assertEquals(2, source.getNumberInstantiated());
+ scopeCtx.onEvent(new HttpSessionEnd(this, session));
+ assertEquals(0, source.getNumberInstantiated());
+ scopeCtx.stop();
+ }
+
+ public void testInitDestroyOrderRequestScope() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ RequestScopeContainer scopeCtx = new RequestScopeContainer(ctx, null);
+ scopeCtx.start();
+ scopeCtx.onEvent(new RequestStart(this));
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source",
+ OrderedDependentPojoImpl.class,
+ scopeCtx,
+ "target",
+ OrderedInitPojoImpl.class,
+ scopeCtx);
+ AtomicComponent sourceComponent = contexts.get("source");
+ AtomicComponent targetComponent = contexts.get("target");
+ scopeCtx.register(sourceComponent);
+ scopeCtx.register(targetComponent);
+ OrderedDependentPojo source = (OrderedDependentPojo) scopeCtx.getInstance(sourceComponent);
+ assertNotNull(source.getPojo());
+ assertEquals(2, source.getNumberInstantiated());
+ scopeCtx.onEvent(new RequestEnd(this));
+ assertEquals(0, source.getNumberInstantiated());
+ scopeCtx.stop();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeInitDestroyErrorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeInitDestroyErrorTestCase.java
new file mode 100644
index 0000000000..7aa2f9a120
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeInitDestroyErrorTestCase.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.component.event.HttpSessionEnd;
+import org.apache.tuscany.core.component.event.HttpSessionStart;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class HttpSessionScopeInitDestroyErrorTestCase extends TestCase {
+
+ public void testDestroyErrorMonitor() throws Exception {
+ ScopeContainerMonitor monitor;
+ monitor = EasyMock.createMock(ScopeContainerMonitor.class);
+ monitor.destructionError(EasyMock.isA(TargetDestructionException.class));
+ EasyMock.replay(monitor);
+ WorkContext workContext = new WorkContextImpl();
+ HttpSessionScopeContainer scope = new HttpSessionScopeContainer(workContext, monitor);
+ scope.start();
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ component.addListener(EasyMock.isA(RuntimeEventListener.class));
+ EasyMock.expect(component.getName()).andReturn("foo").atLeastOnce();
+ EasyMock.expect(component.createInstance()).andReturn(new Object());
+ EasyMock.expect(component.isEagerInit()).andReturn(true);
+ component.init(EasyMock.isA(Object.class));
+ component.destroy(EasyMock.isA(Object.class));
+ EasyMock.expectLastCall().andThrow(new TargetDestructionException("", ""));
+ EasyMock.replay(component);
+ scope.register(component);
+ Object id = new Object();
+ scope.onEvent(new HttpSessionStart(this, id));
+ workContext.setIdentifier(Scope.SESSION, id);
+ scope.getInstance(component);
+ scope.onEvent(new HttpSessionEnd(this, id));
+ EasyMock.verify(monitor);
+ }
+
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeInstanceLifecycleTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeInstanceLifecycleTestCase.java
new file mode 100644
index 0000000000..29d6d54450
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeInstanceLifecycleTestCase.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.TargetException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.component.event.HttpSessionEnd;
+import org.apache.tuscany.core.component.event.HttpSessionStart;
+import org.apache.tuscany.core.mock.component.OrderedInitPojo;
+import org.apache.tuscany.core.mock.component.OrderedInitPojoImpl;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+
+/**
+ * Lifecycle unit tests for the composite scope container
+ *
+ * @version $Rev$ $Date$
+ */
+public class HttpSessionScopeInstanceLifecycleTestCase extends TestCase {
+
+ public void testInitDestroy() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ HttpSessionScopeContainer scope = new HttpSessionScopeContainer(ctx, null);
+ scope.start();
+ Foo comp = new Foo();
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.createInstance()).andReturn(comp);
+ component.addListener(EasyMock.isA(RuntimeEventListener.class));
+ component.init(EasyMock.eq(comp));
+ component.destroy(EasyMock.eq(comp));
+ EasyMock.replay(component);
+ scope.register(component);
+ Object session = new Object();
+ ctx.setIdentifier(Scope.SESSION, session);
+ scope.onEvent(new HttpSessionStart(this, session));
+ assertNotNull(scope.getInstance(component));
+ // expire
+ scope.onEvent(new HttpSessionEnd(this, session));
+ scope.stop();
+ EasyMock.verify(component);
+ scope.stop();
+ }
+
+ public void testDestroyOrder() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ HttpSessionScopeContainer scope = new HttpSessionScopeContainer(ctx, null);
+ scope.start();
+
+ AtomicComponent oneComponent = createComponent();
+ scope.register(oneComponent);
+ AtomicComponent twoComponent = createComponent();
+ scope.register(twoComponent);
+ AtomicComponent threeComponent = createComponent();
+ scope.register(threeComponent);
+
+ Object session = new Object();
+ ctx.setIdentifier(Scope.SESSION, session);
+ scope.onEvent(new HttpSessionStart(this, session));
+ OrderedInitPojo one = (OrderedInitPojo) scope.getInstance(oneComponent);
+ assertNotNull(one);
+ assertEquals(1, one.getNumberInstantiated());
+ assertEquals(1, one.getInitOrder());
+
+ OrderedInitPojo two = (OrderedInitPojo) scope.getInstance(twoComponent);
+ assertNotNull(two);
+ assertEquals(2, two.getNumberInstantiated());
+ assertEquals(2, two.getInitOrder());
+
+ OrderedInitPojo three = (OrderedInitPojo) scope.getInstance(threeComponent);
+ assertNotNull(three);
+ assertEquals(3, three.getNumberInstantiated());
+ assertEquals(3, three.getInitOrder());
+
+ scope.onEvent(new HttpSessionEnd(this, session));
+ assertEquals(0, one.getNumberInstantiated());
+ scope.stop();
+ EasyMock.verify(oneComponent);
+ EasyMock.verify(twoComponent);
+ EasyMock.verify(threeComponent);
+ }
+
+ @SuppressWarnings("unchecked")
+ private AtomicComponent createComponent() throws TargetException {
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.createInstance()).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return new OrderedInitPojoImpl();
+ }
+ });
+ component.addListener(EasyMock.isA(RuntimeEventListener.class));
+ component.init(EasyMock.isA(OrderedInitPojoImpl.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ OrderedInitPojoImpl pojo = (OrderedInitPojoImpl) EasyMock.getCurrentArguments()[0];
+ pojo.init();
+ return null;
+ }
+ });
+ component.destroy(EasyMock.isA(OrderedInitPojoImpl.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ OrderedInitPojoImpl pojo = (OrderedInitPojoImpl) EasyMock.getCurrentArguments()[0];
+ pojo.destroy();
+ return null;
+ }
+ });
+ EasyMock.replay(component);
+ return component;
+ }
+
+ private class Foo {
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeRestartTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeRestartTestCase.java
new file mode 100644
index 0000000000..eff0eb6d3a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/HttpSessionScopeRestartTestCase.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import java.lang.reflect.Constructor;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.component.event.HttpSessionEnd;
+import org.apache.tuscany.core.component.event.HttpSessionStart;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl;
+import org.apache.tuscany.core.injection.MethodEventInvoker;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+
+/**
+ * Verifies the scope container properly disposes resources and canbe restarted
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class HttpSessionScopeRestartTestCase extends TestCase {
+
+ public void testRestart() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ HttpSessionScopeContainer scope = new HttpSessionScopeContainer(ctx, null);
+ scope.start();
+ MethodEventInvoker<Object> initInvoker = new MethodEventInvoker<Object>(
+ HttpSessionScopeRestartTestCase.InitDestroyOnce.class.getMethod("init"));
+ MethodEventInvoker<Object> destroyInvoker =
+ new MethodEventInvoker<Object>(InitDestroyOnce.class.getMethod("destroy"));
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInitInvoker(initInvoker);
+ configuration.setDestroyInvoker(destroyInvoker);
+ Constructor<InitDestroyOnce> ctr = InitDestroyOnce.class.getConstructor((Class<?>[]) null);
+ configuration.setInstanceFactory(new PojoObjectFactory<InitDestroyOnce>(ctr));
+ configuration.setName("InitDestroy");
+ AtomicComponent component = new SystemAtomicComponentImpl(configuration);
+ component.setScopeContainer(scope);
+ component.start();
+
+ Object session = new Object();
+ ctx.setIdentifier(Scope.SESSION, session);
+ scope.onEvent(new HttpSessionStart(this, session));
+ Object instance = component.getTargetInstance();
+ assertSame(instance, component.getTargetInstance());
+
+ scope.onEvent(new HttpSessionEnd(this, session));
+ scope.stop();
+ component.stop();
+
+ scope.start();
+ scope.onEvent(new HttpSessionStart(this, session));
+ component.start();
+ assertNotSame(instance, component.getTargetInstance());
+ scope.onEvent(new HttpSessionEnd(this, session));
+ scope.stop();
+ component.stop();
+ }
+
+ public static class InitDestroyOnce {
+
+ private boolean initialized;
+ private boolean destroyed;
+
+ public InitDestroyOnce() {
+ }
+
+ public void init() {
+ if (!initialized) {
+ initialized = true;
+ } else {
+ fail("Scope did not clean up properly - Init called more than once");
+ }
+ }
+
+ public void destroy() {
+ if (!destroyed) {
+ destroyed = true;
+ } else {
+ fail("Scope did not clean up properly - Destroyed called more than once");
+ }
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/InstanceWrapperTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/InstanceWrapperTestCase.java
new file mode 100644
index 0000000000..5600987d8b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/InstanceWrapperTestCase.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class InstanceWrapperTestCase extends TestCase {
+
+ public void testExceptionInit() throws Exception {
+ AtomicComponent component = getComponent();
+ InstanceWrapper wrapper = new InstanceWrapperImpl(component, new Object());
+ try {
+ wrapper.start();
+ fail();
+ } catch (SomeException e) {
+ // expected
+ }
+ assertFalse(wrapper.isStarted());
+ EasyMock.verify(component);
+ }
+
+ public void testNonStart() throws Exception {
+ AtomicComponent comp = EasyMock.createNiceMock(AtomicComponent.class); // class-level one has an expects
+ InstanceWrapper wrapper = new InstanceWrapperImpl(comp, new Object());
+ try {
+ wrapper.getInstance();
+ fail();
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ }
+
+ private AtomicComponent getComponent() throws Exception {
+ // do not use setUp() since we do not need this in all testcases
+ AtomicComponent comp = EasyMock.createMock(AtomicComponent.class);
+ comp.init(EasyMock.isA(Object.class));
+ EasyMock.expectLastCall().andThrow(new SomeException());
+ EasyMock.replay(comp);
+ return comp;
+ }
+
+ private class SomeException extends RuntimeException {
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/MockFactory.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/MockFactory.java
new file mode 100644
index 0000000000..db947e0d66
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/MockFactory.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.EagerInit;
+import org.osoa.sca.annotations.Init;
+
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl;
+import org.apache.tuscany.core.injection.MethodEventInvoker;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.wire.InboundWireImpl;
+import org.apache.tuscany.core.wire.OutboundWireImpl;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public final class MockFactory {
+
+ private MockFactory() {
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Map<String, AtomicComponent> createWiredComponents(String source,
+ Class<?> sourceClass,
+ ScopeContainer sourceScopeContainer,
+ String target,
+ Class<?> targetClass,
+ ScopeContainer targetScopeContainer)
+ throws NoSuchMethodException {
+
+ Map<String, AtomicComponent> components = new HashMap<String, AtomicComponent>();
+ AtomicComponent targetComponent = createAtomicComponent(target, targetScopeContainer, targetClass);
+ PojoConfiguration sourceConfig = new PojoConfiguration();
+ sourceConfig.setInstanceFactory(new PojoObjectFactory(sourceClass.getConstructor()));
+
+ //create target wire
+ Method[] sourceMethods = sourceClass.getMethods();
+ Class[] interfaces = targetClass.getInterfaces();
+ EagerInit eager = targetClass.getAnnotation(EagerInit.class);
+ if (eager != null) {
+ sourceConfig.setInitLevel(50);
+ }
+
+ Method setter = null;
+ for (Class interfaze : interfaces) {
+
+ for (Method method : sourceMethods) {
+ if (method.getParameterTypes().length == 1) {
+ if (interfaze.isAssignableFrom(method.getParameterTypes()[0])) {
+ setter = method;
+ }
+ }
+ if (method.getAnnotation(Init.class) != null) {
+ sourceConfig.setInitInvoker(new MethodEventInvoker<Object>(method));
+
+ } else if (method.getAnnotation(Destroy.class) != null) {
+ sourceConfig.setDestroyInvoker(new MethodEventInvoker<Object>(method));
+ }
+ }
+
+ }
+ if (setter == null) {
+ throw new IllegalArgumentException("No setter found on source for target");
+ }
+
+ sourceConfig.addReferenceSite(setter.getName(), setter);
+ sourceConfig.setName(source);
+ AtomicComponent sourceComponent = new SystemAtomicComponentImpl(sourceConfig);
+ sourceComponent.setScopeContainer(sourceScopeContainer);
+ QualifiedName targetName = new QualifiedName(target);
+ OutboundWire wire = new OutboundWireImpl();
+ wire.setReferenceName(setter.getName());
+ wire.setServiceContract(new JavaServiceContract(targetClass));
+ InboundWire inboundWire = new InboundWireImpl();
+ inboundWire.setContainer(targetComponent);
+ inboundWire.setServiceContract(new JavaServiceContract(targetClass));
+ inboundWire.setServiceName(targetName.getPortName());
+ wire.setTargetWire(inboundWire);
+ sourceComponent.addOutboundWire(wire);
+ components.put(source, sourceComponent);
+ components.put(target, targetComponent);
+ return components;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static AtomicComponent createAtomicComponent(String name, ScopeContainer container, Class<?> clazz)
+ throws NoSuchMethodException {
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInstanceFactory(new PojoObjectFactory(clazz.getConstructor()));
+ EagerInit eager = clazz.getAnnotation(EagerInit.class);
+ if (eager != null) {
+ configuration.setInitLevel(50);
+ }
+ Method[] methods = clazz.getMethods();
+ for (Method method : methods) {
+ if (method.getAnnotation(Init.class) != null) {
+ configuration.setInitInvoker(new MethodEventInvoker<Object>(method));
+ } else if (method.getAnnotation(Destroy.class) != null) {
+ configuration.setDestroyInvoker(new MethodEventInvoker<Object>(method));
+ }
+ }
+ configuration.setName(name);
+ AtomicComponent component = new SystemAtomicComponentImpl(configuration);
+ component.setScopeContainer(container);
+ return component;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeInitDestroyErrorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeInitDestroyErrorTestCase.java
new file mode 100644
index 0000000000..3f562c9b61
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeInitDestroyErrorTestCase.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.TargetDestructionException;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.component.event.RequestEnd;
+import org.apache.tuscany.core.component.event.RequestStart;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class RequestScopeInitDestroyErrorTestCase extends TestCase {
+
+ public void testDestroyErrorMonitor() throws Exception {
+ ScopeContainerMonitor monitor;
+ monitor = EasyMock.createMock(ScopeContainerMonitor.class);
+ monitor.destructionError(EasyMock.isA(TargetDestructionException.class));
+ EasyMock.replay(monitor);
+ RequestScopeContainer scope = new RequestScopeContainer(new WorkContextImpl(), monitor);
+ scope.start();
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ component.addListener(EasyMock.isA(RuntimeEventListener.class));
+ EasyMock.expect(component.getName()).andReturn("foo").atLeastOnce();
+ EasyMock.expect(component.createInstance()).andReturn(new Object());
+ component.init(EasyMock.isA(Object.class));
+ component.destroy(EasyMock.isA(Object.class));
+ EasyMock.expectLastCall().andThrow(new TargetDestructionException("", ""));
+ EasyMock.replay(component);
+ scope.register(component);
+ scope.onEvent(new RequestStart(this));
+ scope.getInstance(component);
+ scope.onEvent(new RequestEnd(this));
+ EasyMock.verify(monitor);
+ }
+
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeInstanceLifecycleTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeInstanceLifecycleTestCase.java
new file mode 100644
index 0000000000..6601640c3b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeInstanceLifecycleTestCase.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.TargetException;
+import org.apache.tuscany.spi.component.WorkContext;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.component.event.RequestEnd;
+import org.apache.tuscany.core.component.event.RequestStart;
+import org.apache.tuscany.core.mock.component.OrderedInitPojo;
+import org.apache.tuscany.core.mock.component.OrderedInitPojoImpl;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+
+/**
+ * Lifecycle unit tests for the request scope container
+ *
+ * @version $Rev$ $Date$
+ */
+public class RequestScopeInstanceLifecycleTestCase extends TestCase {
+
+ public void testInitDestroy() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ RequestScopeContainer scope = new RequestScopeContainer(ctx, null);
+ scope.start();
+ Foo comp = new Foo();
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.createInstance()).andReturn(comp);
+ component.init(EasyMock.eq(comp));
+ component.destroy(EasyMock.eq(comp));
+ EasyMock.replay(component);
+ scope.register(component);
+ scope.onEvent(new RequestStart(this));
+ assertNotNull(scope.getInstance(component));
+ // expire
+ scope.onEvent(new RequestEnd(this));
+ scope.stop();
+ EasyMock.verify(component);
+ scope.stop();
+ }
+
+ public void testDestroyOrder() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ RequestScopeContainer scope = new RequestScopeContainer(ctx, null);
+ scope.start();
+
+ AtomicComponent oneComponent = createComponent();
+ scope.register(oneComponent);
+ AtomicComponent twoComponent = createComponent();
+ scope.register(twoComponent);
+ AtomicComponent threeComponent = createComponent();
+ scope.register(threeComponent);
+
+ scope.onEvent(new RequestStart(this));
+ OrderedInitPojo one = (OrderedInitPojo) scope.getInstance(oneComponent);
+ assertNotNull(one);
+ assertEquals(1, one.getNumberInstantiated());
+ assertEquals(1, one.getInitOrder());
+
+ OrderedInitPojo two = (OrderedInitPojo) scope.getInstance(twoComponent);
+ assertNotNull(two);
+ assertEquals(2, two.getNumberInstantiated());
+ assertEquals(2, two.getInitOrder());
+
+ OrderedInitPojo three = (OrderedInitPojo) scope.getInstance(threeComponent);
+ assertNotNull(three);
+ assertEquals(3, three.getNumberInstantiated());
+ assertEquals(3, three.getInitOrder());
+
+ scope.onEvent(new RequestEnd(this));
+ assertEquals(0, one.getNumberInstantiated());
+ scope.stop();
+ EasyMock.verify(oneComponent);
+ EasyMock.verify(twoComponent);
+ EasyMock.verify(threeComponent);
+ }
+
+ @SuppressWarnings("unchecked")
+ private AtomicComponent createComponent() throws TargetException {
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.createInstance()).andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return new OrderedInitPojoImpl();
+ }
+ });
+ component.init(EasyMock.isA(OrderedInitPojoImpl.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ OrderedInitPojoImpl pojo = (OrderedInitPojoImpl) EasyMock.getCurrentArguments()[0];
+ pojo.init();
+ return null;
+ }
+ });
+ component.destroy(EasyMock.isA(OrderedInitPojoImpl.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ OrderedInitPojoImpl pojo = (OrderedInitPojoImpl) EasyMock.getCurrentArguments()[0];
+ pojo.destroy();
+ return null;
+ }
+ });
+ EasyMock.replay(component);
+ return component;
+ }
+
+ private class Foo {
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeRestartTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeRestartTestCase.java
new file mode 100644
index 0000000000..335d8c621d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/RequestScopeRestartTestCase.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import java.lang.reflect.Constructor;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.WorkContext;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.component.event.RequestEnd;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.system.component.SystemAtomicComponentImpl;
+import org.apache.tuscany.core.injection.MethodEventInvoker;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+
+/**
+ * Verifies the scope container properly disposes resources and canbe restarted
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class RequestScopeRestartTestCase extends TestCase {
+
+ public void testRestart() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ RequestScopeContainer scope = new RequestScopeContainer(ctx, null);
+ scope.start();
+ MethodEventInvoker<Object> initInvoker =
+ new MethodEventInvoker<Object>(InitDestroyOnce.class.getMethod("init"));
+ MethodEventInvoker<Object> destroyInvoker =
+ new MethodEventInvoker<Object>(InitDestroyOnce.class.getMethod("destroy"));
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInitInvoker(initInvoker);
+ configuration.setDestroyInvoker(destroyInvoker);
+ Constructor<InitDestroyOnce> ctr = InitDestroyOnce.class.getConstructor((Class<?>[]) null);
+ configuration.setInstanceFactory(new PojoObjectFactory<InitDestroyOnce>(ctr));
+ configuration.setName("InitDestroy");
+ AtomicComponent component = new SystemAtomicComponentImpl(configuration);
+ component.setScopeContainer(scope);
+ component.start();
+
+ Object instance = component.getTargetInstance();
+ assertSame(instance, component.getTargetInstance());
+
+ scope.onEvent(new RequestEnd(this));
+ scope.stop();
+ component.stop();
+
+ scope.start();
+ component.start();
+ assertNotSame(instance, component.getTargetInstance());
+ scope.onEvent(new RequestEnd(this));
+ scope.stop();
+ component.stop();
+ }
+
+ public static class InitDestroyOnce {
+
+ private boolean initialized;
+ private boolean destroyed;
+
+ public InitDestroyOnce() {
+ }
+
+ public void init() {
+ if (!initialized) {
+ initialized = true;
+ } else {
+ fail("Scope did not clean up properly - Init called more than once");
+ }
+ }
+
+ public void destroy() {
+ if (!destroyed) {
+ destroyed = true;
+ } else {
+ fail("Scope did not clean up properly - Destroyed called more than once");
+ }
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ScopeRegistryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ScopeRegistryTestCase.java
new file mode 100644
index 0000000000..e1380eb4c0
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/ScopeRegistryTestCase.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+
+/**
+ * Verifies retrieval of standard scope contexts from the default scope registry
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class ScopeRegistryTestCase extends TestCase {
+ public void testScopeContextCreation() throws Exception {
+ WorkContext context = new WorkContextImpl();
+ ScopeRegistry scopeRegistry = new ScopeRegistryImpl();
+ scopeRegistry.registerFactory(Scope.REQUEST, new RequestScopeObjectFactory(context, null));
+ HttpSessionScopeObjectFactory sessionFactory = new HttpSessionScopeObjectFactory(scopeRegistry, context, null);
+ scopeRegistry.registerFactory(Scope.SESSION, sessionFactory);
+ scopeRegistry.registerFactory(Scope.CONVERSATION,
+ new ConversationalScopeObjectFactory(scopeRegistry, context, null, null));
+ ScopeContainer request = scopeRegistry.getScopeContainer(Scope.REQUEST);
+ assertTrue(request instanceof RequestScopeContainer);
+ assertSame(request, scopeRegistry.getScopeContainer(Scope.REQUEST));
+ ScopeContainer session = scopeRegistry.getScopeContainer(Scope.SESSION);
+ assertTrue(session instanceof HttpSessionScopeContainer);
+ assertSame(session, scopeRegistry.getScopeContainer(Scope.SESSION));
+ assertNotSame(request, session);
+ ScopeContainer conversation = scopeRegistry.getScopeContainer(Scope.CONVERSATION);
+ assertTrue(conversation instanceof ConversationalScopeContainer);
+ assertSame(conversation, scopeRegistry.getScopeContainer(Scope.CONVERSATION));
+ assertNotSame(session, conversation);
+ }
+
+ public void testDeregisterFactory() throws Exception {
+ WorkContext context = new WorkContextImpl();
+ ScopeRegistry scopeRegistry = new ScopeRegistryImpl();
+ RequestScopeObjectFactory factory = new RequestScopeObjectFactory(context, null);
+ scopeRegistry.registerFactory(Scope.REQUEST, factory);
+ scopeRegistry.deregisterFactory(Scope.REQUEST);
+ assertNull(scopeRegistry.getScopeContainer(Scope.REQUEST));
+ ConversationalScopeObjectFactory convFactory =
+ new ConversationalScopeObjectFactory(scopeRegistry, context, null, null);
+ scopeRegistry.registerFactory(Scope.CONVERSATION, convFactory);
+ scopeRegistry.deregisterFactory(Scope.CONVERSATION);
+ assertNull(scopeRegistry.getScopeContainer(Scope.CONVERSATION));
+ }
+
+ public void testScopeNotRegistered() throws Exception {
+ WorkContext workContext = new WorkContextImpl();
+ ScopeRegistry scopeRegistry = new ScopeRegistryImpl();
+ assertNull(scopeRegistry.getScopeContainer(Scope.REQUEST));
+ assertNull(scopeRegistry.getScopeContainer(Scope.SESSION));
+ assertNull(scopeRegistry.getScopeContainer(Scope.CONVERSATION));
+ assertNull(scopeRegistry.getScopeContainer(Scope.STATELESS));
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/StatelessScopeContainerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/StatelessScopeContainerTestCase.java
new file mode 100644
index 0000000000..89cd9b51d7
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/StatelessScopeContainerTestCase.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class StatelessScopeContainerTestCase extends TestCase {
+
+ public void testBadStopWithoutStart() throws Exception {
+ StatelessScopeContainer container = new StatelessScopeContainer(null, null);
+ try {
+ container.stop();
+ fail();
+ } catch (IllegalStateException e) {
+ //expected
+ }
+ }
+
+ public void testBadDoubleStart() throws Exception {
+ StatelessScopeContainer container = new StatelessScopeContainer(null, null);
+ try {
+ container.start();
+ container.start();
+ fail();
+ } catch (IllegalStateException e) {
+ //expected
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactoryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactoryTestCase.java
new file mode 100644
index 0000000000..0902b9d78c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/StatelessScopeObjectFactoryTestCase.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class StatelessScopeObjectFactoryTestCase extends TestCase {
+
+ public void testCreation() {
+ ScopeRegistry registry = EasyMock.createMock(ScopeRegistry.class);
+ registry.registerFactory(EasyMock.isA(Scope.class), EasyMock.isA(StatelessScopeObjectFactory.class));
+ assertNotNull(new StatelessScopeObjectFactory(registry, null, null).getInstance());
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/WorkContextTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/WorkContextTestCase.java
new file mode 100644
index 0000000000..8a9fdf4ac4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/component/scope/WorkContextTestCase.java
@@ -0,0 +1,212 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.component.scope;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.WorkContext;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WorkContextTestCase extends TestCase {
+
+ public void testRemoteComponent() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ CompositeComponent component = EasyMock.createNiceMock(CompositeComponent.class);
+ CompositeComponent component2 = EasyMock.createNiceMock(CompositeComponent.class);
+ ctx.setRemoteComponent(component);
+ assertEquals(component, ctx.getRemoteComponent());
+ ctx.setRemoteComponent(component2);
+ assertEquals(component2, ctx.getRemoteComponent());
+ }
+
+ public void testNonSetRemoteComponent() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ assertNull(ctx.getRemoteComponent());
+ }
+
+ public void testSetCurrentAtomicComponent() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class);
+ AtomicComponent component2 = EasyMock.createNiceMock(AtomicComponent.class);
+ ctx.setCurrentAtomicComponent(component);
+ assertEquals(component, ctx.getCurrentAtomicComponent());
+ ctx.setCurrentAtomicComponent(component2);
+ assertEquals(component2, ctx.getCurrentAtomicComponent());
+ }
+
+ public void testNonSetCurrentAtomicComponent() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ assertNull(ctx.getCurrentAtomicComponent());
+ }
+
+ public void testIndentifier() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ Object id = new Object();
+ ctx.setIdentifier(this, id);
+ assertEquals(id, ctx.getIdentifier(this));
+ }
+
+ public void testClearIndentifier() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ Object id = new Object();
+ ctx.setIdentifier(this, id);
+ ctx.clearIdentifier(this);
+ assertNull(ctx.getIdentifier(this));
+ }
+
+ public void testClearIndentifiers() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ Object id = new Object();
+ Object id2 = new Object();
+ ctx.setIdentifier(id, id);
+ ctx.setIdentifier(id2, id2);
+ ctx.clearIdentifiers();
+ assertNull(ctx.getIdentifier(id));
+ assertNull(ctx.getIdentifier(id2));
+ }
+
+ public void testClearNonExistentIndentifier() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ ctx.clearIdentifier(this);
+ }
+
+ public void testNullIndentifier() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ Object id = new Object();
+ ctx.setIdentifier(this, id);
+ ctx.clearIdentifier(null);
+ assertEquals(id, ctx.getIdentifier(this));
+ }
+
+ public void testNoIndentifier() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ assertNull(ctx.getIdentifier(this));
+ }
+
+ public void testSetGetCorrelationId() {
+ WorkContext context = new WorkContextImpl();
+ context.setCurrentCorrelationId("msg-005");
+ assertEquals(context.getCurrentCorrelationId(), "msg-005");
+ context.setCurrentCorrelationId(null);
+ assertNull(context.getCurrentCorrelationId());
+ }
+
+ public void testSetGetCorrelationIdInNewThread() throws InterruptedException {
+ WorkContext context = new WorkContextImpl();
+ context.setCurrentCorrelationId("msg-005");
+ assertEquals(context.getCurrentCorrelationId(), "msg-005");
+ context.setIdentifier("TX", "002");
+ ChildThread t = new ChildThread(context);
+ t.start();
+ t.join();
+ assertTrue(t.passed);
+ context.setCurrentCorrelationId(null);
+ assertNull(context.getCurrentCorrelationId());
+ }
+
+ public void testCurrentAtomicComponentDoesNotPropagateToChildThread() throws InterruptedException {
+ // NOTE should behaviour be to propagate?
+ WorkContext context = new WorkContextImpl();
+ context.setCurrentAtomicComponent(EasyMock.createNiceMock(AtomicComponent.class));
+ TestCurrentAtomicComponentChildThread t = new TestCurrentAtomicComponentChildThread(context);
+ t.start();
+ t.join();
+ assertTrue(t.passed);
+ context.setCurrentAtomicComponent(null);
+ assertNull(context.getCurrentAtomicComponent());
+ }
+
+ public void testCurrentRemoteComponentDoesNotPropagateToChildThread() throws InterruptedException {
+ // NOTE should behaviour be to propagate?
+ WorkContext context = new WorkContextImpl();
+ context.setRemoteComponent(EasyMock.createNiceMock(CompositeComponent.class));
+ TestCurrentRemoteComponentChildThread t = new TestCurrentRemoteComponentChildThread(context);
+ t.start();
+ t.join();
+ assertTrue(t.passed);
+ context.setRemoteComponent(null);
+ assertNull(context.getRemoteComponent());
+ }
+
+ private static final class ChildThread extends Thread {
+ private WorkContext context;
+ private boolean passed = true;
+
+ private ChildThread(WorkContext context) {
+ this.context = context;
+ }
+
+ @Override
+ public void run() {
+ try {
+ assertNull(context.getCurrentCorrelationId());
+ assertEquals("002", context.getIdentifier("TX"));
+ } catch (AssertionError e) {
+ passed = false;
+ }
+ }
+
+ }
+
+ private static final class TestCurrentAtomicComponentChildThread extends Thread {
+ private WorkContext context;
+ private boolean passed = true;
+
+ private TestCurrentAtomicComponentChildThread(WorkContext context) {
+ this.context = context;
+ }
+
+ @Override
+ public void run() {
+ try {
+ assertNull(context.getCurrentAtomicComponent());
+ } catch (AssertionError e) {
+ passed = false;
+ }
+ }
+
+ }
+
+ private static final class TestCurrentRemoteComponentChildThread extends Thread {
+ private WorkContext context;
+ private boolean passed = true;
+
+ private TestCurrentRemoteComponentChildThread(WorkContext context) {
+ this.context = context;
+ }
+
+ @Override
+ public void run() {
+ try {
+ assertNull(context.getRemoteComponent());
+ } catch (AssertionError e) {
+ passed = false;
+ }
+ }
+
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingInterceptorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingInterceptorTestCase.java
new file mode 100644
index 0000000000..ddfb75568d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingInterceptorTestCase.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.databinding.DataBinding;
+import org.apache.tuscany.spi.databinding.Mediator;
+import org.apache.tuscany.spi.model.DataType;
+import org.apache.tuscany.spi.model.Operation;
+import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class DataBindingInterceptorTestCase extends TestCase {
+
+ @SuppressWarnings("unchecked")
+ public final void testInvoke() {
+ DataType<Class> type1 = new DataType<Class>("xml:string", String.class, String.class);
+ List<DataType<Class>> types1 = new ArrayList<DataType<Class>>();
+ types1.add(type1);
+ DataType<List<DataType<Class>>> inputType1 =
+ new DataType<List<DataType<Class>>>("xml:string", Object[].class, types1);
+
+ DataType<Class> type2 = new DataType<Class>("foo", Foo.class, Foo.class);
+ List<DataType<Class>> types2 = new ArrayList<DataType<Class>>();
+ types2.add(type2);
+ DataType<List<DataType<Class>>> inputType2 =
+ new DataType<List<DataType<Class>>>("foo", Object[].class, types2);
+
+ Operation<Class> operation1 =
+ new Operation<Class>("call", inputType1, type1, null, false, "xml:string", NO_CONVERSATION);
+ Operation<Class> operation2 =
+ new Operation<Class>("call", inputType2, type2, null, false, "org.w3c.dom.Node", NO_CONVERSATION);
+
+ DataType<DataType> outputType1 =
+ new DataType<DataType>(DataBinding.IDL_OUTPUT, Object.class, operation1.getOutputType());
+ DataType<DataType> outputType2 =
+ new DataType<DataType>(DataBinding.IDL_OUTPUT, Object.class, operation2.getOutputType());
+
+ OutboundWire outboundWire = EasyMock.createMock(OutboundWire.class);
+ InboundWire inboundWire = EasyMock.createMock(InboundWire.class);
+ CompositeComponent composite = EasyMock.createMock(CompositeComponent.class);
+ Component component = EasyMock.createMock(Component.class);
+ EasyMock.expect(component.getParent()).andReturn(composite).once();
+ EasyMock.expect(outboundWire.getContainer()).andReturn(component);
+ EasyMock.replay(outboundWire, inboundWire, composite, component);
+
+ DataBindingInteceptor interceptor = new DataBindingInteceptor(outboundWire, operation1, operation2);
+ Mediator mediator = createMock(Mediator.class);
+ Object[] source = new Object[]{"<foo>bar</foo>"};
+ Foo foo = new Foo();
+ foo.bar = "bar";
+ Object[] target = new Object[]{foo};
+ expect(mediator.mediate(EasyMock.same(source),
+ EasyMock.same(inputType1),
+ EasyMock.same(inputType2),
+ EasyMock.isA(Map.class))).andReturn(target);
+ // expect(mediator.mediate(target[0], type2,
+ // type1)).andReturn(source[0]);
+ expect(mediator.mediate(EasyMock.same(target[0]),
+ EasyMock.eq(outputType2),
+ EasyMock.eq(outputType1),
+ EasyMock.isA(Map.class))).andReturn(source[0]);
+ replay(mediator);
+ interceptor.setMediator(mediator);
+ Message msg = createMock(Message.class);
+ msg.setBody(EasyMock.anyObject());
+ expectLastCall().anyTimes();
+ expect(msg.getBody()).andReturn(source).once().andReturn(target[0]).once().andReturn(source[0]);
+ expect(msg.isFault()).andReturn(false).once();
+ replay(msg);
+ Interceptor next = createMock(Interceptor.class);
+ expect(next.invoke(msg)).andReturn(msg);
+ replay(next);
+ interceptor.setNext(next);
+ interceptor.invoke(msg);
+ String result = (String) msg.getBody();
+ Assert.assertEquals(source[0], result);
+ EasyMock.verify(mediator, msg, next);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ private static class Foo {
+ private String bar;
+
+ public String getBar() {
+ return bar;
+ }
+
+ public void setBar(String bar) {
+ this.bar = bar;
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingJavaInterfaceProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingJavaInterfaceProcessorTestCase.java
new file mode 100644
index 0000000000..9e181960b4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingJavaInterfaceProcessorTestCase.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION;
+
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.tuscany.api.annotation.DataType;
+import org.apache.tuscany.spi.databinding.DataBindingRegistry;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.Operation;
+import org.osoa.sca.annotations.Remotable;
+import org.w3c.dom.Node;
+
+/**
+ *
+ */
+public class DataBindingJavaInterfaceProcessorTestCase extends TestCase {
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ /**
+ * @throws InvalidServiceContractException
+ */
+ public final void testVisitInterface() throws InvalidServiceContractException {
+ DataBindingRegistry registry = new DataBindingRegistryImpl();
+ DataBindingJavaInterfaceProcessor processor = new DataBindingJavaInterfaceProcessor(registry);
+ JavaServiceContract contract = new JavaServiceContract(MockInterface.class);
+ Map<String, Operation<Type>> operations = new HashMap<String, Operation<Type>>();
+ Operation<Type> operation = new Operation<Type>("call", null, null, null, false, null, NO_CONVERSATION);
+ Operation<Type> operation1 = new Operation<Type>("call1", null, null, null, false, null, NO_CONVERSATION);
+ operations.put("call", operation);
+ operations.put("call1", operation1);
+ contract.setOperations(operations);
+ contract.setRemotable(true);
+ processor.visitInterface(MockInterface.class, null, contract);
+ Assert.assertEquals("org.w3c.dom.Node", contract.getDataBinding());
+ Assert.assertEquals("org.w3c.dom.Node", contract.getOperations().get("call").getDataBinding());
+ Assert.assertEquals("xml:string", contract.getOperations().get("call1").getDataBinding());
+ }
+
+ @DataType(name = "org.w3c.dom.Node")
+ @Remotable
+ public static interface MockInterface {
+ Node call(Node msg);
+
+ @DataType(name = "xml:string")
+ String call1(String msg);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingLoaderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingLoaderTestCase.java
new file mode 100644
index 0000000000..02dd10ee97
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingLoaderTestCase.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.tuscany.spi.loader.InvalidValueException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.model.DataType;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.easymock.EasyMock;
+
+/**
+ * Testcase for DataBindingLoader
+ */
+public class DataBindingLoaderTestCase extends TestCase {
+ private XMLStreamReader reader;
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public final void testLoad() throws LoaderException, XMLStreamException {
+ reader = EasyMock.createMock(XMLStreamReader.class);
+ // EasyMock.expect(reader.getEventType()).andReturn(XMLStreamConstants.START_ELEMENT);
+ EasyMock.expect(reader.hasNext()).andReturn(true).anyTimes();
+ EasyMock.expect(reader.getName()).andReturn(DataTypeLoader.DATA_BINDING);
+ EasyMock.expect(reader.getAttributeValue(null, "name")).andReturn("ABC");
+ EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT);
+ EasyMock.replay(reader);
+
+ ModelObject mo = new DataTypeLoader(null).load(null, null, reader, null);
+ Assert.assertTrue(mo instanceof DataType);
+ Assert.assertEquals("ABC", ((DataType<?>)mo).getDataBinding());
+ EasyMock.verify(reader);
+
+ EasyMock.reset(reader);
+
+ // EasyMock.expect(reader.getEventType()).andReturn(XMLStreamConstants.START_ELEMENT);
+ EasyMock.expect(reader.hasNext()).andReturn(true).anyTimes();
+ EasyMock.expect(reader.getName()).andReturn(DataTypeLoader.DATA_BINDING);
+ EasyMock.expect(reader.getAttributeValue(null, "name")).andReturn(null);
+ EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT);
+ EasyMock.replay(reader);
+ try {
+ mo = new DataTypeLoader(null).load(null, null, reader, null);
+ Assert.fail("InvalidValueException should have been thrown");
+ } catch (InvalidValueException e) {
+ Assert.assertTrue(true);
+ }
+ EasyMock.verify(reader);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingRegistryImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingRegistryImplTestCase.java
new file mode 100644
index 0000000000..3ee5460ac3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingRegistryImplTestCase.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.impl;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+import java.lang.annotation.Annotation;
+
+import javax.xml.stream.XMLStreamReader;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.tuscany.spi.databinding.DataBinding;
+import org.apache.tuscany.spi.databinding.DataBindingRegistry;
+import org.apache.tuscany.spi.model.DataType;
+import org.easymock.EasyMock;
+import org.xml.sax.ContentHandler;
+
+/**
+ *
+ */
+public class DataBindingRegistryImplTestCase extends TestCase {
+ private DataBindingRegistry registry;
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ registry = new DataBindingRegistryImpl();
+ }
+
+ public void testRegistry() {
+ DataBinding db1 = createMock(DataBinding.class);
+ expect(db1.getAliases()).andReturn(new String[] {"db1"}).anyTimes();
+ expect(db1.getName()).andReturn(ContentHandler.class.getName()).anyTimes();
+ DataType<Class> dataType1 = new DataType<Class>(ContentHandler.class, ContentHandler.class);
+ expect(db1.introspect(dataType1, null)).andReturn(true);
+ expect(db1.introspect(EasyMock.not(EasyMock.same(dataType1)), (Annotation[])EasyMock.isNull()))
+ .andReturn(false).anyTimes();
+ replay(db1);
+
+ registry.register(db1);
+
+ DataBinding db2 = createMock(DataBinding.class);
+ expect(db2.getAliases()).andReturn(new String[] {"db2"}).anyTimes();
+ expect(db2.getName()).andReturn(XMLStreamReader.class.getName()).anyTimes();
+ DataType<Class> dataType2 = new DataType<Class>(XMLStreamReader.class, XMLStreamReader.class);
+ expect(db2.introspect(dataType2, null)).andReturn(true);
+ expect(db2.introspect(EasyMock.not(EasyMock.same(dataType2)), (Annotation[])EasyMock.isNull()))
+ .andReturn(false).anyTimes();
+ replay(db2);
+
+ registry.register(db2);
+
+ // Lookup by name
+ String name = db1.getName();
+ DataBinding db3 = registry.getDataBinding(name);
+ assertSame(db1, db3);
+
+ // Look up by alias
+ DataBinding db5 = registry.getDataBinding("db1");
+ assertSame(db1, db5);
+
+ DataType dt = new DataType(ContentHandler.class, null);
+ registry.introspectType(dt, null);
+ assertEquals(dataType1.getLogical(), ContentHandler.class);
+ assertTrue(dt.getDataBinding().equalsIgnoreCase("java.lang.Object"));
+
+ registry.unregister(name);
+ DataBinding db4 = registry.getDataBinding(name);
+ assertNull(db4);
+
+ dt = new DataType(null, String.class, null);
+ registry.introspectType(dt, null);
+ assertEquals("java.lang.Object", dt.getDataBinding());
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingTestCase.java
new file mode 100644
index 0000000000..5abb520b80
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingTestCase.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.impl;
+
+import java.lang.reflect.Method;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.tuscany.api.annotation.DataType;
+
+public class DataBindingTestCase extends TestCase {
+ @SuppressWarnings("unused")
+ public void testDataType() throws Exception {
+ Class<Test> testClass = Test.class;
+ DataType d = testClass.getAnnotation(DataType.class);
+ Assert.assertEquals(d.name(), "sdo");
+
+ Method method = testClass.getMethod("test", new Class[] {Object.class});
+ DataType d2 = method.getAnnotation(DataType.class);
+ Assert.assertEquals(d2.name(), "jaxb");
+ }
+
+ @DataType(name = "sdo")
+ private static interface Test {
+ @DataType(name = "jaxb")
+ Object test(Object object);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessorOptimizationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessorOptimizationTestCase.java
new file mode 100644
index 0000000000..d871978cb4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessorOptimizationTestCase.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.impl;
+
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.databinding.Mediator;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * Verifies that data binding interceptor is not added to invocation chains when the data binding types are not set on
+ * service contracts
+ *
+ * @version $Rev$ $Date$
+ */
+public class DataBindingWirePostProcessorOptimizationTestCase extends TestCase {
+ private DataBindingWirePostProcessor processor;
+ private OutboundInvocationChain outboundChain;
+ private OutboundWire outboundWire;
+ private InboundInvocationChain inboundChain;
+ private InboundWire inboundWire;
+
+ public void testNoInterceptorInterposedOutboundToInbound() {
+ processor.process(outboundWire, inboundWire);
+ EasyMock.verify(outboundChain);
+ EasyMock.verify(inboundChain);
+ EasyMock.verify(outboundWire);
+ EasyMock.verify(inboundWire);
+ }
+
+ public void testNoInterceptorInterposedInboundToOutbound() {
+ processor.process(inboundWire, outboundWire);
+ EasyMock.verify(outboundChain);
+ EasyMock.verify(inboundChain);
+ EasyMock.verify(outboundWire);
+ EasyMock.verify(inboundWire);
+ }
+
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ SCAObject container = EasyMock.createMock(SCAObject.class);
+ EasyMock.expect(container.getName()).andReturn("foo");
+ EasyMock.replay(container);
+
+ Mediator mediator = new MediatorImpl();
+ processor = new DataBindingWirePostProcessor(mediator);
+
+ ServiceContract<Type> contract = new JavaServiceContract(null);
+ Operation<Type> operation = new Operation<Type>("test", null, null, null);
+ operation.setServiceContract(contract);
+ Map<String, Operation<Type>> operations = new HashMap<String, Operation<Type>>();
+ operations.put("test", operation);
+ contract.setOperations(operations);
+ contract.setCallbackOperations(operations);
+
+ inboundChain = EasyMock.createMock(InboundInvocationChain.class);
+ EasyMock.replay(inboundChain);
+ Map<Operation<?>, InboundInvocationChain> inboundChains = new HashMap<Operation<?>, InboundInvocationChain>();
+ inboundChains.put(operation, inboundChain);
+
+ outboundChain = EasyMock.createMock(OutboundInvocationChain.class);
+ EasyMock.replay(outboundChain);
+ Map<Operation<?>, OutboundInvocationChain> outboundChains =
+ new HashMap<Operation<?>, OutboundInvocationChain>();
+ outboundChains.put(operation, outboundChain);
+
+ outboundWire = EasyMock.createMock(OutboundWire.class);
+ EasyMock.expect(outboundWire.getInvocationChains()).andReturn(outboundChains);
+ EasyMock.expect(outboundWire.getServiceContract()).andReturn(contract).anyTimes();
+ EasyMock.expect(outboundWire.getContainer()).andReturn(container).anyTimes();
+ EasyMock.expect(outboundWire.getTargetCallbackInvocationChains()).andReturn(inboundChains).anyTimes();
+ EasyMock.replay(outboundWire);
+
+ inboundWire = EasyMock.createMock(InboundWire.class);
+ EasyMock.expect(inboundWire.getInvocationChains()).andReturn(inboundChains);
+ EasyMock.expect(inboundWire.getContainer()).andReturn(container).anyTimes();
+ EasyMock.expect(inboundWire.getSourceCallbackInvocationChains(EasyMock.eq("foo"))).andReturn(outboundChains)
+ .anyTimes();
+ EasyMock.replay(inboundWire);
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessorTestCase.java
new file mode 100644
index 0000000000..29bf91f2c7
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DataBindingWirePostProcessorTestCase.java
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.w3c.dom.Node;
+
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.databinding.Mediator;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.DataType;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class DataBindingWirePostProcessorTestCase extends TestCase {
+ private DataBindingWirePostProcessor processor;
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ Mediator mediator = new MediatorImpl();
+ this.processor = new DataBindingWirePostProcessor(mediator);
+ }
+
+ public void testProcess1() {
+ InboundWire inboundWire = createMock(InboundWire.class);
+ OutboundWire outboundWire = createMock(OutboundWire.class);
+
+ Component component = createMock(Component.class);
+ CompositeComponent composite = createMock(CompositeComponent.class);
+ expect(component.getParent()).andReturn(composite);
+ expect(inboundWire.getContainer()).andReturn(component);
+ expect(outboundWire.getContainer()).andReturn(component);
+
+ Map<Operation<?>, OutboundInvocationChain> outboundChains =
+ new HashMap<Operation<?>, OutboundInvocationChain>();
+ DataType<Type> type1 = new DataType<Type>(String.class, String.class);
+ List<DataType<Type>> types = new ArrayList<DataType<Type>>();
+ types.add(type1);
+ DataType<List<DataType<Type>>> inputType1 = new DataType<List<DataType<Type>>>(Object[].class, types);
+ DataType<Type> outputType1 = new DataType<Type>(String.class, String.class);
+ Operation<Type> op1 = new Operation<Type>("test", inputType1, outputType1, null);
+ ServiceContract<Type> outboundContract = new JavaServiceContract(null);
+ outboundContract.setDataBinding(String.class.getName());
+ op1.setServiceContract(outboundContract);
+
+ OutboundInvocationChain outboundChain = createMock(OutboundInvocationChain.class);
+ outboundChains.put(op1, outboundChain);
+ expect(outboundWire.getInvocationChains()).andReturn(outboundChains);
+ outboundChain.addInterceptor(EasyMock.anyInt(), (Interceptor) EasyMock.anyObject());
+
+ Map<Operation<?>, InboundInvocationChain> inboundChains =
+ new HashMap<Operation<?>, InboundInvocationChain>();
+ DataType<Type> type2 = new DataType<Type>(Node.class, Node.class);
+ List<DataType<Type>> types2 = new ArrayList<DataType<Type>>();
+ types2.add(type2);
+ DataType<List<DataType<Type>>> inputType2 =
+ new DataType<List<DataType<Type>>>(Object[].class, types2);
+ DataType<Type> outputType2 = new DataType<Type>(String.class, String.class);
+ Operation<Type> op2 = new Operation<Type>("test", inputType2, outputType2, null);
+ ServiceContract<Type> inboundContract = new JavaServiceContract(null);
+ inboundContract.setDataBinding(Node.class.getName());
+ op2.setServiceContract(inboundContract);
+
+ InboundInvocationChain inboundChain = createMock(InboundInvocationChain.class);
+ inboundChains.put(op2, inboundChain);
+ expect(inboundWire.getInvocationChains()).andReturn(inboundChains);
+
+ ServiceContract<Type> contract = new JavaServiceContract();
+ Map<String, Operation<Type>> operations = Collections.emptyMap();
+ contract.setCallbackOperations(operations);
+ expect(outboundWire.getServiceContract()).andReturn(contract);
+
+ EasyMock.replay(composite, component, inboundWire, outboundWire, inboundChain, outboundChain);
+
+ processor.process(outboundWire, inboundWire);
+ }
+
+ public void testProcess2() {
+ InboundWire inboundWire = createMock(InboundWire.class);
+ OutboundWire outboundWire = createMock(OutboundWire.class);
+
+ ReferenceBinding referenceBinding = createMock(ReferenceBinding.class);
+ CompositeComponent composite = createMock(CompositeComponent.class);
+ expect(referenceBinding.getParent()).andReturn(composite);
+ expect(inboundWire.getContainer()).andReturn(referenceBinding).anyTimes();
+ expect(outboundWire.getContainer()).andReturn(referenceBinding).anyTimes();
+
+ Map<Operation<?>, OutboundInvocationChain> outboundChains =
+ new HashMap<Operation<?>, OutboundInvocationChain>();
+ DataType<Type> type1 = new DataType<Type>(String.class, String.class);
+ List<DataType<Type>> types = new ArrayList<DataType<Type>>();
+ types.add(type1);
+ DataType<List<DataType<Type>>> inputType1 = new DataType<List<DataType<Type>>>(Object[].class, types);
+ DataType<Type> outputType1 = new DataType<Type>(String.class, String.class);
+ Operation<Type> op1 = new Operation<Type>("test", inputType1, outputType1, null);
+ ServiceContract<Type> outboundContract = new JavaServiceContract(null);
+ outboundContract.setDataBinding(String.class.getName());
+ op1.setServiceContract(outboundContract);
+
+ OutboundInvocationChain outboundChain = createMock(OutboundInvocationChain.class);
+ outboundChains.put(op1, outboundChain);
+ expect(outboundWire.getInvocationChains()).andReturn(outboundChains).anyTimes();
+ outboundChain.addInterceptor(EasyMock.anyInt(), (Interceptor) EasyMock.anyObject());
+
+ Map<Operation<?>, InboundInvocationChain> inboundChains =
+ new HashMap<Operation<?>, InboundInvocationChain>();
+ DataType<Type> type2 = new DataType<Type>(Node.class, Node.class);
+ List<DataType<Type>> types2 = new ArrayList<DataType<Type>>();
+ types2.add(type2);
+ DataType<List<DataType<Type>>> inputType2 =
+ new DataType<List<DataType<Type>>>(Object[].class, types2);
+ DataType<Type> outputType2 = new DataType<Type>(String.class, String.class);
+ Operation<Type> op2 = new Operation<Type>("test", inputType2, outputType2, null);
+ ServiceContract<Type> inboundContract = new JavaServiceContract(null);
+ inboundContract.setDataBinding(Node.class.getName());
+ op2.setServiceContract(inboundContract);
+
+ InboundInvocationChain inboundChain = createMock(InboundInvocationChain.class);
+ inboundChains.put(op2, inboundChain);
+ expect(inboundWire.getInvocationChains()).andReturn(inboundChains).anyTimes();
+
+ ServiceContract<Type> contract = new JavaServiceContract();
+ Map<String, Operation<Type>> operations = Collections.emptyMap();
+ contract.setCallbackOperations(operations);
+ expect(inboundWire.getServiceContract()).andReturn(contract);
+ expect(inboundChain.getTailInterceptor()).andReturn(null);
+
+ EasyMock.replay(composite, referenceBinding, inboundWire, outboundWire, inboundChain, outboundChain);
+
+ processor.process(inboundWire, outboundWire);
+ }
+
+ public void testProcess3() {
+ InboundWire inboundWire = createMock(InboundWire.class);
+ OutboundWire outboundWire = createMock(OutboundWire.class);
+
+ ServiceBinding serviceBinding = createMock(ServiceBinding.class);
+ CompositeComponent composite = createMock(CompositeComponent.class);
+ expect(serviceBinding.getParent()).andReturn(composite);
+ expect(inboundWire.getContainer()).andReturn(serviceBinding).anyTimes();
+ expect(outboundWire.getContainer()).andReturn(serviceBinding).anyTimes();
+
+ Map<Operation<?>, OutboundInvocationChain> outboundChains =
+ new HashMap<Operation<?>, OutboundInvocationChain>();
+ DataType<Type> type1 = new DataType<Type>(String.class, String.class);
+ List<DataType<Type>> types = new ArrayList<DataType<Type>>();
+ types.add(type1);
+ DataType<List<DataType<Type>>> inputType1 = new DataType<List<DataType<Type>>>(Object[].class, types);
+ DataType<Type> outputType1 = new DataType<Type>(String.class, String.class);
+ Operation<Type> op1 = new Operation<Type>("test", inputType1, outputType1, null);
+ ServiceContract<Type> outboundContract = new JavaServiceContract(null);
+ outboundContract.setDataBinding(String.class.getName());
+ op1.setServiceContract(outboundContract);
+
+ OutboundInvocationChain outboundChain = createMock(OutboundInvocationChain.class);
+ outboundChains.put(op1, outboundChain);
+ expect(outboundWire.getInvocationChains()).andReturn(outboundChains).anyTimes();
+ // outboundChain.addInterceptor(EasyMock.anyInt(), (Interceptor)
+ // EasyMock.anyObject());
+
+ Map<Operation<?>, InboundInvocationChain> inboundChains =
+ new HashMap<Operation<?>, InboundInvocationChain>();
+ DataType<Type> type2 = new DataType<Type>(Node.class, Node.class);
+ List<DataType<Type>> types2 = new ArrayList<DataType<Type>>();
+ types2.add(type2);
+ DataType<List<DataType<Type>>> inputType2 =
+ new DataType<List<DataType<Type>>>(Object[].class, types2);
+ DataType<Type> outputType2 = new DataType<Type>(String.class, String.class);
+ Operation<Type> op2 = new Operation<Type>("test", inputType2, outputType2, null);
+ ServiceContract<Type> inboundContract = new JavaServiceContract(null);
+ inboundContract.setDataBinding(Node.class.getName());
+ op2.setServiceContract(inboundContract);
+
+ InboundInvocationChain inboundChain = createMock(InboundInvocationChain.class);
+ inboundChains.put(op2, inboundChain);
+ expect(inboundWire.getInvocationChains()).andReturn(inboundChains).anyTimes();
+ inboundChain.addInterceptor(EasyMock.anyInt(), (Interceptor) EasyMock.anyObject());
+
+ ServiceContract<Type> contract = new JavaServiceContract();
+ Map<String, Operation<Type>> operations = Collections.emptyMap();
+ contract.setCallbackOperations(operations);
+ expect(inboundWire.getServiceContract()).andReturn(contract);
+
+ EasyMock.replay(composite, serviceBinding, inboundWire, outboundWire, inboundChain, outboundChain);
+
+ processor.process(inboundWire, outboundWire);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DirectedGraphTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DirectedGraphTestCase.java
new file mode 100755
index 0000000000..70244df8e2
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/DirectedGraphTestCase.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.impl;
+
+import java.util.List;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.databinding.impl.DirectedGraph.Edge;
+import org.apache.tuscany.core.databinding.impl.DirectedGraph.Vertex;
+
+public class DirectedGraphTestCase extends TestCase {
+ private DirectedGraph<String, Object> graph;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ graph = new DirectedGraph<String, Object>();
+ graph.addEdge("a", "b", null, 3);
+ graph.addEdge("b", "c", null, 1);
+ graph.addEdge("a", "c", null, 8);
+ graph.addEdge("a", "d", null, 3);
+ graph.addEdge("b", "d", null, 2);
+ graph.addEdge("c", "b", null, 1);
+ graph.addEdge("c", "d", null, 2);
+ graph.addEdge("d", "b", null, 1);
+ graph.addEdge("a", "e", null, 8);
+ graph.addEdge("c", "c", null, 2);
+ }
+
+ public void testGraph() {
+ // System.out.println(graph);
+
+ Vertex vertex = graph.getVertex("a");
+ Assert.assertNotNull(vertex);
+ Assert.assertEquals(vertex.getValue(), "a");
+
+ Assert.assertNull(graph.getVertex("1"));
+
+ Edge edge = graph.getEdge("a", "b");
+ Assert.assertNotNull(edge);
+ Assert.assertEquals(edge.getWeight(), 3);
+
+ edge = graph.getEdge("b", "a");
+ Assert.assertNull(edge);
+
+ DirectedGraph<String, Object>.Path path = graph.getShortestPath("a", "c");
+
+ List<DirectedGraph<String, Object>.Edge> edges = path.getEdges();
+ Assert.assertEquals(edges.size(), 2);
+ Assert.assertEquals(edges.get(0), graph.getEdge("a", "b"));
+ Assert.assertEquals(edges.get(1), graph.getEdge("b", "c"));
+
+ Assert.assertEquals(path.getWeight(), 4);
+
+ DirectedGraph<String, Object>.Path path2 = graph.getShortestPath("b", "e");
+ Assert.assertNull(path2);
+
+ DirectedGraph<String, Object>.Path path3 = graph.getShortestPath("a", "a");
+ Assert.assertTrue(path3.getWeight() == 0 && path3.getEdges().isEmpty());
+
+ DirectedGraph<String, Object>.Path path4 = graph.getShortestPath("c", "c");
+ Assert.assertTrue(path4.getWeight() == 2 && path4.getEdges().size() == 1);
+
+ // System.out.println(path);
+
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/IDLTransformerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/IDLTransformerTestCase.java
new file mode 100644
index 0000000000..7981080f82
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/IDLTransformerTestCase.java
@@ -0,0 +1,217 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.impl;
+
+import static org.apache.tuscany.spi.databinding.DataBinding.IDL_INPUT;
+import static org.apache.tuscany.spi.databinding.DataBinding.IDL_OUTPUT;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.databinding.javabeans.DOMNode2JavaBeanTransformer;
+import org.apache.tuscany.core.databinding.javabeans.JavaBean2DOMNodeTransformer;
+import org.apache.tuscany.core.databinding.xml.DOMDataBinding;
+import org.apache.tuscany.core.databinding.xml.Node2String;
+import org.apache.tuscany.core.databinding.xml.String2Node;
+import org.apache.tuscany.spi.databinding.DataBindingRegistry;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.extension.DOMHelper;
+import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension;
+import org.apache.tuscany.spi.idl.ElementInfo;
+import org.apache.tuscany.spi.idl.TypeInfo;
+import org.apache.tuscany.spi.idl.XMLType;
+import org.apache.tuscany.spi.model.DataType;
+import org.apache.tuscany.spi.model.WrapperInfo;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class IDLTransformerTestCase extends TestCase {
+ private static final String IPO_XML =
+ "<?xml version=\"1.0\"?>" + "<order1"
+ + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
+ + " xmlns:ipo=\"http://www.example.com/IPO\""
+ + " xsi:schemaLocation=\"http://www.example.com/IPO ipo.xsd\""
+ + " orderDate=\"1999-12-01\">"
+ + " <shipTo exportCode=\"1\" xsi:type=\"ipo:UKAddress\">"
+ + " <name>Helen Zoe</name>"
+ + " <street>47 Eden Street</street>"
+ + " <city>Cambridge</city>"
+ + " <postcode>CB1 1JR</postcode>"
+ + " </shipTo>"
+ + " <billTo xsi:type=\"ipo:USAddress\">"
+ + " <name>Robert Smith</name>"
+ + " <street>8 Oak Avenue</street>"
+ + " <city>Old Town</city>"
+ + " <state>PA</state>"
+ + " <zip>95819</zip>"
+ + " </billTo>"
+ + " <items>"
+ + " <item partNum=\"833-AA\">"
+ + " <productName>Lapis necklace</productName>"
+ + " <quantity>1</quantity>"
+ + " <USPrice>99.95</USPrice>"
+ + " <ipo:comment>Want this for the holidays</ipo:comment>"
+ + " <shipDate>1999-12-05</shipDate>"
+ + " </item>"
+ + " </items>"
+ + "</order1>";
+
+ private static final String URI_ORDER_XSD = "http://example.com/order.xsd";
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public void testTransform() throws Exception {
+ List<DataType<XMLType>> types0 = new ArrayList<DataType<XMLType>>();
+ DataType<XMLType> wrapperType =
+ new DataType<XMLType>(null, Object.class, new XMLType(new QName(URI_ORDER_XSD, "checkOrderStatus"), null));
+ types0.add(wrapperType);
+ DataType<List<DataType<XMLType>>> inputType0 =
+ new DataType<List<DataType<XMLType>>>(IDL_INPUT, Object[].class, types0);
+
+ List<DataType<XMLType>> types1 = new ArrayList<DataType<XMLType>>();
+ DataType<XMLType> customerIdType =
+ new DataType<XMLType>(null, Object.class, new XMLType(new QName(URI_ORDER_XSD, "customerId"), null));
+ DataType<XMLType> orderType =
+ new DataType<XMLType>(null, Object.class, new XMLType(new QName(URI_ORDER_XSD, "order"), null));
+ DataType<XMLType> flagType =
+ new DataType<XMLType>(null, Object.class, new XMLType(new QName(URI_ORDER_XSD, "flag"), null));
+ types1.add(customerIdType);
+ types1.add(orderType);
+ types1.add(flagType);
+
+ DataType<XMLType> statusType =
+ new DataType<XMLType>(null, Object.class, new XMLType(new QName(URI_ORDER_XSD, "status"), null));
+ DataType<XMLType> responseType =
+ new DataType<XMLType>(null, Object.class, new XMLType(new QName(URI_ORDER_XSD, "checkOrderStatusResponse"),
+ null));
+
+ org.apache.tuscany.spi.model.Operation<XMLType> op =
+ new org.apache.tuscany.spi.model.Operation<XMLType>("checkOrderStatus", inputType0, responseType, null);
+ op.setDataBinding(DOMDataBinding.NAME);
+
+ inputType0.setOperation(op);
+ op.setWrapperStyle(true);
+ ElementInfo inputElement =
+ new ElementInfo(new QName(URI_ORDER_XSD, "checkOrderStatus"), new TypeInfo(null, false, null));
+ wrapperType.setMetadata(ElementInfo.class.getName(), inputElement);
+
+ ElementInfo customerId =
+ new ElementInfo(new QName("", "customerId"), SimpleTypeMapperExtension.XSD_SIMPLE_TYPES.get("string"));
+ ElementInfo order =
+ new ElementInfo(new QName("", "order"), new TypeInfo(new QName(URI_ORDER_XSD), false, null));
+ ElementInfo flag =
+ new ElementInfo(new QName("", "flag"), SimpleTypeMapperExtension.XSD_SIMPLE_TYPES.get("int"));
+
+ customerIdType.setMetadata(ElementInfo.class.getName(), customerId);
+ orderType.setMetadata(ElementInfo.class.getName(), order);
+ flagType.setMetadata(ElementInfo.class.getName(), flag);
+
+ customerIdType.setOperation(op);
+ orderType.setOperation(op);
+ flagType.setOperation(op);
+
+ List<ElementInfo> inputElements = new ArrayList<ElementInfo>();
+ inputElements.add(customerId);
+ inputElements.add(order);
+ inputElements.add(flag);
+
+ ElementInfo statusElement =
+ new ElementInfo(new QName("", "status"), SimpleTypeMapperExtension.XSD_SIMPLE_TYPES.get("string"));
+
+ statusType.setMetadata(ElementInfo.class.getName(), statusElement);
+ statusType.setOperation(op);
+
+ List<ElementInfo> outputElements = new ArrayList<ElementInfo>();
+ outputElements.add(statusElement);
+
+ ElementInfo outputElement =
+ new ElementInfo(new QName(URI_ORDER_XSD, "checkOrderStatusResponse"), new TypeInfo(null, false, null));
+
+ responseType.setMetadata(ElementInfo.class.getName(), inputElement);
+ responseType.setOperation(op);
+
+ WrapperInfo wrapperInfo =
+ new WrapperInfo(DOMDataBinding.NAME, inputElement, outputElement, inputElements, outputElements);
+ op.setWrapper(wrapperInfo);
+ op.setDataBinding(DOMDataBinding.NAME);
+
+ MediatorImpl m = new MediatorImpl();
+ TransformerRegistryImpl tr = new TransformerRegistryImpl();
+ tr.registerTransformer(new String2Node());
+ tr.registerTransformer(new Node2String());
+ tr.registerTransformer(new DOMNode2JavaBeanTransformer());
+ tr.registerTransformer(new JavaBean2DOMNodeTransformer());
+ m.setTransformerRegistry(tr);
+ DataBindingRegistry dataBindingRegistry = new DataBindingRegistryImpl();
+ dataBindingRegistry.register(new DOMDataBinding());
+ m.setDataBindingRegistry(dataBindingRegistry);
+
+ Object[] source = new Object[] {"cust001", IPO_XML, Integer.valueOf(1)};
+ Input2InputTransformer t = new Input2InputTransformer();
+ t.setMediator(m);
+
+ TransformationContext context = new TransformationContextImpl();
+ List<DataType<Class>> types = new ArrayList<DataType<Class>>();
+ types.add(new DataType<Class>(Object.class.getName(), String.class, String.class));
+ types.add(new DataType<Class>("java.lang.String", String.class, String.class));
+ types.add(new DataType<Class>(Object.class.getName(), int.class, int.class));
+ DataType<List<DataType<Class>>> inputType1 =
+ new DataType<List<DataType<Class>>>(IDL_INPUT, Object[].class, types);
+ context.setSourceDataType(inputType1);
+ context.setTargetDataType(op.getInputType());
+ Object[] results = t.transform(source, context);
+ assertEquals(1, results.length);
+ assertTrue(results[0] instanceof Element);
+ Element element = (Element)results[0];
+ assertEquals("http://example.com/order.xsd", element.getNamespaceURI());
+ assertEquals("checkOrderStatus", element.getLocalName());
+
+ TransformationContext context1 = new TransformationContextImpl();
+ DataType<DataType> sourceType = new DataType<DataType>(IDL_OUTPUT, Object.class, op.getOutputType());
+ sourceType.setOperation(op.getOutputType().getOperation());
+
+ context1.setSourceDataType(sourceType);
+ DataType<DataType> targetType =
+ new DataType<DataType>(IDL_OUTPUT, Object.class, new DataType<Class>("java.lang.Object", String.class,
+ String.class));
+ context1.setTargetDataType(targetType);
+
+ Document factory = DOMHelper.newDocument();
+ Element responseElement =
+ factory.createElementNS("http://example.com/order.wsdl", "p:checkOrderStatusResponse");
+ Element status = factory.createElement("status");
+ responseElement.appendChild(status);
+ status.appendChild(factory.createTextNode("shipped"));
+ Output2OutputTransformer t2 = new Output2OutputTransformer();
+ t2.setMediator(m);
+ Object st = t2.transform(responseElement, context1);
+ assertEquals("shipped", st);
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/MediatorImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/MediatorImplTestCase.java
new file mode 100644
index 0000000000..3cb7f243a9
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/MediatorImplTestCase.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.impl;
+
+import java.io.StringWriter;
+import java.io.Writer;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.databinding.xml.Node2String;
+import org.apache.tuscany.core.databinding.xml.Node2Writer;
+import org.apache.tuscany.core.databinding.xml.SAX2DOMPipe;
+import org.apache.tuscany.core.databinding.xml.String2SAX;
+import org.apache.tuscany.spi.databinding.DataBindingRegistry;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformerRegistry;
+import org.apache.tuscany.spi.model.DataType;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Test case for MediatorImpl
+ */
+public class MediatorImplTestCase extends TestCase {
+ private static final String IPO_XML =
+ "<?xml version=\"1.0\"?>" + "<ipo:purchaseOrder"
+ + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
+ + " xmlns:ipo=\"http://www.example.com/IPO\""
+ + " xsi:schemaLocation=\"http://www.example.com/IPO ipo.xsd\""
+ + " orderDate=\"1999-12-01\">"
+ + " <shipTo exportCode=\"1\" xsi:type=\"ipo:UKAddress\">"
+ + " <name>Helen Zoe</name>"
+ + " <street>47 Eden Street</street>"
+ + " <city>Cambridge</city>"
+ + " <postcode>CB1 1JR</postcode>"
+ + " </shipTo>"
+ + " <billTo xsi:type=\"ipo:USAddress\">"
+ + " <name>Robert Smith</name>"
+ + " <street>8 Oak Avenue</street>"
+ + " <city>Old Town</city>"
+ + "<state>PA</state>"
+ + " <zip>95819</zip>"
+ + " </billTo>"
+ + " <items>"
+ + " <item partNum=\"833-AA\">"
+ + " <productName>Lapis necklace</productName>"
+ + " <quantity>1</quantity>"
+ + "<USPrice>99.95</USPrice>"
+ + " <ipo:comment>Want this for the holidays</ipo:comment>"
+ + " <shipDate>1999-12-05</shipDate>"
+ + " </item>"
+ + " </items>"
+ + "</ipo:purchaseOrder>";
+
+ private MediatorImpl mediator;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ TransformerRegistry registry = new TransformerRegistryImpl();
+ registry.registerTransformer(new String2SAX());
+ registry.registerTransformer(new SAX2DOMPipe());
+ registry.registerTransformer(new Node2String());
+ registry.registerTransformer(new Node2Writer());
+
+ mediator = new MediatorImpl();
+ mediator.setTransformerRegistry(registry);
+
+ DataBindingRegistry dataBindingRegistry = new DataBindingRegistryImpl();
+ mediator.setDataBindingRegistry(dataBindingRegistry);
+ }
+
+ private TransformationContext createTransformationContext(Class sourceType, Class targetType) {
+ TransformationContext context = new TransformationContextImpl();
+ DataType sourceDataType = new DataType<Class>(sourceType, sourceType);
+ DataType targetDataType = new DataType<Class>(targetType, targetType);
+ context.setSourceDataType(sourceDataType);
+ context.setTargetDataType(targetDataType);
+ return context;
+ }
+
+ public void testTransform1() {
+ TransformationContext context = createTransformationContext(String.class, Node.class);
+ Object node =
+ mediator.mediate(IPO_XML, context.getSourceDataType(), context.getTargetDataType(), null);
+ Assert.assertTrue(node instanceof Document);
+ Element root = ((Document)node).getDocumentElement();
+ Assert.assertEquals(root.getNamespaceURI(), "http://www.example.com/IPO");
+ Assert.assertEquals(root.getLocalName(), "purchaseOrder");
+ }
+
+ public void testTransform2() {
+ TransformationContext context = createTransformationContext(String.class, Writer.class);
+ Writer writer = new StringWriter();
+ mediator.mediate(IPO_XML, writer, context.getSourceDataType(), context.getTargetDataType(), null);
+ String str = writer.toString();
+ Assert.assertTrue(str != null && str.indexOf("<shipDate>1999-12-05</shipDate>") != -1);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/PassByValueInterceptorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/PassByValueInterceptorTestCase.java
new file mode 100644
index 0000000000..3e839bdae1
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/PassByValueInterceptorTestCase.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import java.io.Serializable;
+
+import org.apache.tuscany.core.databinding.javabeans.JavaBeansDataBinding;
+import org.apache.tuscany.spi.databinding.DataBinding;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for ByValueInterceptor
+ */
+public class PassByValueInterceptorTestCase extends TestCase {
+ private MySerialiable serialiable = new MySerialiable();
+ private String str = "ABC";
+ private Integer i = new Integer(1);
+ private String[] array = new String[] {"1", "2"};
+ private Object[] values;
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ values = new Object[] {serialiable, str, i, serialiable, array};
+ }
+
+ private static class MySerialiable implements Serializable {
+ private static final long serialVersionUID = 7827201707529055310L;
+ private final String name = "Serializable";
+ private final int age = 100;
+
+ public int getAge() {
+ return age;
+ }
+
+ public String getName() {
+ return name;
+ }
+ }
+
+ public void testCopy() {
+ PassByValueInterceptor interceptor = new PassByValueInterceptor(null);
+ DataBinding db = new JavaBeansDataBinding();
+ interceptor.setParameterDatabindings(new DataBinding[] {db, db, db, db, db});
+ Object[] copy = interceptor.copy(values);
+ assertTrue(copy[0] instanceof MySerialiable);
+ MySerialiable copied = (MySerialiable)copy[0];
+ assertNotSame(serialiable, copy[0]);
+ assertEquals(serialiable.getName(), copied.getName());
+ assertEquals(serialiable.getAge(), copied.getAge());
+ assertSame(copy[1], str);
+ assertSame(copy[2], i);
+ assertSame(copy[0], copy[3]);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/PassByValueWirePostProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/PassByValueWirePostProcessorTestCase.java
new file mode 100644
index 0000000000..1839aa4044
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/PassByValueWirePostProcessorTestCase.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.core.databinding.impl;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.component.TargetResolutionException;
+import org.apache.tuscany.spi.databinding.DataBindingRegistry;
+import org.apache.tuscany.spi.extension.AtomicComponentExtension;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.wire.InboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.OutboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.SynchronousBridgingInterceptor;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+
+/**
+ * Testcase for testing if the PassByValueWireProcessor adds the PassByValueInterceptor to the invocation chains and
+ * also ensure that the outbound and inbound chain of interceptors are linked after this insertion
+ *
+ * @version $Rev$ $Date$
+ */
+public class PassByValueWirePostProcessorTestCase extends TestCase {
+ private PassByValueWirePostProcessor processor;
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.processor = new PassByValueWirePostProcessor();
+ DataBindingRegistry dataBindingRegistry = createMock(DataBindingRegistry.class);
+ processor.setDataBindingRegistry(dataBindingRegistry);
+ }
+
+ public void testProcessInclusionOfInterceptor() {
+
+ InboundWire inboundWire = createMock(InboundWire.class);
+ OutboundWire outboundWire = createMock(OutboundWire.class);
+
+ ServiceContract<Type> serviceContract = new JavaServiceContract(null);
+ serviceContract.setRemotable(true);
+ Map<Operation<?>, InboundInvocationChain> inChainsMap =
+ new Hashtable<Operation<?>, InboundInvocationChain>();
+
+ Operation<Type> operation1 = new Operation<Type>("testMethod", null, null, null);
+ operation1.setServiceContract(serviceContract);
+ InboundInvocationChainImpl inChain = new InboundInvocationChainImpl(operation1);
+ inChainsMap.put(operation1, inChain);
+
+ AtomicComponentExtension componentExtn = new FooComponent();
+ componentExtn.setPassByReferenceMethods(new ArrayList<String>());
+
+ Map<Operation<?>, OutboundInvocationChain> outChainsMap =
+ new Hashtable<Operation<?>, OutboundInvocationChain>();
+ OutboundInvocationChainImpl outChain = new OutboundInvocationChainImpl(operation1);
+ outChainsMap.put(operation1, outChain);
+
+ expect(inboundWire.getServiceContract()).andReturn(serviceContract);
+ expect(inboundWire.getContainer()).andReturn(componentExtn).anyTimes();
+ expect(outboundWire.getContainer()).andReturn(componentExtn).anyTimes();
+ expect(inboundWire.getServiceContract()).andReturn(serviceContract);
+ expect(inboundWire.getInvocationChains()).andReturn(inChainsMap);
+ expect(outboundWire.getServiceContract()).andReturn(serviceContract).times(2);
+ expect(outboundWire.getInvocationChains()).andReturn(outChainsMap).times(2);
+
+ Interceptor inInterceptor = createMock(Interceptor.class);
+ Interceptor outInterceptor = createMock(Interceptor.class);
+ inChain.addInterceptor(0, inInterceptor);
+ outChain.addInterceptor(0, outInterceptor);
+ outChain.addInterceptor(new SynchronousBridgingInterceptor(inChain.getHeadInterceptor()));
+
+ EasyMock.replay(inboundWire, outboundWire);
+ processor.process(outboundWire, inboundWire);
+
+ assertEquals(true, outChain.getHeadInterceptor() instanceof PassByValueInterceptor);
+ assertEquals(true, outChain.getTailInterceptor().getNext().equals(
+ inChain.getHeadInterceptor()));
+
+ }
+
+ public void testProcessExclusionOfInterceptorWhenAllowsPassByReference() {
+ InboundWire inboundWire = createMock(InboundWire.class);
+ OutboundWire outboundWire = createMock(OutboundWire.class);
+
+ ServiceContract<Type> serviceContract = new JavaServiceContract(null);
+ serviceContract.setRemotable(true);
+ Map<Operation<?>, InboundInvocationChain> inChainsMap =
+ new Hashtable<Operation<?>, InboundInvocationChain>();
+
+ Operation<?> operation1 = new Operation<Type>("testMethod", null, null, null);
+ InboundInvocationChainImpl inChain = new InboundInvocationChainImpl(operation1);
+ inChainsMap.put(operation1, inChain);
+
+ AtomicComponentExtension componentExtn = new FooComponent();
+ componentExtn.setAllowsPassByReference(true);
+ componentExtn.setPassByReferenceMethods(new ArrayList<String>());
+
+
+ Map<Operation<?>, OutboundInvocationChain> outChainsMap =
+ new Hashtable<Operation<?>, OutboundInvocationChain>();
+ OutboundInvocationChainImpl outChain = new OutboundInvocationChainImpl(operation1);
+ outChainsMap.put(operation1, outChain);
+
+ expect(inboundWire.getServiceContract()).andReturn(serviceContract);
+ expect(inboundWire.getContainer()).andReturn(componentExtn).anyTimes();
+ expect(outboundWire.getContainer()).andReturn(componentExtn).anyTimes();
+ expect(inboundWire.getServiceContract()).andReturn(serviceContract);
+ expect(inboundWire.getInvocationChains()).andReturn(inChainsMap);
+ expect(outboundWire.getServiceContract()).andReturn(serviceContract).anyTimes();
+ expect(outboundWire.getInvocationChains()).andReturn(outChainsMap).times(2);
+
+ Interceptor inInterceptor = createMock(Interceptor.class);
+ Interceptor outInterceptor = createMock(Interceptor.class);
+ inChain.addInterceptor(0, inInterceptor);
+ outChain.addInterceptor(0, outInterceptor);
+ outChain.addInterceptor(new SynchronousBridgingInterceptor(inChain.getHeadInterceptor()));
+
+ EasyMock.replay(inboundWire, outboundWire);
+ processor.process(outboundWire, inboundWire);
+
+ assertEquals(false, inChain.getHeadInterceptor() instanceof PassByValueInterceptor);
+ assertEquals(false,
+ outChain.getTailInterceptor().getNext() instanceof PassByValueInterceptor);
+ assertEquals(true, outChain.getTailInterceptor().getNext().equals(
+ inChain.getHeadInterceptor()));
+ }
+
+ public void testProcessExclusionOfInterceptorWhenAllowsPassByReferenceAtMethod() {
+ InboundWire inboundWire = createMock(InboundWire.class);
+ OutboundWire outboundWire = createMock(OutboundWire.class);
+
+ ServiceContract<Type> serviceContract = new JavaServiceContract(null);
+ serviceContract.setRemotable(true);
+ Map<Operation<?>, InboundInvocationChain> inChainsMap =
+ new Hashtable<Operation<?>, InboundInvocationChain>();
+
+ Operation<?> operation1 = new Operation<Type>("testMethod", null, null, null);
+ InboundInvocationChainImpl inChain = new InboundInvocationChainImpl(operation1);
+ inChainsMap.put(operation1, inChain);
+
+ AtomicComponentExtension componentExtn = new FooComponent();
+ componentExtn.setPassByReferenceMethods(new ArrayList<String>());
+ componentExtn.getPassByReferenceMethods().add("testMethod");
+
+
+ Map<Operation<?>, OutboundInvocationChain> outChainsMap =
+ new Hashtable<Operation<?>, OutboundInvocationChain>();
+ OutboundInvocationChainImpl outChain = new OutboundInvocationChainImpl(operation1);
+ outChainsMap.put(operation1, outChain);
+
+ expect(inboundWire.getServiceContract()).andReturn(serviceContract);
+ expect(inboundWire.getContainer()).andReturn(componentExtn).anyTimes();
+ expect(outboundWire.getContainer()).andReturn(componentExtn).anyTimes();
+ expect(inboundWire.getServiceContract()).andReturn(serviceContract);
+ expect(inboundWire.getInvocationChains()).andReturn(inChainsMap);
+ expect(outboundWire.getServiceContract()).andReturn(serviceContract).anyTimes();
+ expect(outboundWire.getInvocationChains()).andReturn(outChainsMap).times(2);
+
+ Interceptor inInterceptor = createMock(Interceptor.class);
+ Interceptor outInterceptor = createMock(Interceptor.class);
+ inChain.addInterceptor(0, inInterceptor);
+ outChain.addInterceptor(0, outInterceptor);
+ outChain.addInterceptor(new SynchronousBridgingInterceptor(inChain.getHeadInterceptor()));
+
+ EasyMock.replay(inboundWire, outboundWire);
+ processor.process(outboundWire, inboundWire);
+
+ assertEquals(false, inChain.getHeadInterceptor() instanceof PassByValueInterceptor);
+ assertEquals(false,
+ outChain.getTailInterceptor().getNext() instanceof PassByValueInterceptor);
+ assertEquals(true, outChain.getTailInterceptor().getNext().equals(
+ inChain.getHeadInterceptor()));
+ }
+
+ public void testProcessExclusionOfInterceptorForBinding() {
+ InboundWire inboundWire = createMock(InboundWire.class);
+ OutboundWire outboundWire = createMock(OutboundWire.class);
+
+ ServiceBinding serviceBinding = createMock(ServiceBinding.class);
+ expect(outboundWire.getContainer()).andReturn(serviceBinding).anyTimes();
+ expect(inboundWire.getContainer()).andReturn(null).anyTimes();
+
+ ServiceContract<Type> serviceContract = new JavaServiceContract(null);
+ serviceContract.setRemotable(true);
+ Map<Operation<?>, InboundInvocationChain> inChainsMap =
+ new Hashtable<Operation<?>, InboundInvocationChain>();
+
+ Operation<?> operation1 = new Operation<Type>("testMethod", null, null, null);
+ InboundInvocationChainImpl inChain = new InboundInvocationChainImpl(operation1);
+ inChainsMap.put(operation1, inChain);
+
+ Map<Operation<?>, OutboundInvocationChain> outChainsMap =
+ new Hashtable<Operation<?>, OutboundInvocationChain>();
+ OutboundInvocationChainImpl outChain = new OutboundInvocationChainImpl(operation1);
+ outChainsMap.put(operation1, outChain);
+
+ Interceptor inInterceptor = createMock(Interceptor.class);
+ Interceptor outInterceptor = createMock(Interceptor.class);
+ inChain.addInterceptor(0, inInterceptor);
+ outChain.addInterceptor(0, outInterceptor);
+ outChain.addInterceptor(new SynchronousBridgingInterceptor(inChain.getHeadInterceptor()));
+
+ EasyMock.replay(inboundWire, outboundWire);
+ processor.process(outboundWire, inboundWire);
+
+ assertEquals(false, inChain.getHeadInterceptor() instanceof PassByValueInterceptor);
+ assertEquals(false,
+ outChain.getTailInterceptor().getNext() instanceof PassByValueInterceptor);
+ assertEquals(true, outChain.getTailInterceptor().getNext().equals(
+ inChain.getHeadInterceptor()));
+ }
+
+ private class FooComponent extends AtomicComponentExtension {
+
+ public FooComponent() {
+ super(null, null, null, null, null, null, 0);
+ }
+
+ public Object createInstance() throws ObjectCreationException {
+ return null;
+ }
+
+ public Object getTargetInstance() throws TargetResolutionException {
+ return null;
+ }
+
+ public TargetInvoker createTargetInvoker(String targetName, Operation operation, InboundWire callbackWire) {
+ return null;
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/TransformerRegistryImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/TransformerRegistryImplTestCase.java
new file mode 100644
index 0000000000..6250efd897
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/impl/TransformerRegistryImplTestCase.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.impl;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+import java.util.List;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.TransformerRegistry;
+
+/**
+ *
+ */
+public class TransformerRegistryImplTestCase extends TestCase {
+ private TransformerRegistry registry;
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ registry = new TransformerRegistryImpl();
+ }
+
+ public void testRegisterTransformer1() {
+ Transformer transformer = createMock(Transformer.class);
+ registry.registerTransformer("a", "b", 10, transformer);
+ Transformer t = registry.getTransformer("a", "b");
+ Assert.assertSame(t, transformer);
+ }
+
+ public void testRegisterTransformerTransformer() {
+ Transformer transformer = createMock(Transformer.class);
+ expect(transformer.getSourceDataBinding()).andReturn("a");
+ expect(transformer.getTargetDataBinding()).andReturn("b");
+ expect(transformer.getWeight()).andReturn(10);
+ replay(transformer);
+ registry.registerTransformer(transformer);
+ Transformer t = registry.getTransformer("a", "b");
+ Assert.assertSame(t, transformer);
+ }
+
+ public void testUnregisterTransformer() {
+ Transformer transformer = createMock(Transformer.class);
+ registry.registerTransformer("a", "b", 10, transformer);
+ boolean result = registry.unregisterTransformer("a", "b");
+ Assert.assertTrue(result);
+ Transformer t = registry.getTransformer("a", "b");
+ Assert.assertNull(t);
+ }
+
+ public void testGetTransformerChain() {
+ Transformer t1 = createMock(Transformer.class);
+ expect(t1.getSourceDataBinding()).andReturn("a");
+ expect(t1.getTargetDataBinding()).andReturn("b");
+ expect(t1.getWeight()).andReturn(10);
+ replay(t1);
+ Transformer t2 = createMock(Transformer.class);
+ expect(t2.getSourceDataBinding()).andReturn("b");
+ expect(t2.getTargetDataBinding()).andReturn("c");
+ expect(t2.getWeight()).andReturn(20);
+ replay(t2);
+
+ Transformer t3 = createMock(Transformer.class);
+ expect(t3.getSourceDataBinding()).andReturn("a");
+ expect(t3.getTargetDataBinding()).andReturn("c");
+ expect(t3.getWeight()).andReturn(120);
+ replay(t3);
+
+ registry.registerTransformer(t1);
+ registry.registerTransformer(t2);
+ registry.registerTransformer(t3);
+
+ List<Transformer> l1 = registry.getTransformerChain("a", "b");
+ Assert.assertTrue(l1.size() == 1 && l1.get(0) == t1);
+ List<Transformer> l2 = registry.getTransformerChain("a", "c");
+ Assert.assertTrue(l2.size() == 2 && l2.get(0) == t1 && l2.get(1) == t2);
+ List<Transformer> l3 = registry.getTransformerChain("a", "d");
+ Assert.assertNull(l3);
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/javabeans/DOMNode2JavaBeanTransformerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/javabeans/DOMNode2JavaBeanTransformerTestCase.java
new file mode 100644
index 0000000000..e654fe3ec9
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/javabeans/DOMNode2JavaBeanTransformerTestCase.java
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.javabeans;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.databinding.javabeans.DOMNode2JavaBeanTransformer;
+import org.apache.tuscany.core.databinding.javabeans.JavaBean2DOMNodeTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.extension.DOMHelper;
+import org.apache.tuscany.spi.idl.ElementInfo;
+import org.apache.tuscany.spi.idl.TypeInfo;
+import org.apache.tuscany.spi.idl.XMLType;
+import org.apache.tuscany.spi.model.DataType;
+import org.easymock.EasyMock;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+
+/**
+ * Testcase to test the XMLTypeMapperExtension which is the back bone for all transformations supported by the JavaBeans
+ * Databinding.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DOMNode2JavaBeanTransformerTestCase extends TestCase {
+
+ private DOMNode2JavaBeanTransformer dom2JavaTransformer = new DOMNode2JavaBeanTransformer();
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public void testFieldSettings() throws Exception {
+ String samplePropertyXML =
+ "<property name=\"prop2\" >" + "<integerNumber>27</integerNumber>"
+ + "<floatNumber>79.34</floatNumber>"
+ + "<doubleNumber>184.52</doubleNumber>" + "<innerProperty>"
+ + "<integerNumber>54</integerNumber>" + "<floatNumber>158.68</floatNumber>"
+ + "<doubleNumber>369.04</doubleNumber>" + "</innerProperty>"
+ + "<stringArray>TestString_1</stringArray>"
+ + "<stringArray>TestString_2</stringArray>" + "<boolArray>true</boolArray>"
+ + "<boolArray>false</boolArray>" + "</property>";
+
+ DocumentBuilder builder = DOMHelper.newDocumentBuilder();
+ InputSource inputSource = new InputSource(new StringReader(samplePropertyXML));
+ Node samplePropertyNode = builder.parse(inputSource);
+ TypeInfo typeInfo = new TypeInfo(null, false, null);
+
+ TransformationContext context = EasyMock.createMock(TransformationContext.class);
+ DataType<Class> targetDataType = new DataType<Class>(SamplePropertyBean.class, SamplePropertyBean.class);
+ EasyMock.expect(context.getTargetDataType()).andReturn(targetDataType).anyTimes();
+
+ DataType<XMLType> sourceDataType = new DataType<XMLType>(null, new XMLType(typeInfo));
+ // ElementInfo eleInfo = new ElementInfo(null, typeInfo);
+ // sourceDataType.setMetadata(ElementInfo.class.getName(), eleInfo);
+ EasyMock.expect(context.getSourceDataType()).andReturn(sourceDataType).anyTimes();
+ EasyMock.replay(context);
+
+ Object javaObject =
+ dom2JavaTransformer.transform(((Document) samplePropertyNode).getDocumentElement(), context);
+
+ assertTrue(javaObject instanceof SamplePropertyBean);
+ SamplePropertyBean samplePropBean = (SamplePropertyBean) javaObject;
+ assertEquals(samplePropBean.getIntegerNumber(), 27);
+ assertEquals((float) 79.34, samplePropBean.getFloatNumber());
+ assertEquals(samplePropBean.getInnerProperty().getDoubleNumber(), 369.04);
+
+ assertEquals(samplePropBean.getStringArray()[0], "TestString_1");
+ assertEquals(samplePropBean.boolArray[0], true);
+
+ /** testing for object to node * */
+ javax.xml.transform.Transformer transformer =
+ TransformerFactory.newInstance().newTransformer();
+ JavaBean2DOMNodeTransformer java2DomTransformer = new JavaBean2DOMNodeTransformer();
+ Node aNode = java2DomTransformer.transform(javaObject, context);
+ StringWriter sw = new StringWriter();
+ transformer.transform(new DOMSource(aNode), new StreamResult(sw));
+ String nodeString = sw.toString();
+ //System.out.println(nodeString);
+
+ // testing the case when field and getter method do not have public access
+ assertTrue(nodeString.indexOf("<doubleNumber>184.52</doubleNumber>") == -1);
+ // test the case for fields that are of array type
+ assertTrue(nodeString.indexOf("<stringArray>TestString_1</stringArray>"
+ + "<stringArray>TestString_2</stringArray>") != -1);
+ // testing the case for non-public field with public getter method
+ assertTrue(nodeString.indexOf("<integerNumber>27</integerNumber>") != -1);
+ // test the case for public field that is a another java bean .i.e. embeded javabean
+ int startIndex = nodeString.indexOf("<innerProperty>");
+ int endIndex = nodeString.indexOf("</innerProperty>");
+ String fragment = nodeString.substring(startIndex, endIndex);
+ assertTrue(fragment.indexOf("<integerNumber>54</integerNumber>") != -1);
+
+ // System.out.println(sw.toString());
+
+ }
+
+
+ public static class SamplePropertyBean {
+
+ private float floatNumber = 50;
+ private SamplePropertyBean innerProperty;
+ public boolean[] boolArray;
+ private double doubleNumber = 75;
+ private int integerNumber = 25;
+ private String[] stringArray;
+
+ public SamplePropertyBean() {
+
+ }
+
+ double getDoubleNumber() {
+ return doubleNumber;
+ }
+
+ public void setDoubleNumber(double doubleNumber) {
+ this.doubleNumber = doubleNumber;
+ }
+
+ public float getFloatNumber() {
+ return floatNumber;
+ }
+
+ public void setFloatNumber(float floatNumber) {
+ this.floatNumber = floatNumber;
+ }
+
+ public int getIntegerNumber() {
+ return integerNumber;
+ }
+
+ public void setIntegerNumber(int integerNumber) {
+ this.integerNumber = integerNumber;
+ }
+
+ public SamplePropertyBean getInnerProperty() {
+ return innerProperty;
+ }
+
+ public void setInnerProperty(SamplePropertyBean prop) {
+ this.innerProperty = prop;
+ }
+
+ public String toString() {
+ return Double.toString(integerNumber + floatNumber + doubleNumber) + " & "
+ + ((innerProperty == null) ? "" : innerProperty.toString());
+ }
+
+ public String[] getStringArray() {
+ return stringArray;
+ }
+
+ public void setStringArray(String[] stringArray) {
+ this.stringArray = stringArray;
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2DOMNodeTransformerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2DOMNodeTransformerTestCase.java
new file mode 100644
index 0000000000..95701cc0fb
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/javabeans/JavaBean2DOMNodeTransformerTestCase.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.javabeans;
+
+import java.io.StringWriter;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Node;
+
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.model.DataType;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * Testcase to test the XMLTypeMapperExtension which is the back bone for all transformations supported by the JavaBeans
+ * Databinding.
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaBean2DOMNodeTransformerTestCase extends TestCase {
+ private JavaBean2DOMNodeTransformer aTransformer = new JavaBean2DOMNodeTransformer();
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public void testTranformation() throws Exception {
+ TransformationContext context = EasyMock.createMock(TransformationContext.class);
+ DataType<Class> dataType = new DataType<Class>(null, SamplePropertyBean.class);
+ EasyMock.expect(context.getTargetDataType()).andReturn(dataType).anyTimes();
+ EasyMock.replay(context);
+
+ javax.xml.transform.Transformer transformer =
+ TransformerFactory.newInstance().newTransformer();
+ Object data = new int[]{10, 20, 30, 40};
+ Node aNode = aTransformer.transform(data, context);
+ StringWriter sw = new StringWriter();
+ transformer.transform(new DOMSource(aNode), new StreamResult(sw));
+
+ System.out.println(sw.toString());
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><int_collection><int>10</int><int>20</int>"
+ + "<int>30</int><int>40</int></int_collection>",
+ sw.toString());
+ }
+
+ public static class SamplePropertyBean {
+ private float floatNumber = 50;
+ private SamplePropertyBean innerProperty;
+ private double doubleNumber = 75;
+ private int integerNumber = 25;
+ private String[] stringArray;
+
+ public SamplePropertyBean() {
+
+ }
+
+ double getDoubleNumber() {
+ return doubleNumber;
+ }
+
+ public void setDoubleNumber(double doubleNumber) {
+ this.doubleNumber = doubleNumber;
+ }
+
+ public float getFloatNumber() {
+ return floatNumber;
+ }
+
+ public void setFloatNumber(float floatNumber) {
+ this.floatNumber = floatNumber;
+ }
+
+ public int getIntegerNumber() {
+ return integerNumber;
+ }
+
+ public void setIntegerNumber(int integerNumber) {
+ this.integerNumber = integerNumber;
+ }
+
+ public SamplePropertyBean getInnerProperty() {
+ return innerProperty;
+ }
+
+ public void setInnerProperty(SamplePropertyBean prop) {
+ this.innerProperty = prop;
+ }
+
+ public String toString() {
+ return Double.toString(integerNumber + floatNumber + doubleNumber) + " & "
+ + ((innerProperty == null) ? "" : innerProperty.toString());
+ }
+
+ public String[] getStringArray() {
+ return stringArray;
+ }
+
+ public void setStringArray(String[] stringArray) {
+ this.stringArray = stringArray;
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/DOM2StAXTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/DOM2StAXTestCase.java
new file mode 100644
index 0000000000..bc9ecb2713
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/DOM2StAXTestCase.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.stream.XMLStreamReader;
+
+import junit.framework.TestCase;
+
+import org.w3c.dom.Node;
+
+public class DOM2StAXTestCase extends TestCase {
+ private static final String IPO_XML =
+ "<?xml version=\"1.0\"?>" + "<ipo:purchaseOrder"
+ + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
+ + " xmlns:ipo=\"http://www.example.com/IPO\""
+ + " xsi:schemaLocation=\"http://www.example.com/IPO ipo.xsd\""
+ + " orderDate=\"1999-12-01\">"
+ + " <shipTo exportCode=\"1\" xsi:type=\"ipo:UKAddress\">"
+ + " <name>Helen Zoe</name>"
+ + " <street>47 Eden Street</street>"
+ + " <city>Cambridge</city>"
+ + " <postcode>CB1 1JR</postcode>"
+ + " </shipTo>"
+ + " <billTo xsi:type=\"ipo:USAddress\">"
+ + " <name>Robert Smith</name>"
+ + " <street>8 Oak Avenue</street>"
+ + " <city>Old Town</city>"
+ + " <state>PA</state>"
+ + " <zip>95819</zip>"
+ + " </billTo>"
+ + " <items>"
+ + " <item partNum=\"833-AA\">"
+ + " <productName>Lapis necklace</productName>"
+ + " <quantity>1</quantity>"
+ + " <USPrice>99.95</USPrice>"
+ + " <ipo:comment>Want this for the holidays</ipo:comment>"
+ + " <shipDate>1999-12-05</shipDate>"
+ + " </item>"
+ + " </items>"
+ + "</ipo:purchaseOrder>";
+
+ private static final String CRAZY_XML =
+ "<p:e1 xmlns=\"http://ns0\" xmlns:p=\"http://p1\">"
+ + "<p:e2 xmlns:p=\"http://p2\"/><e3/><e4 xmlns=\"\">E4</e4></p:e1>";
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public void testTransformation() {
+ String2Node t1 = new String2Node();
+ Node node = t1.transform(IPO_XML, null);
+ Node2XMLStreamReader t2 = new Node2XMLStreamReader();
+ XMLStreamReader reader = t2.transform(node, null);
+ XMLStreamReader2String t3 = new XMLStreamReader2String();
+ String xml = t3.transform(reader, null);
+ assertTrue(xml != null && xml.indexOf("<shipDate>1999-12-05</shipDate>") != -1);
+ }
+
+ public void testTransformation2() {
+ String2Node t1 = new String2Node();
+ Node node = t1.transform(CRAZY_XML, null);
+ Node2XMLStreamReader t2 = new Node2XMLStreamReader();
+ XMLStreamReader reader = t2.transform(node, null);
+ XMLStreamReader2String t3 = new XMLStreamReader2String();
+ String xml = t3.transform(reader, null);
+ System.out.println(xml);
+ assertTrue(xml.contains("<p:e2 xmlns:p=\"http://p2\""));
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/DataPipeTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/DataPipeTestCase.java
new file mode 100644
index 0000000000..d4eaf9b2a9
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/DataPipeTestCase.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.databinding.impl.PipedTransformer;
+import org.apache.tuscany.spi.databinding.extension.DOMHelper;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Test case for DataPipe
+ */
+public class DataPipeTestCase extends TestCase {
+
+ public final void testStreamPipe() throws IOException {
+ byte[] bytes = new byte[] {1, 2, 3};
+ StreamDataPipe pipe = new StreamDataPipe();
+ Assert.assertSame(OutputStream.class, pipe.getSourceType());
+ Assert.assertSame(InputStream.class, pipe.getTargetType());
+ OutputStream os = pipe.getSink();
+ os.write(bytes);
+ byte[] newBytes = new byte[16];
+ int count = pipe.getResult().read(newBytes);
+ Assert.assertEquals(3, count);
+ for (int i = 0; i < bytes.length; i++) {
+ Assert.assertEquals(bytes[i], newBytes[i]);
+ }
+ }
+
+ public final void testWriter2ReaderPipe() throws IOException {
+ String str = "ABC";
+ Writer2ReaderDataPipe pipe = new Writer2ReaderDataPipe();
+ Assert.assertSame(Writer.class, pipe.getSourceType());
+ Assert.assertSame(Reader.class, pipe.getTargetType());
+ pipe.getSink().write(str);
+ char[] buf = new char[16];
+ int count = pipe.getResult().read(buf);
+ Assert.assertEquals(3, count);
+ for (int i = 0; i < str.length(); i++) {
+ Assert.assertEquals(str.charAt(i), buf[i]);
+ }
+ }
+
+ public final void testPiped() throws Exception {
+ Node2Writer node2Writer = new Node2Writer();
+ Writer2ReaderDataPipe pipe = new Writer2ReaderDataPipe();
+ PipedTransformer<Node, Writer, Reader> transformer =
+ new PipedTransformer<Node, Writer, Reader>(node2Writer, pipe);
+ Document document = DOMHelper.newDocument();
+ Element element = document.createElementNS("http://ns1", "root");
+ document.appendChild(element);
+ Reader reader = transformer.transform(document, null);
+ Assert.assertEquals(transformer.getWeight(), node2Writer.getWeight() + pipe.getWeight());
+ Assert.assertEquals(transformer.getSourceDataBinding(), node2Writer.getSourceDataBinding());
+ Assert.assertEquals(transformer.getTargetDataBinding(), pipe.getTargetDataBinding());
+ char[] buf = new char[120];
+ int count = reader.read(buf);
+ String xml = new String(buf, 0, count);
+ Assert.assertTrue(xml.contains("<root xmlns=\"http://ns1\"/>"));
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/JavaBean2XMLStreamReaderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/JavaBean2XMLStreamReaderTestCase.java
new file mode 100644
index 0000000000..6eb2c101df
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/JavaBean2XMLStreamReaderTestCase.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.stream.XMLStreamReader;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.databinding.javabeans.JavaBean2XMLStreamReader;
+
+public class JavaBean2XMLStreamReaderTestCase extends TestCase {
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public void testTransformation() {
+ JavaBean2XMLStreamReader t2 = new JavaBean2XMLStreamReader();
+ MyBean bean = new MyBean();
+ bean.str = "ABC";
+ bean.i = 1;
+ bean.arr = new long[] {1, 2, 3};
+ bean.bean = new AnotherBean();
+ bean.bean.setName("Name");
+ XMLStreamReader reader = t2.transform(bean, null);
+ XMLStreamReader2String t3 = new XMLStreamReader2String();
+ String xml = t3.transform(reader, null);
+ assertTrue(xml.contains("<JavaBean2XMLStreamReaderTestCase$MyBean>"
+ + "<arr>1</arr><arr>2</arr><arr>3</arr><bean><name>Name</name></bean>"
+ + "<i>1</i><str>ABC</str></JavaBean2XMLStreamReaderTestCase$MyBean>"));
+ }
+
+ private static class MyBean {
+ private String str;
+ private int i;
+ private long arr[];
+ private AnotherBean bean;
+
+ /**
+ * @return the arr
+ */
+ public long[] getArr() {
+ return arr;
+ }
+
+ /**
+ * @param arr the arr to set
+ */
+ public void setArr(long[] arr) {
+ this.arr = arr;
+ }
+
+ /**
+ * @return the i
+ */
+ public int getI() {
+ return i;
+ }
+
+ /**
+ * @param i the i to set
+ */
+ public void setI(int i) {
+ this.i = i;
+ }
+
+ /**
+ * @return the str
+ */
+ public String getStr() {
+ return str;
+ }
+
+ /**
+ * @param str the str to set
+ */
+ public void setStr(String str) {
+ this.str = str;
+ }
+
+ /**
+ * @return the bean
+ */
+ public AnotherBean getBean() {
+ return bean;
+ }
+
+ /**
+ * @param bean the bean to set
+ */
+ public void setBean(AnotherBean bean) {
+ this.bean = bean;
+ }
+
+ }
+
+ private static class AnotherBean {
+ private String name;
+
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name the name to set
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/Node2StringTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/Node2StringTestCase.java
new file mode 100755
index 0000000000..9b9aa3b893
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/Node2StringTestCase.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.spi.databinding.extension.DOMHelper;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class Node2StringTestCase extends TestCase {
+ public void testTransformation() throws Exception {
+ Document document = DOMHelper.newDocument();
+ Element element = document.createElementNS("http://ns1", "test");
+ document.appendChild(element);
+
+ new Node2String().transform(document, null);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/PushTransformationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/PushTransformationTestCase.java
new file mode 100644
index 0000000000..a2318b2faa
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/PushTransformationTestCase.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.stream.XMLStreamReader;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.databinding.impl.PipedTransformer;
+import org.w3c.dom.Node;
+import org.xml.sax.ContentHandler;
+
+public class PushTransformationTestCase extends TestCase {
+ private static final String IPO_XML =
+ "<?xml version=\"1.0\"?>" + "<ipo:purchaseOrder"
+ + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
+ + " xmlns:ipo=\"http://www.example.com/IPO\""
+ + " xsi:schemaLocation=\"http://www.example.com/IPO ipo.xsd\""
+ + " orderDate=\"1999-12-01\">"
+ + " <shipTo exportCode=\"1\" xsi:type=\"ipo:UKAddress\">"
+ + " <name>Helen Zoe</name>"
+ + " <street>47 Eden Street</street>"
+ + " <city>Cambridge</city>"
+ + " <postcode>CB1 1JR</postcode>"
+ + " </shipTo>"
+ + " <billTo xsi:type=\"ipo:USAddress\">"
+ + " <name>Robert Smith</name>"
+ + " <street>8 Oak Avenue</street>"
+ + " <city>Old Town</city>"
+ + " <state>PA</state>"
+ + " <zip>95819</zip>"
+ + " </billTo>"
+ + " <items>"
+ + " <item partNum=\"833-AA\">"
+ + " <productName>Lapis necklace</productName>"
+ + " <quantity>1</quantity>"
+ + " <USPrice>99.95</USPrice>"
+ + " <ipo:comment>Want this for the holidays</ipo:comment>"
+ + " <shipDate>1999-12-05</shipDate>"
+ + " </item>"
+ + " </items>"
+ + "</ipo:purchaseOrder>";
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public void testTransformation() {
+ String2XMLStreamReader t1 = new String2XMLStreamReader();
+ XMLStreamReader reader = t1.transform(IPO_XML, null);
+ XMLStreamReader2SAX t2 = new XMLStreamReader2SAX();
+ PipedTransformer<XMLStreamReader, ContentHandler, Node> t3 =
+ new PipedTransformer<XMLStreamReader, ContentHandler, Node>(t2, new SAX2DOMPipe());
+ Node node = t3.transform(reader, null);
+ Assert.assertNotNull(node);
+ Node2String t4 = new Node2String();
+ String xml = t4.transform(node, null);
+ Assert.assertTrue(xml != null && xml.indexOf("<shipDate>1999-12-05</shipDate>") != -1);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/StAXHelperTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/StAXHelperTestCase.java
new file mode 100644
index 0000000000..7d18e83ac6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/StAXHelperTestCase.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.xml;
+
+import javax.xml.stream.XMLStreamReader;
+
+import junit.framework.TestCase;
+
+/**
+ * Test Case for StAXHelper
+ */
+public class StAXHelperTestCase extends TestCase {
+ private static final String XML =
+ "<a:foo xmlns:a='http://a' name='foo'><bar name='bar'>" + "<doo a:name='doo' xmlns:a='http://doo'/>"
+ + "</bar></a:foo>";
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public void testHelper() throws Exception {
+ XMLStreamReader reader = StAXHelper.createXMLStreamReader(XML);
+ String xml = StAXHelper.save(reader);
+ reader = StAXHelper.createXMLStreamReader(xml);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/TraxTransformerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/TraxTransformerTestCase.java
new file mode 100644
index 0000000000..7e9494d423
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/databinding/xml/TraxTransformerTestCase.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.databinding.xml;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+import org.w3c.dom.Node;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ *
+ */
+public class TraxTransformerTestCase extends TestCase {
+ private URL url;
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ url = getClass().getResource("foo.xml");
+ }
+
+ public void testTransformDOM() throws IOException {
+ InputStream is = url.openStream();
+ InputStream2Node t1 = new InputStream2Node();
+ Node node = t1.transform(is, null);
+ is.close();
+ Writer writer = new StringWriter();
+ Node2Writer t2 = new Node2Writer();
+ t2.transform(node, writer, null);
+ String str = writer.toString();
+ StringReader reader = new StringReader(str);
+ Reader2Node t3 = new Reader2Node();
+ node = t3.transform(reader, null);
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ Node2OutputStream t4 = new Node2OutputStream();
+ t4.transform(node, os, null);
+ InputSource inputSource = new InputSource(new ByteArrayInputStream(os.toByteArray()));
+ InputSource2Node t5 = new InputSource2Node();
+ node = t5.transform(inputSource, null);
+ }
+
+ public void testTransformSAX() throws IOException {
+ MyContentHandler handler = new MyContentHandler();
+ InputStream is = url.openStream();
+ InputStream2SAX t1 = new InputStream2SAX();
+ t1.transform(is, handler, null);
+ is.close();
+
+ String xml = "<foo xmlns=\"http://foo\">bar</foo>";
+
+ InputSource inputSource = new InputSource(new StringReader(xml));
+ InputSource2SAX t2 = new InputSource2SAX();
+ MyContentHandler handler2 = new MyContentHandler();
+ t2.transform(inputSource, handler2, null);
+
+ }
+
+ private static class MyContentHandler extends DefaultHandler {
+
+ @Override
+ public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
+ throws SAXException {
+ super.startElement(namespaceURI, localName, qName, atts);
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/deployer/BootstrapDeployerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/deployer/BootstrapDeployerTestCase.java
new file mode 100644
index 0000000000..20ae7eecb8
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/deployer/BootstrapDeployerTestCase.java
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.deployer;
+
+import java.net.URL;
+import java.util.Collection;
+import java.util.Map;
+import javax.xml.stream.XMLInputFactory;
+
+import org.apache.tuscany.spi.bootstrap.ComponentNames;
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.model.BindingDefinition;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.ComponentType;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.CompositeReferenceDefinition;
+import org.apache.tuscany.spi.model.Implementation;
+import org.apache.tuscany.spi.model.Include;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.PropertyValue;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.bootstrap.Bootstrapper;
+import org.apache.tuscany.core.bootstrap.DefaultBootstrapper;
+import org.apache.tuscany.core.implementation.system.model.SystemCompositeImplementation;
+import org.apache.tuscany.core.mock.component.BasicInterface;
+import org.apache.tuscany.core.monitor.NullMonitorFactory;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * Verifies the default boostrap deployer
+ *
+ * @version $Rev$ $Date$
+ */
+public class BootstrapDeployerTestCase extends TestCase {
+ private DeployerImpl deployer;
+ private DeploymentContext deploymentContext;
+ private ComponentDefinition<SystemCompositeImplementation> componentDefinition;
+ private SystemCompositeImplementation implementation;
+
+ @SuppressWarnings("unchecked")
+ public void testBoot1Load() throws LoaderException {
+ CompositeComponent parent = createNiceMock(CompositeComponent.class);
+ URL scdl = BootstrapDeployerTestCase.class.getResource("boot1.scdl");
+ implementation.setScdlLocation(scdl);
+ deployer.load(parent, componentDefinition, deploymentContext);
+ CompositeComponentType<ServiceDefinition, CompositeReferenceDefinition, Property<?>> composite =
+ implementation.getComponentType();
+ assertNotNull(composite);
+ assertEquals("boot1", composite.getName());
+
+ // check parse of <service>
+ Map<String, ServiceDefinition> services = composite.getDeclaredServices();
+ assertEquals(1, services.size()); // included doesn't count
+ services = composite.getServices();
+ assertEquals(2, services.size()); // included counts
+ ServiceDefinition serviceDefinition = services.get("service");
+ assertNotNull(serviceDefinition);
+ assertEquals("service", serviceDefinition.getName());
+ assertEquals(BasicInterface.class, serviceDefinition.getServiceContract().getInterfaceClass());
+ Collection<BindingDefinition> bindings = serviceDefinition.getBindings();
+ assertTrue(bindings.isEmpty());
+
+ // check parse of <component>
+ Map<String, ComponentDefinition<? extends Implementation<?>>> components = composite.getDeclaredComponents();
+ assertEquals(1, components.size()); // included doesn't count
+ components = composite.getComponents();
+ assertEquals(2, components.size()); // included counts
+ ComponentDefinition<? extends Implementation<?>> component = components.get("component");
+ assertNotNull(component);
+ PropertyValue<?> propVal = component.getPropertyValues().get("publicProperty");
+ assertEquals("propval", propVal.getValueFactory().getInstance());
+
+ // check introspection of implementation
+ ComponentType<?, ?, ?> componentType = component.getImplementation().getComponentType();
+ assertNotNull(componentType); // details checked in SystemComponentTypeLoaderTestCase
+
+ // check included component
+ Map<String, Include> includes = composite.getIncludes();
+ assertEquals(1, includes.size());
+ Include include = includes.get("boot1-include");
+ assertNotNull(include);
+ CompositeComponentType included = include.getIncluded();
+ assertNotNull(included);
+ assertEquals(1, included.getComponents().size());
+ }
+
+ public void testBoot1Deployment() throws Exception {
+ URL scdl = BootstrapDeployerTestCase.class.getResource("boot1.scdl");
+ implementation.setScdlLocation(scdl);
+ CompositeComponent parent = createNiceMock(CompositeComponent.class);
+ parent.register(isA(SCAObject.class));
+ replay(parent);
+ // load the boot1 file using the bootstrap deployer
+ componentDefinition.setName("simple");
+ Component component = deployer.deploy(parent, componentDefinition);
+ assertNotNull(component);
+ verify(parent);
+ }
+
+ public void testBoot2Deployment() throws Exception {
+ URL scdl = BootstrapDeployerTestCase.class.getResource("boot2.scdl");
+ implementation.setScdlLocation(scdl);
+ CompositeComponent parent = createNiceMock(CompositeComponent.class);
+ parent.register(isA(SCAObject.class));
+ replay(parent);
+
+ // load the boot2 file using the bootstrap deployer
+ componentDefinition.setName("newDeployer");
+ CompositeComponent component = (CompositeComponent) deployer.deploy(parent, componentDefinition);
+ assertNotNull(component);
+ verify(parent);
+ component.start();
+ SCAObject newDeployer = component.getSystemChild(ComponentNames.TUSCANY_DEPLOYER);
+ assertNotNull(newDeployer);
+ SCAObject wireService = component.getSystemChild(ComponentNames.TUSCANY_WIRE_SERVICE);
+ assertNotNull(wireService);
+
+/* // FIXME
+ // load the boot2 file using the newly loaded deployer
+ parent.reset();
+ parent.expects(once()).method("register").withAnyArguments();
+ componentDefinition.setName("newDeployer2");
+ component = newDeployer.deploy((CompositeComponent) parent.proxy(), componentDefinition);
+ assertNotNull(component);
+ parent.verify();
+ component.start();
+ Deployer newDeployer2 = (Deployer) component.getServiceInstance("deployer");
+ assertNotNull(newDeployer2);
+*/
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ XMLInputFactory xmlFactory = XMLInputFactory.newInstance();
+ Bootstrapper bootstrapper = new DefaultBootstrapper(new NullMonitorFactory(), xmlFactory, null);
+ deployer = (DeployerImpl) bootstrapper.createDeployer();
+ deploymentContext = new RootDeploymentContext(null, xmlFactory, null, null);
+ implementation = new SystemCompositeImplementation();
+ implementation.setClassLoader(getClass().getClassLoader());
+ componentDefinition = new ComponentDefinition<SystemCompositeImplementation>(implementation);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/idl/java/ConversationalIntrospectionTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/idl/java/ConversationalIntrospectionTestCase.java
new file mode 100644
index 0000000000..5b0fe34705
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/idl/java/ConversationalIntrospectionTestCase.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.idl.java;
+
+import org.osoa.sca.annotations.EndsConversation;
+import org.osoa.sca.annotations.Scope;
+
+import org.apache.tuscany.spi.idl.InvalidConversationalOperationException;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import static org.apache.tuscany.spi.model.InteractionScope.CONVERSATIONAL;
+import static org.apache.tuscany.spi.model.InteractionScope.NONCONVERSATIONAL;
+import org.apache.tuscany.spi.model.Operation;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ConversationalIntrospectionTestCase extends TestCase {
+ private JavaInterfaceProcessorRegistryImpl registry = new JavaInterfaceProcessorRegistryImpl();
+
+ public void testServiceContractConversationalInformationIntrospection() throws Exception {
+ JavaServiceContract contract = registry.introspect(Foo.class);
+ assertEquals(CONVERSATIONAL, contract.getInteractionScope());
+ int seq = contract.getOperations().get("operation").getConversationSequence();
+ assertEquals(Operation.CONVERSATION_CONTINUE, seq);
+ seq = contract.getOperations().get("endOperation").getConversationSequence();
+ assertEquals(Operation.CONVERSATION_END, seq);
+ }
+
+ public void testBadServiceContract() throws Exception {
+ try {
+ registry.introspect(BadFoo.class);
+ fail();
+ } catch (InvalidConversationalOperationException e) {
+ //expected
+ }
+ }
+
+ public void testNonConversationalInformationIntrospection() throws Exception {
+ JavaServiceContract contract = registry.introspect(NonConversationalFoo.class);
+ assertEquals(NONCONVERSATIONAL, contract.getInteractionScope());
+ int seq = contract.getOperations().get("operation").getConversationSequence();
+ assertEquals(Operation.NO_CONVERSATION, seq);
+ }
+
+ @Scope("CONVERSATION")
+ private interface Foo {
+ void operation();
+
+ @EndsConversation
+ void endOperation();
+ }
+
+ private interface BadFoo {
+ void operation();
+
+ @EndsConversation
+ void endOperation();
+ }
+
+ private interface NonConversationalFoo {
+ void operation();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/idl/java/JavaInterfaceProcessorRegistryImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/idl/java/JavaInterfaceProcessorRegistryImplTestCase.java
new file mode 100644
index 0000000000..e3a7deb10a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/idl/java/JavaInterfaceProcessorRegistryImplTestCase.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.idl.java;
+
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessor;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.DataType;
+import org.apache.tuscany.spi.model.Operation;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.util.JavaIntrospectionHelper;
+import org.easymock.EasyMock;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JavaInterfaceProcessorRegistryImplTestCase extends TestCase {
+ private JavaInterfaceProcessorRegistryImpl impl;
+
+ public void testSimpleInterface() throws InvalidServiceContractException {
+ JavaServiceContract contract = impl.introspect(Simple.class);
+ // TODO spec to clairfy interface name
+ assertEquals(JavaIntrospectionHelper.getBaseName(Simple.class), contract.getInterfaceName());
+ assertEquals(Simple.class, contract.getInterfaceClass());
+ Map<String, Operation<Type>> operations = contract.getOperations();
+ assertEquals(1, operations.size());
+ Operation<Type> baseInt = operations.get("baseInt");
+ assertNotNull(baseInt);
+
+ DataType<Type> returnType = baseInt.getOutputType();
+ assertEquals(Integer.TYPE, returnType.getPhysical());
+ assertEquals(Integer.TYPE, returnType.getLogical());
+
+ List<DataType<Type>> parameterTypes = baseInt.getInputType().getLogical();
+ assertEquals(1, parameterTypes.size());
+ DataType<Type> arg0 = parameterTypes.get(0);
+ assertEquals(Integer.TYPE, arg0.getPhysical());
+ assertEquals(Integer.TYPE, arg0.getLogical());
+
+ List<DataType<Type>> faultTypes = baseInt.getFaultTypes();
+ assertEquals(1, faultTypes.size());
+ DataType<Type> fault0 = faultTypes.get(0);
+ assertEquals(IllegalArgumentException.class, fault0.getPhysical());
+ assertEquals(IllegalArgumentException.class, fault0.getLogical());
+ }
+
+ public void testUnregister() throws Exception {
+ JavaInterfaceProcessor processor = createMock(JavaInterfaceProcessor.class);
+ processor.visitInterface(eq(Base.class), EasyMock.same((Class)null), isA(JavaServiceContract.class));
+ expectLastCall().once();
+ replay(processor);
+ impl.registerProcessor(processor);
+ impl.introspect(Base.class);
+ impl.unregisterProcessor(processor);
+ impl.introspect(Base.class);
+ verify(processor);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ impl = new JavaInterfaceProcessorRegistryImpl();
+
+ }
+
+ private static interface Base {
+ int baseInt(int param) throws IllegalArgumentException;
+ }
+
+ private static interface Simple extends Base {
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/IntrospectionRegistryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/IntrospectionRegistryTestCase.java
new file mode 100644
index 0000000000..fb5e7fbb1f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/IntrospectionRegistryTestCase.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Field;
+import java.lang.reflect.Constructor;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessor;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.IntrospectionRegistryImpl.Monitor;
+import org.apache.tuscany.core.monitor.NullMonitorFactory;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class IntrospectionRegistryTestCase extends TestCase {
+
+ private Monitor monitor;
+
+ public void testRegister() throws Exception {
+ IntrospectionRegistryImpl registry = new IntrospectionRegistryImpl(monitor);
+ ImplementationProcessor processor = EasyMock.createNiceMock(ImplementationProcessor.class);
+ registry.registerProcessor(processor);
+ }
+
+ public void testUnegister() throws Exception {
+ IntrospectionRegistryImpl registry = new IntrospectionRegistryImpl(monitor);
+ ImplementationProcessor processor = EasyMock.createNiceMock(ImplementationProcessor.class);
+ registry.registerProcessor(processor);
+ registry.unregisterProcessor(processor);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testWalk() throws Exception {
+ IntrospectionRegistryImpl registry = new IntrospectionRegistryImpl(monitor);
+ ImplementationProcessor processor = EasyMock.createMock(ImplementationProcessor.class);
+ processor.visitClass(EasyMock.isA(CompositeComponent.class),
+ EasyMock.eq(Bar.class),
+ EasyMock.isA(PojoComponentType.class),
+ EasyMock.isA(DeploymentContext.class));
+ processor.visitConstructor(EasyMock.isA(CompositeComponent.class),
+ EasyMock.isA(Constructor.class),
+ EasyMock.isA(PojoComponentType.class),
+ EasyMock.isA(DeploymentContext.class));
+ processor.visitMethod(EasyMock.isA(CompositeComponent.class),
+ EasyMock.isA(Method.class),
+ EasyMock.isA(PojoComponentType.class),
+ EasyMock.isA(DeploymentContext.class));
+ processor.visitField(EasyMock.isA(CompositeComponent.class),
+ EasyMock.isA(Field.class),
+ EasyMock.isA(PojoComponentType.class),
+ EasyMock.isA(DeploymentContext.class));
+ processor.visitSuperClass(EasyMock.isA(CompositeComponent.class),
+ EasyMock.isA(Class.class),
+ EasyMock.isA(PojoComponentType.class),
+ EasyMock.isA(DeploymentContext.class));
+ processor.visitEnd(EasyMock.isA(CompositeComponent.class),
+ EasyMock.isA(Class.class),
+ EasyMock.isA(PojoComponentType.class),
+ EasyMock.isA(DeploymentContext.class));
+
+ // mock.expects(once()).method("visitClass");
+// mock.expects(once()).method("visitMethod");
+// mock.expects(once()).method("visitField");
+// mock.expects(once()).method("visitConstructor");
+// mock.expects(once()).method("visitSuperClass");
+// mock.expects(once()).method("visitEnd");
+ EasyMock.replay(processor);
+ registry.registerProcessor(processor);
+ registry.introspect(EasyMock.createNiceMock(CompositeComponent.class),
+ Bar.class,
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>(),
+ EasyMock.createNiceMock(DeploymentContext.class));
+ EasyMock.verify(processor);
+ }
+
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ monitor = new NullMonitorFactory().getMonitor(Monitor.class);
+ }
+
+ private class Baz {
+
+ }
+
+ private class Bar extends Baz {
+
+ protected String bar;
+
+ public Bar() {
+ }
+
+ public void bar() {
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/PojoAtomicComponentTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/PojoAtomicComponentTestCase.java
new file mode 100644
index 0000000000..6fcef3622e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/PojoAtomicComponentTestCase.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation;
+
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.TargetInvokerCreationException;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.injection.EventInvoker;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class PojoAtomicComponentTestCase extends TestCase {
+ private PojoObjectFactory<Foo> factory;
+
+ @SuppressWarnings({"unchecked"})
+ public void testDestroy() throws Exception {
+ PojoConfiguration config = new PojoConfiguration();
+ config.setInstanceFactory(factory);
+ EventInvoker<Object> invoker = EasyMock.createMock(EventInvoker.class);
+ invoker.invokeEvent(EasyMock.notNull());
+ EasyMock.replay(invoker);
+ config.setDestroyInvoker(invoker);
+ AtomicComponent component = new TestAtomicComponent(config);
+ assertTrue(component.isDestroyable());
+ component.destroy(new Object());
+ EasyMock.verify(invoker);
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public void testInit() throws Exception {
+ PojoConfiguration config = new PojoConfiguration();
+ config.setInstanceFactory(factory);
+ EventInvoker<Object> invoker = EasyMock.createMock(EventInvoker.class);
+ invoker.invokeEvent(EasyMock.notNull());
+ EasyMock.replay(invoker);
+ config.setInitInvoker(invoker);
+ AtomicComponent component = new TestAtomicComponent(config);
+ component.init(new Object());
+ EasyMock.verify(invoker);
+ }
+
+ public void testOptimizable() throws Exception {
+ PojoConfiguration config = new PojoConfiguration();
+ config.setInstanceFactory(factory);
+ TestAtomicComponent component = new TestAtomicComponent(config);
+ assertTrue(component.isOptimizable());
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public void testDestroyableButOptimizable() throws Exception {
+ PojoConfiguration config = new PojoConfiguration();
+ config.setInstanceFactory(factory);
+ EventInvoker<Object> invoker = EasyMock.createMock(EventInvoker.class);
+ invoker.invokeEvent(EasyMock.notNull());
+ EasyMock.replay(invoker);
+ config.setDestroyInvoker(invoker);
+ TestAtomicComponent component = new TestAtomicComponent(config);
+ assertTrue(component.isOptimizable());
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public void testStatelessOptimizable() throws Exception {
+ PojoConfiguration config = new PojoConfiguration();
+ config.setInstanceFactory(factory);
+ TestStatelessAtomicComponent component = new TestStatelessAtomicComponent(config);
+ assertTrue(component.isOptimizable());
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public void testNotOptimizable() throws Exception {
+ PojoConfiguration config = new PojoConfiguration();
+ config.setInstanceFactory(factory);
+ EventInvoker<Object> invoker = EasyMock.createMock(EventInvoker.class);
+ invoker.invokeEvent(EasyMock.notNull());
+ EasyMock.replay(invoker);
+ config.setDestroyInvoker(invoker);
+ TestStatelessAtomicComponent component = new TestStatelessAtomicComponent(config);
+ assertFalse(component.isOptimizable());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ factory = new PojoObjectFactory<Foo>(Foo.class.getConstructor());
+ }
+
+ private class TestAtomicComponent extends PojoAtomicComponent {
+
+ public TestAtomicComponent(PojoConfiguration configuration) {
+ super(configuration);
+ }
+
+ public Scope getScope() {
+ return Scope.COMPOSITE;
+ }
+
+ protected ObjectFactory<?> createWireFactory(Class<?> interfaze, OutboundWire wire) {
+ return null;
+ }
+
+ public TargetInvoker createTargetInvoker(String targetName, Operation operation, InboundWire callbackWire)
+ throws TargetInvokerCreationException {
+ return null;
+ }
+ }
+
+ private class TestStatelessAtomicComponent extends PojoAtomicComponent {
+
+ public TestStatelessAtomicComponent(PojoConfiguration configuration) {
+ super(configuration);
+ }
+
+ public Scope getScope() {
+ return Scope.STATELESS;
+ }
+
+ protected ObjectFactory<?> createWireFactory(Class<?> interfaze, OutboundWire wire) {
+ return null;
+ }
+
+ public TargetInvoker createTargetInvoker(String targetName, Operation operation, InboundWire callbackWire)
+ throws TargetInvokerCreationException {
+ return null;
+ }
+ }
+
+ private static class Foo {
+ public Foo() {
+ }
+ }
+
+}
+
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/TestUtils.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/TestUtils.java
new file mode 100644
index 0000000000..e18fc99861
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/TestUtils.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.core.implementation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.wire.InboundWireImpl;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public final class TestUtils {
+ private static final JavaInterfaceProcessorRegistry REGISTRY = new JavaInterfaceProcessorRegistryImpl();
+
+ private TestUtils() {
+ }
+
+ public static List<InboundWire> populateInboundWires(AtomicComponent component, List<InboundWire> wires)
+ throws InvalidServiceContractException {
+ for (InboundWire wire : wires) {
+ wire.setContainer(component);
+ }
+ return wires;
+ }
+
+ public static List<InboundWire> createInboundWires(List<Class<?>> interfazes)
+ throws InvalidServiceContractException {
+ List<InboundWire> wires = new ArrayList<InboundWire>(interfazes.size());
+ for (Class<?> interfaze : interfazes) {
+ InboundWire wire = createInboundWire(interfaze);
+ wires.add(wire);
+ }
+ return wires;
+ }
+
+ public static InboundWire createInboundWire(Class<?> interfaze) throws InvalidServiceContractException {
+ InboundWire wire = new InboundWireImpl();
+ JavaServiceContract contract = REGISTRY.introspect(interfaze);
+ wire.setServiceContract(contract);
+ return wire;
+ }
+
+ public static InboundWire createInboundWire(Class<?> interfaze, CompositeComponent parent)
+ throws InvalidServiceContractException {
+ InboundWire wire = createInboundWire(interfaze);
+ wire.setContainer(parent);
+ return wire;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/AutowireResolutionTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/AutowireResolutionTestCase.java
new file mode 100644
index 0000000000..c644c3d7c4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/AutowireResolutionTestCase.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.TestUtils;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * Verfies specific autowire resolution scenarios
+ *
+ * @version $Rev$ $Date$
+ */
+public class AutowireResolutionTestCase extends TestCase {
+
+ public void testConstruction() {
+ CompositeComponent parent = createMock(CompositeComponent.class);
+ replay(parent);
+ CompositeComponent component = new CompositeComponentImpl("test", parent, null, null);
+ assertEquals("test", component.getName());
+ assertSame(parent, component.getParent());
+ verify(parent);
+ }
+
+ public void testResolvedByAutowire() throws Exception {
+ CompositeComponent parent = createMock(CompositeComponent.class);
+ InboundWire wire = TestUtils.createInboundWire(Foo.class, parent);
+ EasyMock.expect(parent.resolveAutowire(eq(Foo.class))).andReturn(wire);
+ EasyMock.expect(parent.resolveSystemAutowire(eq(Foo.class))).andReturn(null);
+ replay(parent);
+ CompositeComponent component = new CompositeComponentImpl("test", parent, null, null);
+ assertSame(wire, component.resolveAutowire(Foo.class));
+ verify(parent);
+ }
+
+ public void testSystemResolvedByAutowire() throws Exception {
+ CompositeComponent parent = createMock(CompositeComponent.class);
+ InboundWire wire = TestUtils.createInboundWire(Foo.class, parent);
+ EasyMock.expect(parent.resolveSystemAutowire(eq(Foo.class))).andReturn(wire);
+ replay(parent);
+ CompositeComponent component = new CompositeComponentImpl("test", parent, null, null);
+ assertSame(wire, component.resolveSystemAutowire(Foo.class));
+ verify(parent);
+ }
+
+ /**
+ * Verify parent resolution strategy for application serviceBindings
+ */
+ public void testNamespaceIsolationAutowire() throws Exception {
+ Foo foo = new Foo() {
+ };
+ CompositeComponent parent = new CompositeComponentImpl("parent", null, null, null);
+ parent.registerJavaObject("foo", Foo.class, foo);
+ CompositeComponent component = new CompositeComponentImpl("test", parent, null, null);
+ assertNotNull(component.resolveAutowire(Foo.class));
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public static interface Foo {
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/AutowireTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/AutowireTestCase.java
new file mode 100644
index 0000000000..341efcd09c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/AutowireTestCase.java
@@ -0,0 +1,230 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.Reference;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.Service;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.TestUtils;
+import org.easymock.EasyMock;
+
+/**
+ * Performs basic autowiring tests to composite artifacts
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class AutowireTestCase extends TestCase {
+
+ /**
+ * Tests autowiring to an system atomic component
+ */
+ public void testSystemAtomicAutowire() throws Exception {
+ CompositeComponent parent = new CompositeComponentImpl("parent", null, null, true);
+ parent.start();
+ List<Class<?>> interfaces = new ArrayList<Class<?>>();
+ interfaces.add(Source.class);
+ interfaces.add(Source2.class);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("source").atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(true).atLeastOnce();
+ List<InboundWire> wires = TestUtils.createInboundWires(interfaces);
+ EasyMock.expect(component.getInboundWires()).andReturn(wires).atLeastOnce();
+ TestUtils.populateInboundWires(component, wires);
+ EasyMock.replay(component);
+ parent.register(component);
+ InboundWire source = parent.resolveSystemAutowire(Source.class);
+ assertNotNull(source);
+ InboundWire sourceBase = parent.resolveSystemAutowire(SourceBase.class);
+ assertSame(source, sourceBase);
+ InboundWire source2 = parent.resolveSystemAutowire(Source2.class);
+ assertSame(source.getContainer(), source2.getContainer());
+ assertNull(parent.resolveSystemExternalAutowire(Source.class));
+ EasyMock.verify(component);
+ }
+
+ /**
+ * Tests autowiring to an system atomic component
+ */
+ public void testAtomicAutowire() throws Exception {
+ CompositeComponent parent = new CompositeComponentImpl("parent", null, null, null);
+ parent.start();
+
+ List<Class<?>> interfaces = new ArrayList<Class<?>>();
+ interfaces.add(Source.class);
+ interfaces.add(Source2.class);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("source").atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(false).atLeastOnce();
+ List<InboundWire> wires = TestUtils.createInboundWires(interfaces);
+ EasyMock.expect(component.getInboundWires()).andReturn(wires).atLeastOnce();
+ TestUtils.populateInboundWires(component, wires);
+
+ EasyMock.replay(component);
+ parent.register(component);
+
+ InboundWire source = parent.resolveAutowire(Source.class);
+ assertNotNull(source);
+ InboundWire sourceBase = parent.resolveAutowire(SourceBase.class);
+ assertSame(source, sourceBase);
+ InboundWire source2 = parent.resolveAutowire(Source2.class);
+ assertSame(source.getContainer(), source2.getContainer());
+ assertNull(parent.resolveExternalAutowire(Source.class));
+ EasyMock.verify(component);
+ }
+
+ /**
+ * Tests autowiring to a system service
+ */
+ public void testSystemServiceAutowire() throws Exception {
+ CompositeComponent parent = new CompositeComponentImpl("parent", null, null, true);
+ parent.start();
+
+ ServiceBinding serviceBinding = EasyMock.createMock(ServiceBinding.class);
+ InboundWire wire = TestUtils.createInboundWire(Source.class);
+ wire.setContainer(serviceBinding);
+ EasyMock.expect(serviceBinding.getInboundWire()).andReturn(wire).atLeastOnce();
+ EasyMock.replay(serviceBinding);
+
+ List<ServiceBinding> bindings = new ArrayList<ServiceBinding>();
+ bindings.add(serviceBinding);
+ Service service = EasyMock.createMock(Service.class);
+ EasyMock.expect(service.getName()).andReturn("service").atLeastOnce();
+ EasyMock.expect(service.isSystem()).andReturn(true).atLeastOnce();
+
+ EasyMock.expect(service.getServiceBindings()).andReturn(bindings).atLeastOnce();
+ EasyMock.replay(service);
+ parent.register(service);
+
+ InboundWire source = parent.resolveSystemExternalAutowire(Source.class);
+ assertSame(serviceBinding, source.getContainer());
+ InboundWire sourceBase = parent.resolveSystemExternalAutowire(SourceBase.class);
+ assertSame(source, sourceBase);
+ InboundWire source2 = parent.resolveSystemExternalAutowire(Source2.class);
+ assertNull(source2);
+ EasyMock.verify(serviceBinding);
+ }
+
+ /**
+ * Tests autowiring to a service
+ */
+ public void testServiceAutowire() throws Exception {
+ CompositeComponent parent = new CompositeComponentImpl("parent", null, null, true);
+ parent.start();
+
+ ServiceBinding serviceBinding = EasyMock.createMock(ServiceBinding.class);
+ InboundWire wire = TestUtils.createInboundWire(Source.class);
+ wire.setContainer(serviceBinding);
+ EasyMock.expect(serviceBinding.getInboundWire()).andReturn(wire).atLeastOnce();
+ EasyMock.replay(serviceBinding);
+
+ List<ServiceBinding> bindings = new ArrayList<ServiceBinding>();
+ bindings.add(serviceBinding);
+ Service service = EasyMock.createMock(Service.class);
+ EasyMock.expect(service.getName()).andReturn("service").atLeastOnce();
+ EasyMock.expect(service.isSystem()).andReturn(false).atLeastOnce();
+
+ EasyMock.expect(service.getServiceBindings()).andReturn(bindings).atLeastOnce();
+ EasyMock.replay(service);
+ parent.register(service);
+
+ InboundWire source = parent.resolveExternalAutowire(Source.class);
+ assertSame(serviceBinding, source.getContainer());
+ InboundWire sourceBase = parent.resolveExternalAutowire(SourceBase.class);
+ assertSame(source, sourceBase);
+ InboundWire source2 = parent.resolveExternalAutowire(Source2.class);
+ assertNull(source2);
+ EasyMock.verify(serviceBinding);
+ }
+
+
+ /**
+ * Tests autowiring to a system reference
+ */
+ public void testSystemReferenceAutowire() throws Exception {
+ CompositeComponent parent = new CompositeComponentImpl("parent", null, null, true);
+ parent.start();
+
+ ReferenceBinding binding = EasyMock.createMock(ReferenceBinding.class);
+ binding.setReference(EasyMock.isA(Reference.class));
+ InboundWire wire = TestUtils.createInboundWire(Source.class);
+ wire.setContainer(binding);
+ EasyMock.expect(binding.getInboundWire()).andReturn(wire).atLeastOnce();
+ EasyMock.replay(binding);
+
+ Reference reference = new ReferenceImpl("foo", null, wire.getServiceContract(), true);
+ reference.addReferenceBinding(binding);
+ parent.register(reference);
+
+ InboundWire source = parent.resolveSystemAutowire(Source.class);
+ assertNotNull(source);
+ InboundWire sourceBase = parent.resolveSystemAutowire(SourceBase.class);
+ assertSame(source, sourceBase);
+ EasyMock.verify(binding);
+ }
+
+ /**
+ * Tests autowiring to a reference
+ */
+ public void testReferenceAutowire() throws Exception {
+ CompositeComponent parent = new CompositeComponentImpl("parent", null, null, true);
+ parent.start();
+
+ ReferenceBinding binding = EasyMock.createMock(ReferenceBinding.class);
+ binding.setReference(EasyMock.isA(Reference.class));
+ InboundWire wire = TestUtils.createInboundWire(Source.class);
+ wire.setContainer(binding);
+ EasyMock.expect(binding.getInboundWire()).andReturn(wire).atLeastOnce();
+ EasyMock.replay(binding);
+
+ Reference reference = new ReferenceImpl("foo", null, wire.getServiceContract(), false);
+ reference.addReferenceBinding(binding);
+ parent.register(reference);
+
+ InboundWire source = parent.resolveAutowire(Source.class);
+ assertNotNull(source);
+ InboundWire sourceBase = parent.resolveAutowire(SourceBase.class);
+ assertSame(source, sourceBase);
+ EasyMock.verify(binding);
+ }
+
+
+ public static class SourceImpl implements Source, Source2 {
+ public SourceImpl() {
+ }
+ }
+
+ public static interface SourceBase {
+ }
+
+ public static interface Source extends SourceBase {
+ }
+
+ public static interface Source2 {
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeBuilderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeBuilderTestCase.java
new file mode 100644
index 0000000000..2c47eab4ba
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeBuilderTestCase.java
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.net.URI;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ScopeContainerMonitor;
+import org.apache.tuscany.spi.component.Service;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.ComponentReferenceDefinition;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.CompositeImplementation;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.CompositeReferenceDefinition;
+import org.apache.tuscany.spi.model.ReferenceTarget;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.apache.tuscany.spi.wire.WireService;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.binding.local.LocalBindingBuilder;
+import org.apache.tuscany.core.binding.local.LocalBindingDefinition;
+import org.apache.tuscany.core.builder.BuilderRegistryImpl;
+import org.apache.tuscany.core.component.scope.CompositeScopeContainer;
+import org.apache.tuscany.core.deployer.RootDeploymentContext;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.implementation.java.JavaComponentBuilder;
+import org.apache.tuscany.core.implementation.java.JavaImplementation;
+import org.apache.tuscany.core.mock.component.OtherTarget;
+import org.apache.tuscany.core.mock.component.Source;
+import org.apache.tuscany.core.mock.component.SourceImpl;
+import org.apache.tuscany.core.mock.component.Target;
+import org.apache.tuscany.core.mock.component.TargetImpl;
+import org.apache.tuscany.core.wire.jdk.JDKWireService;
+import org.easymock.EasyMock;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public class CompositeBuilderTestCase extends TestCase {
+ private DeploymentContext deploymentContext;
+
+ @SuppressWarnings("unchecked")
+ public void testBuild() throws Exception {
+ CompositeComponent parent = new CompositeComponentImpl(null, null, null, null);
+
+ CompositeBuilder builder = new CompositeBuilder();
+ WireService wireService = new JDKWireService();
+ builder.setWireService(wireService);
+ BuilderRegistryImpl builderRegistry = new BuilderRegistryImpl(null, wireService);
+ JavaComponentBuilder jBuilder = new JavaComponentBuilder();
+ jBuilder.setWireService(wireService);
+ builderRegistry.register(JavaImplementation.class, jBuilder);
+ builderRegistry.register(CompositeImplementation.class, builder);
+ builderRegistry.register(LocalBindingDefinition.class, new LocalBindingBuilder());
+ builder.setBuilderRegistry(builderRegistry);
+ CompositeComponent component =
+ (CompositeComponent) builder.build(parent, createTopComponentDef(), deploymentContext);
+
+ component.start();
+ CompositeComponent sourceComponent = (CompositeComponent) component.getChild("SourceComponent");
+ assertTrue(sourceComponent.getChild("InnerSourceService") instanceof Service);
+ AtomicComponent innerSourceComponent = (AtomicComponent) sourceComponent.getChild("InnerSourceComponent");
+ Source innerSourceInstance = (Source) deploymentContext.getCompositeScope().getInstance(innerSourceComponent);
+ assertNotNull(innerSourceInstance);
+ component.stop();
+ }
+
+ private ComponentDefinition createTopComponentDef() throws Exception {
+
+ CompositeComponentType<JavaMappedService, CompositeReferenceDefinition, JavaMappedProperty<?>> outerType =
+ new CompositeComponentType<JavaMappedService, CompositeReferenceDefinition, JavaMappedProperty<?>>();
+ outerType.add(createSourceComponentDef());
+ outerType.add(createTargetComponentDef());
+
+ CompositeImplementation outerImpl = new CompositeImplementation();
+ outerImpl.setComponentType(outerType);
+
+ return new ComponentDefinition<CompositeImplementation>(outerImpl);
+ }
+
+ private ComponentDefinition<CompositeImplementation> createSourceComponentDef() throws Exception {
+
+ CompositeComponentType<ServiceDefinition, CompositeReferenceDefinition, JavaMappedProperty<?>> innerType =
+ new CompositeComponentType<ServiceDefinition, CompositeReferenceDefinition, JavaMappedProperty<?>>();
+ innerType.add(createInnerSourceComponentDef());
+ CompositeReferenceDefinition reference = new CompositeReferenceDefinition();
+ reference.setName("TargetComponentRef");
+ JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ JavaServiceContract targetContract = registry.introspect(Target.class);
+ reference.setServiceContract(targetContract);
+ innerType.add(reference);
+ ServiceDefinition service = new ServiceDefinition();
+ service.setName("InnerSourceService");
+ JavaServiceContract sourceContract = registry.introspect(Source.class);
+ service.setServiceContract(sourceContract);
+ service.setTarget(new URI("InnerSourceComponent"));
+ innerType.add(service);
+
+ CompositeImplementation innerImpl = new CompositeImplementation();
+ innerImpl.setComponentType(innerType);
+
+ ComponentDefinition<CompositeImplementation> sourceComponentDefinition =
+ new ComponentDefinition<CompositeImplementation>("SourceComponent", innerImpl);
+
+ /*ReferenceTarget refTarget = new ReferenceTarget();
+ refTarget.setReferenceName("TargetComponentRef");
+ refTarget.addTarget(new URI("TargetComponent"));
+ sourceComponentDefinition.add(refTarget);*/
+ ComponentReferenceDefinition compRef = new ComponentReferenceDefinition(innerType.getReferences().get("TargetComponentRef"));
+ compRef.setName("TargetComponentRef");
+ compRef.addTarget(new URI("TargetComponent"));
+ sourceComponentDefinition.add(compRef);
+
+ return sourceComponentDefinition;
+ }
+
+ private ComponentDefinition<JavaImplementation> createInnerSourceComponentDef() throws Exception {
+
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> sourceType =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ sourceType.setImplementationScope(Scope.COMPOSITE);
+ JavaMappedReference reference = new JavaMappedReference();
+ reference.setName("targetReference");
+ JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ ServiceContract<?> targetContract = registry.introspect(Target.class);
+ targetContract.setCallbackClass(OtherTarget.class);
+ targetContract.setCallbackName("OtherTarget");
+ reference.setServiceContract(targetContract);
+ reference.setMember(SourceImpl.class.getMethod("setTarget", Target.class));
+ sourceType.add(reference);
+
+ ServiceContract<?> sourceContract = registry.introspect(Source.class);
+
+ JavaMappedService sourceServiceDefinition = new JavaMappedService();
+ sourceServiceDefinition.setName("Source");
+ sourceServiceDefinition.setServiceContract(sourceContract);
+
+ sourceType.add(sourceServiceDefinition);
+ sourceType.setConstructorDefinition(new ConstructorDefinition<SourceImpl>(SourceImpl.class.getConstructor()));
+ JavaImplementation sourceImpl = new JavaImplementation(SourceImpl.class, sourceType);
+ ComponentDefinition<JavaImplementation> innerSourceComponentDefinition =
+ new ComponentDefinition<JavaImplementation>("InnerSourceComponent", sourceImpl);
+
+ ComponentReferenceDefinition compRef = new ComponentReferenceDefinition(sourceType.getReferences().get("targetReference"));
+ compRef.setName("targetReference");
+ compRef.addTarget(new URI("TargetComponentRef"));
+ innerSourceComponentDefinition.add(compRef);
+ /*ReferenceTarget refTarget = new ReferenceTarget();
+ refTarget.setReferenceName("targetReference");
+ refTarget.addTarget(new URI("TargetComponentRef"));
+ innerSourceComponentDefinition.add(refTarget);
+ */
+ return innerSourceComponentDefinition;
+ }
+
+ private ComponentDefinition<JavaImplementation> createTargetComponentDef() throws Exception {
+
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> targetType =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ targetType.setImplementationScope(Scope.COMPOSITE);
+
+ JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ ServiceContract<?> targetContract = registry.introspect(Target.class);
+ targetContract.setCallbackClass(OtherTarget.class);
+ targetContract.setCallbackName("OtherTarget");
+
+ JavaMappedService serviceDefinition = new JavaMappedService();
+ serviceDefinition.setName("Target");
+ serviceDefinition.setServiceContract(targetContract);
+ serviceDefinition.setCallbackReferenceName("otherTarget");
+
+ targetType.add(serviceDefinition);
+ targetType.setConstructorDefinition(new ConstructorDefinition<TargetImpl>(TargetImpl.class.getConstructor()));
+ JavaImplementation targetImpl = new JavaImplementation(TargetImpl.class, targetType);
+ return new ComponentDefinition<JavaImplementation>("TargetComponent", targetImpl);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ ScopeContainerMonitor monitor = EasyMock.createNiceMock(ScopeContainerMonitor.class);
+ CompositeScopeContainer container = new CompositeScopeContainer(monitor);
+ container.start();
+ deploymentContext = new RootDeploymentContext(null, null, container, null);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImplBasicTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImplBasicTestCase.java
new file mode 100644
index 0000000000..1f7c8618d2
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImplBasicTestCase.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.util.Collections;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.Reference;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.Service;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.event.CompositeStart;
+import org.apache.tuscany.core.implementation.TestUtils;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class CompositeComponentImplBasicTestCase extends TestCase {
+ private AtomicComponent component;
+
+ public void testGetScope() {
+ CompositeComponent composite = new CompositeComponentImpl("parent", null, null, null);
+ Assert.assertEquals(Scope.SYSTEM, composite.getScope());
+ }
+
+ public void testReferencesServices() throws Exception {
+ CompositeComponent composite = new CompositeComponentImpl("parent", null, null, null);
+ Service service = EasyMock.createMock(Service.class);
+ EasyMock.expect(service.getName()).andReturn("foo").atLeastOnce();
+ EasyMock.expect(service.isSystem()).andReturn(false).atLeastOnce();
+ service.getServiceBindings();
+ EasyMock.expectLastCall().andReturn(Collections.emptyList()).atLeastOnce();
+ EasyMock.replay(service);
+ composite.register(service);
+ composite.register(getReference("bar"));
+ }
+
+ public void testOnEvent() {
+ CompositeComponent composite = new CompositeComponentImpl("parent", null, null, null);
+ Event event = new Event() {
+ public Object getSource() {
+ return null;
+ }
+ };
+ RuntimeEventListener listener = createMock(RuntimeEventListener.class);
+ listener.onEvent(isA(CompositeStart.class));
+ listener.onEvent(eq(event));
+ expectLastCall();
+ replay(listener);
+ composite.addListener(listener);
+ composite.start();
+ composite.onEvent(event);
+ }
+
+ public void testPrepare() throws Exception {
+ CompositeComponent composite = new CompositeComponentImpl("parent", null, null, null);
+ composite.prepare();
+ }
+
+ private Reference getReference(String name) throws InvalidServiceContractException {
+ ReferenceBinding binding = EasyMock.createNiceMock(ReferenceBinding.class);
+ EasyMock.expect(binding.isSystem()).andReturn(false).atLeastOnce();
+ InboundWire wire = TestUtils.createInboundWire(Bar.class);
+ wire.setContainer(binding);
+ EasyMock.expect(binding.getInboundWire()).andReturn(wire).atLeastOnce();
+
+ binding.getName();
+ expectLastCall().andReturn(name).anyTimes();
+ replay(binding);
+
+ Reference reference = new ReferenceImpl(name, null, wire.getServiceContract());
+ reference.addReferenceBinding(binding);
+ return reference;
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("foo").atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(false).atLeastOnce();
+ component.getInboundWires();
+ EasyMock.expectLastCall().andReturn(Collections.emptyList()).atLeastOnce();
+ EasyMock.replay(component);
+ }
+
+ private interface Bar {
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImplSystemWireTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImplSystemWireTestCase.java
new file mode 100644
index 0000000000..018e068120
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImplSystemWireTestCase.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.PrepareException;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.builder.ConnectorImpl;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class CompositeComponentImplSystemWireTestCase extends TestCase {
+
+ /**
+ * Verifies system services in a CompositeComponentImpl are wired during the parent composite's prepare callback
+ */
+ public void testSystemServiceWire() throws Exception {
+ InboundWire inbound = EasyMock.createMock(InboundWire.class);
+ EasyMock.expect(inbound.getServiceContract()).andReturn(new JavaServiceContract(Foo.class)).atLeastOnce();
+ inbound.getInvocationChains();
+ EasyMock.expectLastCall().andReturn(Collections.emptyMap()).atLeastOnce();
+
+ QualifiedName qName = new QualifiedName("target/bar");
+ OutboundWire outbound = EasyMock.createMock(OutboundWire.class);
+ EasyMock.expect(outbound.getTargetName()).andReturn(qName).atLeastOnce();
+ EasyMock.expect(outbound.isAutowire()).andReturn(false);
+
+ outbound.setTargetWire(EasyMock.eq(inbound));
+ EasyMock.expect(outbound.getServiceContract()).andReturn(new JavaServiceContract(Foo.class)).atLeastOnce();
+ List<OutboundWire> wires = new ArrayList<OutboundWire>();
+ wires.add(outbound);
+ Map<String, List<OutboundWire>> wireMap = new HashMap<String, List<OutboundWire>>();
+ wireMap.put("ref", wires);
+ CompositeComponent parent = new CompositeComponentImpl("foo", "foo", null, new ConnectorImpl(), null);
+ AtomicComponent source = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(source.getScope()).andReturn(Scope.COMPOSITE).atLeastOnce();
+ EasyMock.expect(source.getName()).andReturn("source").atLeastOnce();
+ EasyMock.expect(source.getOutboundWires()).andReturn(wireMap);
+ source.getInboundWires();
+ EasyMock.expectLastCall().andReturn(Collections.emptyList()).atLeastOnce();
+ EasyMock.expect(source.isSystem()).andReturn(true).atLeastOnce();
+ EasyMock.expect(source.getParent()).andReturn(parent).atLeastOnce();
+
+ source.prepare();
+ EasyMock.replay(source);
+
+ EasyMock.expect(outbound.getContainer()).andReturn(source).atLeastOnce();
+ EasyMock.replay(outbound);
+
+ parent.register(source);
+
+ AtomicComponent target = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(target.getName()).andReturn("target").atLeastOnce();
+ EasyMock.expect(target.getInboundWire("bar")).andReturn(inbound).atLeastOnce();
+ List<InboundWire> inboundWires = new ArrayList<InboundWire>();
+ inboundWires.add(inbound);
+ EasyMock.expect(target.getInboundWires()).andReturn(inboundWires).atLeastOnce();
+ EasyMock.expect(target.getScope()).andReturn(Scope.COMPOSITE).atLeastOnce();
+ EasyMock.expect(target.getParent()).andReturn(parent).atLeastOnce();
+
+ target.prepare();
+ target.getOutboundWires();
+ EasyMock.expectLastCall().andReturn(Collections.emptyMap());
+ EasyMock.expect(target.isSystem()).andReturn(true).atLeastOnce();
+ EasyMock.replay(target);
+
+ EasyMock.expect(inbound.getContainer()).andReturn(target);
+ EasyMock.replay(inbound);
+
+ parent.register(target);
+ parent.prepare();
+ EasyMock.verify(source);
+ EasyMock.verify(target);
+ EasyMock.verify(inbound);
+ EasyMock.verify(outbound);
+ }
+
+
+ /**
+ * Verifies an application component cannot be wired to a system service in the same composite
+ */
+ public void testSystemServiceIsolationWire() throws Exception {
+ InboundWire inbound = EasyMock.createMock(InboundWire.class);
+ EasyMock.expect(inbound.getServiceContract()).andReturn(new JavaServiceContract(Foo.class)).atLeastOnce();
+ EasyMock.replay(inbound);
+
+ QualifiedName qName = new QualifiedName("target/bar");
+ OutboundWire outbound = EasyMock.createMock(OutboundWire.class);
+ EasyMock.expect(outbound.isAutowire()).andReturn(false);
+ EasyMock.expect(outbound.getContainer()).andReturn(EasyMock.createNiceMock(SCAObject.class));
+ EasyMock.expect(outbound.getReferenceName()).andReturn("foo");
+ EasyMock.expect(outbound.getTargetName()).andReturn(qName).atLeastOnce();
+ EasyMock.replay(outbound);
+
+ List<OutboundWire> wires = new ArrayList<OutboundWire>();
+ wires.add(outbound);
+ Map<String, List<OutboundWire>> wireMap = new HashMap<String, List<OutboundWire>>();
+ wireMap.put("ref", wires);
+ CompositeComponent parent = new CompositeComponentImpl("foo", "foo", null, new ConnectorImpl(), null);
+ AtomicComponent source = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(source.getName()).andReturn("source").atLeastOnce();
+ List<InboundWire> inboundWires = new ArrayList<InboundWire>();
+ inboundWires.add(inbound);
+ source.getInboundWires();
+ EasyMock.expectLastCall().andReturn(inboundWires).atLeastOnce();
+ EasyMock.expect(source.getOutboundWires()).andReturn(wireMap);
+ EasyMock.expect(source.isSystem()).andReturn(true).atLeastOnce();
+ EasyMock.expect(source.getParent()).andReturn(parent).atLeastOnce();
+ EasyMock.replay(source);
+
+ parent.register(source);
+
+ AtomicComponent target = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(target.getName()).andReturn("target").atLeastOnce();
+ inboundWires.add(inbound);
+ EasyMock.expect(target.getInboundWires()).andReturn(inboundWires).atLeastOnce();
+ EasyMock.expect(target.isSystem()).andReturn(false).atLeastOnce();
+ EasyMock.replay(target);
+
+ parent.register(target);
+ try {
+ parent.prepare();
+ fail();
+ } catch (PrepareException e) {
+ //expected
+ }
+ EasyMock.verify(source);
+ EasyMock.verify(target);
+ EasyMock.verify(inbound);
+ EasyMock.verify(outbound);
+ }
+
+
+ private class Foo {
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImplTestCase.java
new file mode 100644
index 0000000000..eb57c6733d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentImplTestCase.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.TestUtils;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class CompositeComponentImplTestCase extends TestCase {
+
+ public void testSetUri() throws Exception {
+ CompositeComponentImpl component = new CompositeComponentImpl("foo", "foo/bar", null, null, null);
+ assertEquals("foo/bar", component.getURI());
+ }
+
+ public void testRegisterSystemService() throws Exception {
+ List<Class<?>> services = new ArrayList<Class<?>>();
+ services.add(Foo.class);
+ CompositeComponent parent = new CompositeComponentImpl("foo", "foo", null, null, null);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("bar").atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(true).atLeastOnce();
+ List<InboundWire> wires = TestUtils.createInboundWires(services);
+ EasyMock.expect(component.getInboundWires()).andReturn(wires).atLeastOnce();
+ EasyMock.replay(component);
+ parent.register(component);
+ assertNull(parent.getChild("bar"));
+ assertNotNull(parent.getSystemChild("bar"));
+ EasyMock.verify(component);
+ }
+
+ public void testRegister() throws Exception {
+ List<Class<?>> services = new ArrayList<Class<?>>();
+ services.add(Foo.class);
+ CompositeComponent parent = new CompositeComponentImpl("foo", "foo", null, null, null);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("bar").atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(false).atLeastOnce();
+ List<InboundWire> wires = TestUtils.createInboundWires(services);
+ EasyMock.expect(component.getInboundWires()).andReturn(wires).atLeastOnce();
+ EasyMock.replay(component);
+ parent.register(component);
+ assertNull(parent.getSystemChild("bar"));
+ assertNotNull(parent.getChild("bar"));
+ EasyMock.verify(component);
+ }
+
+ /**
+ * Verifies a system service and application component can be registered with the same name in a composite
+ */
+ public void testSystemServiceApplicationNamespaceIsolation() throws Exception {
+ List<Class<?>> services = new ArrayList<Class<?>>();
+ services.add(Foo.class);
+ CompositeComponent parent = new CompositeComponentImpl("foo", "foo", null, null, null);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("bar").atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(true).atLeastOnce();
+ List<InboundWire> wires = TestUtils.createInboundWires(services);
+ EasyMock.expect(component.getInboundWires()).andReturn(wires).atLeastOnce();
+ EasyMock.replay(component);
+ parent.register(component);
+ AtomicComponent component2 = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component2.getName()).andReturn("bar").atLeastOnce();
+ EasyMock.expect(component2.isSystem()).andReturn(false).atLeastOnce();
+ EasyMock.expect(component2.getInboundWires()).andReturn(wires).atLeastOnce();
+ EasyMock.replay(component2);
+ parent.register(component2);
+ EasyMock.verify(component);
+ EasyMock.verify(component2);
+ }
+
+ public void testSystemServiceLifecycle() throws Exception {
+ List<Class<?>> services = new ArrayList<Class<?>>();
+ services.add(Foo.class);
+ CompositeComponent parent = new CompositeComponentImpl("foo", "foo", null, null, null);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ component.start();
+ EasyMock.expect(component.getName()).andReturn("bar").atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(true).atLeastOnce();
+ component.stop();
+ List<InboundWire> wires = TestUtils.createInboundWires(services);
+ EasyMock.expect(component.getInboundWires()).andReturn(wires).atLeastOnce();
+ EasyMock.replay(component);
+ parent.register(component);
+ parent.start();
+ parent.stop();
+ EasyMock.verify(component);
+ }
+
+ public void testComponentLifecycle() throws Exception {
+ List<Class<?>> services = new ArrayList<Class<?>>();
+ services.add(Foo.class);
+ CompositeComponent parent = new CompositeComponentImpl("foo", "foo", null, null, null);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ component.start();
+ EasyMock.expect(component.getName()).andReturn("bar").atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(false).atLeastOnce();
+ List<InboundWire> wires = TestUtils.createInboundWires(services);
+ EasyMock.expect(component.getInboundWires()).andReturn(wires).atLeastOnce();
+ component.stop();
+ EasyMock.replay(component);
+ parent.register(component);
+ parent.start();
+ parent.stop();
+ EasyMock.verify(component);
+ }
+
+ public void testSystemAutowire() throws Exception {
+ List<Class<?>> services = new ArrayList<Class<?>>();
+ services.add(Foo.class);
+ CompositeComponent parent = new CompositeComponentImpl("foo", "foo", null, null, null);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ component.start();
+ EasyMock.expect(component.getName()).andReturn("bar").atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(true).atLeastOnce();
+ List<InboundWire> wires = TestUtils.createInboundWires(services);
+ EasyMock.expect(component.getInboundWires()).andReturn(wires).atLeastOnce();
+ component.stop();
+ EasyMock.replay(component);
+ parent.register(component);
+ parent.start();
+ assertNull(parent.resolveSystemExternalAutowire(Foo.class));
+ assertNotNull(parent.resolveSystemAutowire(Foo.class));
+ parent.stop();
+ EasyMock.verify(component);
+ }
+
+
+ public void testAutowire() throws Exception {
+ List<Class<?>> services = new ArrayList<Class<?>>();
+ services.add(Foo.class);
+ CompositeComponent parent = new CompositeComponentImpl("foo", "foo", null, null, null);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ component.start();
+ EasyMock.expect(component.getName()).andReturn("bar").atLeastOnce();
+ List<InboundWire> wires = TestUtils.createInboundWires(services);
+ TestUtils.populateInboundWires(component, wires);
+ EasyMock.expect(component.getInboundWires()).andReturn(wires).atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(false).atLeastOnce();
+ component.stop();
+ EasyMock.replay(component);
+ parent.register(component);
+ parent.start();
+ assertNull(parent.resolveExternalAutowire(Foo.class));
+ assertNotNull(parent.resolveAutowire(Foo.class));
+ parent.stop();
+ EasyMock.verify(component);
+ }
+
+ private class Foo {
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentResolutionTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentResolutionTestCase.java
new file mode 100644
index 0000000000..f24e1f8e94
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeComponentResolutionTestCase.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.TestUtils;
+import org.apache.tuscany.core.mock.component.Source;
+import org.easymock.EasyMock;
+
+/**
+ * Verifies an atomic component can be resolved from its parent
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class CompositeComponentResolutionTestCase extends TestCase {
+
+ public void testSystemComponentResolution() throws Exception {
+ CompositeComponent parent = new CompositeComponentImpl("foo", null, null, true);
+ parent.start();
+ List<Class<?>> interfaces = new ArrayList<Class<?>>();
+ interfaces.add(Source.class);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("source").atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(true).atLeastOnce();
+ List<InboundWire> wires = TestUtils.createInboundWires(interfaces);
+ TestUtils.populateInboundWires(component, wires);
+ EasyMock.expect(component.getInboundWires()).andReturn(wires).atLeastOnce();
+ EasyMock.replay(component);
+ parent.register(component);
+ assertNull(parent.getChild("source"));
+ assertTrue(parent.getSystemChild("source") instanceof AtomicComponent);
+ EasyMock.verify(component);
+ }
+
+ public void testComponentResolution() throws Exception {
+ CompositeComponent parent = new CompositeComponentImpl("foo", null, null, null);
+ parent.start();
+ List<Class<?>> interfaces = new ArrayList<Class<?>>();
+ interfaces.add(Source.class);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("source").atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(false).atLeastOnce();
+ List<InboundWire> wires = TestUtils.createInboundWires(interfaces);
+ TestUtils.populateInboundWires(component, wires);
+ EasyMock.expect(component.getInboundWires()).andReturn(wires).atLeastOnce();
+ EasyMock.replay(component);
+ parent.register(component);
+ assertNull(parent.getSystemChild("source"));
+ assertTrue(parent.getChild("source") instanceof AtomicComponent);
+ EasyMock.verify(component);
+ }
+
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeLifecycleTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeLifecycleTestCase.java
new file mode 100644
index 0000000000..f5d209fe4c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeLifecycleTestCase.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.TestUtils;
+import org.apache.tuscany.core.mock.component.Source;
+import org.easymock.EasyMock;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public class CompositeLifecycleTestCase extends TestCase {
+
+ public void testLifecycle() throws Exception {
+ CompositeComponent composite = new CompositeComponentImpl("foo", null, null, null);
+ composite.start();
+ assertNull(composite.getChild("nothtere"));
+ composite.stop();
+ composite.start();
+ assertNull(composite.getChild("nothtere"));
+ composite.stop();
+ }
+
+ public void testSystemRestart() throws Exception {
+ List<Class<?>> interfaces = new ArrayList<Class<?>>();
+ interfaces.add(Source.class);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ component.start();
+ component.stop();
+ EasyMock.expectLastCall().times(2);
+ EasyMock.expect(component.getName()).andReturn("source").atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(true).atLeastOnce();
+
+ List<InboundWire> wires = TestUtils.createInboundWires(interfaces);
+ TestUtils.populateInboundWires(component, wires);
+ EasyMock.expect(component.getInboundWires()).andReturn(wires).atLeastOnce();
+
+ EasyMock.replay(component);
+
+ CompositeComponent composite = new CompositeComponentImpl("foo", null, null, null);
+ composite.start();
+ composite.register(component);
+
+ assertTrue(composite.getSystemChild("source") instanceof AtomicComponent);
+ composite.stop();
+ composite.start();
+ assertTrue(composite.getSystemChild("source") instanceof AtomicComponent);
+ composite.stop();
+ EasyMock.verify(component);
+ }
+
+ public void testRestart() throws Exception {
+ List<Class<?>> interfaces = new ArrayList<Class<?>>();
+ interfaces.add(Source.class);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ component.start();
+ component.stop();
+ EasyMock.expectLastCall().times(2);
+ EasyMock.expect(component.getName()).andReturn("source").atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(false).atLeastOnce();
+
+ List<InboundWire> wires = TestUtils.createInboundWires(interfaces);
+ TestUtils.populateInboundWires(component, wires);
+ EasyMock.expect(component.getInboundWires()).andReturn(wires).atLeastOnce();
+
+ EasyMock.replay(component);
+
+ CompositeComponent composite = new CompositeComponentImpl("foo", null, null, null);
+ composite.start();
+ composite.register(component);
+
+ assertTrue(composite.getChild("source") instanceof AtomicComponent);
+ composite.stop();
+ composite.start();
+ assertTrue(composite.getChild("source") instanceof AtomicComponent);
+ composite.stop();
+ EasyMock.verify(component);
+ }
+
+ public void testChildStoppedBeforeParent() throws Exception {
+ CompositeComponent parent = new CompositeComponentImpl("parent", null, null, null);
+ CompositeComponent child = new CompositeComponentImpl("child", null, null, null);
+ parent.register(child);
+ parent.start();
+ child.stop();
+ parent.stop();
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeLoaderWireResolutionTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeLoaderWireResolutionTestCase.java
new file mode 100644
index 0000000000..9906528a84
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositeLoaderWireResolutionTestCase.java
@@ -0,0 +1,232 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.implementation.composite;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.loader.InvalidPromotedReferenceException;
+import org.apache.tuscany.spi.loader.InvalidWireException;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.ComponentReferenceDefinition;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.CompositeReferenceDefinition;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.apache.tuscany.spi.model.WireDefinition;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.java.JavaImplementation;
+
+/**
+ * This class tests the wire resolution function of the composite loader
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompositeLoaderWireResolutionTestCase extends TestCase {
+ private CompositeComponentType<ServiceDefinition, CompositeReferenceDefinition, Property<?>> componentType;
+ private CompositeLoader compositeLoader = new CompositeLoader(null, null);
+
+ public void setUp() throws Exception {
+ componentType = new CompositeComponentType<ServiceDefinition, CompositeReferenceDefinition, Property<?>>();
+ componentType.setName("TestComposite");
+ //add a service to the composite
+ ServiceDefinition serviceDefn = new ServiceDefinition("compositeService1", null, true);
+ ServiceDefinition boundSvcDefn = new ServiceDefinition("boundSvc", null, true, null);
+ ServiceDefinition boundSvcDefnWithTarget =
+ new ServiceDefinition("boundSvcWithTarget", null, true);
+ boundSvcDefnWithTarget.setTarget(new URI("orgTarget"));
+ componentType.add(serviceDefn);
+ componentType.add(boundSvcDefn);
+ componentType.add(boundSvcDefnWithTarget);
+
+ CompositeReferenceDefinition compositeReference = new CompositeReferenceDefinition("compositeReference", null);
+ componentType.add(compositeReference);
+
+ PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> pojoComponentType1 =
+ new PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ ServiceDefinition pojoSvc1 = new ServiceDefinition("pojoSvc1", null, false);
+ pojoComponentType1.add(pojoSvc1);
+ ComponentTypeReferenceDefinition pojoRef1 = new ComponentTypeReferenceDefinition("pojoRef1", null);
+ pojoComponentType1.add(pojoRef1);
+ JavaImplementation pojoImpl1 = new JavaImplementation(null, pojoComponentType1);
+
+ ComponentDefinition<JavaImplementation> component1 =
+ new ComponentDefinition<JavaImplementation>("Component1", pojoImpl1);
+ component1.add(new ComponentReferenceDefinition(pojoRef1));
+ componentType.add(component1);
+
+ PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> pojoComponentType2 =
+ new PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ ServiceDefinition pojoSvc2 = new ServiceDefinition("pojoSvc2", null, false);
+ pojoComponentType2.add(pojoSvc2);
+ ServiceDefinition pojoSvc3 = new ServiceDefinition("pojoSvc3", null, false);
+ pojoComponentType2.add(pojoSvc3);
+ ComponentTypeReferenceDefinition pojoRef2 = new ComponentTypeReferenceDefinition("pojoRef2", null);
+ pojoComponentType2.add(pojoRef2);
+ ComponentTypeReferenceDefinition pojoRef3 = new ComponentTypeReferenceDefinition("pojoRef3", null);
+ pojoComponentType2.add(pojoRef3);
+ JavaImplementation pojoImpl2 = new JavaImplementation(null, pojoComponentType2);
+
+ ComponentDefinition<JavaImplementation> component2 =
+ new ComponentDefinition<JavaImplementation>("Component2", pojoImpl2);
+ component2.add(new ComponentReferenceDefinition(pojoRef2));
+ component2.add(new ComponentReferenceDefinition(pojoRef3));
+ componentType.add(component2);
+ }
+
+ public void testCompositeSvc2CompositeReferenceWire() throws Exception {
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("compositeService1"));
+ wireDefn.setTarget(new URI("compositeReference"));
+ componentType.add(wireDefn);
+ compositeLoader.resolveWires(componentType);
+ }
+
+ public void testCompositeSvc2ComponentValid() throws Exception {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("compositeService1"));
+ wireDefn.setTarget(new URI("Component1"));
+ componentType.add(wireDefn);
+ compositeLoader.resolveWires(componentType);
+ }
+
+ public void testCompositeSvc2ComponentQualifiedValid() throws Exception {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("compositeService1"));
+ wireDefn.setTarget(new URI("Component2/pojoSvc3"));
+ componentType.add(wireDefn);
+ compositeLoader.resolveWires(componentType);
+ }
+
+ public void testCompositeSvc2ComponentQualifiedInvalid() throws URISyntaxException, InvalidPromotedReferenceException {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("compositeService1"));
+ wireDefn.setTarget(new URI("Component2/pojoSvc5"));
+ componentType.add(wireDefn);
+ try {
+ compositeLoader.resolveWires(componentType);
+ fail();
+ } catch (InvalidWireException e) {
+ // expected
+ }
+ }
+
+ public void testCompositeSvc2ComponentUnQualifiedInvalid() throws URISyntaxException, InvalidPromotedReferenceException {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("compositeService1"));
+ wireDefn.setTarget(new URI("Component2"));
+ componentType.add(wireDefn);
+ try {
+ compositeLoader.resolveWires(componentType);
+ fail();
+ } catch (InvalidWireException e) {
+ // expected
+ }
+ }
+
+ public void testComponent2CompositeReferenceValid() throws Exception {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("Component1"));
+ wireDefn.setTarget(new URI("compositeReference"));
+ componentType.add(wireDefn);
+ compositeLoader.resolveWires(componentType);
+ }
+
+ public void testComponent2CompositeReferenceQualifiedValid() throws Exception {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("Component2/pojoRef3"));
+ wireDefn.setTarget(new URI("compositeReference"));
+ componentType.add(wireDefn);
+ compositeLoader.resolveWires(componentType);
+ }
+
+ public void testComponent2CompositeReferenceUnQualifiedInvalid() throws URISyntaxException, InvalidPromotedReferenceException {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("Component2"));
+ wireDefn.setTarget(new URI("compositeReference"));
+ componentType.add(wireDefn);
+
+ try {
+ compositeLoader.resolveWires(componentType);
+ fail();
+ } catch (InvalidWireException e) {
+ // expected
+ }
+ }
+
+ public void testComponent2ComponentQualifedValid() throws Exception {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("Component1"));
+ wireDefn.setTarget(new URI("Component2/pojoSvc3"));
+ componentType.add(wireDefn);
+ compositeLoader.resolveWires(componentType);
+ }
+
+ public void testComponent2ComponentUnQualifedInvalid() throws URISyntaxException, InvalidPromotedReferenceException {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("Component1"));
+ wireDefn.setTarget(new URI("Component2"));
+ componentType.add(wireDefn);
+ try {
+ compositeLoader.resolveWires(componentType);
+ fail();
+ } catch (InvalidWireException e) {
+ // expected
+ }
+ }
+
+ public void testInvalidWireDefinitions() throws URISyntaxException, InvalidPromotedReferenceException {
+ //undefined source and targets
+ WireDefinition wireDefn = new WireDefinition();
+ wireDefn.setSource(new URI("undefinedSource"));
+ wireDefn.setTarget(new URI("compositeReference"));
+ componentType.add(wireDefn);
+
+ try {
+ compositeLoader.resolveWires(componentType);
+ fail();
+ } catch (InvalidWireException e) {
+ // expected
+ }
+
+ try {
+ wireDefn.setSource(new URI("compositeService1"));
+ wireDefn.setTarget(new URI("undefinedTarget"));
+ componentType.add(wireDefn);
+ compositeLoader.resolveWires(componentType);
+ fail();
+ } catch (InvalidWireException e) {
+ // expected
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositePropagationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositePropagationTestCase.java
new file mode 100644
index 0000000000..36e6e98809
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/CompositePropagationTestCase.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.TestUtils;
+import org.apache.tuscany.core.mock.component.Source;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class CompositePropagationTestCase extends TestCase {
+
+ private CompositeComponent parent;
+ private CompositeComponent child2;
+
+ public void testSystemLifecyclePropagation() throws Exception {
+ parent.start();
+ List<Class<?>> interfaces = new ArrayList<Class<?>>();
+ interfaces.add(Source.class);
+ AtomicComponent component = createMock(AtomicComponent.class);
+ expect(component.getName()).andReturn("source").anyTimes();
+ component.stop();
+ EasyMock.expect(component.isSystem()).andReturn(true).atLeastOnce();
+ List<InboundWire> wires = TestUtils.createInboundWires(interfaces);
+ TestUtils.populateInboundWires(component, wires);
+ EasyMock.expect(component.getInboundWires()).andReturn(wires).atLeastOnce();
+
+ replay(component);
+ child2.register(component);
+ parent.stop();
+ verify(component);
+ }
+
+ public void testLifecyclePropagation() throws Exception {
+ parent.start();
+ List<Class<?>> interfaces = new ArrayList<Class<?>>();
+ interfaces.add(Source.class);
+ AtomicComponent component = createMock(AtomicComponent.class);
+ expect(component.getName()).andReturn("source").anyTimes();
+ component.stop();
+ EasyMock.expect(component.isSystem()).andReturn(false).atLeastOnce();
+ List<InboundWire> wires = TestUtils.createInboundWires(interfaces);
+ TestUtils.populateInboundWires(component, wires);
+ EasyMock.expect(component.getInboundWires()).andReturn(wires).atLeastOnce();
+ replay(component);
+ child2.register(component);
+ parent.stop();
+ verify(component);
+ }
+
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ parent = new CompositeComponentImpl("parent", null, null, null);
+ CompositeComponent child1 = new CompositeComponentImpl("child1", parent, null, null);
+ child2 = new CompositeComponentImpl("child2", child1, null, null);
+ child1.register(child2);
+ parent.register(child1);
+ }
+
+ protected void tearDown() throws Exception {
+ parent.stop();
+ super.tearDown();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/DuplicateRegistrationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/DuplicateRegistrationTestCase.java
new file mode 100644
index 0000000000..72c2ffd827
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/DuplicateRegistrationTestCase.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.DuplicateNameException;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.TestUtils;
+import org.apache.tuscany.core.mock.component.Source;
+import org.easymock.EasyMock;
+
+/**
+ * Verfies children with the same name cannot be registered in the same composite
+ *
+ * @version $Rev$ $Date$
+ */
+public class DuplicateRegistrationTestCase extends TestCase {
+
+ public void testDuplicateRegistration() throws Exception {
+ CompositeComponent parent = new CompositeComponentImpl(null, null, null, null);
+ parent.start();
+
+ List<Class<?>> interfaces = new ArrayList<Class<?>>();
+ interfaces.add(Source.class);
+ AtomicComponent component1 = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component1.getName()).andReturn("source").atLeastOnce();
+ EasyMock.expect(component1.isSystem()).andReturn(true).atLeastOnce();
+ component1.stop();
+ List<InboundWire> wires = TestUtils.createInboundWires(interfaces);
+ TestUtils.populateInboundWires(component1, wires);
+ EasyMock.expect(component1.getInboundWires()).andReturn(wires).atLeastOnce();
+ EasyMock.replay(component1);
+
+ AtomicComponent component2 = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component2.getName()).andReturn("source").atLeastOnce();
+ EasyMock.expect(component2.isSystem()).andReturn(true).atLeastOnce();
+ component2.stop();
+ EasyMock.replay(component2);
+
+ parent.register(component1);
+ try {
+ parent.register(component2);
+ fail();
+ } catch (DuplicateNameException e) {
+ // ok
+ }
+ parent.stop();
+ }
+
+ public void testDuplicateNameSystemService() throws Exception {
+ List<Class<?>> services = new ArrayList<Class<?>>();
+ services.add(Source.class);
+ CompositeComponent parent = new CompositeComponentImpl("foo", "foo", null, null, null);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getName()).andReturn("bar").atLeastOnce();
+ EasyMock.expect(component.isSystem()).andReturn(true).atLeastOnce();
+ List<InboundWire> wires = TestUtils.createInboundWires(services);
+ TestUtils.populateInboundWires(component, wires);
+ EasyMock.expect(component.getInboundWires()).andReturn(wires).atLeastOnce();
+ EasyMock.replay(component);
+ parent.register(component);
+ AtomicComponent component2 = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component2.getName()).andReturn("bar").atLeastOnce();
+ EasyMock.expect(component2.isSystem()).andReturn(true).atLeastOnce();
+ EasyMock.replay(component2);
+ try {
+ parent.register(component2);
+ fail();
+ } catch (DuplicateNameException e) {
+ // expected
+ }
+ }
+
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/ImplementationCompositeLoaderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/ImplementationCompositeLoaderTestCase.java
new file mode 100644
index 0000000000..7d4ebc1ac3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/ImplementationCompositeLoaderTestCase.java
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import javax.xml.namespace.QName;
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import static org.osoa.sca.Constants.SCA_NS;
+
+import org.apache.tuscany.spi.deployer.CompositeClassLoader;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.model.CompositeImplementation;
+import org.apache.tuscany.spi.services.artifact.Artifact;
+import org.apache.tuscany.spi.services.artifact.ArtifactRepository;
+
+import junit.framework.TestCase;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reportMatcher;
+import static org.easymock.EasyMock.verify;
+import org.easymock.IArgumentMatcher;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ImplementationCompositeLoaderTestCase extends TestCase {
+ private static final QName IMPLEMENTATION_COMPOSITE = new QName(SCA_NS, "implementation.composite");
+
+ private ClassLoader cl;
+ private ImplementationCompositeLoader loader;
+ private XMLStreamReader reader;
+ private DeploymentContext context;
+ private ArtifactRepository artifactRepository;
+
+ public void testName() throws LoaderException, XMLStreamException, MalformedURLException {
+ String name = "foo";
+ expect(reader.getName()).andReturn(IMPLEMENTATION_COMPOSITE);
+ expect(reader.getAttributeValue(null, "name")).andReturn(name);
+ expect(reader.getAttributeValue(null, "group")).andReturn(null);
+ expect(reader.getAttributeValue(null, "version")).andReturn(null);
+ expect(reader.getAttributeValue(null, "scdlLocation")).andReturn(null);
+ expect(reader.getAttributeValue(null, "jarLocation")).andReturn(null);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ replay(reader);
+
+ replay(context);
+ replay(artifactRepository);
+
+ CompositeImplementation impl = loader.load(null, null, reader, context);
+ verify(reader);
+ verify(context);
+ verify(artifactRepository);
+ assertEquals(name, impl.getName());
+ assertNull(impl.getScdlLocation());
+ assertNull(impl.getClassLoader());
+ }
+
+ public void testWithArtifact() throws LoaderException, XMLStreamException, MalformedURLException {
+ String name = "foo";
+ expect(reader.getName()).andReturn(IMPLEMENTATION_COMPOSITE);
+ expect(reader.getAttributeValue(null, "name")).andReturn(name);
+ expect(reader.getAttributeValue(null, "group")).andReturn("com.example");
+ expect(reader.getAttributeValue(null, "version")).andReturn("1.0");
+ expect(reader.getAttributeValue(null, "scdlLocation")).andReturn(null);
+ expect(reader.getAttributeValue(null, "jarLocation")).andReturn(null);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ replay(reader);
+
+ expect(context.getClassLoader()).andReturn(cl);
+ replay(context);
+ URL url = new URL("http://www.example.com/sca/base.jar");
+ artifactRepository.resolve(artifactMatcher(url, "com.example", name, "1.0"));
+ replay(artifactRepository);
+
+ CompositeImplementation impl = loader.load(null, null, reader, context);
+ verify(reader);
+ verify(context);
+ verify(artifactRepository);
+ assertEquals(name, impl.getName());
+ assertEquals(new URL("jar:http://www.example.com/sca/base.jar!/META-INF/sca/default.scdl"),
+ impl.getScdlLocation());
+ assertTrue(impl.getClassLoader() instanceof CompositeClassLoader);
+ }
+
+ public void testWithScdlLocation() throws LoaderException, XMLStreamException, MalformedURLException {
+ String name = "foo";
+ expect(reader.getName()).andReturn(IMPLEMENTATION_COMPOSITE);
+ expect(reader.getAttributeValue(null, "name")).andReturn(name);
+ expect(reader.getAttributeValue(null, "group")).andReturn(null);
+ expect(reader.getAttributeValue(null, "version")).andReturn(null);
+ expect(reader.getAttributeValue(null, "scdlLocation")).andReturn("bar.scdl");
+ expect(reader.getAttributeValue(null, "jarLocation")).andReturn(null);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ replay(reader);
+
+ expect(context.getScdlLocation()).andReturn(new URL("http://www.example.com/sca/base.scdl"));
+ expect(context.getClassLoader()).andReturn(cl);
+ replay(context);
+ replay(artifactRepository);
+
+ CompositeImplementation impl = loader.load(null, null, reader, context);
+ verify(reader);
+ verify(context);
+ verify(artifactRepository);
+ assertEquals(name, impl.getName());
+ assertEquals(new URL("http://www.example.com/sca/bar.scdl"), impl.getScdlLocation());
+ assertSame(cl, impl.getClassLoader());
+ }
+
+ public void testWithJarLocation() throws LoaderException, XMLStreamException, MalformedURLException {
+ String name = "foo";
+ expect(reader.getName()).andReturn(IMPLEMENTATION_COMPOSITE);
+ expect(reader.getAttributeValue(null, "name")).andReturn(name);
+ expect(reader.getAttributeValue(null, "group")).andReturn(null);
+ expect(reader.getAttributeValue(null, "version")).andReturn(null);
+ expect(reader.getAttributeValue(null, "scdlLocation")).andReturn(null);
+ expect(reader.getAttributeValue(null, "jarLocation")).andReturn("bar.jar");
+ expect(reader.next()).andReturn(END_ELEMENT);
+ replay(reader);
+
+ expect(context.getScdlLocation()).andReturn(new URL("http://www.example.com/sca/base.scdl"));
+ expect(context.getClassLoader()).andReturn(cl);
+ replay(context);
+ replay(artifactRepository);
+
+ CompositeImplementation impl = loader.load(null, null, reader, context);
+ verify(reader);
+ verify(context);
+ verify(artifactRepository);
+ assertEquals(name, impl.getName());
+ assertEquals(new URL("jar:http://www.example.com/sca/bar.jar!/META-INF/sca/default.scdl"),
+ impl.getScdlLocation());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ artifactRepository = createMock(ArtifactRepository.class);
+ reader = createMock(XMLStreamReader.class);
+ context = createMock(DeploymentContext.class);
+ cl = getClass().getClassLoader();
+ loader = new ImplementationCompositeLoader(null, artifactRepository);
+ }
+
+ protected static Artifact artifactMatcher(final URL url,
+ final String group,
+ final String name,
+ final String version) {
+ reportMatcher(new IArgumentMatcher() {
+
+ public boolean matches(Object object) {
+ if (!(object instanceof Artifact)) {
+ return false;
+ }
+
+ Artifact artifact = (Artifact) object;
+ boolean match = group.equals(artifact.getGroup())
+ && name.equals(artifact.getName())
+ && version.equals(artifact.getVersion())
+ && "jar".equals(artifact.getType());
+ if (match) {
+ artifact.setUrl(url);
+ }
+ return match;
+ }
+
+ public void appendTo(StringBuffer stringBuffer) {
+ stringBuffer.append(group).append(':').append(name).append(':').append(version);
+ }
+ });
+ return null;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/JavaObjectRegistrationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/JavaObjectRegistrationTestCase.java
new file mode 100644
index 0000000000..f0fdd8b704
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/JavaObjectRegistrationTestCase.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.DuplicateNameException;
+import org.apache.tuscany.spi.component.SCAObject;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.event.CompositeStart;
+import org.apache.tuscany.core.component.event.CompositeStop;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JavaObjectRegistrationTestCase extends TestCase {
+ private CompositeComponent composite;
+
+ public void testRegistration() throws Exception {
+ MockComponent instance = new MockComponent();
+ composite.registerJavaObject("foo", MockComponent.class, instance);
+ SCAObject child = composite.getSystemChild("foo");
+ assertTrue(child instanceof AtomicComponent);
+ MockComponent resolvedInstance = (MockComponent) ((AtomicComponent) child).getTargetInstance();
+ assertSame(instance, resolvedInstance);
+ }
+
+ public void testDuplicateRegistration() throws Exception {
+ MockComponent instance = new MockComponent();
+ composite.registerJavaObject("foo", MockComponent.class, instance);
+ try {
+ composite.registerJavaObject("foo", MockComponent.class, instance);
+ fail();
+ } catch (DuplicateNameException e) {
+ // ok
+ }
+ }
+
+ public void testSystemAutowireToObject() throws Exception {
+ MockComponent instance = new MockComponent();
+ composite.registerJavaObject("foo", MockComponent.class, instance);
+ assertSame(instance, composite.resolveSystemAutowire(MockComponent.class).getTargetService());
+ assertNull(composite.resolveSystemExternalAutowire(MockComponent.class));
+ }
+
+ public void testApplicationAutowireToObject() throws Exception {
+ MockComponent instance = new MockComponent();
+ composite.registerJavaObject("foo", MockComponent.class, instance);
+ assertNotNull(composite.resolveAutowire(MockComponent.class));
+ assertNull(composite.resolveExternalAutowire(MockComponent.class));
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ composite = new CompositeComponentImpl(null, null, null, null);
+ composite.start();
+ composite.publish(new CompositeStart(this, null));
+ }
+
+ protected void tearDown() throws Exception {
+ composite.publish(new CompositeStop(this, null));
+ composite.stop();
+ super.tearDown();
+ }
+
+ private static class MockComponent {
+ public String hello(String message) {
+ return message;
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/ManagedRequestContextTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/ManagedRequestContextTestCase.java
new file mode 100644
index 0000000000..12299e762b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/ManagedRequestContextTestCase.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import org.osoa.sca.RequestContext;
+
+import org.apache.tuscany.spi.component.WorkContext;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ManagedRequestContextTestCase extends TestCase {
+
+ public void testGetServiceName() {
+ WorkContext workContext = EasyMock.createMock(WorkContext.class);
+ EasyMock.expect(workContext.getCurrentServiceName()).andReturn("foo");
+ EasyMock.replay(workContext);
+ RequestContext context = new ManagedRequestContext(workContext);
+ assertEquals("foo", context.getServiceName());
+ EasyMock.verify(workContext);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/ReferenceImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/ReferenceImplTestCase.java
new file mode 100644
index 0000000000..251833a554
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/ReferenceImplTestCase.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import org.apache.tuscany.spi.component.Reference;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ReferenceImplTestCase extends TestCase {
+
+ public void testStart() {
+ ReferenceBinding binding = EasyMock.createMock(ReferenceBinding.class);
+ binding.setReference(EasyMock.isA(Reference.class));
+ binding.start();
+ EasyMock.replay(binding);
+ Reference reference = new ReferenceImpl(null, null, null);
+ reference.addReferenceBinding(binding);
+ reference.start();
+ EasyMock.verify(binding);
+
+ }
+
+ public void testStop() {
+ ReferenceBinding binding = EasyMock.createMock(ReferenceBinding.class);
+ binding.setReference(EasyMock.isA(Reference.class));
+ binding.stop();
+ EasyMock.replay(binding);
+ Reference reference = new ReferenceImpl(null, null, null);
+ reference.addReferenceBinding(binding);
+ reference.stop();
+ EasyMock.verify(binding);
+
+ }
+
+ public void testIsSystem() {
+ Reference service = new ReferenceImpl(null, null, null, true);
+ assertTrue(service.isSystem());
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/ServiceImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/ServiceImplTestCase.java
new file mode 100644
index 0000000000..88d40a50eb
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/ServiceImplTestCase.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import org.apache.tuscany.spi.component.Service;
+import org.apache.tuscany.spi.component.ServiceBinding;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ServiceImplTestCase extends TestCase {
+
+ public void testStart() {
+ ServiceBinding binding = EasyMock.createMock(ServiceBinding.class);
+ binding.setService(EasyMock.isA(Service.class));
+ binding.start();
+ EasyMock.replay(binding);
+ Service service = new ServiceImpl(null, null, null);
+ service.addServiceBinding(binding);
+ service.start();
+ EasyMock.verify(binding);
+
+ }
+
+ public void testStop() {
+ ServiceBinding binding = EasyMock.createMock(ServiceBinding.class);
+ binding.setService(EasyMock.isA(Service.class));
+ binding.stop();
+ EasyMock.replay(binding);
+ Service service = new ServiceImpl(null, null, null);
+ service.addServiceBinding(binding);
+ service.stop();
+ EasyMock.verify(binding);
+
+ }
+
+ public void testIsSystem() {
+ Service service = new ServiceImpl(null, null, null, null, true);
+ assertTrue(service.isSystem());
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/SystemComponentBuilderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/SystemComponentBuilderTestCase.java
new file mode 100644
index 0000000000..4645075a7a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/SystemComponentBuilderTestCase.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.PropertyValue;
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.event.CompositeStart;
+import org.apache.tuscany.core.component.event.CompositeStop;
+import org.apache.tuscany.core.component.scope.CompositeScopeContainer;
+import org.apache.tuscany.core.implementation.system.builder.SystemComponentBuilder;
+import org.apache.tuscany.core.implementation.system.model.SystemImplementation;
+import org.apache.tuscany.core.injection.SingletonObjectFactory;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SystemComponentBuilderTestCase extends TestCase {
+
+ CompositeComponent parent;
+ DeploymentContext deploymentContext;
+ SystemComponentBuilder builder = new SystemComponentBuilder();
+ CompositeScopeContainer container;
+
+ /**
+ * Verifies lifecycle callbacks are made
+ */
+ public void testLifecycleBuild() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ type.setInitLevel(50);
+ Method initMethod = FooImpl.class.getMethod("init");
+ initMethod.setAccessible(true);
+ type.setInitMethod(initMethod);
+ Method destroyMethod = FooImpl.class.getMethod("destroy");
+ destroyMethod.setAccessible(true);
+ type.setDestroyMethod(destroyMethod);
+ type.setImplementationScope(Scope.COMPOSITE);
+ ConstructorDefinition<FooImpl> ctorDef = new ConstructorDefinition<FooImpl>(FooImpl.class.getConstructor());
+ type.setConstructorDefinition(ctorDef);
+ SystemImplementation impl = new SystemImplementation();
+ impl.setComponentType(type);
+ impl.setImplementationClass(FooImpl.class);
+ ComponentDefinition<SystemImplementation> definition = new ComponentDefinition<SystemImplementation>(impl);
+ AtomicComponent component = builder.build(parent, definition, deploymentContext);
+ component.setScopeContainer(container);
+ component.start();
+ container.onEvent(new CompositeStart(this, null));
+ FooImpl foo = (FooImpl) component.getTargetInstance();
+ assertTrue(foo.initialized);
+ container.onEvent(new CompositeStop(this, null));
+ assertTrue(foo.destroyed);
+ }
+
+ /**
+ * Verifies properties are built properly
+ */
+ public void testPropertyBuild() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ type.setInitLevel(50);
+ Method initMethod = FooImpl.class.getMethod("init");
+ initMethod.setAccessible(true);
+ type.setInitMethod(initMethod);
+ Method destroyMethod = FooImpl.class.getMethod("destroy");
+ destroyMethod.setAccessible(true);
+ type.setDestroyMethod(destroyMethod);
+ type.setImplementationScope(Scope.COMPOSITE);
+ JavaMappedProperty mappedProp = new JavaMappedProperty();
+ mappedProp.setName("prop");
+ Method propMethod = FooImpl.class.getMethod("setProp", String.class);
+ propMethod.setAccessible(true);
+ mappedProp.setMember(propMethod);
+ type.add(mappedProp);
+ ConstructorDefinition<FooImpl> ctorDef = new ConstructorDefinition<FooImpl>(FooImpl.class.getConstructor());
+ type.setConstructorDefinition(ctorDef);
+ SystemImplementation impl = new SystemImplementation();
+ impl.setComponentType(type);
+ impl.setImplementationClass(FooImpl.class);
+ ComponentDefinition<SystemImplementation> definition = new ComponentDefinition<SystemImplementation>(impl);
+ PropertyValue<String> propVal = new PropertyValue<String>();
+ propVal.setName("prop");
+ propVal.setValueFactory(new SingletonObjectFactory<String>("value"));
+ definition.add(propVal);
+ AtomicComponent component = builder.build(parent, definition, deploymentContext);
+ component.setScopeContainer(container);
+ component.start();
+ FooImpl foo = (FooImpl) component.getTargetInstance();
+ assertEquals("value", foo.prop);
+ container.onEvent(new CompositeStop(this, null));
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ parent = EasyMock.createNiceMock(CompositeComponent.class);
+ container = new CompositeScopeContainer(null);
+ container.start();
+ deploymentContext = EasyMock.createMock(DeploymentContext.class);
+ EasyMock.expect(deploymentContext.getCompositeScope()).andReturn(container).atLeastOnce();
+ EasyMock.replay(deploymentContext);
+ }
+
+ private static interface Foo {
+
+ }
+
+ private static class FooImpl implements Foo {
+ private boolean initialized;
+ private boolean destroyed;
+ private String prop;
+ private Foo ref;
+
+ public FooImpl() {
+ }
+
+ public void init() {
+ if (initialized) {
+ fail();
+ }
+ initialized = true;
+ }
+
+ public void destroy() {
+ if (destroyed) {
+ fail();
+ }
+ destroyed = true;
+ }
+
+ public boolean isInitialized() {
+ return initialized;
+ }
+
+ public String getProp() {
+ return prop;
+ }
+
+ public void setProp(String prop) {
+ this.prop = prop;
+ }
+
+ public Foo getRef() {
+ return ref;
+ }
+
+ public void setRef(Foo ref) {
+ this.ref = ref;
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/SystemSingletonAtomicComponentTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/SystemSingletonAtomicComponentTestCase.java
new file mode 100644
index 0000000000..9c482b994f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/composite/SystemSingletonAtomicComponentTestCase.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.composite;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.component.TargetException;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SystemSingletonAtomicComponentTestCase extends TestCase {
+
+ public void testGetInstance() throws TargetException {
+ FooImpl foo = new FooImpl();
+ SystemSingletonAtomicComponent<Foo, FooImpl> component =
+ new SystemSingletonAtomicComponent<Foo, FooImpl>("foo", null, Foo.class, foo);
+ assertEquals(foo, component.getTargetInstance());
+ }
+
+ public void testGetInstanceMultipleServices() throws TargetException {
+ FooImpl foo = new FooImpl();
+ List<Class<?>> services = new ArrayList<Class<?>>();
+ services.add(Foo.class);
+ services.add(Bar.class);
+ SystemSingletonAtomicComponent<Foo, FooImpl> component =
+ new SystemSingletonAtomicComponent<Foo, FooImpl>("foo", null, services, foo);
+ assertEquals(foo, component.getTargetInstance());
+ }
+
+ private interface Foo {
+
+ }
+
+ private interface Bar {
+
+ }
+
+ private class FooImpl implements Foo, Bar {
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponentMetadataInjectionTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponentMetadataInjectionTestCase.java
new file mode 100644
index 0000000000..5186119345
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponentMetadataInjectionTestCase.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests SCA metadata such as <code>@ComponentName</code> and <code>@SCAObject</code> are handled properly
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaAtomicComponentMetadataInjectionTestCase extends TestCase {
+
+ public void testComponentNameSet() throws Exception {
+ // TODO implement
+ }
+
+ public void testCompositeContextSet() throws Exception {
+ // TODO implement
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponentNegativeMetadataTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponentNegativeMetadataTestCase.java
new file mode 100644
index 0000000000..dfd62c8c53
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaAtomicComponentNegativeMetadataTestCase.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import junit.framework.TestCase;
+
+
+/**
+ * Performs rudimentary negative testing by using malformed metadata on a POJO
+ *
+ * @version $Rev $Date
+ */
+public class JavaAtomicComponentNegativeMetadataTestCase extends TestCase {
+
+ /**
+ * Tests that a pojo with <code>@ComponentName</code> specified on a non-String type generates an error.
+ * <p/>
+ * <strong>NB:</strong> the test assumes an error with a message containing "@ComponentName" is generated
+ */
+ public void testBadNameType() throws Exception {
+ // TODO implement
+ }
+
+ /**
+ * Tests that a pojo with <code>@Context</code> specified on a non-CompositeContext type generates an error.
+ * <p/>
+ * <strong>NB:</strong> the test assumes an error with a message containing "@Context" is generated
+ */
+ public void testContextType() throws Exception {
+ // TODO implement
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaBuilderPropertyTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaBuilderPropertyTestCase.java
new file mode 100644
index 0000000000..d484a5d944
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaBuilderPropertyTestCase.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.PropertyValue;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.injection.SingletonObjectFactory;
+import org.easymock.EasyMock;
+
+/**
+ * Verifies that the java component builder handles configured properties correctly
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaBuilderPropertyTestCase extends TestCase {
+ private DeploymentContext deploymentContext;
+ private CompositeComponent parent;
+ private ScopeRegistry registry;
+
+ @SuppressWarnings("unchecked")
+ public void testPropertyHandling() throws Exception {
+ JavaComponentBuilder builder = new JavaComponentBuilder();
+ builder.setScopeRegistry(registry);
+ PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, JavaMappedProperty<?>> type =
+ new PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, JavaMappedProperty<?>>();
+ JavaMappedProperty<String> property = new JavaMappedProperty<String>();
+ property.setName("test");
+ property.setDefaultValueFactory(new SingletonObjectFactory<String>("foo"));
+ property.setMember(JavaBuilderPropertyTestCase.Foo.class.getMethod("setTest", String.class));
+ type.add(property);
+ type.setConstructorDefinition(new ConstructorDefinition<Foo>(Foo.class.getConstructor((Class[]) null)));
+ type.setImplementationScope(Scope.STATELESS);
+ JavaImplementation impl = new JavaImplementation(Foo.class, type);
+ ComponentDefinition<JavaImplementation> definition = new ComponentDefinition<JavaImplementation>(impl);
+ PropertyValue propertyValue = new PropertyValue(property.getName(), property.getDefaultValueFactory());
+ definition.getPropertyValues().put(property.getName(), propertyValue);
+ AtomicComponent component = builder.build(parent, definition, deploymentContext);
+ JavaBuilderPropertyTestCase.Foo foo = (JavaBuilderPropertyTestCase.Foo) component.createInstance();
+ assertEquals("foo", foo.getTest());
+ }
+
+ public void testIntPropertyHandling() throws Exception {
+ JavaComponentBuilder builder = new JavaComponentBuilder();
+ builder.setScopeRegistry(registry);
+ PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, JavaMappedProperty<?>> type =
+ new PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, JavaMappedProperty<?>>();
+ JavaMappedProperty<Integer> property = new JavaMappedProperty<Integer>();
+ property.setName("test");
+ property.setDefaultValueFactory(new SingletonObjectFactory<Integer>(1));
+ property.setMember(JavaBuilderPropertyTestCase.FooInt.class.getMethod("setTest", Integer.TYPE));
+ type.add(property);
+ type.setConstructorDefinition(new ConstructorDefinition<FooInt>(FooInt.class.getConstructor((Class[]) null)));
+ type.setImplementationScope(Scope.STATELESS);
+ JavaImplementation impl = new JavaImplementation(Foo.class, type);
+ ComponentDefinition<JavaImplementation> definition = new ComponentDefinition<JavaImplementation>(impl);
+ ObjectFactory<?> defaultValueFactory = property.getDefaultValueFactory();
+ PropertyValue<Integer> propertyValue =
+ new PropertyValue<Integer>(property.getName(), defaultValueFactory);
+ definition.getPropertyValues().put(property.getName(), propertyValue);
+ AtomicComponent component = builder.build(parent, definition, deploymentContext);
+ FooInt foo = (FooInt) component.createInstance();
+ assertEquals(1, foo.getTest());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ deploymentContext = EasyMock.createMock(DeploymentContext.class);
+ EasyMock.replay(deploymentContext);
+ parent = EasyMock.createNiceMock(CompositeComponent.class);
+ ScopeContainer mockContainer = EasyMock.createNiceMock(ScopeContainer.class);
+ EasyMock.replay(mockContainer);
+ registry = EasyMock.createMock(ScopeRegistry.class);
+ EasyMock.expect(registry.getScopeContainer(EasyMock.isA(Scope.class))).andReturn(mockContainer);
+ EasyMock.replay(registry);
+ }
+
+ private static class Foo {
+ private String test;
+
+ public Foo() {
+ }
+
+ public String getTest() {
+ return test;
+ }
+
+ public void setTest(String test) {
+ this.test = test;
+ }
+ }
+
+ private static class FooInt {
+ private int test;
+
+ public FooInt() {
+ }
+
+ public int getTest() {
+ return test;
+ }
+
+ public void setTest(int test) {
+ this.test = test;
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderConversationIDTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderConversationIDTestCase.java
new file mode 100644
index 0000000000..5c83af0e7d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderConversationIDTestCase.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import java.lang.reflect.Field;
+
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+import org.osoa.sca.annotations.ConversationID;
+
+/**
+ * @version $Rev: 473859 $ $Date: 2006-11-11 22:31:55 -0500 (Sat, 11 Nov 2006) $
+ */
+public class JavaComponentBuilderConversationIDTestCase extends TestCase {
+
+ @SuppressWarnings("unchecked")
+ public void testResourceInjection() throws Exception {
+ ScopeContainer container = EasyMock.createNiceMock(ScopeContainer.class);
+ ScopeRegistry registry = EasyMock.createMock(ScopeRegistry.class);
+ EasyMock.expect(registry.getScopeContainer(Scope.STATELESS)).andReturn(container);
+ EasyMock.replay(registry);
+ JavaComponentBuilder builder = new JavaComponentBuilder();
+ builder.setScopeRegistry(registry);
+ WorkContext workContext = new WorkContextImpl();
+ workContext.setIdentifier(Scope.CONVERSATION, "convID");
+ builder.setWorkContext(workContext);
+
+ ConstructorDefinition<Foo> ctorDef = new ConstructorDefinition<Foo>(Foo.class.getConstructor());
+ PojoComponentType type = new PojoComponentType();
+ Field field = Foo.class.getDeclaredField("conversationID");
+ type.setConversationIDMember(field);
+ type.setImplementationScope(Scope.STATELESS);
+ type.setConstructorDefinition(ctorDef);
+
+ JavaImplementation impl = new JavaImplementation(Foo.class, type);
+ ComponentDefinition<JavaImplementation> definition = new ComponentDefinition<JavaImplementation>("foo", impl);
+ CompositeComponent parent = EasyMock.createMock(CompositeComponent.class);
+ JavaAtomicComponent component = (JavaAtomicComponent) builder.build(parent, definition, null);
+ Foo foo = (Foo) component.createInstance();
+ assertEquals("convID", foo.conversationID);
+ }
+
+ private static class Foo {
+
+ @ConversationID
+ protected String conversationID;
+
+ public Foo() {
+ }
+
+ }
+}
+
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderMetadataTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderMetadataTestCase.java
new file mode 100644
index 0000000000..e4adae73d3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderMetadataTestCase.java
@@ -0,0 +1,112 @@
+package org.apache.tuscany.core.implementation.java;
+
+import java.lang.reflect.Constructor;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.composite.CompositeComponentImpl;
+import org.apache.tuscany.core.mock.component.Source;
+import org.apache.tuscany.core.mock.component.SourceImpl;
+import org.apache.tuscany.core.mock.component.Target;
+import org.easymock.EasyMock;
+
+/**
+ * Verifies component type metadata is properly applied to the component
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class JavaComponentBuilderMetadataTestCase extends TestCase {
+ private DeploymentContext deploymentContext;
+ private Constructor<SourceImpl> constructor;
+ private CompositeComponent parent;
+ private PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type;
+ private ComponentDefinition<JavaImplementation> definition;
+ private ScopeContainer scopeContainer;
+
+ public void testInitLevel() throws Exception {
+ type.setInitLevel(1);
+ JavaComponentBuilder builder = new JavaComponentBuilder();
+ JavaAtomicComponent component = (JavaAtomicComponent) builder.build(parent, definition, deploymentContext);
+ assertEquals(1, component.getInitLevel());
+ }
+
+ public void testMaxAge() throws Exception {
+ type.setMaxAge(100);
+ JavaComponentBuilder builder = new JavaComponentBuilder();
+ JavaAtomicComponent component = (JavaAtomicComponent) builder.build(parent, definition, deploymentContext);
+ assertEquals(100, component.getMaxAge());
+ }
+
+ public void testMaxIdleTime() throws Exception {
+ type.setMaxIdleTime(100);
+ JavaComponentBuilder builder = new JavaComponentBuilder();
+ JavaAtomicComponent component = (JavaAtomicComponent) builder.build(parent, definition, deploymentContext);
+ assertEquals(100, component.getMaxIdleTime());
+ }
+
+ public void testNoMaxAgeNoMaxIdleTime() throws Exception {
+ JavaComponentBuilder builder = new JavaComponentBuilder();
+ JavaAtomicComponent component = (JavaAtomicComponent) builder.build(parent, definition, deploymentContext);
+ assertEquals(-1, component.getMaxAge());
+ assertEquals(-1, component.getMaxIdleTime());
+ }
+
+ public void testScope() throws Exception {
+ JavaComponentBuilder builder = new JavaComponentBuilder();
+ JavaAtomicComponent component = (JavaAtomicComponent) builder.build(parent, definition, deploymentContext);
+ component.setScopeContainer(scopeContainer);
+ assertEquals(Scope.COMPOSITE, component.getScope());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ parent = new CompositeComponentImpl(null, null, null, null);
+ constructor = SourceImpl.class.getConstructor((Class[]) null);
+ createDeploymentContext();
+ createComponentDefinitionAndType();
+ }
+
+
+ private void createDeploymentContext() {
+ scopeContainer = EasyMock.createMock(ScopeContainer.class);
+ scopeContainer.start();
+ scopeContainer.stop();
+ scopeContainer.register(EasyMock.isA(AtomicComponent.class));
+ EasyMock.expectLastCall().atLeastOnce();
+ EasyMock.expect(scopeContainer.getScope()).andReturn(Scope.COMPOSITE).atLeastOnce();
+ EasyMock.replay(scopeContainer);
+ deploymentContext = EasyMock.createMock(DeploymentContext.class);
+ EasyMock.replay(deploymentContext);
+ }
+
+ private void createComponentDefinitionAndType() throws Exception {
+ type = new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ type.setImplementationScope(Scope.COMPOSITE);
+ JavaMappedReference reference = new JavaMappedReference();
+ reference.setName("target");
+ reference.setMember(SourceImpl.class.getMethod("setTarget", Target.class));
+ type.add(reference);
+ ServiceContract<?> contract = new JavaServiceContract(Source.class);
+ JavaMappedService serviceDefinition = new JavaMappedService();
+ serviceDefinition.setName("Source");
+ serviceDefinition.setServiceContract(contract);
+ type.add(serviceDefinition);
+ type.setConstructorDefinition(new ConstructorDefinition<SourceImpl>(constructor));
+ JavaImplementation sourceImpl = new JavaImplementation(SourceImpl.class, type);
+ definition = new ComponentDefinition<JavaImplementation>(sourceImpl);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderReferenceTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderReferenceTestCase.java
new file mode 100644
index 0000000000..c9d1f93a57
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderReferenceTestCase.java
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import java.lang.reflect.Constructor;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.InteractionScope;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.WireService;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.composite.CompositeComponentImpl;
+import org.apache.tuscany.core.mock.component.Source;
+import org.apache.tuscany.core.mock.component.SourceImpl;
+import org.apache.tuscany.core.mock.component.Target;
+import org.apache.tuscany.core.wire.jdk.JDKWireService;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public class JavaComponentBuilderReferenceTestCase extends TestCase {
+ private DeploymentContext deploymentContext;
+ private WireService wireService;
+ private Constructor<SourceImpl> constructor;
+ private CompositeComponent parent;
+ private OutboundWire wire;
+ private ScopeContainer scopeContainer;
+
+ public void testBuildReference() throws Exception {
+
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> sourceType =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ sourceType.setImplementationScope(Scope.COMPOSITE);
+ JavaMappedReference reference = new JavaMappedReference();
+ reference.setName("target");
+ reference.setMember(SourceImpl.class.getMethod("setTarget", Target.class));
+ sourceType.add(reference);
+ ServiceContract<?> contract = new JavaServiceContract(Source.class);
+ JavaMappedService serviceDefinition = new JavaMappedService();
+ serviceDefinition.setName("Source");
+ serviceDefinition.setServiceContract(contract);
+ sourceType.add(serviceDefinition);
+ sourceType.setConstructorDefinition(new ConstructorDefinition<SourceImpl>(constructor));
+ JavaImplementation sourceImpl = new JavaImplementation(SourceImpl.class, sourceType);
+ ComponentDefinition<JavaImplementation> definition = new ComponentDefinition<JavaImplementation>(sourceImpl);
+
+ JavaComponentBuilder builder = new JavaComponentBuilder();
+ builder.setWireService(wireService);
+ JavaAtomicComponent component = (JavaAtomicComponent) builder.build(parent, definition, deploymentContext);
+ component.setScopeContainer(scopeContainer);
+ component.addOutboundWire(wire);
+ deploymentContext.getCompositeScope().start();
+ component.start();
+
+ Source source = (Source) component.getTargetInstance();
+ assertNotNull(source.getTarget());
+ component.stop();
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ wireService = new JDKWireService();
+ parent = new CompositeComponentImpl(null, null, null, null);
+ constructor = SourceImpl.class.getConstructor((Class[]) null);
+ createDeploymentContext();
+ createWire();
+ }
+
+
+ private void createDeploymentContext() throws Exception {
+ scopeContainer = EasyMock.createMock(ScopeContainer.class);
+ scopeContainer.start();
+ scopeContainer.stop();
+ scopeContainer.register(EasyMock.isA(AtomicComponent.class));
+ EasyMock.expectLastCall().atLeastOnce();
+ EasyMock.expect(scopeContainer.getScope()).andReturn(Scope.COMPOSITE).atLeastOnce();
+ scopeContainer.getInstance(EasyMock.isA(AtomicComponent.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ private Map<AtomicComponent, Object> cache = new HashMap<AtomicComponent, Object>();
+
+ public Object answer() throws Throwable {
+ AtomicComponent component = (AtomicComponent) EasyMock.getCurrentArguments()[0];
+ Object instance = cache.get(component);
+ if (instance == null) {
+ instance = component.createInstance();
+ cache.put(component, instance);
+ }
+ return instance;
+ }
+ }).anyTimes();
+ EasyMock.replay(scopeContainer);
+ deploymentContext = EasyMock.createMock(DeploymentContext.class);
+ EasyMock.expect(deploymentContext.getCompositeScope()).andReturn(scopeContainer).atLeastOnce();
+ EasyMock.replay(deploymentContext);
+ }
+
+ private void createWire() {
+ SCAObject scaObject = EasyMock.createNiceMock(SCAObject.class);
+ Map<Operation<?>, OutboundInvocationChain> chains = Collections.emptyMap();
+ wire = EasyMock.createMock(OutboundWire.class);
+ EasyMock.expect(wire.getReferenceName()).andReturn("target").atLeastOnce();
+ EasyMock.expect(wire.getInvocationChains()).andReturn(chains).atLeastOnce();
+ EasyMock.expect(wire.isOptimizable()).andReturn(false);
+ JavaServiceContract targetContract = new JavaServiceContract(Target.class);
+ targetContract.setInteractionScope(InteractionScope.NONCONVERSATIONAL);
+ EasyMock.expect(wire.getServiceContract()).andReturn(targetContract).atLeastOnce();
+ EasyMock.expect(wire.getContainer()).andReturn(scaObject).atLeastOnce();
+ EasyMock.replay(wire);
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderResourceTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderResourceTestCase.java
new file mode 100644
index 0000000000..f5ee684e0b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentBuilderResourceTestCase.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.Resource;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JavaComponentBuilderResourceTestCase extends TestCase {
+
+ @SuppressWarnings("unchecked")
+ public void testResourceInjection() throws Exception {
+ ScopeContainer container = EasyMock.createNiceMock(ScopeContainer.class);
+ ScopeRegistry registry = EasyMock.createMock(ScopeRegistry.class);
+ EasyMock.expect(registry.getScopeContainer(Scope.STATELESS)).andReturn(container);
+ EasyMock.replay(registry);
+ JavaComponentBuilder builder = new JavaComponentBuilder();
+ builder.setScopeRegistry(registry);
+ ConstructorDefinition<Foo> ctorDef = new ConstructorDefinition<Foo>(Foo.class.getConstructor());
+ PojoComponentType type = new PojoComponentType();
+ Resource resource = new Resource();
+ resource.setType(String.class);
+ resource.setName("resource");
+ resource.setMember(Foo.class.getDeclaredField("resource"));
+ type.add(resource);
+ type.setImplementationScope(Scope.STATELESS);
+ type.setConstructorDefinition(ctorDef);
+ JavaImplementation impl = new JavaImplementation(Foo.class, type);
+ ComponentDefinition<JavaImplementation> definition = new ComponentDefinition<JavaImplementation>("foo", impl);
+ InboundWire resourceWire = EasyMock.createMock(InboundWire.class);
+ EasyMock.expect(resourceWire.getTargetService()).andReturn("result");
+ EasyMock.replay(resourceWire);
+
+ CompositeComponent parent = EasyMock.createMock(CompositeComponent.class);
+ EasyMock.expect(parent.resolveSystemAutowire(String.class)).andReturn(resourceWire);
+ EasyMock.replay(parent);
+ JavaAtomicComponent component = (JavaAtomicComponent) builder.build(parent, definition, null);
+ Foo foo = (Foo) component.createInstance();
+ assertEquals("result", foo.resource);
+ EasyMock.verify(parent);
+ }
+
+ private static class Foo {
+
+ protected String resource;
+
+ public Foo() {
+ }
+
+ }
+}
+
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentTypeLoaderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentTypeLoaderTestCase.java
new file mode 100644
index 0000000000..ef74c86d2e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaComponentTypeLoaderTestCase.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import java.net.URL;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.IntrospectionRegistry;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JavaComponentTypeLoaderTestCase extends TestCase {
+
+ @SuppressWarnings("unchecked")
+ public void testPojoComponentTypeCreatedForIntrospection() throws Exception {
+ IntrospectionRegistry registry = EasyMock.createMock(IntrospectionRegistry.class);
+ registry.introspect(
+ (CompositeComponent) EasyMock.isNull(),
+ (Class) EasyMock.isNull(),
+ EasyMock.isA(PojoComponentType.class),
+ (DeploymentContext) EasyMock.isNull());
+ EasyMock.expectLastCall().andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return EasyMock.getCurrentArguments()[2];
+ }
+ });
+ EasyMock.replay(registry);
+ JavaComponentTypeLoader loader = new JavaComponentTypeLoader(null, registry);
+ loader.loadByIntrospection(null, new JavaImplementation(), null);
+ EasyMock.verify(registry);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testPojoComponentTypeCreatedForSideFileLoadAndReturned() throws Exception {
+ LoaderRegistry registry = EasyMock.createMock(LoaderRegistry.class);
+ registry.load(
+ (CompositeComponent) EasyMock.isNull(),
+ EasyMock.isA(PojoComponentType.class),
+ (URL) EasyMock.isNull(),
+ EasyMock.eq(PojoComponentType.class),
+ (DeploymentContext) EasyMock.isNull());
+ EasyMock.expectLastCall().andStubAnswer(new IAnswer() {
+ public Object answer() throws Throwable {
+ return EasyMock.getCurrentArguments()[1];
+ }
+ });
+ EasyMock.replay(registry);
+ JavaComponentTypeLoader loader = new JavaComponentTypeLoader(registry, null);
+ assertEquals(PojoComponentType.class, loader.loadFromSidefile(null, null, null).getClass());
+ EasyMock.verify(registry);
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaReferenceWireTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaReferenceWireTestCase.java
new file mode 100644
index 0000000000..0fe6df8b6b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaReferenceWireTestCase.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import java.lang.reflect.Constructor;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.TargetException;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.WireService;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+
+/**
+ * Validates wiring from a Java atomic context
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class JavaReferenceWireTestCase extends TestCase {
+
+ @SuppressWarnings({"unchecked"})
+ public void testReferenceSet() throws Exception {
+ ScopeContainer scope = createMock();
+ scope.start();
+ final Target target = new TargetImpl();
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.addReferenceSite("target", SourceImpl.class.getMethod("setTarget", Target.class));
+ Constructor<SourceImpl> ctr = SourceImpl.class.getConstructor();
+ configuration.setInstanceFactory(new PojoObjectFactory<SourceImpl>(ctr));
+ OutboundWire wire = EasyMock.createMock(OutboundWire.class);
+ wire.getInvocationChains();
+ EasyMock.expectLastCall().andReturn(new HashMap<Operation<?>, OutboundInvocationChain>()).atLeastOnce();
+ EasyMock.expect(wire.getReferenceName()).andReturn("target").atLeastOnce();
+ EasyMock.expect(wire.isOptimizable()).andReturn(false);
+ EasyMock.replay(wire);
+ WireService service = EasyMock.createMock(WireService.class);
+ EasyMock.expect(service.createProxy(EasyMock.eq(Target.class), EasyMock.eq(wire), EasyMock.isA(Map.class)))
+ .andAnswer(new IAnswer<Target>() {
+ public Target answer() throws Throwable {
+ OutboundWire wire = (OutboundWire) EasyMock.getCurrentArguments()[1];
+ wire.getInvocationChains();
+ return target;
+ }
+
+ }).atLeastOnce();
+ EasyMock.replay(service);
+ configuration.setWireService(service);
+ configuration.setName("source");
+ JavaAtomicComponent component = new JavaAtomicComponent(configuration);
+ component.setScopeContainer(scope);
+ component.addOutboundWire(wire);
+ component.start();
+ Source source = (Source) component.getTargetInstance();
+ assertSame(target, source.getTarget());
+ scope.stop();
+ EasyMock.verify(wire);
+ EasyMock.verify(scope);
+ EasyMock.verify(service);
+ }
+
+ private ScopeContainer createMock() throws TargetException {
+ ScopeContainer scope = EasyMock.createMock(ScopeContainer.class);
+ scope.start();
+ scope.stop();
+ scope.register(EasyMock.isA(AtomicComponent.class));
+ EasyMock.expectLastCall().atLeastOnce();
+ EasyMock.expect(scope.getScope()).andReturn(Scope.COMPOSITE).atLeastOnce();
+ scope.getInstance(EasyMock.isA(AtomicComponent.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ private Map<AtomicComponent, Object> cache = new HashMap<AtomicComponent, Object>();
+
+ public Object answer() throws Throwable {
+ AtomicComponent component = (AtomicComponent) EasyMock.getCurrentArguments()[0];
+ Object instance = cache.get(component);
+ if (instance == null) {
+ instance = component.createInstance();
+ cache.put(component, instance);
+ }
+ return instance;
+ }
+ }).anyTimes();
+ EasyMock.replay(scope);
+ return scope;
+ }
+
+ private interface Source {
+ Target getTarget();
+ }
+
+ private static class SourceImpl implements Source {
+ private Target target;
+
+ public SourceImpl() {
+ }
+
+ public Target getTarget() {
+ return target;
+ }
+
+ public void setTarget(Target target) {
+ this.target = target;
+ }
+ }
+
+ private interface Target {
+
+ String getString();
+
+ void setString(String val);
+ }
+
+ private static class TargetImpl implements Target {
+ private String string;
+
+ public TargetImpl() {
+ }
+
+ public String getString() {
+ return string;
+ }
+
+ public void setString(String string) {
+ this.string = string;
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerBasicInvocationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerBasicInvocationTestCase.java
new file mode 100644
index 0000000000..30f7948673
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerBasicInvocationTestCase.java
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.extension.ExecutionMonitor;
+import org.apache.tuscany.spi.wire.InboundWire;
+import static org.apache.tuscany.spi.wire.TargetInvoker.NONE;
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.easymock.classextension.EasyMock;
+
+public class JavaTargetInvokerBasicInvocationTestCase extends TestCase {
+ private Method echoMethod;
+ private Method arrayMethod;
+ private Method nullParamMethod;
+ private Method primitiveMethod;
+ private Method checkedMethod;
+ private Method runtimeMethod;
+ private InboundWire wire;
+ private WorkContext context;
+ private ExecutionMonitor monitor;
+
+ public JavaTargetInvokerBasicInvocationTestCase(String arg0) {
+ super(arg0);
+ }
+
+ public void setUp() throws Exception {
+ echoMethod = TestBean.class.getDeclaredMethod("echo", String.class);
+ arrayMethod = TestBean.class.getDeclaredMethod("arrayEcho", String[].class);
+ nullParamMethod = TestBean.class.getDeclaredMethod("nullParam", (Class[]) null);
+ primitiveMethod = TestBean.class.getDeclaredMethod("primitiveEcho", Integer.TYPE);
+ checkedMethod = TestBean.class.getDeclaredMethod("checkedException", (Class[]) null);
+ runtimeMethod = TestBean.class.getDeclaredMethod("runtimeException", (Class[]) null);
+ wire = EasyMock.createNiceMock(InboundWire.class);
+ context = EasyMock.createNiceMock(WorkContext.class);
+ monitor = EasyMock.createNiceMock(ExecutionMonitor.class);
+ assertNotNull(echoMethod);
+ assertNotNull(checkedMethod);
+ assertNotNull(runtimeMethod);
+ }
+
+ public void testObjectInvoke() throws Throwable {
+ TestBean bean = new TestBean();
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(bean);
+ EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(echoMethod, component, wire, context, monitor);
+ Object ret = invoker.invokeTarget("foo", NONE);
+ assertEquals("foo", ret);
+ }
+
+ public void testArrayInvoke() throws Throwable {
+ TestBean bean = new TestBean();
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(bean);
+ EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(arrayMethod, component, wire, context, monitor);
+
+ String[] args = new String[]{"foo", "bar"};
+ Object ret = invoker.invokeTarget(new Object[]{args}, NONE);
+ String[] retA = (String[]) ret;
+ assertNotNull(retA);
+ assertEquals(2, retA.length);
+ assertEquals("foo", retA[0]);
+ assertEquals("bar", retA[1]);
+ }
+
+ public void testNullInvoke() throws Throwable {
+ TestBean bean = new TestBean();
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(bean);
+ EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(nullParamMethod, component, wire, context, monitor);
+ Object ret = invoker.invokeTarget(null, NONE);
+ String retS = (String) ret;
+ assertEquals("foo", retS);
+ }
+
+ public void testPrimitiveInvoke() throws Throwable {
+ TestBean bean = new TestBean();
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(bean);
+ EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(primitiveMethod, component, wire, context, monitor);
+ Object ret = invoker.invokeTarget(new Integer[]{1}, NONE);
+ Integer retI = (Integer) ret;
+ assertEquals(1, retI.intValue());
+ }
+
+ public void testInvokeCheckedException() throws Throwable {
+ TestBean bean = new TestBean();
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(bean);
+ EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(checkedMethod, component, wire, context, monitor);
+ try {
+ invoker.invokeTarget(null, NONE);
+ } catch (InvocationTargetException e) {
+ if (e.getCause() != null && TestException.class.equals(e.getCause().getClass())) {
+ return;
+ }
+ } catch (Throwable e) {
+ //ok
+ }
+ fail(TestException.class.getName() + " should have been thrown");
+ }
+
+ public void testInvokeRuntimeException() throws Throwable {
+ TestBean bean = new TestBean();
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(bean);
+ EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(runtimeMethod, component, wire, context, monitor);
+ try {
+ invoker.invokeTarget(null, NONE);
+ } catch (InvocationTargetException e) {
+ if (e.getCause() != null && e.getCause() instanceof TestRuntimeException) {
+ return;
+ }
+ }
+ fail(TestException.class.getName() + " should have been thrown");
+ }
+
+ private class TestBean {
+
+ public String echo(String msg) throws Exception {
+ assertEquals("foo", msg);
+ return msg;
+ }
+
+ public String[] arrayEcho(String[] msg) throws Exception {
+ assertNotNull(msg);
+ assertEquals(2, msg.length);
+ assertEquals("foo", msg[0]);
+ assertEquals("bar", msg[1]);
+ return msg;
+ }
+
+ public String nullParam() throws Exception {
+ return "foo";
+ }
+
+ public int primitiveEcho(int i) throws Exception {
+ return i;
+ }
+
+ public void checkedException() throws TestException {
+ throw new TestException();
+ }
+
+ public void runtimeException() throws TestRuntimeException {
+ throw new TestRuntimeException();
+ }
+ }
+
+ public class TestException extends Exception {
+ }
+
+ public class TestRuntimeException extends RuntimeException {
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerMediationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerMediationTestCase.java
new file mode 100644
index 0000000000..936673d0a6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerMediationTestCase.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import java.lang.reflect.Method;
+
+import static org.apache.tuscany.spi.wire.TargetInvoker.NONE;
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.easymock.classextension.EasyMock;
+
+/**
+ * Tests invoking on a different interface from the one actually implemented by the target
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaTargetInvokerMediationTestCase extends TestCase {
+
+ private Method hello;
+
+ public void setUp() throws Exception {
+ hello = Hello.class.getMethod("hello", String.class);
+ }
+
+ public void testMediation() throws Exception {
+ Target target = EasyMock.createMock(Target.class);
+ EasyMock.expect(target.hello("foo")).andReturn("foo");
+ EasyMock.replay(target);
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(target);
+ EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(hello, component, null, null, null);
+ assertEquals("foo", invoker.invokeTarget("foo", NONE));
+ }
+
+ public interface Hello {
+ String hello(String message) throws Exception;
+ }
+
+ private interface Target {
+ String hello(String message);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerNonBlockingInvocationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerNonBlockingInvocationTestCase.java
new file mode 100644
index 0000000000..25466a01ff
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerNonBlockingInvocationTestCase.java
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.extension.ExecutionMonitor;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import static org.apache.tuscany.spi.wire.TargetInvoker.NONE;
+
+import junit.framework.TestCase;
+import org.easymock.classextension.EasyMock;
+
+/**
+ * Verifies dispatching invocations to a Java implementation instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaTargetInvokerNonBlockingInvocationTestCase extends TestCase {
+
+ private Method echoMethod;
+ private Method arrayMethod;
+ private Method nullParamMethod;
+ private Method primitiveMethod;
+ private Method checkedMethod;
+ private Method runtimeMethod;
+ private InboundWire wire;
+ private WorkContext context;
+ private ExecutionMonitor monitor;
+
+ public JavaTargetInvokerNonBlockingInvocationTestCase(String arg0) {
+ super(arg0);
+ }
+
+ public void testInvoke() throws Exception {
+ AsyncTarget target = EasyMock.createMock(AsyncTarget.class);
+ target.invoke();
+ EasyMock.expectLastCall().once();
+ EasyMock.replay(target);
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(target);
+ EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.replay(component);
+ ExecutionMonitor monitor = EasyMock.createMock(ExecutionMonitor.class);
+ EasyMock.replay(monitor);
+
+ Message msg = new MessageImpl();
+ Object id = new Object();
+ msg.setMessageId(id);
+
+ WorkContext context = EasyMock.createMock(WorkContext.class);
+ context.setCurrentCorrelationId(id);
+ EasyMock.replay(context);
+ Method method = AsyncTarget.class.getMethod("invoke");
+ method.setAccessible(true);
+ InboundWire wire = EasyMock.createMock(InboundWire.class);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(method, component, wire, context, monitor);
+ invoker.invoke(msg);
+ EasyMock.verify(target);
+ EasyMock.verify(component);
+ }
+
+ public void setUp() throws Exception {
+ echoMethod = TestBean.class.getDeclaredMethod("echo", String.class);
+ arrayMethod = TestBean.class.getDeclaredMethod("arrayEcho", String[].class);
+ nullParamMethod = TestBean.class.getDeclaredMethod("nullParam", (Class[]) null);
+ primitiveMethod = TestBean.class.getDeclaredMethod("primitiveEcho", Integer.TYPE);
+ checkedMethod = TestBean.class.getDeclaredMethod("checkedException", (Class[]) null);
+ runtimeMethod = TestBean.class.getDeclaredMethod("runtimeException", (Class[]) null);
+ wire = EasyMock.createNiceMock(InboundWire.class);
+ context = EasyMock.createNiceMock(WorkContext.class);
+ monitor = EasyMock.createNiceMock(ExecutionMonitor.class);
+ assertNotNull(echoMethod);
+ assertNotNull(checkedMethod);
+ assertNotNull(runtimeMethod);
+ }
+
+ public void testObjectInvoke() throws Throwable {
+ TestBean bean = new TestBean();
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(bean);
+ EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(echoMethod, component, wire, context, monitor);
+ Object ret = invoker.invokeTarget("foo", NONE);
+ assertEquals("foo", ret);
+ }
+
+ public void testArrayInvoke() throws Throwable {
+ TestBean bean = new TestBean();
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(bean);
+ EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(arrayMethod, component, wire, context, monitor);
+
+ String[] args = new String[]{"foo", "bar"};
+ Object ret = invoker.invokeTarget(new Object[]{args}, NONE);
+ String[] retA = (String[]) ret;
+ assertNotNull(retA);
+ assertEquals(2, retA.length);
+ assertEquals("foo", retA[0]);
+ assertEquals("bar", retA[1]);
+ }
+
+ public void testNullInvoke() throws Throwable {
+ TestBean bean = new TestBean();
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(bean);
+ EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(nullParamMethod, component, wire, context, monitor);
+ Object ret = invoker.invokeTarget(null, NONE);
+ String retS = (String) ret;
+ assertEquals("foo", retS);
+ }
+
+ public void testPrimitiveInvoke() throws Throwable {
+ TestBean bean = new TestBean();
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(bean);
+ EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(primitiveMethod, component, wire, context, monitor);
+ Object ret = invoker.invokeTarget(new Integer[]{1}, NONE);
+ Integer retI = (Integer) ret;
+ assertEquals(1, retI.intValue());
+ }
+
+ public void testInvokeCheckedException() throws Throwable {
+ TestBean bean = new TestBean();
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(bean);
+ EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(checkedMethod, component, wire, context, monitor);
+ try {
+ invoker.invokeTarget(null, NONE);
+ } catch (InvocationTargetException e) {
+ if (e.getCause() != null && TestException.class.equals(e.getCause().getClass())) {
+ return;
+ }
+ } catch (Throwable e) {
+ //ok
+ }
+ fail(TestException.class.getName() + " should have been thrown");
+ }
+
+ public void testInvokeRuntimeException() throws Throwable {
+ TestBean bean = new TestBean();
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(bean);
+ EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(runtimeMethod, component, wire, context, monitor);
+ try {
+ invoker.invokeTarget(null, NONE);
+ } catch (InvocationTargetException e) {
+ if (e.getCause() != null && e.getCause() instanceof TestRuntimeException) {
+ return;
+ }
+ }
+ fail(TestException.class.getName() + " should have been thrown");
+ }
+
+ private class TestBean {
+
+ public String echo(String msg) throws Exception {
+ assertEquals("foo", msg);
+ return msg;
+ }
+
+ public String[] arrayEcho(String[] msg) throws Exception {
+ assertNotNull(msg);
+ assertEquals(2, msg.length);
+ assertEquals("foo", msg[0]);
+ assertEquals("bar", msg[1]);
+ return msg;
+ }
+
+ public String nullParam() throws Exception {
+ return "foo";
+ }
+
+ public int primitiveEcho(int i) throws Exception {
+ return i;
+ }
+
+ public void checkedException() throws TestException {
+ throw new TestException();
+ }
+
+ public void runtimeException() throws TestRuntimeException {
+ throw new TestRuntimeException();
+ }
+ }
+
+ public class TestException extends Exception {
+ }
+
+ public class TestRuntimeException extends RuntimeException {
+ }
+
+ public interface AsyncTarget {
+ void invoke();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerSequenceTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerSequenceTestCase.java
new file mode 100644
index 0000000000..acb2ed5e14
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerSequenceTestCase.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import junit.framework.TestCase;
+import org.easymock.classextension.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JavaTargetInvokerSequenceTestCase extends TestCase {
+
+ /**
+ * Verifies an invocation marked as non-conversational has an existing or new instance returned
+ */
+ public void testNoSequence() throws Exception {
+ Foo foo = EasyMock.createMock(Foo.class);
+ foo.invoke();
+ EasyMock.replay(foo);
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(foo);
+ EasyMock.expect(component.getScope()).andReturn(Scope.CONVERSATION);
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(Foo.class.getMethod("invoke"), component, null, null, null);
+ Message msg = new MessageImpl();
+ msg.setConversationSequence(TargetInvoker.NONE);
+ invoker.invoke(msg);
+ EasyMock.verify(foo);
+ EasyMock.verify(component);
+ }
+
+ /**
+ * Verifies that an invocation marked as starting a conversation has a new instance returned
+ */
+ public void testStartSequence() throws Exception {
+ Foo foo = EasyMock.createMock(Foo.class);
+ foo.invoke();
+ EasyMock.replay(foo);
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(foo);
+ EasyMock.expect(component.getScope()).andReturn(Scope.CONVERSATION);
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(Foo.class.getMethod("invoke"), component, null, null, null);
+ Message msg = new MessageImpl();
+ msg.setConversationSequence(TargetInvoker.START);
+ invoker.invoke(msg);
+ EasyMock.verify(foo);
+ EasyMock.verify(component);
+ }
+
+ /**
+ * Verifies that an invocation marked as continuing a conversation has an associated instance returned
+ */
+ public void testContinueSequence() throws Exception {
+ Foo foo = EasyMock.createMock(Foo.class);
+ foo.invoke();
+ EasyMock.replay(foo);
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getAssociatedTargetInstance()).andReturn(foo);
+ EasyMock.expect(component.getScope()).andReturn(Scope.CONVERSATION);
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(Foo.class.getMethod("invoke"), component, null, null, null);
+ Message msg = new MessageImpl();
+ msg.setConversationSequence(TargetInvoker.CONTINUE);
+ invoker.invoke(msg);
+ EasyMock.verify(foo);
+ EasyMock.verify(component);
+ }
+
+ /**
+ * Verifies that an invocation marked as ending a conversation has an associated instance returned and it is removed
+ * following the dispatch to the instance
+ */
+ public void testEndSequence() throws Exception {
+ Foo foo = EasyMock.createMock(Foo.class);
+ foo.invoke();
+ EasyMock.replay(foo);
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getAssociatedTargetInstance()).andReturn(foo);
+ EasyMock.expect(component.getScope()).andReturn(Scope.CONVERSATION);
+ component.removeInstance();
+ component.destroy(EasyMock.eq(foo));
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(Foo.class.getMethod("invoke"), component, null, null, null);
+ Message msg = new MessageImpl();
+ msg.setConversationSequence(TargetInvoker.END);
+ invoker.invoke(msg);
+ EasyMock.verify(foo);
+ EasyMock.verify(component);
+ }
+
+
+ private interface Foo {
+ void invoke();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerStatelessDestroyTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerStatelessDestroyTestCase.java
new file mode 100644
index 0000000000..c87649f99e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerStatelessDestroyTestCase.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.easymock.classextension.EasyMock;
+
+public class JavaTargetInvokerStatelessDestroyTestCase extends TestCase {
+
+ public JavaTargetInvokerStatelessDestroyTestCase(String arg0) {
+ super(arg0);
+ }
+
+ public void testDestroy() throws Exception {
+ Method echoMethod = Echo.class.getDeclaredMethod("echo", String.class);
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(new JavaTargetInvokerStatelessDestroyTestCase.Echo());
+ EasyMock.expect(component.getScope()).andReturn(Scope.STATELESS);
+ component.destroy(EasyMock.isA(Echo.class));
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(echoMethod, component, null, null, null);
+ invoker.setCacheable(false);
+ assertEquals("foo", invoker.invokeTarget("foo", JavaTargetInvoker.NONE));
+ EasyMock.verify(component);
+ }
+
+ public static class Echo {
+ public String echo(String message) throws Exception {
+ return message;
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerTestCase.java
new file mode 100644
index 0000000000..043af2d891
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/JavaTargetInvokerTestCase.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.easymock.classextension.EasyMock;
+
+public class JavaTargetInvokerTestCase extends TestCase {
+
+ public JavaTargetInvokerTestCase(String arg0) {
+ super(arg0);
+ }
+
+ public void testInvoke() throws Exception {
+ Method echoMethod = Echo.class.getDeclaredMethod("echo", String.class);
+ JavaAtomicComponent component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn(new Echo());
+ EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.replay(component);
+ JavaTargetInvoker invoker = new JavaTargetInvoker(echoMethod, component, null, null, null);
+ invoker.setCacheable(false);
+ assertEquals("foo", invoker.invokeTarget("foo", JavaTargetInvoker.NONE));
+ EasyMock.verify(component);
+ }
+
+ public static class Echo {
+ public String echo(String message) throws Exception {
+ return message;
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/MultiplicityTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/MultiplicityTestCase.java
new file mode 100644
index 0000000000..ba478c9634
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/MultiplicityTestCase.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import junit.framework.TestCase;
+
+
+/**
+ * Tests wires that are configured with a multiplicity
+ *
+ * @version $Rev$ $Date$
+ */
+public class MultiplicityTestCase extends TestCase {
+
+ public void testMultiplicity() throws Exception {
+ // TODO implement
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/ResourceInjectionTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/ResourceInjectionTestCase.java
new file mode 100644
index 0000000000..f4cc56f158
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/ResourceInjectionTestCase.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.injection.ResourceObjectFactory;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ResourceInjectionTestCase extends TestCase {
+
+ public void testResourceMemberInjection() throws Exception {
+ ScopeContainer containter = EasyMock.createNiceMock(ScopeContainer.class);
+ Constructor<Foo> ctor = Foo.class.getConstructor();
+ Field field = Foo.class.getDeclaredField("resource");
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setName("component");
+ configuration.setInstanceFactory(new PojoObjectFactory<Foo>(ctor));
+ configuration.addResourceSite("bar", field);
+ JavaAtomicComponent component = new JavaAtomicComponent(configuration);
+ component.setScopeContainer(containter);
+
+ InboundWire wire = EasyMock.createMock(InboundWire.class);
+ EasyMock.expect(wire.getTargetService()).andReturn("result");
+ EasyMock.replay(wire);
+
+ CompositeComponent parent = EasyMock.createMock(CompositeComponent.class);
+ EasyMock.expect(parent.resolveSystemAutowire(EasyMock.eq(String.class))).andReturn(wire);
+ EasyMock.replay(parent);
+ ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, false, parent, null);
+ component.addResourceFactory("bar", factory);
+
+ Foo foo = (Foo) component.createInstance();
+ assertEquals("result", foo.resource);
+ EasyMock.verify(parent);
+ }
+
+
+ public void testResourceConstructorInjection() throws Exception {
+ ScopeContainer containter = EasyMock.createNiceMock(ScopeContainer.class);
+ Constructor<FooConstructor> ctor = FooConstructor.class.getConstructor(String.class);
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setName("component");
+ configuration.setInstanceFactory(new PojoObjectFactory<FooConstructor>(ctor));
+ List<String> ctorNames = new ArrayList<String>();
+ ctorNames.add("bar");
+ configuration.setConstructorParamNames(ctorNames);
+ JavaAtomicComponent component = new JavaAtomicComponent(configuration);
+ component.setScopeContainer(containter);
+
+ InboundWire wire = EasyMock.createMock(InboundWire.class);
+ EasyMock.expect(wire.getTargetService()).andReturn("result");
+ EasyMock.replay(wire);
+ CompositeComponent parent = EasyMock.createMock(CompositeComponent.class);
+
+ EasyMock.expect(parent.resolveSystemAutowire(EasyMock.eq(String.class))).andReturn(wire);
+ EasyMock.replay(parent);
+ ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, false, parent, null);
+ component.addResourceFactory("bar", factory);
+
+ FooConstructor foo = (FooConstructor) component.createInstance();
+ assertEquals("result", foo.resource);
+ EasyMock.verify(parent);
+ }
+
+ public static class Foo {
+ protected String resource;
+
+ public Foo() {
+ }
+
+ }
+
+ public static class FooConstructor {
+ protected String resource;
+
+ public FooConstructor(String resource) {
+ this.resource = resource;
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/integration/CallbackInvocationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/integration/CallbackInvocationTestCase.java
new file mode 100644
index 0000000000..898f89383a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/integration/CallbackInvocationTestCase.java
@@ -0,0 +1,395 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java.integration;
+
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.osoa.sca.NoRegisteredCallbackException;
+import org.osoa.sca.annotations.Callback;
+
+import org.apache.tuscany.spi.builder.Connector;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.ComponentReferenceDefinition;
+import org.apache.tuscany.spi.model.ReferenceTarget;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.services.work.WorkScheduler;
+import org.apache.tuscany.spi.wire.WireService;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.builder.ConnectorImpl;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.component.scope.CompositeScopeContainer;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.implementation.java.JavaAtomicComponent;
+import org.apache.tuscany.core.implementation.java.JavaComponentBuilder;
+import org.apache.tuscany.core.implementation.java.JavaImplementation;
+import org.apache.tuscany.core.wire.jdk.JDKWireService;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.getCurrentArguments;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import org.easymock.IAnswer;
+
+/**
+ * Verifies callback integration scenarios with Java components.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CallbackInvocationTestCase extends TestCase {
+ private ScopeContainer container;
+ private DeploymentContext context;
+ private JavaComponentBuilder builder;
+ private WireService wireService;
+ private WorkScheduler scheduler;
+ private WorkContext workContext;
+
+ /**
+ * Verifies callback wires are built and callback invocations are handled properly
+ */
+ public void testComponentToComponentCallback() throws Exception {
+ ComponentDefinition<JavaImplementation> targetDefinition = createTarget();
+ JavaAtomicComponent fooComponent =
+ (JavaAtomicComponent) builder.build(null, targetDefinition, context);
+ fooComponent.setScopeContainer(container);
+ wireService.createWires(fooComponent, targetDefinition);
+ container.register(fooComponent);
+
+ CompositeComponent parent = createMock(CompositeComponent.class);
+ parent.getChild(isA(String.class));
+ expectLastCall().andReturn(fooComponent).anyTimes();
+ replay(parent);
+
+ ComponentDefinition<JavaImplementation> sourceDefinition = createSource("fooClient");
+ JavaAtomicComponent clientComponent =
+ (JavaAtomicComponent) builder.build(parent, sourceDefinition, context);
+ clientComponent.setScopeContainer(container);
+ wireService.createWires(clientComponent, sourceDefinition);
+ container.register(clientComponent);
+
+ Connector connector = new ConnectorImpl(new JDKWireService(), null, scheduler, workContext);
+
+ connector.connect(clientComponent);
+ FooClient client = (FooClient) clientComponent.getTargetInstance();
+ client.invoke();
+ assertTrue(client.invoked);
+ client.invokeMultiCallback();
+ assertTrue(client.count == 2);
+ }
+
+ /**
+ * Verifies exception is thrown when callback is not implemented
+ */
+ public void testCallbackNotRegistered() throws Exception {
+ ComponentDefinition<JavaImplementation> targetDefinition = createTarget();
+ JavaAtomicComponent fooComponent =
+ (JavaAtomicComponent) builder.build(null, targetDefinition, context);
+ fooComponent.setScopeContainer(container);
+ wireService.createWires(fooComponent, targetDefinition);
+ container.register(fooComponent);
+
+ CompositeComponent parent = createMock(CompositeComponent.class);
+ parent.getChild(isA(String.class));
+ expectLastCall().andReturn(fooComponent).anyTimes();
+ replay(parent);
+
+ ComponentDefinition<JavaImplementation> sourceDefinition = createPlainSource("fooPlainClient");
+ JavaAtomicComponent clientComponent =
+ (JavaAtomicComponent) builder.build(parent, sourceDefinition, context);
+ clientComponent.setScopeContainer(container);
+ wireService.createWires(clientComponent, sourceDefinition);
+ container.register(clientComponent);
+
+ Connector connector = new ConnectorImpl(new JDKWireService(), null, scheduler, workContext);
+
+ connector.connect(clientComponent);
+ FooPlainClient client = (FooPlainClient) clientComponent.getTargetInstance();
+ try {
+ client.invoke();
+ fail();
+ } catch (NoRegisteredCallbackException e) {
+ // expected
+ }
+ }
+
+ /**
+ * Verifies a callback in response to an invocation from two different client components is routed back to the
+ * appropriate client.
+ */
+ public void testTwoSourceComponentToComponentCallback() throws Exception {
+ ComponentDefinition<JavaImplementation> targetDefinition = createTarget();
+ JavaAtomicComponent fooComponent =
+ (JavaAtomicComponent) builder.build(null, targetDefinition, context);
+ fooComponent.setScopeContainer(container);
+ wireService.createWires(fooComponent, targetDefinition);
+ container.register(fooComponent);
+
+ CompositeComponent parent = createMock(CompositeComponent.class);
+ parent.getChild(isA(String.class));
+ expectLastCall().andReturn(fooComponent).anyTimes();
+ replay(parent);
+
+ ComponentDefinition<JavaImplementation> sourceDefinition1 = createSource("fooCleint1");
+ ComponentDefinition<JavaImplementation> sourceDefinition2 = createSource("fooCleint2");
+ JavaAtomicComponent clientComponent1 =
+ (JavaAtomicComponent) builder.build(parent, sourceDefinition1, context);
+ clientComponent1.setScopeContainer(container);
+ wireService.createWires(clientComponent1, sourceDefinition1);
+ container.register(clientComponent1);
+ JavaAtomicComponent clientComponent2 =
+ (JavaAtomicComponent) builder.build(parent, sourceDefinition2, context);
+ clientComponent2.setScopeContainer(container);
+ wireService.createWires(clientComponent2, sourceDefinition2);
+ container.register(clientComponent2);
+
+ Connector connector = new ConnectorImpl(new JDKWireService(), null, scheduler, workContext);
+ connector.connect(clientComponent1);
+ connector.connect(clientComponent2);
+ FooClient client1 = (FooClient) clientComponent1.getTargetInstance();
+ client1.invoke();
+ assertTrue(client1.invoked);
+ FooClient client2 = (FooClient) clientComponent2.getTargetInstance();
+ client2.invoke();
+ assertTrue(client2.invoked);
+ }
+
+
+ private ComponentDefinition<JavaImplementation> createTarget() throws NoSuchMethodException,
+ InvalidServiceContractException {
+ ConstructorDefinition<FooImpl> ctorDef = new ConstructorDefinition<FooImpl>(FooImpl.class.getConstructor());
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ type.setConstructorDefinition(ctorDef);
+ type.setImplementationScope(Scope.COMPOSITE);
+ Method method = FooImpl.class.getMethod("setCallback", FooCallback.class);
+ JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ ServiceContract<?> contract = registry.introspect(Foo.class);
+ contract.setCallbackClass(FooCallback.class);
+ contract.setCallbackName("callback");
+ JavaMappedService mappedService = new JavaMappedService("Foo", contract, false, "callback", method);
+ type.getServices().put("Foo", mappedService);
+
+ JavaImplementation impl = new JavaImplementation(FooImpl.class, type);
+ impl.setComponentType(type);
+ impl.setImplementationClass(FooImpl.class);
+ return new ComponentDefinition<JavaImplementation>("foo", impl);
+ }
+
+ private ComponentDefinition<JavaImplementation> createSource(String name)
+ throws NoSuchMethodException, URISyntaxException, InvalidServiceContractException {
+ ConstructorDefinition<FooClient> ctorDef =
+ new ConstructorDefinition<FooClient>(FooClient.class.getConstructor());
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ type.setConstructorDefinition(ctorDef);
+ type.setImplementationScope(Scope.COMPOSITE);
+ Method method = FooClient.class.getMethod("setFoo", Foo.class);
+ JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ ServiceContract<?> contract = registry.introspect(Foo.class);
+ contract.setCallbackClass(FooCallback.class);
+ contract.setCallbackName("callback");
+ JavaMappedReference mappedReference = new JavaMappedReference("foo", contract, method);
+ type.getReferences().put("foo", mappedReference);
+ ReferenceTarget refTarget = new ReferenceTarget();
+ refTarget.setReferenceName("foo");
+ refTarget.getTargets().add(new URI("foo"));
+ JavaImplementation impl = new JavaImplementation(FooClient.class, type);
+ impl.setComponentType(type);
+ impl.setImplementationClass(FooClient.class);
+ ComponentDefinition<JavaImplementation> def = new ComponentDefinition<JavaImplementation>(name, impl);
+ ComponentReferenceDefinition compRef = new ComponentReferenceDefinition(type.getReferences().get("foo"));
+ compRef.addTarget(new URI("foo"));
+ def.add(compRef);
+ //def.getReferenceTargets().put("foo", refTarget);
+ return def;
+ }
+
+ private ComponentDefinition<JavaImplementation> createPlainSource(String name)
+ throws NoSuchMethodException, URISyntaxException, InvalidServiceContractException {
+ ConstructorDefinition<FooPlainClient> ctorDef =
+ new ConstructorDefinition<FooPlainClient>(FooPlainClient.class.getConstructor());
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ type.setConstructorDefinition(ctorDef);
+ type.setImplementationScope(Scope.COMPOSITE);
+ Method method = FooPlainClient.class.getMethod("setFoo", Foo.class);
+ JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ ServiceContract<?> contract = registry.introspect(Foo.class);
+ contract.setCallbackClass(FooCallback.class);
+ contract.setCallbackName("callback");
+ JavaMappedReference mappedReference = new JavaMappedReference("foo", contract, method);
+ type.getReferences().put("foo", mappedReference);
+ ReferenceTarget refTarget = new ReferenceTarget();
+ refTarget.setReferenceName("foo");
+ refTarget.getTargets().add(new URI("foo"));
+ JavaImplementation impl = new JavaImplementation(FooPlainClient.class, type);
+ ComponentDefinition<JavaImplementation> def = new ComponentDefinition<JavaImplementation>(name, impl);
+ ComponentReferenceDefinition compRef = new ComponentReferenceDefinition(type.getReferences().get("foo"));
+ compRef.addTarget(new URI("foo"));
+ def.add(compRef);
+ //def.getReferenceTargets().put("foo", refTarget);
+ return def;
+ }
+
+ @Callback(FooCallback.class)
+ public static interface Foo {
+ void call();
+
+ void callMultiCallback();
+
+ void callFromPlain();
+ }
+
+ public static class FooImpl implements Foo {
+ private FooCallback callback;
+
+ public FooImpl() {
+ }
+
+ @Callback
+ public void setCallback(FooCallback callback) {
+ this.callback = callback;
+ }
+
+ public void call() {
+ callback.callback();
+ }
+
+ public void callMultiCallback() {
+ callback.multiCallback();
+ callback.multiCallback();
+ }
+
+ public void callFromPlain() {
+ try {
+ callback.callback();
+ fail();
+ } catch (NoRegisteredCallbackException e) {
+ // expected
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static class FooClient implements FooCallback {
+
+ private Foo foo;
+ private boolean invoked;
+ private int count;
+
+ public FooClient() {
+ }
+
+ public void setFoo(Foo foo) {
+ this.foo = foo;
+ }
+
+ public void callback() {
+ if (invoked) {
+ fail();
+ }
+ invoked = true;
+ }
+
+ public void multiCallback() {
+ count++;
+ }
+
+ public void invoke() {
+ foo.call();
+ }
+
+ public void invokeMultiCallback() {
+ foo.callMultiCallback();
+ }
+ }
+
+ public interface FooCallback {
+ void callback();
+
+ void multiCallback();
+ }
+
+ public static class FooPlainClient /* implements FooCallback */ { // do NOT implement the callback
+
+ private Foo foo;
+
+ public FooPlainClient() {
+ }
+
+ public void setFoo(Foo foo) {
+ this.foo = foo;
+ }
+
+ public void invoke() {
+ foo.callFromPlain();
+ }
+
+ public void callback() {
+
+ }
+
+ public void multiCallback() {
+
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ wireService = new JDKWireService();
+ container = new CompositeScopeContainer(null);
+ container.start();
+ context = createMock(DeploymentContext.class);
+ context.getCompositeScope();
+ expectLastCall().andReturn(container).anyTimes();
+ replay(context);
+
+ scheduler = createMock(WorkScheduler.class);
+ scheduler.scheduleWork(isA(Runnable.class));
+ expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ Runnable runnable = (Runnable) getCurrentArguments()[0];
+ runnable.run();
+ return null;
+ }
+ });
+ replay(scheduler);
+
+ builder = new JavaComponentBuilder();
+ workContext = new WorkContextImpl();
+ builder.setWorkContext(workContext);
+ builder.setWireService(new JDKWireService(workContext, null));
+ builder.setWorkScheduler(scheduler);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/integration/OutboundWireToJavaTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/integration/OutboundWireToJavaTestCase.java
new file mode 100644
index 0000000000..f2d88955e4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/java/integration/OutboundWireToJavaTestCase.java
@@ -0,0 +1,233 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.java.integration;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.builder.WiringException;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.InteractionScope;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.WireService;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.builder.ConnectorImpl;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.component.event.CompositeStart;
+import org.apache.tuscany.core.component.event.CompositeStop;
+import org.apache.tuscany.core.component.event.HttpSessionEnd;
+import org.apache.tuscany.core.component.event.HttpSessionStart;
+import org.apache.tuscany.core.component.event.RequestEnd;
+import org.apache.tuscany.core.component.event.RequestStart;
+import org.apache.tuscany.core.component.scope.CompositeScopeContainer;
+import org.apache.tuscany.core.component.scope.HttpSessionScopeContainer;
+import org.apache.tuscany.core.component.scope.RequestScopeContainer;
+import org.apache.tuscany.core.component.scope.StatelessScopeContainer;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.java.JavaAtomicComponent;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.integration.mock.MockFactory;
+import org.apache.tuscany.core.mock.component.Target;
+import org.apache.tuscany.core.mock.component.TargetImpl;
+import org.apache.tuscany.core.wire.OutboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.OutboundWireImpl;
+import org.apache.tuscany.core.wire.jdk.JDKWireService;
+import org.easymock.EasyMock;
+
+/**
+ * Validates wiring from a wire to Java atomic component by scope
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class OutboundWireToJavaTestCase extends TestCase {
+ private WorkContext workContext = new WorkContextImpl();
+ private WireService wireService = new JDKWireService(new WorkContextImpl(), null);
+
+ public void testToStatelessScope() throws Exception {
+ StatelessScopeContainer scope = new StatelessScopeContainer(workContext, null);
+ scope.start();
+ final OutboundWire wire = getWire(scope);
+ Target service = wireService.createProxy(Target.class, wire);
+ assertNotNull(service);
+ service.setString("foo");
+ assertEquals(null, service.getString());
+ scope.stop();
+ }
+
+ public void testToRequestScope() throws Exception {
+ final RequestScopeContainer scope = new RequestScopeContainer(workContext, null);
+ scope.start();
+
+ scope.onEvent(new RequestStart(this));
+
+ final OutboundWire wire = getWire(scope);
+ Target service = wireService.createProxy(Target.class, wire);
+ assertNotNull(service);
+ service.setString("foo");
+
+ // another request
+ Executor executor = Executors.newSingleThreadExecutor();
+ FutureTask<Void> future = new FutureTask<Void>(new Runnable() {
+ public void run() {
+ scope.onEvent(new RequestStart(this));
+ Target service2 = wireService.createProxy(Target.class, wire);
+ Target target2 = wireService.createProxy(Target.class, wire);
+ assertEquals(null, service2.getString());
+ service2.setString("bar");
+ assertEquals("bar", service2.getString());
+ assertEquals("bar", target2.getString());
+ scope.onEvent(new RequestEnd(this));
+ }
+ }, null);
+ executor.execute(future);
+ future.get();
+
+ assertEquals("foo", service.getString());
+ scope.onEvent(new RequestEnd(this));
+ scope.stop();
+ }
+
+ public void testToSessionScope() throws Exception {
+ HttpSessionScopeContainer scope = new HttpSessionScopeContainer(workContext, null);
+ scope.start();
+ Object session1 = new Object();
+ workContext.setIdentifier(Scope.SESSION, session1);
+ scope.onEvent(new HttpSessionStart(this, session1));
+
+ final OutboundWire wire = getWire(scope);
+ Target service = wireService.createProxy(Target.class, wire);
+ Target target = wireService.createProxy(Target.class, wire);
+ assertNotNull(service);
+ service.setString("foo");
+ assertEquals("foo", service.getString());
+ assertEquals("foo", target.getString());
+
+ workContext.clearIdentifier(Scope.SESSION);
+
+ //second session
+ Object session2 = new Object();
+ workContext.setIdentifier(Scope.SESSION, session2);
+ scope.onEvent(new HttpSessionStart(this, session2));
+
+ Target service2 = wireService.createProxy(Target.class, wire);
+ assertNotNull(service2);
+ assertNull(service2.getString());
+ Target target2 = wireService.createProxy(Target.class, wire);
+ service2.setString("bar");
+ assertEquals("bar", service2.getString());
+ assertEquals("bar", target2.getString());
+
+ scope.onEvent(new HttpSessionEnd(this, session2));
+ workContext.clearIdentifier(Scope.SESSION);
+
+ workContext.setIdentifier(Scope.SESSION, session1);
+ assertEquals("foo", service.getString());
+
+ scope.onEvent(new HttpSessionEnd(this, session1));
+
+ scope.stop();
+ }
+
+ public void testToCompositeScope() throws Exception {
+ CompositeScopeContainer scope = new CompositeScopeContainer(null);
+ scope.start();
+ scope.onEvent(new CompositeStart(this, null));
+ final OutboundWire wire = getWire(scope);
+ Target service = wireService.createProxy(Target.class, wire);
+ Target target = wireService.createProxy(Target.class, wire);
+ assertNotNull(service);
+ service.setString("foo");
+ assertEquals("foo", service.getString());
+ assertEquals("foo", target.getString());
+ scope.onEvent(new CompositeStop(this, null));
+ scope.stop();
+ }
+
+ private OutboundWire getWire(ScopeContainer scope) throws NoSuchMethodException,
+ InvalidServiceContractException, WiringException {
+ ConnectorImpl connector = new ConnectorImpl();
+ CompositeComponent parent = EasyMock.createMock(CompositeComponent.class);
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInstanceFactory(new PojoObjectFactory<TargetImpl>(TargetImpl.class.getConstructor()));
+ configuration.setParent(parent);
+ configuration.setWorkContext(workContext);
+ configuration.setName("source");
+
+ JavaAtomicComponent source = new JavaAtomicComponent(configuration);
+ source.setScopeContainer(scope);
+ OutboundWire outboundWire = createOutboundWire(new QualifiedName("target/Target"), Target.class);
+ outboundWire.setContainer(source);
+ source.addOutboundWire(outboundWire);
+ configuration.setName("target");
+ JavaAtomicComponent target = new JavaAtomicComponent(configuration);
+ target.setScopeContainer(scope);
+ InboundWire targetWire = MockFactory.createInboundWire("Target", Target.class);
+ targetWire.setContainer(target);
+ target.addInboundWire(targetWire);
+ InboundWire inboundWire = target.getInboundWire("Target");
+ inboundWire.setContainer(target);
+
+ EasyMock.expect(parent.getChild("target")).andReturn(target);
+ EasyMock.replay(parent);
+
+ connector.connect(source);
+ target.start();
+ return outboundWire;
+ }
+
+ private static <T> OutboundWire createOutboundWire(QualifiedName targetName, Class<T> interfaze)
+ throws InvalidServiceContractException {
+ OutboundWire wire = new OutboundWireImpl();
+ JavaServiceContract contract = new JavaServiceContract(interfaze);
+ contract.setInteractionScope(InteractionScope.NONCONVERSATIONAL);
+ wire.setServiceContract(contract);
+ wire.setTargetName(targetName);
+ wire.addInvocationChains(createInvocationChains(interfaze));
+ return wire;
+ }
+
+ private static Map<Operation<?>, OutboundInvocationChain> createInvocationChains(Class<?> interfaze)
+ throws InvalidServiceContractException {
+ Map<Operation<?>, OutboundInvocationChain> invocations = new HashMap<Operation<?>, OutboundInvocationChain>();
+ JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ ServiceContract<?> contract = registry.introspect(interfaze);
+ for (Operation operation : contract.getOperations().values()) {
+ OutboundInvocationChain chain = new OutboundInvocationChainImpl(operation);
+ invocations.put(operation, chain);
+ }
+ return invocations;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/AllowsPassByReferenceProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/AllowsPassByReferenceProcessorTestCase.java
new file mode 100644
index 0000000000..9fd3fbfc9d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/AllowsPassByReferenceProcessorTestCase.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.osoa.sca.annotations.AllowsPassByReference;
+
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev: 452761 $ $Date: 2006-10-04 12:03:20 +0530 (Wed, 04 Oct 2006) $
+ */
+public class AllowsPassByReferenceProcessorTestCase extends TestCase {
+
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type;
+ AllowsPassByReferenceProcessor processor;
+
+ public void testClassAnnotation() throws Exception {
+ processor.visitClass(null, Foo.class, type, null);
+ assertEquals(true, type.isAllowsPassByReference());
+
+ processor.visitClass(null, Bar.class, type, null);
+ assertEquals(false, type.isAllowsPassByReference());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ type = new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor = new AllowsPassByReferenceProcessor();
+ }
+
+ @AllowsPassByReference
+ private class Foo {
+ }
+
+ //no annotation
+ private class Bar {
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorAutowireTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorAutowireTestCase.java
new file mode 100644
index 0000000000..c67d226b41
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorAutowireTestCase.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Constructor;
+import java.util.List;
+
+import org.osoa.sca.annotations.Property;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ConstructorAutowireTestCase extends TestCase {
+
+ ConstructorProcessor processor =
+ new ConstructorProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl()));
+
+ public void testAutowire() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo> ctor = Foo.class.getConstructor(Bar.class);
+ processor.visitConstructor(null, ctor, type, null);
+ assertNotNull(type.getReferences().get("myRef"));
+ }
+
+ public void testNamesOnConstructor() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo> ctor = Foo.class.getConstructor(Bar.class, Bar.class);
+ processor.visitConstructor(null, ctor, type, null);
+ assertEquals(2, type.getConstructorDefinition().getInjectionNames().size());
+ assertNotNull(type.getReferences().get("myRef1"));
+ assertNotNull(type.getReferences().get("myRef2"));
+ }
+
+ public void testNoName() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo2> ctor = Foo2.class.getConstructor(Bar.class);
+ processor.visitConstructor(null, ctor, type, null);
+ assertNotNull(type.getReferences().get(Bar.class.getName() + "0"));
+ }
+
+ public void testInvalidNumberOfNames() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<BadFoo> ctor = BadFoo.class.getConstructor(Bar.class, Bar.class);
+ try {
+ processor.visitConstructor(null, ctor, type, null);
+ fail();
+ } catch (InvalidAutowireException e) {
+ // expected
+ }
+ }
+
+ public void testNoMatchingNames() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<BadFoo> ctor = BadFoo.class.getConstructor(List.class, List.class);
+ try {
+ processor.visitConstructor(null, ctor, type, null);
+ fail();
+ } catch (InvalidConstructorException e) {
+ // expected
+ }
+ }
+
+ /**
+ * Verifies processing executes with additional extension annotations
+ */
+ public void testRandomAnnotation() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo3> ctor = Foo3.class.getConstructor(String.class, String.class);
+ processor.visitConstructor(null, ctor, type, null);
+ assertEquals(1, type.getProperties().size());
+ assertNotNull(type.getProperties().get("prop1"));
+ }
+
+ private static interface Bar {
+
+ }
+
+ private static class Foo {
+
+ @org.osoa.sca.annotations.Constructor()
+ public Foo(@Autowire(name = "myRef") Bar ref) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor({"myRef1", "myRef2"})
+ public Foo(@Autowire Bar ref1, @Autowire Bar ref2) {
+
+ }
+
+ }
+
+ private static class Foo2 {
+ @org.osoa.sca.annotations.Constructor()
+ public Foo2(@Autowire Bar ref) {
+
+ }
+ }
+
+ private static class BadFoo {
+
+ @org.osoa.sca.annotations.Constructor({"ref1"})
+ public BadFoo(@Autowire Bar ref1, @Autowire Bar ref2) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor({"myRef", "myRef2"})
+ public BadFoo(@Autowire List ref, @Autowire(name = "myOtherRef") List ref2) {
+
+ }
+
+ }
+
+ public static class Foo3 {
+
+ @org.osoa.sca.annotations.Constructor
+ public Foo3(@Property(name = "prop1") String prop, @Baz String baz) {
+ }
+ }
+
+ public @interface Baz {
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessorExtensibilityTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessorExtensibilityTestCase.java
new file mode 100644
index 0000000000..25a8ab9a1a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessorExtensibilityTestCase.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Constructor;
+
+import org.osoa.sca.annotations.Property;
+
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+
+/**
+ * Verifies the constructor processor works when parameters are marked with custom extension annotations
+ *
+ * @version $Rev$ $Date$
+ */
+public class ConstructorProcessorExtensibilityTestCase extends TestCase {
+ private ConstructorProcessor processor =
+ new ConstructorProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl()));
+
+ public void testProcessFirst() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo> ctor1 = Foo.class.getConstructor(String.class, String.class);
+ processor.visitConstructor(null, ctor1, type, null);
+ assertEquals("foo", type.getConstructorDefinition().getInjectionNames().get(0));
+ }
+
+ /**
+ * Verifies the constructor processor can be called after another processor has evaluated the constructor and found
+ * an annotation
+ *
+ * @throws Exception
+ */
+ public void testProcessLast() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo> ctor1 = Foo.class.getConstructor(String.class, String.class);
+ ConstructorDefinition<Foo> definition = new ConstructorDefinition<Foo>(ctor1);
+ definition.getInjectionNames().add("");
+ definition.getInjectionNames().add("mybar");
+ type.setConstructorDefinition(definition);
+ processor.visitConstructor(null, ctor1, type, null);
+ assertEquals("foo", type.getConstructorDefinition().getInjectionNames().get(0));
+ }
+
+
+ private @interface Bar {
+
+ }
+
+ private static class Foo {
+ @org.osoa.sca.annotations.Constructor
+ public Foo(@Property(name = "foo") String foo, @Bar String bar) {
+
+ }
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessorTestCase.java
new file mode 100644
index 0000000000..4e48523e8c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorProcessorTestCase.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Constructor;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import org.osoa.sca.annotations.Property;
+import org.osoa.sca.annotations.Reference;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.model.Multiplicity;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ConstructorProcessorTestCase extends TestCase {
+ private ConstructorProcessor processor =
+ new ConstructorProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl()));
+
+ public void testDuplicateConstructor() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ try {
+ processor.visitClass(null, BadFoo.class, type, null);
+ fail();
+ } catch (DuplicateConstructorException e) {
+ // expected
+ }
+ }
+
+ public void testConstructorAnnotation() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo> ctor1 = Foo.class.getConstructor(String.class);
+ processor.visitConstructor(null, ctor1, type, null);
+ assertEquals("foo", type.getConstructorDefinition().getInjectionNames().get(0));
+ }
+
+ public void testNoAnnotation() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<NoAnnotation> ctor1 = NoAnnotation.class.getConstructor();
+ processor.visitConstructor(null, ctor1, type, null);
+ assertNull(type.getConstructorDefinition());
+ }
+
+ public void testBadAnnotation() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<BadAnnotation> ctor1 = BadAnnotation.class.getConstructor(String.class, Foo.class);
+ try {
+ processor.visitConstructor(null, ctor1, type, null);
+ fail();
+ } catch (InvalidConstructorException e) {
+ // expected
+ }
+ }
+
+ public void testMixedParameters() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Mixed> ctor1 = Mixed.class.getConstructor(String.class, String.class, String.class);
+ processor.visitConstructor(null, ctor1, type, null);
+ assertEquals("java.lang.String0", type.getConstructorDefinition().getInjectionNames().get(0));
+ assertEquals("foo", type.getConstructorDefinition().getInjectionNames().get(1));
+ assertEquals("bar", type.getConstructorDefinition().getInjectionNames().get(2));
+ }
+
+ public void testAllAutowireWithNoNames() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<AllAutowireNoName> ctor1 =
+ AllAutowireNoName.class.getConstructor(String.class, String.class, String.class);
+ processor.visitConstructor(null, ctor1, type, null);
+ assertEquals("java.lang.String0", type.getConstructorDefinition().getInjectionNames().get(0));
+ assertEquals("java.lang.String1", type.getConstructorDefinition().getInjectionNames().get(1));
+ assertEquals("java.lang.String2", type.getConstructorDefinition().getInjectionNames().get(2));
+ }
+
+ private static class BadFoo {
+
+ @org.osoa.sca.annotations.Constructor("foo")
+ public BadFoo(String foo) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor({"foo", "bar"})
+ public BadFoo(String foo, String bar) {
+
+ }
+ }
+
+ private static class Foo {
+ @org.osoa.sca.annotations.Constructor("foo")
+ public Foo(String foo) {
+
+ }
+ }
+
+ private static class NoAnnotation {
+ public NoAnnotation() {
+ }
+ }
+
+ private static class BadAnnotation {
+ @org.osoa.sca.annotations.Constructor("foo")
+ public BadAnnotation(String foo, Foo ref) {
+ }
+ }
+
+
+ public static final class Mixed {
+ @org.osoa.sca.annotations.Constructor
+ public Mixed(@Autowire String param1,
+ @Property(name = "foo")String param2,
+ @Reference(name = "bar")String param3) {
+ }
+ }
+
+ public static final class AllAutowireNoName {
+ @org.osoa.sca.annotations.Constructor
+ public AllAutowireNoName(@Autowire String param1, @Autowire String param2, @Autowire String param3) {
+ }
+ }
+
+ public static final class Multiple {
+ @org.osoa.sca.annotations.Constructor
+ public Multiple(@Autowire Collection<String> param1,
+ @Property(name = "foo")String[] param2,
+ @Reference(name = "bar", required = true)List<String> param3,
+ @Property(name = "abc")Set<String> param4,
+ @Reference(name = "xyz")String[] param5) {
+ }
+ }
+
+ public void testMultiplicity() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Multiple> ctor1 =
+ Multiple.class.getConstructor(Collection.class, String[].class, List.class, Set.class, String[].class);
+ processor.visitConstructor(null, ctor1, type, null);
+ JavaMappedReference ref0 = type.getReferences().get("java.util.Collection0");
+ assertNotNull(ref0);
+ assertEquals(Multiplicity.ONE_N, ref0.getMultiplicity());
+ JavaMappedReference ref1 = type.getReferences().get("bar");
+ assertNotNull(ref1);
+ assertEquals(Multiplicity.ONE_N, ref1.getMultiplicity());
+ JavaMappedReference ref2 = type.getReferences().get("xyz");
+ assertNotNull(ref2);
+ assertEquals(Multiplicity.ZERO_N, ref2.getMultiplicity());
+ JavaMappedProperty prop1 = type.getProperties().get("foo");
+ assertNotNull(prop1);
+ assertTrue(prop1.isMany());
+ JavaMappedProperty prop2 = type.getProperties().get("abc");
+ assertNotNull(prop2);
+ assertTrue(prop2.isMany());
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorPropertyTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorPropertyTestCase.java
new file mode 100644
index 0000000000..fb125ca0f4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorPropertyTestCase.java
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Constructor;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.spi.implementation.java.DuplicatePropertyException;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.osoa.sca.annotations.Property;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ConstructorPropertyTestCase extends TestCase {
+
+ ConstructorProcessor processor =
+ new ConstructorProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl()));
+
+ public void testProperty() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo> ctor = Foo.class.getConstructor(String.class);
+ processor.visitConstructor(null, ctor, type, null);
+ JavaMappedProperty<?> property = type.getProperties().get("myProp");
+ assertEquals(property.isMustSupply(), true);
+ assertEquals("myProp", property.getName());
+ }
+
+ public void testTwoPropertiesSameType() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo> ctor = Foo.class.getConstructor(String.class, String.class);
+ processor.visitConstructor(null, ctor, type, null);
+ assertNotNull(type.getProperties().get("myProp1"));
+ assertNotNull(type.getProperties().get("myProp2"));
+ }
+
+ public void testDuplicateProperty() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<BadFoo> ctor = BadFoo.class.getConstructor(String.class, String.class);
+ try {
+ processor.visitConstructor(null, ctor, type, null);
+ fail();
+ } catch (DuplicatePropertyException e) {
+ // expected
+ }
+ }
+
+ public void testNoName() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<BadFoo> ctor = BadFoo.class.getConstructor(String.class);
+ try {
+ processor.visitConstructor(null, ctor, type, null);
+ fail();
+ } catch (InvalidPropertyException e) {
+ // expected
+ }
+ }
+
+ public void testNamesOnConstructor() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo> ctor = Foo.class.getConstructor(Integer.class);
+ processor.visitConstructor(null, ctor, type, null);
+ assertNotNull(type.getProperties().get("myProp"));
+ }
+
+ public void testInvalidNumberOfNames() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<BadFoo> ctor = BadFoo.class.getConstructor(Integer.class, Integer.class);
+ try {
+ processor.visitConstructor(null, ctor, type, null);
+ fail();
+ } catch (InvalidPropertyException e) {
+ // expected
+ }
+ }
+
+ public void testNoMatchingNames() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<BadFoo> ctor = BadFoo.class.getConstructor(List.class, List.class);
+ try {
+ processor.visitConstructor(null, ctor, type, null);
+ fail();
+ } catch (InvalidConstructorException e) {
+ // expected
+ }
+ }
+
+// public void testMultiplicityRequired() throws Exception {
+ // TODO multiplicity
+// }
+
+ private static class Foo {
+
+ @org.osoa.sca.annotations.Constructor()
+ public Foo(@Property(name = "myProp", required = true) String prop) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor("myProp")
+ public Foo(@Property Integer prop) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor()
+ public Foo(@Property(name = "myProp1") String prop1, @Property(name = "myProp2") String prop2) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor()
+ public Foo(@Property List prop) {
+
+ }
+ }
+
+ private static class BadFoo {
+
+ @org.osoa.sca.annotations.Constructor()
+ public BadFoo(@Property(name = "myProp") String prop1, @Property(name = "myProp") String prop2) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor()
+ public BadFoo(@Property String prop) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor("myProp")
+ public BadFoo(@Property Integer prop, @Property Integer prop2) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor({"myRef", "myRef2"})
+ public BadFoo(@Property List ref, @Property(name = "myOtherRef") List ref2) {
+
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorReferenceTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorReferenceTestCase.java
new file mode 100644
index 0000000000..152f3b63d1
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorReferenceTestCase.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Constructor;
+import java.util.List;
+
+import org.osoa.sca.annotations.Reference;
+
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ConstructorReferenceTestCase extends TestCase {
+
+ ConstructorProcessor processor;
+
+ public void testReference() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo> ctor = Foo.class.getConstructor(String.class);
+ processor.visitConstructor(null, ctor, type, null);
+ JavaMappedReference reference = type.getReferences().get("myRef");
+ assertEquals("myRef", reference.getName());
+ }
+
+ public void testTwoReferencesSameType() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo> ctor = Foo.class.getConstructor(String.class, String.class);
+ processor.visitConstructor(null, ctor, type, null);
+ assertNotNull(type.getReferences().get("myRef1"));
+ assertNotNull(type.getReferences().get("myRef2"));
+ }
+
+ public void testDuplicateProperty() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<BadFoo> ctor = BadFoo.class.getConstructor(String.class, String.class);
+ try {
+ processor.visitConstructor(null, ctor, type, null);
+ fail();
+ } catch (DuplicateReferenceException e) {
+ // expected
+ }
+ }
+
+ public void testNoName() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<BadFoo> ctor = BadFoo.class.getConstructor(String.class);
+ try {
+ processor.visitConstructor(null, ctor, type, null);
+ fail();
+ } catch (InvalidReferenceException e) {
+ // expected
+ }
+ }
+
+ public void testNamesOnConstructor() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo> ctor = Foo.class.getConstructor(Integer.class);
+ processor.visitConstructor(null, ctor, type, null);
+ assertNotNull(type.getReferences().get("myRef"));
+ }
+
+ public void testInvalidNumberOfNames() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<BadFoo> ctor = BadFoo.class.getConstructor(Integer.class, Integer.class);
+ try {
+ processor.visitConstructor(null, ctor, type, null);
+ fail();
+ } catch (InvalidReferenceException e) {
+ // expected
+ }
+ }
+
+ public void testNoMatchingNames() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<BadFoo> ctor = BadFoo.class.getConstructor(List.class, List.class);
+ try {
+ processor.visitConstructor(null, ctor, type, null);
+ fail();
+ } catch (InvalidConstructorException e) {
+ // expected
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ processor =
+ new ConstructorProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl()));
+ }
+
+// public void testMultiplicityRequired() throws Exception {
+ // TODO multiplicity
+// }
+
+ private static class Foo {
+
+ @org.osoa.sca.annotations.Constructor()
+ public Foo(@Reference(name = "myRef", required = true) String prop) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor()
+ public Foo(@Reference(name = "myRef1") String prop1, @Reference(name = "myRef2") String prop2) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor("myRef")
+ public Foo(@Reference Integer prop) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor()
+ public Foo(@Reference List prop) {
+
+ }
+ }
+
+ private static class BadFoo {
+
+ @org.osoa.sca.annotations.Constructor
+ public BadFoo(@Reference(name = "myRef") String prop1, @Reference(name = "myRef") String prop2) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor
+ public BadFoo(@Reference String prop) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor("myRef")
+ public BadFoo(@Reference Integer ref, @Reference Integer ref2) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor({"myRef", "myRef2"})
+ public BadFoo(@Reference List ref, @Reference(name = "myOtherRef") List ref2) {
+
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorResourceTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorResourceTestCase.java
new file mode 100644
index 0000000000..c691a4d6bc
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConstructorResourceTestCase.java
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Constructor;
+import java.util.List;
+
+import org.apache.tuscany.api.annotation.Resource;
+
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ConstructorResourceTestCase extends TestCase {
+
+ ConstructorProcessor processor =
+ new ConstructorProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl()));
+
+ public void testResource() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo> ctor = Foo.class.getConstructor(String.class);
+ processor.visitConstructor(null, ctor, type, null);
+ org.apache.tuscany.spi.implementation.java.Resource resource = type.getResources().get("myResource");
+ assertFalse(resource.isOptional());
+ }
+
+ public void testTwoResourcesSameType() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo> ctor = Foo.class.getConstructor(String.class, String.class);
+ processor.visitConstructor(null, ctor, type, null);
+ assertNotNull(type.getResources().get("myResource1"));
+ assertNotNull(type.getResources().get("myResource2"));
+ }
+
+ public void testDuplicateResource() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<BadFoo> ctor = BadFoo.class.getConstructor(String.class, String.class);
+ try {
+ processor.visitConstructor(null, ctor, type, null);
+ fail();
+ } catch (DuplicateResourceException e) {
+ // expected
+ }
+ }
+
+ public void testNoName() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<ConstructorResourceTestCase.BadFoo> ctor =
+ ConstructorResourceTestCase.BadFoo.class.getConstructor(String.class);
+ try {
+ processor.visitConstructor(null, ctor, type, null);
+ fail();
+ } catch (InvalidResourceException e) {
+ // expected
+ }
+ }
+
+ public void testNamesOnConstructor() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo> ctor = Foo.class.getConstructor(Integer.class);
+ processor.visitConstructor(null, ctor, type, null);
+ assertNotNull(type.getResources().get("myResource"));
+ }
+
+ public void testInvalidNumberOfNames() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<ConstructorResourceTestCase.BadFoo> ctor =
+ ConstructorResourceTestCase.BadFoo.class.getConstructor(Integer.class, Integer.class);
+ try {
+ processor.visitConstructor(null, ctor, type, null);
+ fail();
+ } catch (InvalidResourceException e) {
+ // expected
+ }
+ }
+
+ public void testNoMatchingNames() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<ConstructorResourceTestCase.BadFoo> ctor =
+ ConstructorResourceTestCase.BadFoo.class.getConstructor(List.class, List.class);
+ try {
+ processor.visitConstructor(null, ctor, type, null);
+ fail();
+ } catch (InvalidConstructorException e) {
+ // expected
+ }
+ }
+
+ private static class Foo {
+
+ @org.osoa.sca.annotations.Constructor
+ public Foo(@Resource(name = "myResource") String resource) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor("myResource")
+ public Foo(@Resource Integer resource) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor
+ public Foo(@Resource(name = "myResource1") String res1, @Resource(name = "myResource2") String res2) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor
+ public Foo(@Resource List res) {
+
+ }
+ }
+
+ private static class BadFoo {
+
+ @org.osoa.sca.annotations.Constructor
+ public BadFoo(@Resource(name = "myResource") String res1, @Resource(name = "myResource") String res2) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor
+ public BadFoo(@Resource String res) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor("myProp")
+ public BadFoo(@Resource Integer res, @Resource Integer res2) {
+
+ }
+
+ @org.osoa.sca.annotations.Constructor({"myRes", "myRes2"})
+ public BadFoo(@Resource List res, @Resource(name = "myOtherRes") List res2) {
+
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ContextProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ContextProcessorTestCase.java
new file mode 100644
index 0000000000..1ad92bfee9
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ContextProcessorTestCase.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+import org.osoa.sca.ComponentContext;
+import org.osoa.sca.RequestContext;
+import org.osoa.sca.annotations.Context;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.wire.WireService;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ContextProcessorTestCase extends TestCase {
+ private ContextProcessor processor;
+ private CompositeComponent composite;
+
+ // FIXME: resurrect to test ComponentContext injection
+/*
+ public void testCompositeContextMethod() throws Exception {
+ Method method = Foo.class.getMethod("setContext", ComponentContext.class);
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitMethod(composite, method, type, null);
+ assertNotNull(type.getResources().get("context"));
+ }
+*/
+
+ // FIXME: resurrect to test ComponentContext injection
+/*
+ public void testCompositeContextField() throws Exception {
+ Field field = Foo.class.getDeclaredField("context");
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitField(composite, field, type, null);
+ assertNotNull(type.getResources().get("context"));
+ }
+*/
+
+ public void testRequestContextMethod() throws Exception {
+ Method method = Foo.class.getMethod("setRequestContext", RequestContext.class);
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitMethod(composite, method, type, null);
+ assertNotNull(type.getResources().get("requestContext"));
+ }
+
+ public void testRequestContextField() throws Exception {
+ Field field = Foo.class.getDeclaredField("requestContext");
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitField(composite, field, type, null);
+ assertNotNull(type.getResources().get("requestContext"));
+ }
+
+ public void testInvalidParamType() throws Exception {
+ Method method = Foo.class.getMethod("setContext", String.class);
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ try {
+ processor.visitMethod(composite, method, type, null);
+ fail();
+ } catch (UnknownContextTypeException e) {
+ // expected
+ }
+ }
+
+ public void testInvalidParamTypeField() throws Exception {
+ Field field = Foo.class.getDeclaredField("badContext");
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ try {
+ processor.visitField(composite, field, type, null);
+ fail();
+ } catch (UnknownContextTypeException e) {
+ // expected
+ }
+ }
+
+
+ public void testInvalidParamNum() throws Exception {
+ Method method = Foo.class.getMethod("setContext", ComponentContext.class, String.class);
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ try {
+ processor.visitMethod(composite, method, type, null);
+ fail();
+ } catch (IllegalContextException e) {
+ // expected
+ }
+ }
+
+ public void testInvalidNoParams() throws Exception {
+ Method method = Foo.class.getMethod("setContext");
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ try {
+ processor.visitMethod(composite, method, type, null);
+ fail();
+ } catch (IllegalContextException e) {
+ // expected
+ }
+ }
+
+ public void testNoContext() throws Exception {
+ Method method = Foo.class.getMethod("noContext", ComponentContext.class);
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitMethod(composite, method, type, null);
+ assertEquals(0, type.getResources().size());
+ }
+
+ public void testNoContextField() throws Exception {
+ Field field = Foo.class.getDeclaredField("noContext");
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitField(composite, field, type, null);
+ assertEquals(0, type.getResources().size());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ processor = new ContextProcessor();
+ processor.setWireService(EasyMock.createNiceMock(WireService.class));
+ processor.setWorkContext(EasyMock.createNiceMock(WorkContext.class));
+ composite = EasyMock.createNiceMock(CompositeComponent.class);
+ }
+
+ private class Foo {
+ @Context
+ protected ComponentContext context;
+
+ @Context
+ protected Object badContext;
+
+ protected ComponentContext noContext;
+
+ @Context
+ protected RequestContext requestContext;
+
+ @Context
+ public void setContext(ComponentContext context) {
+
+ }
+
+ @Context
+ public void setContext(String context) {
+
+ }
+
+ @Context
+ public void setContext(ComponentContext context, String string) {
+
+ }
+
+ @Context
+ public void setContext() {
+
+ }
+
+ public void noContext(ComponentContext context) {
+
+ }
+
+ @Context
+ public void setRequestContext(RequestContext requestContext) {
+ this.requestContext = requestContext;
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConversationProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConversationProcessorTestCase.java
new file mode 100644
index 0000000000..0433fed3a6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConversationProcessorTestCase.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.osoa.sca.annotations.ConversationAttributes;
+import org.osoa.sca.annotations.ConversationID;
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ConversationProcessorTestCase extends TestCase {
+ private ConversationProcessor processor = new ConversationProcessor();
+
+ public void testMaxIdleTime() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(null, FooMaxIdle.class, type, null);
+ assertEquals(10000L, type.getMaxIdleTime());
+ assertEquals(-1, type.getMaxAge());
+ }
+
+ public void testMaxAge() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(null, FooMaxAge.class, type, null);
+ assertEquals(10000L, type.getMaxAge());
+ assertEquals(-1, type.getMaxIdleTime());
+ }
+
+ public void testBadFooBoth() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ try {
+ processor.visitClass(null, BadFooBoth.class, type, null);
+ fail();
+ } catch (InvalidConversationalImplementation e) {
+ // expected
+ }
+ }
+
+ public void testImplicitScope() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(null, ImplicitFooScope.class, type, null);
+ assertEquals(org.apache.tuscany.spi.model.Scope.CONVERSATION, type.getImplementationScope());
+ }
+
+ public void testBadFooScope() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ try {
+ processor.visitClass(null, BadFooScope.class, type, null);
+ fail();
+ } catch (InvalidConversationalImplementation e) {
+ // expected
+ }
+ }
+
+ public void testJustConversation() throws Exception {
+ // TODO do we want these semantics
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(null, FooJustConversation.class, type, null);
+ assertEquals(org.apache.tuscany.spi.model.Scope.CONVERSATION, type.getImplementationScope());
+ assertEquals(-1, type.getMaxAge());
+ assertEquals(-1, type.getMaxIdleTime());
+ }
+
+ public void testSetConversationIDField() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Field field = FooWithConversationIDField.class.getDeclaredField("conversationID");
+ processor.visitField(null, field, type, null);
+ assertNotNull(type.getConversationIDMember());
+ assertEquals(field, type.getConversationIDMember());
+ }
+
+ public void testSetConversationIDMethod() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Method method = FooWithConversationIDMethod.class.getDeclaredMethods()[0];
+ processor.visitMethod(null, method, type, null);
+ assertNotNull(type.getConversationIDMember());
+ assertEquals(method, type.getConversationIDMember());
+ }
+
+ @Scope("CONVERSATION")
+ @ConversationAttributes(maxIdleTime = "10 seconds")
+ private class FooMaxIdle {
+ }
+
+ @Scope("CONVERSATION")
+ @ConversationAttributes(maxAge = "10 seconds")
+ private class FooMaxAge {
+ }
+
+ @Scope("CONVERSATION")
+ @ConversationAttributes(maxAge = "10 seconds", maxIdleTime = "10 seconds")
+ private class BadFooBoth {
+ }
+
+ @ConversationAttributes(maxAge = "10 seconds")
+ private class ImplicitFooScope {
+ }
+
+ @Scope("STATELESS")
+ @ConversationAttributes(maxAge = "10 seconds")
+ private class BadFooScope {
+ }
+
+ @ConversationAttributes
+ private class FooJustConversation {
+ }
+
+ private class FooWithConversationIDField {
+ @ConversationID
+ private String conversationID;
+ }
+
+ private class FooWithConversationIDMethod {
+ @ConversationID
+ void setConversationID(String conversationID) {
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConvertTimeMillisTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConvertTimeMillisTestCase.java
new file mode 100644
index 0000000000..556416a797
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ConvertTimeMillisTestCase.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ConvertTimeMillisTestCase extends TestCase {
+ private MockProcessor registy;
+
+ public void testConvertSeconds() throws Exception {
+ assertEquals(10000L, registy.convertTimeMillis("10 seconds"));
+ assertEquals(10000L, registy.convertTimeMillis("10 SECONDS"));
+ try {
+ registy.convertTimeMillis("10seconds");
+ fail();
+ } catch (NumberFormatException e) {
+ // expected
+ }
+ }
+
+ public void testConvertMinutes() throws Exception {
+ assertEquals(600000L, registy.convertTimeMillis("10 minutes"));
+ assertEquals(600000L, registy.convertTimeMillis("10 MINUTES"));
+ try {
+ registy.convertTimeMillis("10minutes");
+ fail();
+ } catch (NumberFormatException e) {
+ // expected
+ }
+ }
+
+ public void testConvertHours() throws Exception {
+ assertEquals(36000000L, registy.convertTimeMillis("10 hours"));
+ assertEquals(36000000L, registy.convertTimeMillis("10 HOURS"));
+ try {
+ registy.convertTimeMillis("10hours");
+ fail();
+ } catch (NumberFormatException e) {
+ // expected
+ }
+ }
+
+ public void testConvertDays() throws Exception {
+ assertEquals(864000000L, registy.convertTimeMillis("10 days"));
+ assertEquals(864000000L, registy.convertTimeMillis("10 DAYS"));
+ try {
+ registy.convertTimeMillis("10days");
+ fail();
+ } catch (NumberFormatException e) {
+ // expected
+ }
+ }
+
+ public void testConvertYears() throws Exception {
+ assertEquals(315569260000L, registy.convertTimeMillis("10 years"));
+ assertEquals(315569260000L, registy.convertTimeMillis("10 YEARS"));
+ try {
+ registy.convertTimeMillis("10years");
+ fail();
+ } catch (NumberFormatException e) {
+ // expected
+ }
+ }
+
+ public void testConvertDefault() throws Exception {
+ assertEquals(10000L, registy.convertTimeMillis("10 "));
+ assertEquals(10000L, registy.convertTimeMillis("10"));
+ }
+
+ public void testInvalid() throws Exception {
+ try {
+ registy.convertTimeMillis("foo");
+ fail();
+ } catch (NumberFormatException e) {
+ // expected
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ registy = new MockProcessor();
+ }
+
+ private class MockProcessor extends ConversationProcessor {
+
+ @Override
+ protected long convertTimeMillis(String expr) throws NumberFormatException {
+ return super.convertTimeMillis(expr);
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/DestroyProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/DestroyProcessorTestCase.java
new file mode 100644
index 0000000000..6929250298
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/DestroyProcessorTestCase.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Method;
+
+import org.osoa.sca.annotations.Destroy;
+
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class DestroyProcessorTestCase extends TestCase {
+
+ public void testDestroy() throws Exception {
+ DestroyProcessor processor = new DestroyProcessor();
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Method method = Foo.class.getMethod("destroy");
+ processor.visitMethod(null, method, type, null);
+ assertNotNull(type.getDestroyMethod());
+ }
+
+ public void testBadDestroy() throws Exception {
+ DestroyProcessor processor = new DestroyProcessor();
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Method method = Bar.class.getMethod("badDestroy", String.class);
+ try {
+ processor.visitMethod(null, method, type, null);
+ fail();
+ } catch (IllegalDestructorException e) {
+ // expected
+ }
+ }
+
+ public void testTwoDestroy() throws Exception {
+ DestroyProcessor processor = new DestroyProcessor();
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Method method = Bar.class.getMethod("destroy");
+ Method method2 = Bar.class.getMethod("destroy2");
+ processor.visitMethod(null, method, type, null);
+ try {
+ processor.visitMethod(null, method2, type, null);
+ fail();
+ } catch (DuplicateDestructorException e) {
+ // expected
+ }
+ }
+
+
+ private class Foo {
+
+ @Destroy
+ public void destroy() {
+ }
+ }
+
+
+ private class Bar {
+
+ @Destroy
+ public void destroy() {
+ }
+
+ @Destroy
+ public void destroy2() {
+ }
+
+ @Destroy
+ public void badDestroy(String foo) {
+ }
+
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/EagerInitProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/EagerInitProcessorTestCase.java
new file mode 100644
index 0000000000..22770cbfce
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/EagerInitProcessorTestCase.java
@@ -0,0 +1,54 @@
+package org.apache.tuscany.core.implementation.processor;
+
+import org.osoa.sca.annotations.EagerInit;
+
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class EagerInitProcessorTestCase extends TestCase {
+
+ public void testNoLevel() throws ProcessingException {
+ EagerInitProcessor processor = new EagerInitProcessor();
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(null, NoLevel.class, type, null);
+ assertEquals(50, type.getInitLevel());
+ }
+
+ public void testLevel() throws ProcessingException {
+ EagerInitProcessor processor = new EagerInitProcessor();
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(null, Level.class, type, null);
+ assertEquals(50, type.getInitLevel());
+ }
+
+ public void testSubclass() throws ProcessingException {
+ EagerInitProcessor processor = new EagerInitProcessor();
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(null, SubClass.class, type, null);
+ assertEquals(50, type.getInitLevel());
+ }
+
+ @EagerInit
+ private class NoLevel {
+ }
+
+ @EagerInit
+ private class Level {
+ }
+
+ private class SubClass extends Level {
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicAndPropertyTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicAndPropertyTestCase.java
new file mode 100644
index 0000000000..93de605e33
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicAndPropertyTestCase.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Constructor;
+
+import org.osoa.sca.annotations.Property;
+
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class HeuristicAndPropertyTestCase extends TestCase {
+
+ private PropertyProcessor propertyProcessor;
+ private HeuristicPojoProcessor heuristicProcessor;
+
+ /**
+ * Verifies the property and heuristic processors don't collide
+ */
+ @SuppressWarnings("unchecked")
+ public void testPropertyProcessorWithHeuristicProcessor() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor ctor = Foo.class.getConstructor(String.class);
+ type.setConstructorDefinition(new ConstructorDefinition(ctor));
+ propertyProcessor.visitConstructor(null, ctor, type, null);
+ heuristicProcessor.visitEnd(null, Foo.class, type, null);
+ assertEquals(1, type.getProperties().size());
+ assertNotNull(type.getProperties().get("foo"));
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ ImplementationProcessorServiceImpl service =
+ new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl());
+ propertyProcessor = new PropertyProcessor(service);
+ heuristicProcessor = new HeuristicPojoProcessor(service);
+ }
+
+ public static class Foo {
+ public Foo(@Property(name = "foo") String prop) {
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicConstructorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicConstructorTestCase.java
new file mode 100644
index 0000000000..92f6d54366
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicConstructorTestCase.java
@@ -0,0 +1,330 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.osoa.sca.annotations.Property;
+import org.osoa.sca.annotations.Reference;
+import org.osoa.sca.annotations.Remotable;
+
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.model.ServiceContract;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class HeuristicConstructorTestCase extends TestCase {
+
+ private HeuristicPojoProcessor processor =
+ new HeuristicPojoProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl()));
+
+ /**
+ * Verifies a single constructor is chosen with a parameter as the type
+ */
+ public void testSingleConstructorWithParam() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ JavaMappedProperty<String> prop = new JavaMappedProperty<String>();
+ prop.setName("foo");
+ prop.setJavaType(String.class);
+ type.getProperties().put("foo", prop);
+ processor.visitEnd(null, Foo1.class, type, null);
+ assertNotNull(type.getConstructorDefinition().getConstructor());
+ assertEquals("foo", type.getConstructorDefinition().getInjectionNames().get(0));
+ }
+
+ /**
+ * Verifies a single constructor is chosen with a reference as the type
+ */
+ public void testSingleConstructorWithRef() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ JavaMappedReference ref = new JavaMappedReference();
+ ref.setName("foo");
+ ServiceContract contract = new JavaServiceContract(String.class);
+ ref.setServiceContract(contract);
+ type.getReferences().put("foo", ref);
+ processor.visitEnd(null, Foo1.class, type, null);
+ assertNotNull(type.getConstructorDefinition().getConstructor());
+ assertEquals("foo", type.getConstructorDefinition().getInjectionNames().get(0));
+ }
+
+ /**
+ * Verifies a single constructor is chosen with a property and a reference as the type
+ */
+ public void testSingleConstructorWithPropRef() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+
+ JavaMappedProperty<String> prop = new JavaMappedProperty<String>();
+ prop.setName("foo");
+ prop.setJavaType(String.class);
+ type.getProperties().put("foo", prop);
+
+ JavaMappedReference ref = new JavaMappedReference();
+ ref.setName("ref");
+ ServiceContract contract = new JavaServiceContract(Foo1.class);
+ ref.setServiceContract(contract);
+ type.getReferences().put("ref", ref);
+ processor.visitEnd(null, Foo2.class, type, null);
+ assertNotNull(type.getConstructorDefinition().getConstructor());
+ assertEquals(2, type.getConstructorDefinition().getInjectionNames().size());
+ }
+
+
+ public void testSingleConstructorResolvableParam() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitEnd(null, Foo5.class, type, null);
+ assertEquals(String.class, type.getProperties().get("string").getJavaType());
+ }
+
+ public void testSingleConstructorResolvableRef() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitEnd(null, Foo6.class, type, null);
+ assertEquals(Ref.class,
+ type.getReferences().get("heuristicconstructortestcase$ref").getServiceContract().getInterfaceClass());
+ }
+
+ public void testSingleConstructorAmbiguousRef() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ JavaMappedReference ref = new JavaMappedReference();
+ ref.setName("ref");
+ ServiceContract contract = new JavaServiceContract(Foo1.class);
+ ref.setServiceContract(contract);
+ type.getReferences().put("ref", ref);
+ JavaMappedReference ref2 = new JavaMappedReference();
+ ref2.setName("ref2");
+ ref2.setServiceContract(contract);
+ type.getReferences().put("ref2", ref2);
+ try {
+ processor.visitEnd(null, Foo4.class, type, null);
+ fail();
+ } catch (AmbiguousConstructorException e) {
+ // expected
+ }
+ }
+
+ public void testConstructorPropertyAnnotatedParamsOnly() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitEnd(null, Foo7.class, type, null);
+ assertNotNull(type.getProperties().get("myProp"));
+ }
+
+ public void testConstructorReferenceAnnotatedParamsOnly() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitEnd(null, Foo8.class, type, null);
+ assertNotNull(type.getReferences().get("myRef"));
+ }
+
+ public void testConstructorAutowireAnnotatedParamsOnly() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitEnd(null, Foo9.class, type, null);
+ assertNotNull(type.getReferences().get("myAutowire"));
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testDefaultConstructor() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitEnd(null, Foo3.class, type, null);
+ assertNotNull(type.getConstructorDefinition().getConstructor());
+ }
+
+ public void testSameTypesButAnnotated() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitEnd(null, Foo12.class, type, null);
+ assertEquals(2, type.getProperties().size());
+ assertNotNull(type.getProperties().get("prop1"));
+ assertNotNull(type.getProperties().get("prop2"));
+ }
+
+ /**
+ * Verifies processing executes with additional extension annotations
+ */
+ public void testRandomAnnotation() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitEnd(null, Foo11.class, type, null);
+ assertEquals(1, type.getProperties().size());
+ assertNotNull(type.getProperties().get("prop1"));
+ }
+
+ public void testAutowire() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitEnd(null, Foo13.class, type, null);
+ assertEquals(1, type.getReferences().size());
+ assertNotNull(type.getReferences().get(String.class.getName() + "0"));
+ }
+
+ public void testMultipleAutowire() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitEnd(null, Foo15.class, type, null);
+ assertEquals(2, type.getReferences().size());
+ assertNotNull(type.getReferences().get(String.class.getName() + "0"));
+ assertNotNull(type.getReferences().get(String.class.getName() + "1"));
+ }
+
+ public void testNoAutowireNameInConstructor() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitEnd(null, Foo16.class, type, null);
+ assertEquals(2, type.getReferences().size());
+ assertNotNull(type.getReferences().get(String.class.getName() + "0"));
+ assertNotNull(type.getReferences().get("bar"));
+ assertNotNull(type.getProperties().get("foo"));
+ }
+
+ public void testPrivateConstructor() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ try {
+ processor.visitEnd(null, Foo14.class, type, null);
+ fail();
+ } catch (NoConstructorException e) {
+ // expected
+ }
+ }
+
+
+ public void testMultipleConstructors() throws Exception {
+ // throw new UnsupportedOperationException("Finish heuristic multiple constructors - Foo10");
+ }
+
+
+ public static class Foo1 {
+ public Foo1(String val) {
+ }
+ }
+
+ public static class Foo2 {
+ public Foo2(String val, Foo1 ref) {
+ }
+ }
+
+ public static class Foo3 {
+ }
+
+ public static class Foo4 {
+ public Foo4(Foo1 ref) {
+ }
+ }
+
+ public static class Prop {
+
+ }
+
+ @Remotable
+ public static interface Ref {
+
+ }
+
+ public static class Foo5 {
+ public Foo5(String val) {
+ }
+ }
+
+ public static class Foo6 {
+ public Foo6(Ref ref) {
+ }
+ }
+
+ public static class Foo7 {
+ public Foo7(@Property(name = "myProp") String prop) {
+ }
+ }
+
+
+ public static class Foo8 {
+ public Foo8(@Reference(name = "myRef") String ref) {
+ }
+ }
+
+ public static class Foo9 {
+ public Foo9(@Autowire(name = "myAutowire") String autowire) {
+ }
+ }
+
+ public static class Foo10 {
+
+ public Foo10() {
+ }
+
+ public Foo10(String prop) {
+ }
+
+ public Foo10(@Property(name = "prop1") String prop1, @Property(name = "prop2") String prop2) {
+
+ }
+ }
+
+ public static class Foo11 {
+
+ public Foo11(@Property(name = "prop1") String prop, @Baz String baz) {
+ }
+ }
+
+ public static class Foo12 {
+
+ public Foo12(@Property(name = "prop1") String prop, @Property(name = "prop2") String baz) {
+ }
+ }
+
+ public @interface Baz {
+
+ }
+
+ public static class Foo13 {
+ public Foo13(@Autowire String foo) {
+ }
+ }
+
+ public static final class Foo14 {
+ private Foo14() {
+ }
+ }
+
+ public static final class Foo15 {
+ public Foo15(@Autowire String param1, @Autowire String param2) {
+ }
+ }
+
+ public static final class Foo16 {
+ public Foo16(@Autowire String param1,
+ @Property(name = "foo") String param2,
+ @Reference(name = "bar") String param3) {
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicPojoProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicPojoProcessorTestCase.java
new file mode 100644
index 0000000000..2b3c12a3aa
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeuristicPojoProcessorTestCase.java
@@ -0,0 +1,395 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Constructor;
+import java.util.Collection;
+import java.util.List;
+
+import org.osoa.sca.annotations.Property;
+import org.osoa.sca.annotations.Reference;
+import org.osoa.sca.annotations.Remotable;
+import org.osoa.sca.annotations.Service;
+
+import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension;
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+
+/**
+ * Verfies component type information is properly introspected from an unadorned POJO according to the SCA Java Client
+ * and Implementation Model Specification
+ *
+ * @version $Rev$ $Date$
+ */
+public class HeuristicPojoProcessorTestCase extends TestCase {
+
+ private HeuristicPojoProcessor processor =
+ new HeuristicPojoProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl()));
+
+ /**
+ * Verifies a single service interface is computed when only one interface is implemented
+ */
+ public void testSingleInterface() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<SingleInterfaceImpl> ctor = SingleInterfaceImpl.class.getConstructor();
+ type.setConstructorDefinition(new ConstructorDefinition<SingleInterfaceImpl>(ctor));
+ processor.visitEnd(null, SingleInterfaceImpl.class, type, null);
+ assertEquals(1, type.getServices().size());
+ assertEquals(PropertyInterface.class,
+ type.getServices().get(PropertyInterface.class.getSimpleName())
+ .getServiceContract().getInterfaceClass());
+ assertTrue(type.getProperties().isEmpty());
+ assertTrue(type.getReferences().isEmpty());
+ }
+
+ /**
+ * Verifies property and reference setters are computed
+ */
+ public void testPropertyReference() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<SingleInterfaceWithPropertyReferenceImpl> ctor =
+ SingleInterfaceWithPropertyReferenceImpl.class.getConstructor();
+ type.setConstructorDefinition(new ConstructorDefinition<SingleInterfaceWithPropertyReferenceImpl>(ctor));
+ processor.visitEnd(null, SingleInterfaceWithPropertyReferenceImpl.class, type, null);
+ assertEquals(1, type.getServices().size());
+ assertEquals(Interface1.class,
+ type.getServices().get(Interface1.class.getSimpleName())
+ .getServiceContract().getInterfaceClass());
+ assertEquals(1, type.getProperties().size());
+ assertEquals(ComplexProperty.class, type.getProperties().get("property").getJavaType());
+ assertEquals(1, type.getReferences().size());
+ assertEquals(Ref.class, type.getReferences().get("reference").getServiceContract().getInterfaceClass());
+ }
+
+ /**
+ * Verifies that a property setter is not introspected if an analogous operation is in the service interface
+ */
+ public void testPropertySetterInInterface() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<SingleInterfaceImpl> ctor = SingleInterfaceImpl.class.getConstructor();
+ type.setConstructorDefinition(new ConstructorDefinition<SingleInterfaceImpl>(ctor));
+ processor.visitEnd(null, SingleInterfaceImpl.class, type, null);
+ assertEquals(0, type.getProperties().size());
+ }
+
+ /**
+ * Verifies that a reference setter is not introspected if an analogous operation is in the service interface
+ */
+ public void testReferenceSetterInInterface() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<RefInterfaceImpl> ctor = RefInterfaceImpl.class.getConstructor();
+ type.setConstructorDefinition(new ConstructorDefinition<RefInterfaceImpl>(ctor));
+ processor.visitEnd(null, RefInterfaceImpl.class, type, null);
+ assertEquals(0, type.getReferences().size());
+ }
+
+ /**
+ * Verifies collection generic types or array types are introspected as references according to spec rules
+ */
+ public void testReferenceCollectionType() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<ReferenceCollectionImpl> ctor = ReferenceCollectionImpl.class.getConstructor();
+ type.setConstructorDefinition(new ConstructorDefinition<ReferenceCollectionImpl>(ctor));
+ processor.visitEnd(null, ReferenceCollectionImpl.class, type, null);
+ assertEquals(0, type.getProperties().size());
+ assertEquals(4, type.getReferences().size());
+ }
+
+ /**
+ * Verifies collection generic types or array types are introspected as properties according to spec rules
+ */
+ public void testPropertyCollectionType() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<PropertyCollectionImpl> ctor = PropertyCollectionImpl.class.getConstructor();
+ type.setConstructorDefinition(new ConstructorDefinition<PropertyCollectionImpl>(ctor));
+ processor.visitEnd(null, PropertyCollectionImpl.class, type, null);
+ assertEquals(0, type.getReferences().size());
+ assertEquals(4, type.getProperties().size());
+ }
+
+ /**
+ * Verifies references are calculated when the type marked with is @Remotable
+ */
+ public void testRemotableRef() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<RemotableRefImpl> ctor = RemotableRefImpl.class.getConstructor();
+ type.setConstructorDefinition(new ConstructorDefinition<RemotableRefImpl>(ctor));
+ processor.visitEnd(null, RemotableRefImpl.class, type, null);
+ assertEquals(2, type.getReferences().size());
+ assertEquals(0, type.getProperties().size());
+ }
+
+ public void testParentInterface() throws ProcessingException, NoSuchMethodException {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Child> ctor = Child.class.getConstructor();
+ type.setConstructorDefinition(new ConstructorDefinition<Child>(ctor));
+ processor.visitEnd(null, Child.class, type, null);
+ assertTrue(type.getServices().containsKey(Interface1.class.getSimpleName()));
+ }
+
+ /**
+ * Verifies a service inteface is calculated when only props and refs are given
+ */
+ public void testExcludedPropertyAndReference() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ JavaMappedReference ref = new JavaMappedReference();
+ ref.setName("reference");
+ type.add(ref);
+ JavaMappedReference ref2 = new JavaMappedReference();
+ ref2.setName("reference2");
+ type.add(ref2);
+ JavaMappedProperty<?> prop1 = new JavaMappedProperty();
+ prop1.setName("string1");
+ type.add(prop1);
+ JavaMappedProperty<?> prop2 = new JavaMappedProperty();
+ prop2.setName("string2");
+ type.add(prop2);
+ processor.visitEnd(null, MockService.class, type, null);
+ assertEquals(1, type.getServices().size());
+ }
+
+ public void testProtectedRemotableRefField() throws ProcessingException, NoSuchMethodException {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<ProtectedRemotableRefFieldImpl> ctor = ProtectedRemotableRefFieldImpl.class.getConstructor();
+ type.setConstructorDefinition(new ConstructorDefinition<ProtectedRemotableRefFieldImpl>(ctor));
+ processor.visitEnd(null, ProtectedRemotableRefFieldImpl.class, type, null);
+ assertNotNull(type.getReferences().get("otherRef"));
+ }
+
+ public void testProtectedRemotableRefMethod() throws ProcessingException, NoSuchMethodException {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<ProtectedRemotableRefMethodImpl> ctor = ProtectedRemotableRefMethodImpl.class.getConstructor();
+ type.setConstructorDefinition(new ConstructorDefinition<ProtectedRemotableRefMethodImpl>(ctor));
+ processor.visitEnd(null, ProtectedRemotableRefMethodImpl.class, type, null);
+ assertNotNull(type.getReferences().get("otherRef"));
+ }
+
+ public void testSetDataTypes() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<PropertyIntTypeOnConstructor> ctor = PropertyIntTypeOnConstructor.class.getConstructor(int.class);
+ type.setConstructorDefinition(new ConstructorDefinition<PropertyIntTypeOnConstructor>(ctor));
+ processor.visitEnd(null, ProtectedRemotableRefMethodImpl.class, type, null);
+ org.apache.tuscany.spi.model.Property<?> foo = type.getProperties().get("foo");
+ assertEquals(int.class, foo.getJavaType());
+ assertEquals(SimpleTypeMapperExtension.XSD_INT, foo.getXmlType());
+ }
+
+ private static class PropertyIntTypeOnConstructor {
+ private int foo;
+
+ public PropertyIntTypeOnConstructor(@Property(name = "foo")int foo) {
+ this.foo = foo;
+ }
+
+ public int getFoo() {
+ return foo;
+ }
+ }
+
+ private interface PropertyInterface {
+ void setString1(String val);
+ }
+
+ private interface Interface1 {
+ }
+
+ private static class Parent implements Interface1 {
+
+ }
+
+ private static class Child extends Parent {
+ public Child() {
+ }
+
+ }
+
+ private static class SingleInterfaceImpl implements PropertyInterface {
+ public SingleInterfaceImpl() {
+ }
+
+ public void setString1(String val) {
+ }
+
+ }
+
+ private interface HeuristicServiceInterface {
+ void fooOperation(String ref);
+
+ void setInvalid1(); // No parameter
+
+ void setInvalid2(String str, int i); // More than one parameter
+
+ String setInvalid3(String str); // return should be void
+ }
+
+ public static class MockService implements PropertyInterface, RefInterface, HeuristicServiceInterface {
+
+ @Property
+ public void setString1(String val) {
+ }
+
+ @Property
+ public void setString2(String val) {
+ }
+
+ @Reference
+ public void setReference(Ref ref) {
+ }
+
+ @Reference
+ public void setReference2(Ref ref) {
+ }
+
+ public void fooOperation(String ref) {
+
+ }
+
+ public void setInvalid1() {
+ }
+
+ public void setInvalid2(String str, int i) {
+ }
+
+ public String setInvalid3(String str) {
+ return null;
+ }
+
+ }
+
+ @Service
+ private interface Ref {
+ }
+
+ private class ComplexProperty {
+ }
+
+ private interface RefInterface {
+ void setReference(Ref ref);
+ }
+
+ private static class RefInterfaceImpl implements RefInterface {
+ public RefInterfaceImpl() {
+ }
+
+ public void setReference(Ref ref) {
+ }
+ }
+
+ private static class SingleInterfaceWithPropertyReferenceImpl implements Interface1 {
+ public SingleInterfaceWithPropertyReferenceImpl() {
+ }
+
+ public void setReference(Ref ref) {
+ }
+
+ public void setProperty(ComplexProperty prop) {
+ }
+ }
+
+ private static class ReferenceCollectionImpl implements Interface1 {
+ public ReferenceCollectionImpl() {
+ }
+
+ public void setCollectionReference(Collection<Ref> ref) {
+ }
+
+ public void setNonGenericCollectionReference(Collection ref) {
+ }
+
+ public void setListReference(List<Ref> ref) {
+ }
+
+ public void setArrayReference(Ref[] ref) {
+ }
+ }
+
+ private static class PropertyCollectionImpl implements Interface1 {
+ public PropertyCollectionImpl() {
+ }
+
+ public void setCollectionProperty(Collection<ComplexProperty> prop) {
+ }
+
+ public void setCollectionProperty2(Collection<String> prop) {
+ }
+
+ public void setArrayProperty(ComplexProperty[] prop) {
+ }
+
+ public void setArrayProperty2(String[] prop) {
+ }
+ }
+
+ @Remotable
+ private interface RemotableRef {
+ }
+
+ private static class RemotableRefImpl implements Interface1 {
+ protected RemotableRef otherRef;
+
+ public RemotableRefImpl() {
+ }
+
+ public void setRef(RemotableRef ref) {
+
+ }
+ }
+
+ private static class ProtectedRemotableRefFieldImpl implements Interface1 {
+ protected RemotableRef otherRef;
+
+ public ProtectedRemotableRefFieldImpl() {
+ }
+
+ public ProtectedRemotableRefFieldImpl(RemotableRef otherRef) {
+ this.otherRef = otherRef;
+ }
+
+ }
+
+ private static class ProtectedRemotableRefMethodImpl implements Interface1 {
+ public ProtectedRemotableRefMethodImpl() {
+ }
+
+ protected void setOtherRef(RemotableRef otherRef) {
+ }
+
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeutisticExtensibleConstructorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeutisticExtensibleConstructorTestCase.java
new file mode 100644
index 0000000000..4e6c1063d8
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/HeutisticExtensibleConstructorTestCase.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Constructor;
+import java.util.List;
+
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+
+/**
+ * Verifies constructors that have extensible annotation types, i.e. that have parameters marked by annotations which
+ * are themselves processed by some other implementation processor
+ *
+ * @version $Rev$ $Date$
+ */
+public class HeutisticExtensibleConstructorTestCase extends TestCase {
+
+ private HeuristicPojoProcessor processor =
+ new HeuristicPojoProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl()));
+
+ /**
+ * Verifies heuristic processing can be called priot to an extension annotation processors being called.
+ */
+ public void testBarAnnotationProcessedFirst() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo> ctor = Foo.class.getConstructor(String.class, String.class);
+ ConstructorDefinition<Foo> definition = new ConstructorDefinition<Foo>(ctor);
+ type.setConstructorDefinition(definition);
+ JavaMappedProperty property = new JavaMappedProperty();
+ property.setName("myBar");
+ definition.getInjectionNames().add("myBar");
+ type.getProperties().put("myBar", property);
+ processor.visitEnd(null, Foo.class, type, null);
+ assertEquals(2, type.getProperties().size());
+ }
+
+ /**
+ * Verifies heuristic processing can be called before an extension annotation processors is called.
+ * <p/>
+ * For example, given:
+ * <pre> Foo(@Bar String prop, @org.osoa.sca.annotations.Property(name = "foo") String prop2)</pre>
+ * <p/>
+ * Heuristic evaluation of @Property can occur prior to another implementation processor evaluating @Bar
+ *
+ * @throws Exception
+ */
+ public void testBarAnnotationProcessedLast() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitEnd(null, Foo.class, type, null);
+
+ // now simulate process the bar impl
+ ConstructorDefinition<?> definition = type.getConstructorDefinition();
+ List<String> injectionNames = definition.getInjectionNames();
+ injectionNames.remove(0);
+ injectionNames.add(0, "mybar");
+ type.getProperties().put("mybar", new JavaMappedProperty<String>());
+
+ assertEquals(2, type.getProperties().size());
+ assertEquals("foo", definition.getInjectionNames().get(1));
+ }
+
+ /**
+ * Verifies heuristic processing can be called before an extension annotation processors is called with the
+ * extension parameter in a middle position. Specifically, verifies that the heuristic processor updates injection
+ * names and preserves their ordering.
+ */
+ public void testBarAnnotationProcessedFirstInMiddle() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Foo2> ctor = Foo2.class.getConstructor(String.class, String.class, String.class);
+ ConstructorDefinition<Foo2> definition = new ConstructorDefinition<Foo2>(ctor);
+ type.setConstructorDefinition(definition);
+ // insert placeholder for first param, which would be done by a processor
+ definition.getInjectionNames().add("");
+ JavaMappedProperty property = new JavaMappedProperty();
+ property.setName("myBar");
+ definition.getInjectionNames().add("myBar");
+ type.getProperties().put("myBar", property);
+ processor.visitEnd(null, Foo2.class, type, null);
+ assertEquals("baz", definition.getInjectionNames().get(0));
+ assertEquals(2, type.getProperties().size());
+ assertEquals(1, type.getReferences().size());
+ }
+
+ public @interface Bar {
+
+ }
+
+ public static class Foo {
+ public Foo(@Bar String prop, @org.osoa.sca.annotations.Property(name = "foo") String prop2) {
+ }
+ }
+
+ public static class Foo2 {
+ public Foo2(@org.osoa.sca.annotations.Reference(name = "baz") String prop1,
+ @Bar String prop2,
+ @org.osoa.sca.annotations.Property(name = "foo") String prop3) {
+ }
+ }
+
+
+}
+
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceTestCase.java
new file mode 100644
index 0000000000..e843467866
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceTestCase.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.osoa.sca.annotations.Callback;
+import org.osoa.sca.annotations.Property;
+import org.osoa.sca.annotations.Remotable;
+import org.osoa.sca.annotations.Scope;
+
+import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.model.InteractionScope;
+import org.apache.tuscany.spi.model.ServiceContract;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ImplementationProcessorServiceTestCase extends TestCase {
+ private JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ private ImplementationProcessorService implService = new ImplementationProcessorServiceImpl(registry);
+
+
+ public void testCreateConversationalService() throws Exception {
+ JavaMappedService service = implService.createService(Foo.class);
+ service.setServiceContract(registry.introspect(Foo.class, true));
+ assertTrue(Foo.class.equals(service.getServiceContract().getInterfaceClass()));
+ assertTrue(service.isRemotable());
+ assertEquals(InteractionScope.CONVERSATIONAL, service.getServiceContract().getInteractionScope());
+ ServiceContract serviceContract = service.getServiceContract();
+ assertTrue(Bar.class.equals(serviceContract.getCallbackClass()));
+ assertTrue("ImplementationProcessorServiceTestCase$Bar".equals(serviceContract.getCallbackName()));
+ }
+
+ public void testCreateDefaultService() throws Exception {
+ JavaMappedService service = implService.createService(Baz.class);
+ service.setServiceContract(registry.introspect(Baz.class, true));
+ assertTrue(Baz.class.equals(service.getServiceContract().getInterfaceClass()));
+ assertTrue(!service.isRemotable());
+ assertEquals(InteractionScope.NONCONVERSATIONAL, service.getServiceContract().getInteractionScope());
+ }
+
+ public void testProcessParamProperty() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<PropertyClass> ctor = PropertyClass.class.getConstructor(int.class);
+ Annotation[] paramAnnotations = ctor.getParameterAnnotations()[0];
+ List<String> injectionNames = new ArrayList<String>();
+ String[] names = new String[]{"foo"};
+ implService.processParam(int.class,
+ ctor.getGenericParameterTypes()[0],
+ paramAnnotations,
+ names,
+ 0,
+ type,
+ injectionNames);
+ org.apache.tuscany.spi.model.Property<?> property = type.getProperties().get("foo");
+ assertEquals(int.class, property.getJavaType());
+ assertEquals(SimpleTypeMapperExtension.XSD_INT, property.getXmlType());
+ }
+
+
+ @Callback(Bar.class)
+ @Remotable
+ @Scope("CONVERSATION")
+ public interface Foo {
+
+ }
+
+ public interface Bar {
+
+ }
+
+ public interface Baz {
+
+ }
+
+ public static class PropertyClass {
+ private int foo;
+
+ public PropertyClass(@Property(name = "foo") int foo) {
+ this.foo = foo;
+ }
+
+ public int getFoo() {
+ return foo;
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceUniqueTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceUniqueTestCase.java
new file mode 100644
index 0000000000..da45ed2d46
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ImplementationProcessorServiceUniqueTestCase.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ImplementationProcessorServiceUniqueTestCase extends TestCase {
+
+ private ImplementationProcessorService service =
+ new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl());
+
+ public void testUniquess1() throws Exception {
+ Class[] classes = new Class[2];
+ classes[0] = String.class;
+ classes[1] = Integer.class;
+ assertTrue(service.areUnique(classes));
+ }
+
+ public void testUniquess2() throws Exception {
+ Class[] classes = new Class[2];
+ classes[0] = String.class;
+ classes[1] = String.class;
+ assertFalse(service.areUnique(classes));
+ }
+
+ public void testUniquess3() throws Exception {
+ Class[] classes = new Class[1];
+ classes[0] = String.class;
+ assertTrue(service.areUnique(classes));
+ }
+
+ public void testUniquess4() throws Exception {
+ Class[] classes = new Class[3];
+ classes[0] = String.class;
+ classes[1] = Integer.class;
+ classes[2] = String.class;
+ assertFalse(service.areUnique(classes));
+ }
+
+ public void testUniquess5() throws Exception {
+ Class[] classes = new Class[0];
+ assertTrue(service.areUnique(classes));
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/InitProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/InitProcessorTestCase.java
new file mode 100644
index 0000000000..13fe7d003a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/InitProcessorTestCase.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Method;
+
+import org.osoa.sca.annotations.Init;
+
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class InitProcessorTestCase extends TestCase {
+
+ public void testInit() throws Exception {
+ InitProcessor processor = new InitProcessor();
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Method method = InitProcessorTestCase.Foo.class.getMethod("init");
+ processor.visitMethod(null, method, type, null);
+ assertNotNull(type.getInitMethod());
+ assertEquals(0, type.getInitLevel());
+ }
+
+ public void testBadInit() throws Exception {
+ InitProcessor processor = new InitProcessor();
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Method method = InitProcessorTestCase.Bar.class.getMethod("badInit", String.class);
+ try {
+ processor.visitMethod(null, method, type, null);
+ fail();
+ } catch (IllegalInitException e) {
+ // expected
+ }
+ }
+
+ public void testTwoInit() throws Exception {
+ InitProcessor processor = new InitProcessor();
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Method method = InitProcessorTestCase.Bar.class.getMethod("init");
+ Method method2 = InitProcessorTestCase.Bar.class.getMethod("init2");
+ processor.visitMethod(null, method, type, null);
+ try {
+ processor.visitMethod(null, method2, type, null);
+ fail();
+ } catch (DuplicateInitException e) {
+ // expected
+ }
+ }
+
+
+ private class Foo {
+ @Init
+ public void init() {
+ }
+ }
+
+
+ private class Bar {
+ @Init
+ public void init() {
+ }
+
+ @Init
+ public void init2() {
+ }
+
+ @Init
+ public void badInit(String foo) {
+ }
+
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/MonitorProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/MonitorProcessorTestCase.java
new file mode 100644
index 0000000000..8982fa3991
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/MonitorProcessorTestCase.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.IllegalPropertyException;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.api.annotation.Monitor;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.injection.SingletonObjectFactory;
+import org.apache.tuscany.host.MonitorFactory;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MonitorProcessorTestCase extends TestCase {
+
+ private MonitorProcessor processor;
+ private MonitorFactory monitorFactory;
+
+ public void testSetter() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Method method = Foo.class.getMethod("setMonitor", Foo.class);
+ EasyMock.expect(monitorFactory.getMonitor(EasyMock.eq(Foo.class))).andReturn(null);
+ EasyMock.replay(monitorFactory);
+ processor.visitMethod(null, method, type, null);
+ Map<String, JavaMappedProperty<?>> properties = type.getProperties();
+ assertTrue(properties.get("monitor").getDefaultValueFactory() instanceof SingletonObjectFactory);
+ EasyMock.verify(monitorFactory);
+ }
+
+
+ public void testBadSetter() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Method method = BadMonitor.class.getMethod("setMonitor");
+ try {
+ processor.visitMethod(null, method, type, null);
+ fail();
+ } catch (IllegalPropertyException e) {
+ // expected
+ }
+ }
+
+ public void testField() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Field field = Foo.class.getDeclaredField("bar");
+ EasyMock.expect(monitorFactory.getMonitor(EasyMock.eq(Foo.class))).andReturn(null);
+ EasyMock.replay(monitorFactory);
+ processor.visitField(null, field, type, null);
+ Map<String, JavaMappedProperty<?>> properties = type.getProperties();
+ assertTrue(properties.get("bar").getDefaultValueFactory() instanceof SingletonObjectFactory);
+ EasyMock.verify(monitorFactory);
+ }
+
+ public void testConstructor() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Bar> ctor = Bar.class.getConstructor(BazMonitor.class);
+ EasyMock.expect(monitorFactory.getMonitor(EasyMock.eq(BazMonitor.class))).andReturn(null);
+ EasyMock.replay(monitorFactory);
+ processor.visitConstructor(null, ctor, type, null);
+ Map<String, JavaMappedProperty<?>> properties = type.getProperties();
+ assertTrue(
+ properties.get(BazMonitor.class.getName()).getDefaultValueFactory() instanceof SingletonObjectFactory);
+ EasyMock.verify(monitorFactory);
+ }
+
+ /**
+ * Verifies calling the monitor processor to evaluate a constructor can be done after a property parameter is
+ * processed
+ */
+ public void testConstructorAfterProperty() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Bar> ctor = Bar.class.getConstructor(String.class, BazMonitor.class);
+ EasyMock.expect(monitorFactory.getMonitor(EasyMock.eq(BazMonitor.class))).andReturn(null);
+ EasyMock.replay(monitorFactory);
+ ConstructorDefinition<Bar> definition = new ConstructorDefinition<Bar>(ctor);
+ JavaMappedProperty prop = new JavaMappedProperty();
+ definition.getInjectionNames().add("prop");
+ type.setConstructorDefinition(definition);
+ type.getProperties().put("prop", prop);
+ processor.visitConstructor(null, ctor, type, null);
+ Map<String, JavaMappedProperty<?>> properties = type.getProperties();
+ assertEquals(BazMonitor.class.getName(), definition.getInjectionNames().get(1));
+ assertEquals(2, type.getProperties().size());
+ String name = BazMonitor.class.getName();
+ assertTrue(properties.get(name).getDefaultValueFactory() instanceof SingletonObjectFactory);
+ EasyMock.verify(monitorFactory);
+ }
+
+ /**
+ * Verifies calling the monitor processor to evaluate a constructor can be done before a property parameter is
+ * processed
+ */
+ public void testConstructorBeforeProperty() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ Constructor<Bar> ctor = Bar.class.getConstructor(String.class, BazMonitor.class);
+ EasyMock.expect(monitorFactory.getMonitor(EasyMock.eq(BazMonitor.class))).andReturn(null);
+ EasyMock.replay(monitorFactory);
+ processor.visitConstructor(null, ctor, type, null);
+ Map<String, JavaMappedProperty<?>> properties = type.getProperties();
+ ConstructorDefinition definition = type.getConstructorDefinition();
+ assertEquals(2, definition.getInjectionNames().size());
+ assertEquals(BazMonitor.class.getName(), definition.getInjectionNames().get(1));
+ String name = BazMonitor.class.getName();
+ assertTrue(properties.get(name).getDefaultValueFactory() instanceof SingletonObjectFactory);
+ EasyMock.verify(monitorFactory);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ monitorFactory = EasyMock.createMock(MonitorFactory.class);
+ JavaInterfaceProcessorRegistryImpl registry = new JavaInterfaceProcessorRegistryImpl();
+ ImplementationProcessorServiceImpl processor = new ImplementationProcessorServiceImpl(registry);
+ this.processor = new MonitorProcessor(monitorFactory, processor);
+ }
+
+ private class Foo {
+
+ @Monitor
+ protected Foo bar;
+
+ @Monitor
+ public void setMonitor(Foo foo) {
+ }
+ }
+
+
+ private class BadMonitor {
+
+ @Monitor
+ public void setMonitor() {
+ }
+ }
+
+ private interface BazMonitor {
+
+ }
+
+ private static class Bar {
+
+ public Bar(@Monitor BazMonitor monitor) {
+ }
+
+ public Bar(String prop, @Monitor BazMonitor monitor) {
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/PropertyProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/PropertyProcessorTestCase.java
new file mode 100644
index 0000000000..a4a60f13a0
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/PropertyProcessorTestCase.java
@@ -0,0 +1,204 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.util.Collection;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.spi.implementation.java.DuplicatePropertyException;
+import org.apache.tuscany.spi.implementation.java.IllegalPropertyException;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.osoa.sca.annotations.Property;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class PropertyProcessorTestCase extends TestCase {
+
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type;
+ PropertyProcessor processor;
+
+ public void testMethodAnnotation() throws Exception {
+ processor.visitMethod(null, Foo.class.getMethod("setFoo", String.class), type, null);
+ assertNotNull(type.getProperties().get("foo"));
+ }
+
+ public void testMethodRequired() throws Exception {
+ processor.visitMethod(null, Foo.class.getMethod("setFooRequired", String.class), type, null);
+ JavaMappedProperty prop = type.getProperties().get("fooRequired");
+ assertNotNull(prop);
+ }
+
+ public void testMethodName() throws Exception {
+ processor.visitMethod(null, Foo.class.getMethod("setBarMethod", String.class), type, null);
+ assertNotNull(type.getProperties().get("bar"));
+ }
+
+ public void testFieldAnnotation() throws Exception {
+ processor.visitField(null, Foo.class.getDeclaredField("baz"), type, null);
+ assertNotNull(type.getProperties().get("baz"));
+ }
+
+ public void testFieldRequired() throws Exception {
+ processor.visitField(null, Foo.class.getDeclaredField("bazRequired"), type, null);
+ JavaMappedProperty prop = type.getProperties().get("bazRequired");
+ assertNotNull(prop);
+ }
+
+ public void testFieldName() throws Exception {
+ processor.visitField(null, Foo.class.getDeclaredField("bazField"), type, null);
+ assertNotNull(type.getProperties().get("theBaz"));
+ }
+
+ public void testDuplicateFields() throws Exception {
+ processor.visitField(null, Bar.class.getDeclaredField("dup"), type, null);
+ try {
+ processor.visitField(null, Bar.class.getDeclaredField("baz"), type, null);
+ fail();
+ } catch (DuplicatePropertyException e) {
+ // expected
+ }
+ }
+
+ public void testDuplicateMethods() throws Exception {
+ processor.visitMethod(null, Bar.class.getMethod("dupMethod", String.class), type, null);
+ try {
+ processor.visitMethod(null, Bar.class.getMethod("dupSomeMethod", String.class), type, null);
+ fail();
+ } catch (DuplicatePropertyException e) {
+ // expected
+ }
+ }
+
+ public void testInvalidProperty() throws Exception {
+ try {
+ processor.visitMethod(null, Bar.class.getMethod("badMethod"), type, null);
+ fail();
+ } catch (IllegalPropertyException e) {
+ // expected
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ type = new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ JavaInterfaceProcessorRegistryImpl registry = new JavaInterfaceProcessorRegistryImpl();
+ processor = new PropertyProcessor(new ImplementationProcessorServiceImpl(registry));
+ }
+
+ private class Foo {
+
+ @Property
+ protected String baz;
+ @Property(required = true)
+ protected String bazRequired;
+ @Property(name = "theBaz")
+ protected String bazField;
+
+ @Property
+ public void setFoo(String string) {
+ }
+
+ @Property(required = true)
+ public void setFooRequired(String string) {
+ }
+
+ @Property(name = "bar")
+ public void setBarMethod(String string) {
+ }
+
+ }
+
+ private class Bar {
+
+ @Property
+ protected String dup;
+
+ @Property(name = "dup")
+ protected String baz;
+
+ @Property
+ public void dupMethod(String s) {
+ }
+
+ @Property(name = "dupMethod")
+ public void dupSomeMethod(String s) {
+ }
+
+ @Property
+ public void badMethod() {
+ }
+
+ }
+
+ private class Multiple {
+ @Property
+ protected List<String> refs1;
+
+ @Property
+ protected String[] refs2;
+
+ @Property
+ public void setRefs3(String[] refs) {
+ }
+
+ @Property
+ public void setRefs4(Collection<String> refs) {
+ }
+
+ }
+
+ public void testMultiplicityCollection() throws Exception {
+ processor.visitField(null, Multiple.class.getDeclaredField("refs1"), type, null);
+ JavaMappedProperty prop = type.getProperties().get("refs1");
+ assertNotNull(prop);
+ assertSame(String.class, prop.getJavaType());
+ assertTrue(prop.isMany());
+ }
+
+ public void testMultiplicityArray() throws Exception {
+ processor.visitField(null, Multiple.class.getDeclaredField("refs2"), type, null);
+ JavaMappedProperty prop = type.getProperties().get("refs2");
+ assertNotNull(prop);
+ assertSame(String.class, prop.getJavaType());
+ assertTrue(prop.isMany());
+ }
+
+ public void testMultiplicityArrayMethod() throws Exception {
+ processor.visitMethod(null, Multiple.class.getMethod("setRefs3", String[].class), type, null);
+ JavaMappedProperty prop = type.getProperties().get("refs3");
+ assertNotNull(prop);
+ assertSame(String.class, prop.getJavaType());
+ assertTrue(prop.isMany());
+ }
+
+ public void testMultiplicityCollectionMethod() throws Exception {
+ processor.visitMethod(null, Multiple.class.getMethod("setRefs4", Collection.class), type, null);
+ JavaMappedProperty prop = type.getProperties().get("refs4");
+ assertNotNull(prop);
+ assertSame(String.class, prop.getJavaType());
+ assertTrue(prop.isMany());
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ReferenceProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ReferenceProcessorTestCase.java
new file mode 100644
index 0000000000..80d3687170
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ReferenceProcessorTestCase.java
@@ -0,0 +1,225 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.osoa.sca.annotations.Reference;
+
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.model.Multiplicity;
+import org.apache.tuscany.spi.model.ServiceContract;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ReferenceProcessorTestCase extends TestCase {
+
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ ReferenceProcessor processor = new ReferenceProcessor(new JavaInterfaceProcessorRegistryImpl());
+
+ public void testMethodAnnotation() throws Exception {
+ processor.visitMethod(null, ReferenceProcessorTestCase.Foo.class.getMethod("setFoo", Ref.class), type, null);
+ JavaMappedReference reference = type.getReferences().get("foo");
+ assertNotNull(reference);
+ ServiceContract contract = reference.getServiceContract();
+ assertEquals(Ref.class, contract.getInterfaceClass());
+ assertEquals("ReferenceProcessorTestCase$Ref", contract.getInterfaceName());
+ }
+
+ public void testMethodRequired() throws Exception {
+ processor.visitMethod(null,
+ ReferenceProcessorTestCase.Foo.class.getMethod("setFooRequired", Ref.class),
+ type,
+ null);
+ JavaMappedReference prop = type.getReferences().get("fooRequired");
+ assertNotNull(prop);
+ }
+
+ public void testMethodName() throws Exception {
+ processor.visitMethod(null,
+ ReferenceProcessorTestCase.Foo.class.getMethod("setBarMethod", Ref.class),
+ type,
+ null);
+ assertNotNull(type.getReferences().get("bar"));
+ }
+
+ public void testFieldAnnotation() throws Exception {
+ processor.visitField(null, ReferenceProcessorTestCase.Foo.class.getDeclaredField("baz"), type, null);
+ JavaMappedReference reference = type.getReferences().get("baz");
+ assertNotNull(reference);
+ ServiceContract contract = reference.getServiceContract();
+ assertEquals(Ref.class, contract.getInterfaceClass());
+ assertEquals("ReferenceProcessorTestCase$Ref", contract.getInterfaceName());
+ }
+
+ public void testFieldRequired() throws Exception {
+ processor.visitField(null, ReferenceProcessorTestCase.Foo.class.getDeclaredField("bazRequired"), type, null);
+ JavaMappedReference prop = type.getReferences().get("bazRequired");
+ assertNotNull(prop);
+ }
+
+ public void testFieldName() throws Exception {
+ processor.visitField(null, ReferenceProcessorTestCase.Foo.class.getDeclaredField("bazField"), type, null);
+ assertNotNull(type.getReferences().get("theBaz"));
+ }
+
+ public void testDuplicateFields() throws Exception {
+ processor.visitField(null, ReferenceProcessorTestCase.Bar.class.getDeclaredField("dup"), type, null);
+ try {
+ processor.visitField(null, ReferenceProcessorTestCase.Bar.class.getDeclaredField("baz"), type, null);
+ fail();
+ } catch (DuplicateReferenceException e) {
+ // expected
+ }
+ }
+
+ public void testDuplicateMethods() throws Exception {
+ processor.visitMethod(null, ReferenceProcessorTestCase.Bar.class.getMethod("dupMethod", Ref.class), type, null);
+ try {
+ processor.visitMethod(null,
+ ReferenceProcessorTestCase.Bar.class.getMethod("dupSomeMethod", Ref.class),
+ type,
+ null);
+ fail();
+ } catch (DuplicateReferenceException e) {
+ // expected
+ }
+ }
+
+ public void testInvalidProperty() throws Exception {
+ try {
+ processor.visitMethod(null, ReferenceProcessorTestCase.Bar.class.getMethod("badMethod"), type, null);
+ fail();
+ } catch (IllegalReferenceException e) {
+ // expected
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ type = new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor = new ReferenceProcessor(new JavaInterfaceProcessorRegistryImpl());
+ }
+
+ private interface Ref {
+ }
+
+ private class Foo {
+
+ @Reference
+ protected Ref baz;
+ @Reference(required = true)
+ protected Ref bazRequired;
+ @Reference(name = "theBaz")
+ protected Ref bazField;
+
+ @Reference
+ public void setFoo(Ref ref) {
+ }
+
+ @Reference(required = true)
+ public void setFooRequired(Ref ref) {
+ }
+
+ @Reference(name = "bar")
+ public void setBarMethod(Ref ref) {
+ }
+
+ }
+
+ private class Bar {
+
+ @Reference
+ protected Ref dup;
+
+ @Reference(name = "dup")
+ protected Ref baz;
+
+ @Reference
+ public void dupMethod(Ref s) {
+ }
+
+ @Reference(name = "dupMethod")
+ public void dupSomeMethod(Ref s) {
+ }
+
+ @Reference
+ public void badMethod() {
+ }
+
+ }
+
+ private class Multiple {
+ @Reference(required = true)
+ protected List<Ref> refs1;
+
+ @Reference(required = false)
+ protected Ref[] refs2;
+
+ @Reference(required = true)
+ public void setRefs3(Ref[] refs) {
+ }
+
+ @Reference(required = false)
+ public void setRefs4(Collection<Ref> refs) {
+ }
+
+ }
+
+ public void testMultiplicity1ToN() throws Exception {
+ processor.visitField(null, Multiple.class.getDeclaredField("refs1"), type, null);
+ JavaMappedReference prop = type.getReferences().get("refs1");
+ assertNotNull(prop);
+ assertSame(Ref.class, prop.getServiceContract().getInterfaceClass());
+ assertEquals(Multiplicity.ONE_N, prop.getMultiplicity());
+ }
+
+ public void testMultiplicityTo0ToN() throws Exception {
+ processor.visitField(null, Multiple.class.getDeclaredField("refs2"), type, null);
+ JavaMappedReference prop = type.getReferences().get("refs2");
+ assertNotNull(prop);
+ assertSame(Ref.class, prop.getServiceContract().getInterfaceClass());
+ assertEquals(Multiplicity.ZERO_N, prop.getMultiplicity());
+ }
+
+ public void testMultiplicity1ToNMethod() throws Exception {
+ processor.visitMethod(null, Multiple.class.getMethod("setRefs3", Ref[].class), type, null);
+ JavaMappedReference prop = type.getReferences().get("refs3");
+ assertNotNull(prop);
+ assertSame(Ref.class, prop.getServiceContract().getInterfaceClass());
+ assertEquals(Multiplicity.ONE_N, prop.getMultiplicity());
+ }
+
+ public void testMultiplicity0ToNMethod() throws Exception {
+ processor.visitMethod(null, Multiple.class.getMethod("setRefs4", Collection.class), type, null);
+ JavaMappedReference prop = type.getReferences().get("refs4");
+ assertNotNull(prop);
+ assertSame(Ref.class, prop.getServiceContract().getInterfaceClass());
+ assertEquals(Multiplicity.ZERO_N, prop.getMultiplicity());
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ResourceProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ResourceProcessorTestCase.java
new file mode 100644
index 0000000000..96bf4a3ed3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ResourceProcessorTestCase.java
@@ -0,0 +1,99 @@
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.Resource;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ResourceProcessorTestCase extends TestCase {
+
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type;
+ ResourceProcessor processor = new ResourceProcessor();
+
+ public void testVisitField() throws Exception {
+ Field field = Foo.class.getDeclaredField("bar");
+ processor.visitField(null, field, type, null);
+ Resource resource = type.getResources().get("bar");
+ assertFalse(resource.isOptional());
+ assertNull(resource.getMappedName());
+ assertEquals(field.getType(), resource.getType());
+ }
+
+ public void testVisitMethod() throws Exception {
+ Method method = Foo.class.getMethod("setBar", Bar.class);
+ processor.visitMethod(null, method, type, null);
+ Resource resource = type.getResources().get("bar");
+ assertFalse(resource.isOptional());
+ assertNull(resource.getMappedName());
+ assertEquals(method.getParameterTypes()[0], resource.getType());
+ }
+
+ public void testVisitNamedMethod() throws Exception {
+ Method method = Foo.class.getMethod("setBar2", Bar.class);
+ processor.visitMethod(null, method, type, null);
+ Resource resource = type.getResources().get("someName");
+ assertFalse(resource.isOptional());
+ assertEquals("mapped", resource.getMappedName());
+ }
+
+ public void testVisitBadMethod() throws Exception {
+ Method method = Foo.class.getMethod("setBad");
+ try {
+ processor.visitMethod(null, method, type, null);
+ fail();
+ } catch (IllegalResourceException e) {
+ // expected
+ }
+ }
+
+ public void testDuplicateResources() throws Exception {
+ Field field = Foo.class.getDeclaredField("bar");
+ processor.visitField(null, field, type, null);
+ try {
+ processor.visitField(null, field, type, null);
+ fail();
+ } catch (DuplicateResourceException e) {
+ //expected
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ type = new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ }
+
+ private class Foo {
+
+ @org.apache.tuscany.api.annotation.Resource
+ protected Bar bar;
+
+ @org.apache.tuscany.api.annotation.Resource(optional = true)
+ protected Bar barNotRequired;
+
+ @org.apache.tuscany.api.annotation.Resource
+ public void setBar(Bar bar) {
+ }
+
+ @org.apache.tuscany.api.annotation.Resource(name = "someName", mappedName = "mapped")
+ public void setBar2(Bar bar) {
+ }
+
+ @org.apache.tuscany.api.annotation.Resource
+ public void setBad() {
+ }
+
+ }
+
+ private interface Bar {
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ScopeProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ScopeProcessorTestCase.java
new file mode 100644
index 0000000000..dc65dc44f4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ScopeProcessorTestCase.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ScopeProcessorTestCase extends TestCase {
+
+ CompositeComponent parent;
+
+ public void testCompositeScope() throws ProcessingException {
+ ScopeProcessor processor = new ScopeProcessor();
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+
+ processor.visitClass(parent, Composite.class, type, null);
+ assertEquals(Scope.COMPOSITE, type.getImplementationScope());
+ }
+
+ public void testSessionScope() throws ProcessingException {
+ ScopeProcessor processor = new ScopeProcessor();
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(parent, Session.class, type, null);
+ assertEquals(Scope.SESSION, type.getImplementationScope());
+ }
+
+ public void testConversationalScope() throws ProcessingException {
+ ScopeProcessor processor = new ScopeProcessor();
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(parent, Conversation.class, type, null);
+ assertEquals(Scope.CONVERSATION, type.getImplementationScope());
+ }
+
+ public void testRequestScope() throws ProcessingException {
+ ScopeProcessor processor = new ScopeProcessor();
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(parent, Request.class, type, null);
+ assertEquals(Scope.REQUEST, type.getImplementationScope());
+ }
+
+ public void testSystemScope() throws ProcessingException {
+ ScopeProcessor processor = new ScopeProcessor();
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(parent, System.class, type, null);
+ assertEquals(Scope.SYSTEM, type.getImplementationScope());
+ }
+
+ public void testStatelessScope() throws ProcessingException {
+ ScopeProcessor processor = new ScopeProcessor();
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(parent, Stateless.class, type, null);
+ assertEquals(Scope.STATELESS, type.getImplementationScope());
+ }
+
+ public void testNoScope() throws ProcessingException {
+ ScopeProcessor processor = new ScopeProcessor();
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(parent, None.class, type, null);
+ assertEquals(Scope.STATELESS, type.getImplementationScope());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ parent = EasyMock.createNiceMock(CompositeComponent.class);
+ }
+
+ @org.osoa.sca.annotations.Scope("COMPOSITE")
+ private class Composite {
+ }
+
+ @org.osoa.sca.annotations.Scope("SESSION")
+ private class Session {
+ }
+
+ @org.osoa.sca.annotations.Scope("CONVERSATION")
+ private class Conversation {
+ }
+
+ @org.osoa.sca.annotations.Scope("REQUEST")
+ private class Request {
+ }
+
+ @org.osoa.sca.annotations.Scope("SYSTEM")
+ private class System {
+ }
+
+ @org.osoa.sca.annotations.Scope("STATELESS")
+ private class Stateless {
+ }
+
+ private class None {
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ServiceCallbackTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ServiceCallbackTestCase.java
new file mode 100644
index 0000000000..29cae3beae
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ServiceCallbackTestCase.java
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.osoa.sca.annotations.Callback;
+import org.osoa.sca.annotations.Service;
+
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.idl.java.IllegalCallbackException;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ServiceCallbackTestCase extends TestCase {
+
+ ServiceProcessor processor =
+ new ServiceProcessor(new ImplementationProcessorServiceImpl(new JavaInterfaceProcessorRegistryImpl()));
+
+ public void testMethodCallbackInterface() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(null, FooImpl.class, type, null);
+ JavaMappedService service = type.getServices().get(Foo.class.getSimpleName());
+ assertNotNull(service);
+ Method method = FooImpl.class.getMethod("setCallback", FooCallback.class);
+ processor.visitMethod(null, method, type, null);
+ assertEquals(method, service.getCallbackMember());
+ }
+
+ public void testFieldCallbackInterface() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(null, FooImpl.class, type, null);
+ JavaMappedService service = type.getServices().get(Foo.class.getSimpleName());
+ assertNotNull(service);
+ Field field = FooImpl.class.getDeclaredField("callback");
+ processor.visitField(null, field, type, null);
+ assertEquals(field, service.getCallbackMember());
+ }
+
+ public void testMethodDoesNotMatchCallback() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(null, BadBarImpl.class, type, null);
+ Method method = BadBarImpl.class.getMethod("setWrongInterfaceCallback", String.class);
+ try {
+ processor.visitMethod(null, method, type, null);
+ fail();
+ } catch (IllegalCallbackReferenceException e) {
+ // expected
+ }
+ }
+
+ public void testNoParamCallback() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(null, BadBarImpl.class, type, null);
+ Method method = BadBarImpl.class.getMethod("setNoParamCallback");
+ try {
+ processor.visitMethod(null, method, type, null);
+ fail();
+ } catch (IllegalCallbackReferenceException e) {
+ // expected
+ }
+ }
+
+ public void testFieldDoesNotMatchCallback() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ processor.visitClass(null, BadBarImpl.class, type, null);
+ Field field = BadBarImpl.class.getDeclaredField("wrongInterfaceCallback");
+ try {
+ processor.visitField(null, field, type, null);
+ fail();
+ } catch (IllegalCallbackReferenceException e) {
+ // expected
+ }
+ }
+
+ public void testBadCallbackInterfaceAnnotation() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ try {
+ processor.visitClass(null, BadFooImpl.class, type, null);
+ fail();
+ } catch (ProcessingException e) {
+ // expected
+ assertTrue(e.getCause() instanceof IllegalCallbackException);
+ }
+ }
+
+ @Callback(FooCallback.class)
+ private interface Foo {
+
+ }
+
+ private interface FooCallback {
+
+ }
+
+ @Service(Foo.class)
+ private static class FooImpl implements Foo {
+
+ @Callback
+ protected FooCallback callback;
+
+ @Callback
+ public void setCallback(FooCallback cb) {
+
+ }
+ }
+
+ private static class BadBarImpl implements Foo {
+ @Callback
+ protected String wrongInterfaceCallback;
+
+ @Callback
+ public void setWrongInterfaceCallback(String cb) {
+
+ }
+
+ @Callback
+ public void setNoParamCallback() {
+
+ }
+
+ }
+
+ @Callback
+ private interface BadFoo {
+
+ }
+
+ @Service(BadFoo.class)
+ private static class BadFooImpl implements BadFoo {
+
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ServiceProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ServiceProcessorTestCase.java
new file mode 100644
index 0000000000..ed7cc6b8e6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/processor/ServiceProcessorTestCase.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.processor;
+
+import org.osoa.sca.annotations.Callback;
+import org.osoa.sca.annotations.Remotable;
+import org.osoa.sca.annotations.Service;
+
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.model.ServiceContract;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ServiceProcessorTestCase extends TestCase {
+ private ServiceProcessor processor;
+ private PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type;
+
+ public void testMultipleInterfaces() throws Exception {
+ processor.visitClass(null, FooMultiple.class, type, null);
+ assertEquals(2, type.getServices().size());
+ JavaMappedService service = type.getServices().get(Baz.class.getSimpleName());
+ ServiceContract contract = service.getServiceContract();
+ assertEquals(Baz.class, contract.getInterfaceClass());
+ assertEquals(Bar.class, contract.getCallbackClass());
+ assertEquals("ServiceProcessorTestCase$Bar", contract.getCallbackName());
+ assertNotNull(type.getServices().get(Bar.class.getSimpleName()));
+ }
+
+ public void testSingleInterfaces() throws Exception {
+ processor.visitClass(null, FooSingle.class, type, null);
+ assertEquals(1, type.getServices().size());
+ assertNotNull(type.getServices().get(Baz.class.getSimpleName()));
+ }
+
+ public void testMultipleNoService() throws Exception {
+ processor.visitClass(null, FooMultipleNoService.class, type, null);
+ assertEquals(0, type.getServices().size());
+ }
+
+ public void testRemotableNoService() throws Exception {
+ processor.visitClass(null, FooRemotableNoService.class, type, null);
+ assertEquals(1, type.getServices().size());
+ JavaMappedService service = type.getServices().get(BazRemotable.class.getSimpleName());
+ ServiceContract contract = service.getServiceContract();
+ assertEquals(BazRemotable.class, contract.getInterfaceClass());
+ }
+
+ public void testNonInterface() throws Exception {
+ try {
+ processor.visitClass(null, BadImpl.class, type, null);
+ fail();
+ } catch (InvalidServiceType e) {
+ //expected
+ }
+ }
+
+ public void testNoInterfaces() throws Exception {
+ try {
+ processor.visitClass(null, BadDefinition.class, type, null);
+ fail();
+ } catch (IllegalServiceDefinitionException e) {
+ //expected
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ JavaInterfaceProcessorRegistryImpl registry = new JavaInterfaceProcessorRegistryImpl();
+ processor = new ServiceProcessor(new ImplementationProcessorServiceImpl(registry));
+ type = new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ }
+
+ @Callback(Bar.class)
+ private interface Baz {
+ }
+
+ private interface Bar {
+ }
+
+ @Remotable
+ private interface BazRemotable {
+ }
+
+ @Service(interfaces = {Baz.class, Bar.class})
+ private class FooMultiple implements Baz, Bar {
+
+ }
+
+ @Service(Baz.class)
+ private class FooSingle implements Baz, Bar {
+
+ }
+
+ private class FooMultipleNoService implements Baz, Bar {
+
+ }
+
+ private class FooRemotableNoService implements BazRemotable, Bar {
+
+ }
+
+ @Service(FooSingle.class)
+ private class BadImpl extends FooSingle {
+
+ }
+
+
+ @Service()
+ private class BadDefinition extends FooSingle {
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/builder/SystemComponentBuilderResourceTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/builder/SystemComponentBuilderResourceTestCase.java
new file mode 100644
index 0000000000..091f231f37
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/builder/SystemComponentBuilderResourceTestCase.java
@@ -0,0 +1,75 @@
+package org.apache.tuscany.core.implementation.system.builder;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.implementation.system.model.SystemImplementation;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.Resource;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SystemComponentBuilderResourceTestCase extends TestCase {
+
+ @SuppressWarnings("unchecked")
+ public void testResourceInjection() throws Exception {
+ ScopeContainer container = EasyMock.createNiceMock(ScopeContainer.class);
+ DeploymentContext ctx = EasyMock.createNiceMock(DeploymentContext.class);
+ ScopeRegistry registry = EasyMock.createMock(ScopeRegistry.class);
+ EasyMock.expect(registry.getScopeContainer(Scope.STATELESS)).andReturn(container);
+ EasyMock.replay(registry);
+ SystemComponentBuilder builder = new SystemComponentBuilder();
+ builder.setScopeRegistry(registry);
+ ConstructorDefinition<Foo> ctorDef = new ConstructorDefinition<SystemComponentBuilderResourceTestCase.Foo>(
+ SystemComponentBuilderResourceTestCase.Foo.class.getConstructor());
+ PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> type =
+ new PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ Resource resource = new Resource();
+ resource.setType(String.class);
+ resource.setName("resource");
+ resource.setMember(SystemComponentBuilderResourceTestCase.Foo.class.getDeclaredField("resource"));
+ type.add(resource);
+ type.setImplementationScope(Scope.STATELESS);
+ type.setConstructorDefinition(ctorDef);
+ SystemImplementation impl = new SystemImplementation();
+ impl.setImplementationClass(SystemComponentBuilderResourceTestCase.Foo.class);
+ impl.setComponentType(type);
+ ComponentDefinition<SystemImplementation> definition =
+ new ComponentDefinition<SystemImplementation>("foo", impl);
+
+ InboundWire wire = EasyMock.createMock(InboundWire.class);
+ EasyMock.expect(wire.getTargetService()).andReturn("result");
+ EasyMock.replay(wire);
+
+ CompositeComponent parent = EasyMock.createMock(CompositeComponent.class);
+ EasyMock.expect(parent.resolveSystemAutowire(String.class)).andReturn(wire);
+ EasyMock.replay(parent);
+ AtomicComponent component = builder.build(parent, definition, ctx);
+ SystemComponentBuilderResourceTestCase.Foo foo =
+ (SystemComponentBuilderResourceTestCase.Foo) component.createInstance();
+ assertEquals("result", foo.resource);
+ EasyMock.verify(parent);
+ }
+
+ private static class Foo {
+
+ protected String resource;
+
+ public Foo() {
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentTestCase.java
new file mode 100644
index 0000000000..b8789cb8b4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentTestCase.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.system.component;
+
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.injection.EventInvoker;
+import org.apache.tuscany.core.injection.MethodEventInvoker;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.injection.SingletonObjectFactory;
+import org.easymock.EasyMock;
+
+/**
+ * Verifies a system atomic component can be started and initialized
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class SystemAtomicComponentTestCase extends TestCase {
+
+ private EventInvoker<Object> initInvoker;
+ private EventInvoker<Object> destroyInvoker;
+
+ public void testDefaultCreationAndInit() throws Exception {
+ PojoObjectFactory<Foo> factory = new PojoObjectFactory<Foo>(Foo.class.getConstructor((Class[]) null));
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInstanceFactory(factory);
+ configuration.setInitInvoker(initInvoker);
+ configuration.setName("foo");
+ SystemAtomicComponentImpl component = new SystemAtomicComponentImpl(configuration);
+ Foo foo = (Foo) component.createInstance();
+ component.init(foo);
+ assertTrue(foo.initialized);
+ }
+
+ public void testDestroy() throws Exception {
+ PojoObjectFactory<Foo> factory = new PojoObjectFactory<Foo>(Foo.class.getConstructor((Class[]) null));
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInstanceFactory(factory);
+ configuration.setDestroyInvoker(destroyInvoker);
+ configuration.setName("foo");
+ SystemAtomicComponentImpl component = new SystemAtomicComponentImpl(configuration);
+ Foo foo = (Foo) component.createInstance();
+ component.destroy(foo);
+ assertTrue(foo.destroyed);
+ }
+
+ public void testReferenceAndPropertyConstructor() throws Exception {
+ PojoObjectFactory<Bar> factory = new PojoObjectFactory<Bar>(Bar.class.getConstructor(String.class, Foo.class));
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInstanceFactory(factory);
+ configuration.setInitInvoker(initInvoker);
+ configuration.addConstructorParamName("foo");
+ configuration.addConstructorParamType(String.class);
+ configuration.addConstructorParamName("ref");
+ configuration.addConstructorParamType(Foo.class);
+ configuration.setName("foo");
+ SystemAtomicComponentImpl component = new SystemAtomicComponentImpl(configuration);
+ component.addPropertyFactory("foo", new SingletonObjectFactory<String>("baz"));
+ Foo target = new Foo();
+ OutboundWire wire = EasyMock.createMock(OutboundWire.class);
+ EasyMock.expect(wire.getTargetService()).andReturn(target);
+ EasyMock.expect(wire.getReferenceName()).andReturn("ref").anyTimes();
+ EasyMock.replay(wire);
+ component.addOutboundWire(wire);
+ Bar bar = (Bar) component.createInstance();
+ assertEquals("baz", bar.foo);
+ assertEquals(target, bar.ref);
+ EasyMock.verify(wire);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ initInvoker = new MethodEventInvoker<Object>(Foo.class.getMethod("init"));
+ destroyInvoker = new MethodEventInvoker<Object>(Foo.class.getMethod("destroy"));
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public static class Foo {
+ private boolean initialized;
+ private boolean destroyed;
+
+ public void init() {
+ initialized = true;
+ }
+
+ public void destroy() {
+ destroyed = true;
+ }
+ }
+
+ public static class Bar {
+
+ private String foo;
+ private Foo ref;
+
+ public Bar(String foo, Foo ref) {
+ this.foo = foo;
+ this.ref = ref;
+ }
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentWireInvocationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentWireInvocationTestCase.java
new file mode 100644
index 0000000000..c4a2664228
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/component/SystemAtomicComponentWireInvocationTestCase.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.system.component;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.scope.CompositeScopeContainer;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.mock.component.Source;
+import org.apache.tuscany.core.mock.component.SourceImpl;
+import org.apache.tuscany.core.mock.component.Target;
+import org.apache.tuscany.core.mock.component.TargetImpl;
+import org.easymock.EasyMock;
+
+/**
+ * Tests reference wires are injected properly into system component instances
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class SystemAtomicComponentWireInvocationTestCase extends TestCase {
+
+ public void testWireResolution() throws Exception {
+ CompositeScopeContainer scope = new CompositeScopeContainer(null);
+ scope.start();
+ Target target = new TargetImpl();
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.addReferenceSite("setTarget", SourceImpl.class.getMethod("setTarget", Target.class));
+ configuration.setInstanceFactory(new PojoObjectFactory<SourceImpl>(SourceImpl.class.getConstructor()));
+ configuration.setName("source");
+ AtomicComponent component = new SystemAtomicComponentImpl(configuration);
+ component.setScopeContainer(scope);
+ OutboundWire outboundWire = EasyMock.createMock(OutboundWire.class);
+ EasyMock.expect(outboundWire.getReferenceName()).andReturn("setTarget").atLeastOnce();
+ EasyMock.expect(outboundWire.getTargetService()).andReturn(target);
+ EasyMock.replay(outboundWire);
+ component.addOutboundWire(outboundWire);
+ component.start();
+ assertSame(((Source) component.getTargetInstance()).getTarget(), target);
+ EasyMock.verify(outboundWire);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/loader/SystemComponentTypeLoaderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/loader/SystemComponentTypeLoaderTestCase.java
new file mode 100644
index 0000000000..bc86d82f34
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/loader/SystemComponentTypeLoaderTestCase.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.system.loader;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.implementation.java.ProcessingException;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.implementation.IntrospectionRegistryImpl;
+import org.apache.tuscany.core.implementation.processor.ConstructorProcessor;
+import org.apache.tuscany.core.implementation.processor.DestroyProcessor;
+import org.apache.tuscany.core.implementation.processor.HeuristicPojoProcessor;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService;
+import org.apache.tuscany.core.implementation.processor.ImplementationProcessorServiceImpl;
+import org.apache.tuscany.core.implementation.processor.InitProcessor;
+import org.apache.tuscany.core.implementation.processor.PropertyProcessor;
+import org.apache.tuscany.core.implementation.processor.ReferenceProcessor;
+import org.apache.tuscany.core.implementation.processor.ScopeProcessor;
+import org.apache.tuscany.core.implementation.processor.ServiceProcessor;
+import org.apache.tuscany.core.implementation.system.model.SystemImplementation;
+import org.apache.tuscany.core.mock.component.BasicInterface;
+import org.apache.tuscany.core.mock.component.BasicInterfaceImpl;
+import org.apache.tuscany.core.monitor.NullMonitorFactory;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SystemComponentTypeLoaderTestCase extends TestCase {
+ private SystemComponentTypeLoader loader;
+
+ public void testIntrospectUnannotatedClass() throws ProcessingException {
+ CompositeComponent parent = EasyMock.createNiceMock(CompositeComponent.class);
+ SystemImplementation impl = new SystemImplementation(BasicInterfaceImpl.class);
+ PojoComponentType<?, ?, ?> componentType = loader.loadByIntrospection(parent, impl, null);
+ ServiceDefinition service = componentType.getServices().get(BasicInterface.class.getSimpleName());
+ assertEquals(BasicInterface.class, service.getServiceContract().getInterfaceClass());
+ Property<?> property = componentType.getProperties().get("publicProperty");
+ assertEquals(String.class, property.getJavaType());
+ AbstractReferenceDefinition referenceDefinition = componentType.getReferences().get("protectedReference");
+ assertEquals(BasicInterface.class, referenceDefinition.getServiceContract().getInterfaceClass());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ JavaInterfaceProcessorRegistryImpl interfaceProcessorRegistry = new JavaInterfaceProcessorRegistryImpl();
+ ImplementationProcessorService service =
+ new ImplementationProcessorServiceImpl(interfaceProcessorRegistry);
+ IntrospectionRegistryImpl registry = new IntrospectionRegistryImpl();
+ registry.setMonitor(new NullMonitorFactory().getMonitor(IntrospectionRegistryImpl.Monitor.class));
+ registry.registerProcessor(new ConstructorProcessor(service));
+ registry.registerProcessor(new DestroyProcessor());
+ registry.registerProcessor(new InitProcessor());
+ registry.registerProcessor(new ScopeProcessor());
+ registry.registerProcessor(new PropertyProcessor(service));
+ registry.registerProcessor(new ReferenceProcessor(interfaceProcessorRegistry));
+ registry.registerProcessor(new ServiceProcessor(service));
+ registry.registerProcessor(new HeuristicPojoProcessor(service));
+ loader = new SystemComponentTypeLoader(registry);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/loader/SystemImplementationLoaderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/loader/SystemImplementationLoaderTestCase.java
new file mode 100644
index 0000000000..6cb059d629
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/implementation/system/loader/SystemImplementationLoaderTestCase.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.implementation.system.loader;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.UnrecognizedElementException;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.system.model.SystemImplementation;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SystemImplementationLoaderTestCase extends TestCase {
+
+ public static final QName SYSTEM_IMPLEMENTATION =
+ new QName("http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT", "implementation.system");
+
+ public void testLoad() throws Exception {
+ LoaderRegistry registry = EasyMock.createNiceMock(LoaderRegistry.class);
+ EasyMock.replay(registry);
+ DeploymentContext context = EasyMock.createMock(DeploymentContext.class);
+ EasyMock.expect(context.getClassLoader()).andReturn(getClass().getClassLoader());
+ EasyMock.replay(context);
+ XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class);
+ EasyMock.expect(reader.getName()).andReturn(SYSTEM_IMPLEMENTATION);
+ EasyMock.expect(reader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("class")))
+ .andReturn(getClass().getName());
+ EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT);
+ EasyMock.replay(reader);
+ SystemImplementationLoader loader = new SystemImplementationLoader(registry);
+ SystemImplementation impl = loader.load(null, null, reader, context);
+ assertEquals(getClass(), impl.getImplementationClass());
+ EasyMock.verify(reader);
+ EasyMock.verify(context);
+ }
+
+ public void testUnrecognizedElement() throws Exception {
+ LoaderRegistry registry = EasyMock.createNiceMock(LoaderRegistry.class);
+ EasyMock.replay(registry);
+ DeploymentContext context = EasyMock.createMock(DeploymentContext.class);
+ EasyMock.expect(context.getClassLoader()).andReturn(getClass().getClassLoader());
+ EasyMock.replay(context);
+ XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class);
+ EasyMock.expect(reader.getName()).andReturn(SYSTEM_IMPLEMENTATION).atLeastOnce();
+ EasyMock.expect(reader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("class")))
+ .andReturn(getClass().getName());
+ EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.START_ELEMENT);
+ EasyMock.expect(reader.getLocation()).andReturn(new MockLocation());
+ EasyMock.replay(reader);
+ SystemImplementationLoader loader = new SystemImplementationLoader(registry);
+ try {
+ loader.load(null, null, reader, context);
+ fail();
+ } catch (UnrecognizedElementException e) {
+ // expected
+ }
+ }
+
+ private class MockLocation implements Location {
+
+ public int getLineNumber() {
+ return 0;
+ }
+
+ public int getColumnNumber() {
+ return 0;
+ }
+
+ public int getCharacterOffset() {
+ return 0;
+ }
+
+ public String getPublicId() {
+ return null;
+ }
+
+ public String getSystemId() {
+ return null;
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/CallbackWireObjectFactoryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/CallbackWireObjectFactoryTestCase.java
new file mode 100644
index 0000000000..0a3a052024
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/CallbackWireObjectFactoryTestCase.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import org.apache.tuscany.spi.wire.WireService;
+
+import junit.framework.TestCase;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class CallbackWireObjectFactoryTestCase extends TestCase {
+
+ public void testCreateInstance() throws Exception {
+ WireService service = createMock(WireService.class);
+ service.createCallbackProxy(Foo.class, null);
+ expectLastCall().andReturn(null);
+ replay(service);
+ CallbackWireObjectFactory factory = new CallbackWireObjectFactory(Foo.class, service, null);
+ factory.getInstance();
+ verify(service);
+ }
+
+ private interface Foo {
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/FieldInjectorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/FieldInjectorTestCase.java
new file mode 100644
index 0000000000..d31347f7e6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/FieldInjectorTestCase.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import java.lang.reflect.Field;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class FieldInjectorTestCase extends TestCase {
+
+ protected Field protectedField;
+
+ public void testIllegalAccess() throws Exception {
+ FieldInjector<Foo> injector = new FieldInjector<Foo>(protectedField, new SingletonObjectFactory<String>("foo"));
+ Foo foo = new Foo();
+ injector.inject(foo);
+ assertEquals("foo", foo.hidden);
+ }
+
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ protectedField = Foo.class.getDeclaredField("hidden");
+ }
+
+ private class Foo {
+ private String hidden;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/JNDIObjectFactoryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/JNDIObjectFactoryTestCase.java
new file mode 100644
index 0000000000..91214fd02d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/JNDIObjectFactoryTestCase.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JNDIObjectFactoryTestCase extends TestCase {
+
+ public void testGetInstance() throws Exception {
+ Context ctx = EasyMock.createMock(Context.class);
+ EasyMock.expect(ctx.lookup(EasyMock.eq("foo"))).andReturn(new Foo());
+ EasyMock.replay(ctx);
+ JNDIObjectFactory<Foo> factory = new JNDIObjectFactory<Foo>(ctx, "foo");
+ assertTrue(factory.getInstance() instanceof Foo); // must do an instanceof b/c of type erasure
+ EasyMock.verify(ctx);
+ }
+
+ public void testGetInstanceError() throws Exception {
+ Context ctx = EasyMock.createMock(Context.class);
+ EasyMock.expect(ctx.lookup(EasyMock.eq("foo"))).andThrow(new NamingException());
+ EasyMock.replay(ctx);
+ JNDIObjectFactory<Foo> factory = new JNDIObjectFactory<Foo>(ctx, "foo");
+ try {
+ factory.getInstance();
+ fail();
+ } catch (ObjectCreationException e) {
+ //expected
+ }
+ EasyMock.verify(ctx);
+ }
+
+
+ private class Foo {
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/MethodEventInvokerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/MethodEventInvokerTestCase.java
new file mode 100644
index 0000000000..3bb882da2d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/MethodEventInvokerTestCase.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import java.lang.reflect.Method;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MethodEventInvokerTestCase extends TestCase {
+ private Method privateMethod;
+ private Method exceptionMethod;
+
+ public void testIllegalAccess() throws Exception {
+ MethodEventInvoker<MethodEventInvokerTestCase.Foo> injector = new MethodEventInvoker<Foo>(privateMethod);
+ try {
+ injector.invokeEvent(new Foo());
+ fail();
+ } catch (AssertionError e) {
+ // expected
+ }
+ }
+
+ public void testException() throws Exception {
+ MethodEventInvoker<MethodEventInvokerTestCase.Foo> injector = new MethodEventInvoker<Foo>(exceptionMethod);
+ try {
+ injector.invokeEvent(new Foo());
+ fail();
+ } catch (RuntimeException e) {
+ // expected
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ privateMethod = MethodEventInvokerTestCase.Foo.class.getDeclaredMethod("hidden");
+ exceptionMethod = MethodEventInvokerTestCase.Foo.class.getDeclaredMethod("exception");
+
+ }
+
+ private class Foo {
+
+ public void foo() {
+ }
+
+ private void hidden() {
+ }
+
+ public void exception() {
+ throw new RuntimeException();
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/MethodInjectorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/MethodInjectorTestCase.java
new file mode 100644
index 0000000000..b21ba4ccfa
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/MethodInjectorTestCase.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.ObjectFactory;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MethodInjectorTestCase extends TestCase {
+ private Method fooMethod;
+ private Method privateMethod;
+ private Method exceptionMethod;
+
+ public void testIllegalArgument() throws Exception {
+ ObjectFactory<Object> factory = new SingletonObjectFactory<Object>(new Object());
+ MethodInjector<Foo> injector = new MethodInjector<Foo>(fooMethod, factory);
+ try {
+ injector.inject(new Foo());
+ fail();
+ } catch (ObjectCreationException e) {
+ // expected
+ }
+ }
+
+ public void testException() throws Exception {
+ ObjectFactory<Object> factory = new SingletonObjectFactory<Object>("foo");
+ MethodInjector<Foo> injector = new MethodInjector<Foo>(exceptionMethod, factory);
+ try {
+ injector.inject(new Foo());
+ fail();
+ } catch (RuntimeException e) {
+ // expected
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ fooMethod = Foo.class.getMethod("foo", String.class);
+ privateMethod = Foo.class.getDeclaredMethod("hidden", String.class);
+ exceptionMethod = Foo.class.getDeclaredMethod("exception", String.class);
+
+ }
+
+ private class Foo {
+
+ public void foo(String bar) {
+ }
+
+ private void hidden(String bar) {
+ }
+
+ public void exception(String bar) {
+ throw new RuntimeException();
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/PojoObjectFactoryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/PojoObjectFactoryTestCase.java
new file mode 100644
index 0000000000..7aba6dbab3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/PojoObjectFactoryTestCase.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import java.lang.reflect.Constructor;
+import java.util.List;
+import java.util.ArrayList;
+
+import org.apache.tuscany.spi.ObjectFactory;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class PojoObjectFactoryTestCase extends TestCase {
+
+ private Constructor<Foo> ctor;
+
+ public void testConstructorInjection() throws Exception {
+ List<ObjectFactory> initializers = new ArrayList<ObjectFactory>();
+ initializers.add(new SingletonObjectFactory<String>("foo"));
+ PojoObjectFactory<Foo> factory = new PojoObjectFactory<Foo>(ctor, initializers);
+ Foo foo = factory.getInstance();
+ assertEquals("foo", foo.foo);
+ }
+
+ public void testConstructorInitializerInjection() throws Exception {
+ PojoObjectFactory<Foo> factory = new PojoObjectFactory<Foo>(ctor);
+ factory.setInitializerFactory(0, new SingletonObjectFactory<String>("foo"));
+ Foo foo = factory.getInstance();
+ assertEquals("foo", foo.foo);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ ctor = Foo.class.getConstructor(String.class);
+ }
+
+ private static class Foo {
+
+ private String foo;
+
+ public Foo(String foo) {
+ this.foo = foo;
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/RequestContextObjectFactoryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/RequestContextObjectFactoryTestCase.java
new file mode 100644
index 0000000000..a1a41bbada
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/RequestContextObjectFactoryTestCase.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import org.apache.tuscany.spi.component.WorkContext;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class RequestContextObjectFactoryTestCase extends TestCase {
+
+ public void testInstanceCreate() {
+ WorkContext workContext = EasyMock.createNiceMock(WorkContext.class);
+ RequestContextObjectFactory factory = new RequestContextObjectFactory(workContext);
+ assertNotNull(factory.getInstance());
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/ResourceObjectFactoryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/ResourceObjectFactoryTestCase.java
new file mode 100644
index 0000000000..073bda1458
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/ResourceObjectFactoryTestCase.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.host.ResourceHost;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ResourceObjectFactoryTestCase extends TestCase {
+
+ public void testResolveFromHostByType() throws Exception {
+ ResourceHost host = EasyMock.createMock(ResourceHost.class);
+ EasyMock.expect(host.resolveResource(EasyMock.eq(String.class))).andReturn("foo");
+ EasyMock.replay(host);
+ CompositeComponent parent = EasyMock.createMock(CompositeComponent.class);
+ EasyMock.expect(parent.resolveSystemAutowire(EasyMock.eq(String.class))).andReturn(null);
+ EasyMock.replay(parent);
+ ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, false, parent, host);
+ assertEquals("foo", factory.getInstance());
+ EasyMock.verify(host);
+ EasyMock.verify(parent);
+ }
+
+ public void testResolveFromHostByName() throws Exception {
+ ResourceHost host = EasyMock.createMock(ResourceHost.class);
+ EasyMock.expect(host.resolveResource(EasyMock.eq(String.class),
+ EasyMock.eq("sca://localhost/bar"))).andReturn("foo");
+ EasyMock.replay(host);
+ ResourceObjectFactory<String> factory =
+ new ResourceObjectFactory<String>(String.class, "sca://localhost/bar", false, null, host);
+ assertEquals("foo", factory.getInstance());
+ EasyMock.verify(host);
+ }
+
+ public void testResolveFromParentByType() throws Exception {
+ CompositeComponent parent = EasyMock.createMock(CompositeComponent.class);
+ InboundWire wire = EasyMock.createMock(InboundWire.class);
+ EasyMock.expect(wire.getTargetService()).andReturn("foo");
+ EasyMock.replay(wire);
+
+ EasyMock.expect(parent.resolveSystemAutowire(EasyMock.eq(String.class))).andReturn(wire);
+ EasyMock.replay(parent);
+ ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, false, parent, null);
+ assertEquals("foo", factory.getInstance());
+ EasyMock.verify(parent);
+ }
+
+ public void testResolveFromParentByName() throws Exception {
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getTargetInstance()).andReturn("foo");
+ EasyMock.replay(component);
+ CompositeComponent parent = EasyMock.createMock(CompositeComponent.class);
+ EasyMock.expect(parent.getSystemChild(EasyMock.eq("bar"))).andReturn(component);
+ EasyMock.replay(parent);
+ ResourceObjectFactory<String> factory =
+ new ResourceObjectFactory<String>(String.class, "bar", false, parent, null);
+ assertEquals("foo", factory.getInstance());
+ EasyMock.verify(parent);
+ EasyMock.verify(component);
+ }
+
+ /**
+ * Verifies if a resource is not found as a child of the parent, the host namespace will be searched
+ */
+ public void testResolveFromParentThenResolveFromHost() throws Exception {
+ ResourceHost host = EasyMock.createMock(ResourceHost.class);
+ EasyMock.expect(host.resolveResource(EasyMock.eq(String.class))).andReturn("foo");
+ EasyMock.replay(host);
+
+ CompositeComponent parent = EasyMock.createMock(CompositeComponent.class);
+ EasyMock.expect(parent.resolveSystemAutowire(EasyMock.eq(String.class))).andReturn(null);
+ EasyMock.replay(parent);
+ ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, false, parent, host);
+ assertEquals("foo", factory.getInstance());
+ EasyMock.verify(parent);
+ EasyMock.verify(host);
+ }
+
+ public void testResolveFromParentThenResolveFromHostNotFound() throws Exception {
+ ResourceHost host = EasyMock.createMock(ResourceHost.class);
+ EasyMock.expect(host.resolveResource(EasyMock.eq(String.class))).andReturn(null);
+ EasyMock.replay(host);
+ CompositeComponent parent = EasyMock.createMock(CompositeComponent.class);
+ EasyMock.expect(parent.resolveSystemAutowire(EasyMock.eq(String.class))).andReturn(null);
+ EasyMock.replay(parent);
+ ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, true, parent, host);
+ assertNull(factory.getInstance());
+ EasyMock.verify(parent);
+ EasyMock.verify(host);
+ }
+
+ public void testResolveByTypeNotFound() throws Exception {
+ ResourceHost host = EasyMock.createMock(ResourceHost.class);
+ EasyMock.expect(host.resolveResource(EasyMock.eq(String.class))).andReturn(null);
+ EasyMock.replay(host);
+
+ InboundWire wire = EasyMock.createMock(InboundWire.class);
+ EasyMock.expect(wire.getTargetService()).andReturn(null);
+ EasyMock.replay(wire);
+
+ CompositeComponent parent = EasyMock.createMock(CompositeComponent.class);
+ EasyMock.expect(parent.resolveSystemAutowire(EasyMock.eq(String.class))).andReturn(null);
+ EasyMock.replay(parent);
+ ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, false, parent, host);
+ try {
+ factory.getInstance();
+ fail();
+ } catch (ResourceNotFoundException e) {
+ //expected
+ }
+ EasyMock.verify(parent);
+ EasyMock.verify(host);
+ }
+
+ public void testResolveByTypeNotFoundOptional() throws Exception {
+ ResourceHost host = EasyMock.createMock(ResourceHost.class);
+ EasyMock.expect(host.resolveResource(EasyMock.eq(String.class))).andReturn(null);
+ EasyMock.replay(host);
+ CompositeComponent parent = EasyMock.createMock(CompositeComponent.class);
+ EasyMock.expect(parent.resolveSystemAutowire(EasyMock.eq(String.class))).andReturn(null);
+ EasyMock.replay(parent);
+ ResourceObjectFactory<String> factory = new ResourceObjectFactory<String>(String.class, true, parent, host);
+ assertNull(factory.getInstance());
+ EasyMock.verify(parent);
+ EasyMock.verify(host);
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/SingletonObjectFactoryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/SingletonObjectFactoryTestCase.java
new file mode 100644
index 0000000000..876e68d5b3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/injection/SingletonObjectFactoryTestCase.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.injection;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SingletonObjectFactoryTestCase extends TestCase {
+
+ public void testSingleton() throws Exception {
+ Object o = new Object();
+ SingletonObjectFactory<Object> factory = new SingletonObjectFactory<Object>(o);
+ assertEquals(o, factory.getInstance());
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/conversation/AbstractConversationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/conversation/AbstractConversationTestCase.java
new file mode 100644
index 0000000000..f9135e2eb9
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/conversation/AbstractConversationTestCase.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.integration.conversation;
+
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.services.store.StoreMonitor;
+import org.apache.tuscany.spi.wire.WirePostProcessorRegistry;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.builder.ConnectorImpl;
+import org.apache.tuscany.core.builder.WirePostProcessorRegistryImpl;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.component.scope.ConversationalScopeContainer;
+import org.apache.tuscany.core.implementation.java.JavaAtomicComponent;
+import org.apache.tuscany.core.services.store.memory.MemoryStore;
+import org.easymock.classextension.EasyMock;
+
+/**
+ * Provides helper methods for setting up a partial runtime for conversational test cases.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractConversationTestCase extends TestCase {
+ protected ScopeContainer container;
+ protected MemoryStore store;
+ protected WorkContext workContext;
+ protected ConnectorImpl connector;
+ protected JavaAtomicComponent target;
+
+
+ protected void createRuntime() {
+ workContext = new WorkContextImpl();
+ WirePostProcessorRegistry processorRegistry = new WirePostProcessorRegistryImpl();
+ connector = new ConnectorImpl(null, processorRegistry, null, workContext);
+ store = new MemoryStore(EasyMock.createNiceMock(StoreMonitor.class));
+ container = new ConversationalScopeContainer(store, workContext, null);
+
+ }
+
+ protected void initializeRuntime() {
+ store.init();
+ container.start();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationIdleExpireTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationIdleExpireTestCase.java
new file mode 100644
index 0000000000..4aec333cad
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationIdleExpireTestCase.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.integration.conversation;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.java.JavaAtomicComponent;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.integration.mock.MockFactory;
+import org.apache.tuscany.core.wire.jdk.JDKOutboundInvocationHandler;
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.component.TargetNotFoundException;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.easymock.classextension.EasyMock;
+import org.osoa.sca.annotations.EndsConversation;
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * Verifies conversational resources are cleaned up if the maximum idle time is exceeded
+ *
+ * @version $Rev$ $Date$
+ */
+public class ConversationIdleExpireTestCase extends AbstractConversationTestCase {
+ private JDKOutboundInvocationHandler handler;
+ private OutboundWire owire;
+ private Foo targetInstance;
+ private Method operation1;
+ private Method operation2;
+ private final Object mutex = new Object();
+
+ public void testConversationExpire() throws Throwable {
+ workContext.setIdentifier(org.apache.tuscany.spi.model.Scope.CONVERSATION, "12345A");
+ // start the conversation
+ handler.invoke(operation1, null);
+ // verify the instance was persisted
+ assertEquals(targetInstance, store.readRecord(target, "12345A"));
+ synchronized (mutex) {
+ mutex.wait(100);
+ }
+ // verify the instance was expired
+ assertNull(store.readRecord(target, "12345A"));
+ // continue the conversation - should throw an error
+ try {
+ handler.invoke(operation2, null);
+ fail();
+ } catch (TargetNotFoundException e) {
+ // expected
+ }
+ }
+
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ createRuntime();
+ store.setReaperInterval(10);
+ initializeRuntime();
+
+ targetInstance = EasyMock.createMock(Foo.class);
+ targetInstance.operation1();
+ targetInstance.operation2();
+ targetInstance.end();
+ EasyMock.replay(targetInstance);
+ target = createMaxIdleTimeAtomicComponent();
+ // create source component mock
+ JavaAtomicComponent source = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(source.getName()).andReturn("source").atLeastOnce();
+ EasyMock.expect(source.isSystem()).andReturn(false).atLeastOnce();
+ EasyMock.replay(source);
+
+ owire = MockFactory.createOutboundWire("foo", Foo.class);
+ owire.setContainer(source);
+ owire.setTargetName(new QualifiedName("foo/bar"));
+ InboundWire iwire = MockFactory.createInboundWire("foo", Foo.class);
+ iwire.setContainer(target);
+ connector.connect(owire, iwire, false);
+ handler = new JDKOutboundInvocationHandler(Foo.class, owire, workContext);
+ operation1 = Foo.class.getMethod("operation1");
+ operation2 = Foo.class.getMethod("operation2");
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ container.stop();
+ store.destroy();
+ }
+
+ private JavaAtomicComponent createMaxIdleTimeAtomicComponent() throws Exception {
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setName("target");
+ configuration.setMaxIdleTime(50);
+ configuration.setInstanceFactory(new MockPojoFactory(Object.class.getConstructor()));
+ JavaAtomicComponent component = new JavaAtomicComponent(configuration);
+ component.setScopeContainer(container);
+ component.start();
+ return component;
+ }
+
+ private class MockPojoFactory extends PojoObjectFactory<Object> {
+ public MockPojoFactory(Constructor<Object> ctr) {
+ super(ctr);
+ }
+
+ public Foo getInstance() throws ObjectCreationException {
+ return targetInstance;
+ }
+ }
+
+ @Scope("CONVERSATION")
+ public static interface Foo {
+
+ void operation1();
+
+ void operation2();
+
+ @EndsConversation
+ void end();
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationMaxAgeExpireTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationMaxAgeExpireTestCase.java
new file mode 100644
index 0000000000..1c9bc4a290
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationMaxAgeExpireTestCase.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.integration.conversation;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.java.JavaAtomicComponent;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.integration.mock.MockFactory;
+import org.apache.tuscany.core.wire.jdk.JDKOutboundInvocationHandler;
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.component.TargetNotFoundException;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.easymock.classextension.EasyMock;
+import org.osoa.sca.annotations.EndsConversation;
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * Verifies conversational resources are cleaned up if the maximum age is exceeded
+ *
+ * @version $Rev$ $Date$
+ */
+public class ConversationMaxAgeExpireTestCase extends AbstractConversationTestCase {
+ private JDKOutboundInvocationHandler handler;
+ private OutboundWire owire;
+ private Foo targetInstance;
+ private Method operation1;
+ private Method operation2;
+ private final Object mutex = new Object();
+
+ public void testConversationExpire() throws Throwable {
+ workContext.setIdentifier(org.apache.tuscany.spi.model.Scope.CONVERSATION, "12345A");
+ // start the conversation
+ handler.invoke(operation1, null);
+ // verify the instance was persisted
+ assertEquals(targetInstance, store.readRecord(target, "12345A"));
+ synchronized (mutex) {
+ mutex.wait(100);
+ }
+ // verify the instance was expired
+ assertNull(store.readRecord(target, "12345A"));
+ // continue the conversation - should throw an error
+ try {
+ handler.invoke(operation2, null);
+ fail();
+ } catch (TargetNotFoundException e) {
+ // expected
+ }
+ }
+
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ createRuntime();
+ store.setReaperInterval(10);
+ initializeRuntime();
+
+ targetInstance = EasyMock.createMock(ConversationMaxAgeExpireTestCase.Foo.class);
+ targetInstance.operation1();
+ targetInstance.operation2();
+ targetInstance.end();
+ EasyMock.replay(targetInstance);
+ target = createMaxIdleTimeAtomicComponent();
+ // create source component mock
+ JavaAtomicComponent source = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(source.getName()).andReturn("source").atLeastOnce();
+ EasyMock.expect(source.isSystem()).andReturn(false).atLeastOnce();
+ EasyMock.replay(source);
+
+ owire = MockFactory.createOutboundWire("foo", Foo.class);
+ owire.setContainer(source);
+ owire.setTargetName(new QualifiedName("foo/bar"));
+ InboundWire iwire = MockFactory.createInboundWire("foo", Foo.class);
+ iwire.setContainer(target);
+ connector.connect(owire, iwire, false);
+ handler = new JDKOutboundInvocationHandler(Foo.class, owire, workContext);
+ operation1 = Foo.class.getMethod("operation1");
+ operation2 = Foo.class.getMethod("operation2");
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ container.stop();
+ store.destroy();
+ }
+
+ private JavaAtomicComponent createMaxIdleTimeAtomicComponent() throws Exception {
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setName("target");
+ configuration.setMaxAge(50);
+ Constructor<Object> ctor = Object.class.getConstructor();
+ configuration.setInstanceFactory(new ConversationMaxAgeExpireTestCase.MockPojoFactory(ctor));
+ JavaAtomicComponent component = new JavaAtomicComponent(configuration);
+ component.setScopeContainer(container);
+ component.start();
+ return component;
+ }
+
+ private class MockPojoFactory extends PojoObjectFactory<Object> {
+ public MockPojoFactory(Constructor<Object> ctr) {
+ super(ctr);
+ }
+
+ public ConversationMaxAgeExpireTestCase.Foo getInstance() throws ObjectCreationException {
+ return targetInstance;
+ }
+ }
+
+ @Scope("CONVERSATION")
+ public static interface Foo {
+
+ void operation1();
+
+ void operation2();
+
+ @EndsConversation
+ void end();
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationStartStopEndTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationStartStopEndTestCase.java
new file mode 100644
index 0000000000..e7a0bc3cfc
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/conversation/ConversationStartStopEndTestCase.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.integration.conversation;
+
+import static org.apache.tuscany.spi.model.Scope.CONVERSATION;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.java.JavaAtomicComponent;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.integration.mock.MockFactory;
+import org.apache.tuscany.core.wire.jdk.JDKOutboundInvocationHandler;
+import org.apache.tuscany.spi.ObjectCreationException;
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.easymock.classextension.EasyMock;
+import org.osoa.sca.annotations.EndsConversation;
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * Verifies start, continue and end conversation invocations are processed properly. Checks that a target instance is
+ * properly instantiated and persisted in the store. Additionally verifies that invocations are dispatched to a target
+ * instance, and that start, continue, and end operations are performed correctly. Finally, verfies that the target
+ * instance is removed from the store when the conversation ends.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ConversationStartStopEndTestCase extends AbstractConversationTestCase {
+ private OutboundWire owire;
+ private Foo targetInstance;
+ private JDKOutboundInvocationHandler handler;
+ private Method operation1;
+ private Method operation2;
+ private Method endOperation;
+
+ public void testConversationStartContinueEnd() throws Throwable {
+ workContext.setIdentifier(CONVERSATION, "12345A");
+ // start the conversation
+ handler.invoke(operation1, null);
+ // verify the instance was persisted
+ assertEquals(targetInstance, store.readRecord(target, "12345A"));
+ // continue the conversation
+ handler.invoke(operation2, null);
+ // verify the instance was persisted
+ assertEquals(targetInstance, store.readRecord(target, "12345A"));
+ // end the conversation
+ handler.invoke(endOperation, null);
+ workContext.clearIdentifier(CONVERSATION);
+ EasyMock.verify(targetInstance);
+ // verify the store has removed the instance
+ assertNull(store.readRecord(target, "12345A"));
+ }
+
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ createRuntime();
+ initializeRuntime();
+ targetInstance = EasyMock.createMock(Foo.class);
+ targetInstance.operation1();
+ targetInstance.operation2();
+ targetInstance.end();
+ EasyMock.replay(targetInstance);
+ // create target component mock
+ target = createAtomicComponent();
+ // create source component mock
+ JavaAtomicComponent source = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(source.getName()).andReturn("source").atLeastOnce();
+ EasyMock.expect(source.isSystem()).andReturn(false).atLeastOnce();
+ EasyMock.replay(source);
+
+ owire = MockFactory.createOutboundWire("foo", Foo.class);
+ owire.setContainer(source);
+ owire.setTargetName(new QualifiedName("foo/bar"));
+ InboundWire iwire = MockFactory.createInboundWire("foo", Foo.class);
+ iwire.setContainer(target);
+ connector.connect(owire, iwire, false);
+ handler = new JDKOutboundInvocationHandler(Foo.class, owire, workContext);
+ operation1 = Foo.class.getMethod("operation1");
+ operation2 = Foo.class.getMethod("operation2");
+ endOperation = Foo.class.getMethod("end");
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ container.stop();
+ store.destroy();
+ }
+
+ private JavaAtomicComponent createAtomicComponent() throws Exception {
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setName("target");
+ configuration.setInstanceFactory(new MockPojoFactory(Object.class.getConstructor()));
+ JavaAtomicComponent component = new JavaAtomicComponent(configuration);
+ component.setScopeContainer(container);
+ component.start();
+ return component;
+ }
+
+ private class MockPojoFactory extends PojoObjectFactory<Object> {
+ public MockPojoFactory(Constructor<Object> ctr) {
+ super(ctr);
+ }
+
+ public Foo getInstance() throws ObjectCreationException {
+ return targetInstance;
+ }
+ }
+
+ @Scope("CONVERSATION")
+ public static interface Foo {
+
+ void operation1();
+
+ void operation2();
+
+ @EndsConversation
+ void end();
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/implementation/IntrospectionRegistryIntegrationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/implementation/IntrospectionRegistryIntegrationTestCase.java
new file mode 100644
index 0000000000..f551aa3e98
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/implementation/IntrospectionRegistryIntegrationTestCase.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.integration.implementation;
+
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Property;
+import org.osoa.sca.annotations.Reference;
+import org.osoa.sca.annotations.Scope;
+import org.apache.tuscany.api.annotation.Resource;
+
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.JavaMappedReference;
+import org.apache.tuscany.spi.implementation.java.JavaMappedService;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import static org.apache.tuscany.spi.model.Scope.COMPOSITE;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.implementation.IntrospectionRegistryImpl;
+import org.apache.tuscany.core.implementation.processor.DestroyProcessor;
+import org.apache.tuscany.core.implementation.processor.ImplementationProcessorServiceImpl;
+import org.apache.tuscany.core.implementation.processor.InitProcessor;
+import org.apache.tuscany.core.implementation.processor.PropertyProcessor;
+import org.apache.tuscany.core.implementation.processor.ReferenceProcessor;
+import org.apache.tuscany.core.implementation.processor.ResourceProcessor;
+import org.apache.tuscany.core.implementation.processor.ScopeProcessor;
+import org.apache.tuscany.core.monitor.NullMonitorFactory;
+
+/**
+ * Sanity check of the <code>IntegrationRegistry</code> to verify operation with processors
+ *
+ * @version $Rev$ $Date$
+ */
+public class IntrospectionRegistryIntegrationTestCase extends TestCase {
+
+ private IntrospectionRegistryImpl registry;
+
+ public void testSimpleComponentTypeParsing() throws Exception {
+ PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>> type =
+ new PojoComponentType<JavaMappedService, JavaMappedReference, JavaMappedProperty<?>>();
+ registry.introspect(null, Foo.class, type, null);
+ assertEquals(Foo.class.getMethod("init"), type.getInitMethod());
+ assertEquals(Foo.class.getMethod("destroy"), type.getDestroyMethod());
+ assertEquals(COMPOSITE, type.getImplementationScope());
+ assertEquals(Foo.class.getMethod("setBar", String.class), type.getProperties().get("bar").getMember());
+ assertEquals(Foo.class.getMethod("setTarget", Foo.class), type.getReferences().get("target").getMember());
+ assertEquals(Foo.class.getMethod("setResource", Foo.class), type.getResources().get("resource").getMember());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ registry = new IntrospectionRegistryImpl();
+ registry.setMonitor(new NullMonitorFactory().getMonitor(IntrospectionRegistryImpl.Monitor.class));
+ registry.registerProcessor(new DestroyProcessor());
+ registry.registerProcessor(new InitProcessor());
+ registry.registerProcessor(new ScopeProcessor());
+ JavaInterfaceProcessorRegistryImpl interfaceProcessorRegistry = new JavaInterfaceProcessorRegistryImpl();
+ ImplementationProcessorService service = new ImplementationProcessorServiceImpl(interfaceProcessorRegistry);
+ registry.registerProcessor(new PropertyProcessor(service));
+ registry.registerProcessor(new ReferenceProcessor(interfaceProcessorRegistry));
+ registry.registerProcessor(new ResourceProcessor());
+ }
+
+ @Scope("COMPOSITE")
+ private static class Foo {
+ protected Foo target;
+ protected String bar;
+ protected Foo resource;
+ private boolean initialized;
+ private boolean destroyed;
+
+
+ @Init
+ public void init() {
+ if (initialized) {
+ fail();
+ }
+ initialized = true;
+ }
+
+ @Destroy
+ public void destroy() {
+ if (destroyed) {
+ fail();
+ }
+ destroyed = true;
+ }
+
+ public Foo getTarget() {
+ return target;
+ }
+
+ @Reference
+ public void setTarget(Foo target) {
+ this.target = target;
+ }
+
+ public String getBar() {
+ return bar;
+ }
+
+ @Property
+ public void setBar(String bar) {
+ this.bar = bar;
+ }
+
+ @Resource
+ public void setResource(Foo resource) {
+ this.resource = resource;
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/implementation/system/builder/SystemBuilderPropertyTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/implementation/system/builder/SystemBuilderPropertyTestCase.java
new file mode 100644
index 0000000000..4a4939b495
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/implementation/system/builder/SystemBuilderPropertyTestCase.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.integration.implementation.system.builder;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.ConstructorDefinition;
+import org.apache.tuscany.spi.implementation.java.JavaMappedProperty;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.deployer.RootDeploymentContext;
+import org.apache.tuscany.core.implementation.system.builder.SystemComponentBuilder;
+import org.apache.tuscany.core.implementation.system.model.SystemImplementation;
+import org.apache.tuscany.core.injection.SingletonObjectFactory;
+import org.easymock.EasyMock;
+
+/**
+ * Verifies that the system builder handles configured properties correctly
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemBuilderPropertyTestCase extends TestCase {
+
+ DeploymentContext deploymentContext;
+ CompositeComponent parent;
+
+ @SuppressWarnings("unchecked")
+ public void testPropertyHandling() throws Exception {
+ SystemComponentBuilder builder = new SystemComponentBuilder();
+ PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, JavaMappedProperty<?>> type =
+ new PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, JavaMappedProperty<?>>();
+ type.setConstructorDefinition(new ConstructorDefinition<Foo>(Foo.class.getConstructor((Class[]) null)));
+ JavaMappedProperty<String> property = new JavaMappedProperty<String>();
+ property.setName("test");
+ property.setDefaultValueFactory(new SingletonObjectFactory<String>("foo"));
+ property.setMember(Foo.class.getMethod("setTest", String.class));
+ type.add(property);
+ SystemImplementation impl = new SystemImplementation();
+ impl.setComponentType(type);
+ impl.setImplementationClass(Foo.class);
+ ComponentDefinition<SystemImplementation> definition = new ComponentDefinition<SystemImplementation>(impl);
+ AtomicComponent component = builder.build(parent, definition, deploymentContext);
+ Foo foo = (Foo) component.createInstance();
+ assertEquals("foo", foo.getTest());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ deploymentContext = new RootDeploymentContext(null, null, null, null);
+ parent = EasyMock.createNiceMock(CompositeComponent.class);
+ }
+
+ private static class Foo {
+ private String test;
+
+ public Foo() {
+ }
+
+ public String getTest() {
+ return test;
+ }
+
+ public void setTest(String test) {
+ this.test = test;
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/mock/MockFactory.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/mock/MockFactory.java
new file mode 100644
index 0000000000..0c331ae7d7
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/mock/MockFactory.java
@@ -0,0 +1,278 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.integration.mock;
+
+import java.lang.reflect.Member;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.WireService;
+
+import org.apache.tuscany.core.builder.ConnectorImpl;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.implementation.PojoConfiguration;
+import org.apache.tuscany.core.implementation.java.JavaAtomicComponent;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.wire.InboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.InboundWireImpl;
+import org.apache.tuscany.core.wire.InvokerInterceptor;
+import org.apache.tuscany.core.wire.OutboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.OutboundWireImpl;
+import org.apache.tuscany.core.wire.jdk.JDKWireService;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public final class MockFactory {
+
+ private static final WireService WIRE_SERVICE = new JDKWireService(new WorkContextImpl(), null);
+ private static final JavaInterfaceProcessorRegistry REGISTRY = new JavaInterfaceProcessorRegistryImpl();
+ private static final ConnectorImpl CONNECTOR = new ConnectorImpl();
+
+ private MockFactory() {
+ }
+
+ /**
+ * Wires two components together where the reference interface is the same as target service
+ *
+ * @param sourceName
+ * @param sourceClass
+ * @param sourceScope
+ * @param members
+ * @param targetName
+ * @param targetService
+ * @param targetClass
+ * @param targetScope
+ * @return
+ * @throws Exception
+ */
+ public static Map<String, AtomicComponent> createWiredComponents(String sourceName,
+ Class<?> sourceClass,
+ ScopeContainer sourceScope,
+ Map<String, Member> members,
+ String targetName,
+ Class<?> targetService,
+ Class<?> targetClass,
+ ScopeContainer targetScope) throws Exception {
+ return createWiredComponents(sourceName,
+ sourceClass,
+ targetService,
+ sourceScope,
+ null,
+ members,
+ targetName,
+ targetService,
+ targetClass,
+ targetScope,
+ null);
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Map<String, AtomicComponent> createWiredComponents(String sourceName, Class<?> sourceClass,
+ Class<?> sourceReferenceClass,
+ ScopeContainer sourceScope,
+ Interceptor sourceHeadInterceptor,
+ Map<String, Member> members,
+ String targetName, Class<?> targetService,
+ Class<?> targetClass,
+ ScopeContainer targetScope,
+ Interceptor targetHeadInterceptor)
+ throws Exception {
+
+ JavaAtomicComponent targetComponent =
+ createJavaComponent(targetName, targetScope, targetClass);
+ String serviceName = targetService.getName().substring(targetService.getName().lastIndexOf('.') + 1);
+ InboundWire inboundWire = createInboundWire(serviceName, targetService, targetHeadInterceptor);
+ targetComponent.addInboundWire(inboundWire);
+ inboundWire.setContainer(targetComponent);
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInstanceFactory(new PojoObjectFactory(sourceClass.getConstructor()));
+ configuration.setWireService(WIRE_SERVICE);
+ for (Map.Entry<String, Member> entry : members.entrySet()) {
+ configuration.addReferenceSite(entry.getKey(), entry.getValue());
+ }
+ configuration.setWorkContext(new WorkContextImpl());
+ configuration.setName(sourceName);
+ JavaAtomicComponent sourceComponent = new JavaAtomicComponent(configuration);
+ sourceComponent.setScopeContainer(sourceScope);
+ OutboundWire outboundWire = createOutboundWire(targetName, sourceReferenceClass, sourceHeadInterceptor);
+ sourceComponent.addOutboundWire(outboundWire);
+ outboundWire.setContainer(sourceComponent);
+ outboundWire.setTargetName(new QualifiedName(targetName + "/" + serviceName));
+ targetScope.register(targetComponent);
+ sourceScope.register(sourceComponent);
+ CONNECTOR.connect(outboundWire, inboundWire, false);
+ Map<String, AtomicComponent> contexts = new HashMap<String, AtomicComponent>();
+ contexts.put(sourceName, sourceComponent);
+ contexts.put(targetName, targetComponent);
+ return contexts;
+ }
+
+
+ /**
+ * Wires two contexts using a multiplicity reference
+ *
+ * @param sourceName
+ * @param sourceClass
+ * @param sourceReferenceClass
+ * @param sourceScope
+ * @param targetName
+ * @param targetService
+ * @param targetClass
+ * @param members
+ * @param targetScope
+ * @return
+ * @throws Exception
+ */
+ @SuppressWarnings("unchecked")
+ public static Map<String, AtomicComponent> createWiredMultiplicity(String sourceName, Class<?> sourceClass,
+ Class<?> sourceReferenceClass,
+ ScopeContainer sourceScope,
+ String targetName, Class<?> targetService,
+ Class<?> targetClass,
+ Map<String, Member> members,
+ ScopeContainer targetScope) throws Exception {
+ JavaAtomicComponent targetComponent =
+ createJavaComponent(targetName, targetScope, targetClass);
+ String serviceName = targetService.getName().substring(targetService.getName().lastIndexOf('.') + 1);
+ InboundWire inboundWire = createInboundWire(serviceName, targetService, null);
+ targetComponent.addInboundWire(inboundWire);
+ inboundWire.setContainer(targetComponent);
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInstanceFactory(new PojoObjectFactory(sourceClass.getConstructor()));
+ configuration.setWireService(WIRE_SERVICE);
+ for (Map.Entry<String, Member> entry : members.entrySet()) {
+ configuration.addReferenceSite(entry.getKey(), entry.getValue());
+ }
+ configuration.setWorkContext(new WorkContextImpl());
+ configuration.setName(sourceName);
+
+ JavaAtomicComponent sourceComponent = new JavaAtomicComponent(configuration);
+ sourceComponent.setScopeContainer(sourceScope);
+ OutboundWire outboundWire = createOutboundWire(targetName, sourceReferenceClass, null);
+ outboundWire.setContainer(sourceComponent);
+ outboundWire.setTargetName(new QualifiedName(targetName + "/" + serviceName));
+ List<OutboundWire> factories = new ArrayList<OutboundWire>();
+ factories.add(outboundWire);
+ sourceComponent.addOutboundWires(factories);
+ targetScope.register(targetComponent);
+ sourceScope.register(sourceComponent);
+ CONNECTOR.connect(outboundWire, inboundWire, false);
+ Map<String, AtomicComponent> components = new HashMap<String, AtomicComponent>();
+ components.put(sourceName, sourceComponent);
+ components.put(targetName, targetComponent);
+ return components;
+ }
+
+ public static <T> InboundWire createInboundWire(String serviceName, Class<T> interfaze)
+ throws InvalidServiceContractException {
+ return createInboundWire(serviceName, interfaze, null);
+ }
+
+ public static <T> InboundWire createInboundWire(String serviceName, Class<T> interfaze, Interceptor interceptor)
+ throws InvalidServiceContractException {
+ InboundWire wire = new InboundWireImpl();
+ ServiceContract<?> contract = REGISTRY.introspect(interfaze);
+ wire.setServiceContract(contract);
+ wire.setServiceName(serviceName);
+ wire.addInvocationChains(createInboundChains(interfaze, interceptor));
+ return wire;
+ }
+
+ public static <T> OutboundWire createOutboundWire(String refName, Class<T> interfaze)
+ throws InvalidServiceContractException {
+ return createOutboundWire(refName, interfaze, null);
+ }
+
+ public static <T> OutboundWire createOutboundWire(String refName, Class<T> interfaze, Interceptor interceptor)
+ throws InvalidServiceContractException {
+
+ OutboundWire wire = new OutboundWireImpl();
+ wire.setReferenceName(refName);
+ Map<Operation<?>, OutboundInvocationChain> outboundChains = createOutboundChains(interfaze, interceptor);
+ wire.addInvocationChains(outboundChains);
+ ServiceContract<?> contract = REGISTRY.introspect(interfaze);
+ wire.setServiceContract(contract);
+ return wire;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ private static <T> JavaAtomicComponent createJavaComponent(String name, ScopeContainer scope, Class<T> clazz)
+ throws NoSuchMethodException {
+ PojoConfiguration configuration = new PojoConfiguration();
+ configuration.setInstanceFactory(new PojoObjectFactory(clazz.getConstructor()));
+ configuration.setWireService(WIRE_SERVICE);
+ configuration.setWorkContext(new WorkContextImpl());
+ configuration.setName(name);
+ JavaAtomicComponent component = new JavaAtomicComponent(configuration);
+ component.setScopeContainer(scope);
+ return component;
+ }
+
+ private static Map<Operation<?>, OutboundInvocationChain> createOutboundChains(Class<?> interfaze,
+ Interceptor interceptor)
+ throws InvalidServiceContractException {
+ Map<Operation<?>, OutboundInvocationChain> invocations = new HashMap<Operation<?>, OutboundInvocationChain>();
+ ServiceContract<?> contract = REGISTRY.introspect(interfaze);
+ for (Operation<?> operation : contract.getOperations().values()) {
+ OutboundInvocationChain chain = new OutboundInvocationChainImpl(operation);
+ if (interceptor != null) {
+ chain.addInterceptor(interceptor);
+ }
+ invocations.put(operation, chain);
+ }
+ return invocations;
+ }
+
+ private static Map<Operation<?>, InboundInvocationChain> createInboundChains(Class<?> interfaze,
+ Interceptor interceptor)
+ throws InvalidServiceContractException {
+
+ Map<Operation<?>, InboundInvocationChain> invocations = new HashMap<Operation<?>, InboundInvocationChain>();
+ ServiceContract<?> contract = REGISTRY.introspect(interfaze);
+ for (Operation<?> method : contract.getOperations().values()) {
+ InboundInvocationChain chain = new InboundInvocationChainImpl(method);
+ if (interceptor != null) {
+ chain.addInterceptor(interceptor);
+ }
+ // add tail interceptor
+ chain.addInterceptor(new InvokerInterceptor());
+ invocations.put(method, chain);
+ }
+ return invocations;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/scope/ScopeReferenceTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/scope/ScopeReferenceTestCase.java
new file mode 100644
index 0000000000..4cd5ac8d9b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/scope/ScopeReferenceTestCase.java
@@ -0,0 +1,781 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.integration.scope;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.TargetException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.component.event.CompositeStart;
+import org.apache.tuscany.core.component.event.CompositeStop;
+import org.apache.tuscany.core.component.event.HttpSessionEnd;
+import org.apache.tuscany.core.component.event.HttpSessionStart;
+import org.apache.tuscany.core.component.event.RequestEnd;
+import org.apache.tuscany.core.component.event.RequestStart;
+import org.apache.tuscany.core.component.scope.CompositeScopeContainer;
+import org.apache.tuscany.core.component.scope.HttpSessionScopeContainer;
+import org.apache.tuscany.core.component.scope.RequestScopeContainer;
+import org.apache.tuscany.core.component.scope.StatelessScopeContainer;
+import org.apache.tuscany.core.integration.mock.MockFactory;
+import org.apache.tuscany.core.mock.component.Source;
+import org.apache.tuscany.core.mock.component.SourceImpl;
+import org.apache.tuscany.core.mock.component.Target;
+import org.apache.tuscany.core.mock.component.TargetImpl;
+import org.apache.tuscany.core.util.JavaIntrospectionHelper;
+
+/**
+ * Tests scoping is properly handled for service references
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScopeReferenceTestCase extends TestCase {
+
+ private Map<String, Member> members;
+
+ /**
+ * Tests a composite-to-composite scoped wire
+ */
+ public void testCompositeToComposite() throws Exception {
+ ScopeContainer scope = new CompositeScopeContainer(null);
+ scope.start();
+
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class,
+ scope, members, "target", Target.class, TargetImpl.class, scope);
+ scope.onEvent(new CompositeStart(this, null));
+ AtomicComponent sourceComponent = contexts.get("source");
+ AtomicComponent targetComponent = contexts.get("target");
+ Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = (Target) targetComponent.getTargetInstance();
+ assertNull(source.getTarget().getString());
+ assertNull(target.getString());
+ target.setString("foo");
+ assertTrue(Proxy.isProxyClass(source.getTarget().getClass()));
+ assertEquals("foo", source.getTarget().getString());
+ scope.onEvent(new CompositeStop(this, null));
+ scope.stop();
+ }
+
+ /**
+ * Tests a composite-to-session scoped wire is setup properly by the runtime
+ */
+ public void testCompositeToSession() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ ScopeContainer compositeScope = new CompositeScopeContainer(null);
+ compositeScope.start();
+ ScopeContainer sessionScope = new HttpSessionScopeContainer(ctx, null);
+ sessionScope.start();
+
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class,
+ compositeScope, members, "target", Target.class, TargetImpl.class, sessionScope);
+ compositeScope.onEvent(new CompositeStart(this, null));
+ Object session1 = new Object();
+ ctx.setIdentifier(Scope.SESSION, session1);
+ sessionScope.onEvent(new HttpSessionStart(this, session1));
+ AtomicComponent sourceComponent = contexts.get("source");
+ AtomicComponent targetComponent = contexts.get("target");
+ Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = (Target) targetComponent.getTargetInstance();
+ assertNull(source.getTarget().getString());
+ assertNull(target.getString());
+ target.setString("foo");
+ assertTrue(Proxy.isProxyClass(source.getTarget().getClass()));
+ assertEquals("foo", source.getTarget().getString());
+ ctx.clearIdentifier(Scope.SESSION);
+ sessionScope.onEvent(new HttpSessionEnd(this, session1));
+
+ //second session
+ Object session2 = new Object();
+ ctx.setIdentifier(Scope.SESSION, session2);
+ sessionScope.onEvent(new HttpSessionStart(this, session2));
+
+ Target target2 = (Target) targetComponent.getTargetInstance();
+ assertFalse("foo".equals(target2.getString()));
+
+ assertFalse("foo".equals(source.getTarget().getString()));
+ source.getTarget().setString("bar");
+ assertEquals("bar", target2.getString());
+ assertEquals("bar", source.getTarget().getString());
+ sessionScope.onEvent(new HttpSessionEnd(this, session2));
+
+ ctx.clearIdentifier(Scope.SESSION);
+ compositeScope.onEvent(new CompositeStop(this, null));
+ sessionScope.stop();
+ compositeScope.stop();
+ }
+
+ /**
+ * Tests a composite-to-request scoped wire
+ */
+ public void testCompositeToRequest() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ ScopeContainer compositeScope = new CompositeScopeContainer(null);
+ compositeScope.start();
+ final ScopeContainer requestScope = new RequestScopeContainer(ctx, null);
+ requestScope.start();
+
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class,
+ compositeScope, members, "target", Target.class, TargetImpl.class, requestScope);
+ compositeScope.onEvent(new CompositeStart(this, null));
+ requestScope.onEvent(new RequestStart(this));
+
+ AtomicComponent sourceComponent = contexts.get("source");
+ final AtomicComponent targetComponent = contexts.get("target");
+ final Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = (Target) targetComponent.getTargetInstance();
+ assertNull(source.getTarget().getString());
+ assertNull(target.getString());
+ target.setString("foo");
+ assertTrue(Proxy.isProxyClass(source.getTarget().getClass()));
+ assertEquals("foo", source.getTarget().getString());
+
+ // spin off another request
+ Executor executor = Executors.newSingleThreadExecutor();
+ FutureTask<Void> future = new FutureTask<Void>(new Runnable() {
+ public void run() {
+ requestScope.onEvent(new RequestStart(this));
+ Target target2 = null;
+ try {
+ target2 = (Target) targetComponent.getTargetInstance();
+ } catch (TargetException e) {
+ fail(e.getMessage());
+ }
+ assertFalse("foo".equals(target2.getString()));
+ assertFalse("foo".equals(source.getTarget().getString()));
+ source.getTarget().setString("bar");
+ assertEquals("bar", target2.getString());
+ assertEquals("bar", source.getTarget().getString());
+ requestScope.onEvent(new RequestEnd(this));
+ }
+ }, null);
+ executor.execute(future);
+ future.get();
+ assertEquals("foo", source.getTarget().getString());
+ requestScope.onEvent(new RequestEnd(this));
+ compositeScope.onEvent(new CompositeStop(this, null));
+ requestScope.stop();
+ compositeScope.stop();
+ }
+
+ /**
+ * Tests a composite-to-stateless scoped wire is setup properly by the runtime
+ */
+ public void testCompositeToStateless() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ ScopeContainer compositeScope = new CompositeScopeContainer(null);
+ compositeScope.start();
+ ScopeContainer statelessScope = new StatelessScopeContainer(ctx, null);
+ statelessScope.start();
+
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class,
+ compositeScope, members, "target", Target.class, TargetImpl.class, statelessScope);
+ compositeScope.onEvent(new CompositeStart(this, null));
+
+ AtomicComponent sourceComponent = contexts.get("source");
+ AtomicComponent targetComponent = contexts.get("target");
+ Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = (Target) targetComponent.getTargetInstance();
+ assertTrue(Proxy.isProxyClass(source.getTarget().getClass()));
+ assertNull(source.getTarget().getString());
+ assertNull(target.getString());
+ target.setString("foo");
+ assertFalse("foo".equals(source.getTarget().getString()));
+ Target target2 = (Target) targetComponent.getTargetInstance();
+ assertFalse("foo".equals(target2.getString()));
+ source.getTarget().setString("bar");
+ assertFalse("bar".equals(source.getTarget().getString()));
+ compositeScope.onEvent(new CompositeStop(this, null));
+ compositeScope.stop();
+ statelessScope.stop();
+ }
+
+
+ /**
+ * Tests a session-to-session scoped wire
+ */
+ public void testSessionToSession() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ ScopeContainer sessionScope = new HttpSessionScopeContainer(ctx, null);
+ sessionScope.start();
+
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class,
+ sessionScope, members, "target", Target.class, TargetImpl.class, sessionScope);
+
+ Object session1 = new Object();
+ ctx.setIdentifier(Scope.SESSION, session1);
+ sessionScope.onEvent(new HttpSessionStart(this, session1));
+ AtomicComponent sourceComponent = contexts.get("source");
+ AtomicComponent targetComponent = contexts.get("target");
+ Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = (Target) targetComponent.getTargetInstance();
+ source.getTarget().setString("foo");
+ source.getTarget().setString("foo");
+ assertEquals("foo", target.getString());
+
+ ctx.clearIdentifier(Scope.SESSION);
+ sessionScope.onEvent(new HttpSessionEnd(this, session1));
+
+ //second session
+ Object session2 = new Object();
+ ctx.setIdentifier(Scope.SESSION, session2);
+ sessionScope.onEvent(new HttpSessionStart(this, session2));
+
+ Source source2 = (Source) sourceComponent.getTargetInstance();
+ assertNotNull(source2);
+ Target target2 = (Target) targetComponent.getTargetInstance();
+
+ assertNotNull(target2);
+ assertNull(target2.getString());
+ assertEquals(null, source2.getTarget().getString());
+ source2.getTarget().setString("baz");
+ assertEquals("baz", source2.getTarget().getString());
+ assertEquals("baz", target2.getString());
+ ctx.clearIdentifier(Scope.SESSION);
+ sessionScope.onEvent(new HttpSessionEnd(this, session2));
+ sessionScope.stop();
+ }
+
+
+ /**
+ * Tests a session-to-composite scoped wire
+ */
+ public void testSessionToComposite() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ ScopeContainer compositeScope = new CompositeScopeContainer(null);
+ compositeScope.start();
+ ScopeContainer sessionScope = new HttpSessionScopeContainer(ctx, null);
+ sessionScope.start();
+
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class,
+ sessionScope, members, "target", Target.class, TargetImpl.class, compositeScope);
+ compositeScope.onEvent(new CompositeStart(this, null));
+ Object session1 = new Object();
+ ctx.setIdentifier(Scope.SESSION, session1);
+ sessionScope.onEvent(new HttpSessionStart(this, session1));
+ AtomicComponent sourceComponent = contexts.get("source");
+ AtomicComponent targetComponent = contexts.get("target");
+ Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = (Target) targetComponent.getTargetInstance();
+ assertNull(source.getTarget().getString());
+ assertNull(target.getString());
+ target.setString("foo");
+ assertTrue(Proxy.isProxyClass(source.getTarget().getClass()));
+ assertEquals("foo", source.getTarget().getString());
+ ctx.clearIdentifier(Scope.SESSION);
+ sessionScope.onEvent(new HttpSessionEnd(this, session1));
+
+ //second session
+ Object session2 = new Object();
+ ctx.setIdentifier(Scope.SESSION, session2);
+ sessionScope.onEvent(new HttpSessionStart(this, session2));
+
+ Target target2 = (Target) targetComponent.getTargetInstance();
+ Source source2 = (Source) sourceComponent.getTargetInstance();
+ assertEquals("foo", target2.getString());
+ assertEquals("foo", source2.getTarget().getString());
+ source2.getTarget().setString("baz");
+ assertEquals("baz", source2.getTarget().getString());
+ assertEquals("baz", target2.getString());
+ assertEquals("baz", target.getString());
+ ctx.clearIdentifier(Scope.SESSION);
+ sessionScope.onEvent(new HttpSessionEnd(this, session2));
+ compositeScope.stop();
+ sessionScope.stop();
+ }
+
+ /**
+ * Tests a session-to-request scoped wire is setup properly by the runtime
+ */
+ public void testSessionToRequest() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ final ScopeContainer requestScope = new RequestScopeContainer(ctx, null);
+ requestScope.start();
+ ScopeContainer sessionScope = new HttpSessionScopeContainer(ctx, null);
+ sessionScope.start();
+
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class,
+ sessionScope, members, "target", Target.class, TargetImpl.class, requestScope);
+ Object session1 = new Object();
+ ctx.setIdentifier(Scope.SESSION, session1);
+ sessionScope.onEvent(new HttpSessionStart(this, session1));
+ requestScope.onEvent(new RequestStart(this));
+ AtomicComponent sourceComponent = contexts.get("source");
+ final AtomicComponent targetComponent = contexts.get("target");
+ final Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = (Target) targetComponent.getTargetInstance();
+ assertNull(source.getTarget().getString());
+ assertNull(target.getString());
+ target.setString("foo");
+ assertTrue(Proxy.isProxyClass(source.getTarget().getClass()));
+ assertEquals("foo", source.getTarget().getString());
+
+ // spin off another request
+ Executor executor = Executors.newSingleThreadExecutor();
+ FutureTask<Void> future = new FutureTask<Void>(new Runnable() {
+ public void run() {
+ requestScope.onEvent(new RequestStart(this));
+ Target target2 = null;
+ try {
+ target2 = (Target) targetComponent.getTargetInstance();
+ } catch (TargetException e) {
+ fail(e.getMessage());
+ }
+ assertFalse("foo".equals(target2.getString()));
+ assertFalse("foo".equals(source.getTarget().getString()));
+ source.getTarget().setString("bar");
+ assertEquals("bar", target2.getString());
+ assertEquals("bar", source.getTarget().getString());
+ requestScope.onEvent(new RequestEnd(this));
+ }
+ }, null);
+ executor.execute(future);
+ future.get();
+ assertEquals("foo", source.getTarget().getString());
+ requestScope.onEvent(new RequestEnd(this));
+ ctx.clearIdentifier(Scope.SESSION);
+ sessionScope.onEvent(new HttpSessionEnd(this, session1));
+ requestScope.stop();
+ sessionScope.stop();
+ }
+
+
+ /**
+ * Tests a session-to-stateless scoped wire is setup properly by the runtime
+ */
+ public void testSessionToStateless() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ ScopeContainer sessionScope = new HttpSessionScopeContainer(ctx, null);
+ sessionScope.start();
+ ScopeContainer statelessScope = new StatelessScopeContainer(ctx, null);
+ statelessScope.start();
+
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class,
+ sessionScope, members, "target", Target.class, TargetImpl.class, statelessScope);
+
+ Object session1 = new Object();
+ ctx.setIdentifier(Scope.SESSION, session1);
+ sessionScope.onEvent(new HttpSessionStart(this, session1));
+
+ AtomicComponent sourceComponent = contexts.get("source");
+ AtomicComponent targetComponent = contexts.get("target");
+ Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = (Target) targetComponent.getTargetInstance();
+ assertTrue(Proxy.isProxyClass(source.getTarget().getClass()));
+ assertNull(source.getTarget().getString());
+ assertNull(target.getString());
+ target.setString("foo");
+ assertFalse("foo".equals(source.getTarget().getString()));
+ Target target2 = (Target) targetComponent.getTargetInstance();
+ assertFalse("foo".equals(target2.getString()));
+ source.getTarget().setString("bar");
+ assertFalse("bar".equals(source.getTarget().getString()));
+
+ ctx.clearIdentifier(Scope.SESSION);
+ sessionScope.onEvent(new HttpSessionEnd(this, session1));
+ sessionScope.stop();
+ statelessScope.stop();
+ }
+
+ /**
+ * Tests a request-to-request scoped wire is setup properly by the runtime
+ */
+ public void testRequestToRequest() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ final ScopeContainer requestScope = new RequestScopeContainer(ctx, null);
+ requestScope.start();
+
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class,
+ requestScope, members, "target", Target.class, TargetImpl.class, requestScope);
+ requestScope.onEvent(new RequestStart(this));
+
+ final AtomicComponent sourceComponent = contexts.get("source");
+ final AtomicComponent targetComponent = contexts.get("target");
+ Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = (Target) targetComponent.getTargetInstance();
+ assertNull(source.getTarget().getString());
+ assertNull(target.getString());
+ target.setString("foo");
+ assertTrue(Proxy.isProxyClass(source.getTarget().getClass()));
+ assertEquals("foo", source.getTarget().getString());
+
+ // spin off another request
+ Executor executor = Executors.newSingleThreadExecutor();
+ FutureTask<Void> future = new FutureTask<Void>(new Runnable() {
+ public void run() {
+ requestScope.onEvent(new RequestStart(this));
+ Source source2 = null;
+ Target target2 = null;
+ try {
+ source2 = (Source) sourceComponent.getTargetInstance();
+ target2 = (Target) targetComponent.getTargetInstance();
+ } catch (TargetException e) {
+ fail(e.getMessage());
+ }
+ assertFalse("foo".equals(target2.getString()));
+ assertFalse("foo".equals(source2.getTarget().getString()));
+ source2.getTarget().setString("bar");
+ assertEquals("bar", target2.getString());
+ assertEquals("bar", source2.getTarget().getString());
+ requestScope.onEvent(new RequestEnd(this));
+ }
+ }, null);
+ executor.execute(future);
+ future.get();
+ requestScope.onEvent(new RequestEnd(this));
+ requestScope.stop();
+ }
+
+ /**
+ * Tests a request-to-composite scoped wire
+ */
+ public void testRequestToComposite() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ final ScopeContainer requestScope = new RequestScopeContainer(ctx, null);
+ final ScopeContainer compositeScope = new CompositeScopeContainer(null);
+ requestScope.start();
+ compositeScope.start();
+ compositeScope.onEvent(new CompositeStart(this, null));
+
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class,
+ requestScope, members, "target", Target.class, TargetImpl.class, compositeScope);
+ requestScope.onEvent(new RequestStart(this));
+
+ final AtomicComponent sourceComponent = contexts.get("source");
+ final AtomicComponent targetComponent = contexts.get("target");
+ Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = (Target) targetComponent.getTargetInstance();
+ assertNull(source.getTarget().getString());
+ assertNull(target.getString());
+ target.setString("foo");
+ assertTrue(Proxy.isProxyClass(source.getTarget().getClass()));
+ assertEquals("foo", source.getTarget().getString());
+
+ // spin off another request
+ Executor executor = Executors.newSingleThreadExecutor();
+ FutureTask<Void> future = new FutureTask<Void>(new Runnable() {
+ public void run() {
+ requestScope.onEvent(new RequestStart(this));
+ Source source2 = null;
+ Target target2 = null;
+ try {
+ source2 = (Source) sourceComponent.getTargetInstance();
+ target2 = (Target) targetComponent.getTargetInstance();
+ } catch (TargetException e) {
+ fail(e.getMessage());
+ }
+ assertEquals("foo", target2.getString());
+ assertEquals("foo", source2.getTarget().getString());
+ source2.getTarget().setString("bar");
+ assertEquals("bar", target2.getString());
+ assertEquals("bar", source2.getTarget().getString());
+ requestScope.onEvent(new RequestEnd(this));
+ }
+ }, null);
+ executor.execute(future);
+ future.get();
+ assertEquals("bar", target.getString());
+
+ requestScope.onEvent(new RequestEnd(this));
+ requestScope.stop();
+ compositeScope.onEvent(new CompositeStop(this, null));
+ compositeScope.stop();
+ }
+
+ /**
+ * Tests a request-to-session scoped wire is setup properly by the runtime
+ */
+ public void testRequestToSession() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ final ScopeContainer requestScope = new RequestScopeContainer(ctx, null);
+ final ScopeContainer sessionScope = new HttpSessionScopeContainer(ctx, null);
+ requestScope.start();
+ sessionScope.start();
+
+ Object session1 = new Object();
+ ctx.setIdentifier(Scope.SESSION, session1);
+ sessionScope.onEvent(new HttpSessionStart(this, session1));
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class,
+ requestScope, members, "target", Target.class, TargetImpl.class, sessionScope);
+
+ final AtomicComponent sourceComponent = contexts.get("source");
+ final AtomicComponent targetComponent = contexts.get("target");
+ requestScope.onEvent(new RequestStart(this));
+ Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = (Target) targetComponent.getTargetInstance();
+ assertNull(source.getTarget().getString());
+ assertNull(target.getString());
+ target.setString("foo");
+ assertTrue(Proxy.isProxyClass(source.getTarget().getClass()));
+ assertEquals("foo", source.getTarget().getString());
+
+ // spin off another request
+ Executor executor = Executors.newSingleThreadExecutor();
+ FutureTask<Void> future = new FutureTask<Void>(new Runnable() {
+ public void run() {
+ requestScope.onEvent(new RequestStart(this));
+ Source source2 = null;
+ Target target2 = null;
+ try {
+ source2 = (Source) sourceComponent.getTargetInstance();
+ target2 = (Target) targetComponent.getTargetInstance();
+ } catch (TargetException e) {
+ fail(e.getMessage());
+ }
+ assertEquals("foo", target2.getString());
+ assertEquals("foo", source2.getTarget().getString());
+ source2.getTarget().setString("bar");
+ assertEquals("bar", target2.getString());
+ assertEquals("bar", source2.getTarget().getString());
+ requestScope.onEvent(new RequestEnd(this));
+ }
+ }, null);
+ executor.execute(future);
+ future.get();
+ assertEquals("bar", target.getString());
+
+ requestScope.onEvent(new RequestEnd(this));
+ requestScope.stop();
+ ctx.clearIdentifier(Scope.SESSION);
+ sessionScope.onEvent(new HttpSessionEnd(this, session1));
+ sessionScope.stop();
+ }
+
+
+ /**
+ * Tests a request-to-stateless scoped wire is setup properly by the runtime
+ */
+ public void testRequestToStateless() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ ScopeContainer requestScope = new RequestScopeContainer(ctx, null);
+ requestScope.start();
+ ScopeContainer statelessScope = new StatelessScopeContainer(ctx, null);
+ statelessScope.start();
+
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class,
+ requestScope, members, "target", Target.class, TargetImpl.class, statelessScope);
+
+ AtomicComponent sourceComponent = contexts.get("source");
+ AtomicComponent targetComponent = contexts.get("target");
+ requestScope.onEvent(new RequestStart(this));
+ Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = (Target) targetComponent.getTargetInstance();
+ assertTrue(Proxy.isProxyClass(source.getTarget().getClass()));
+ assertNull(source.getTarget().getString());
+ assertNull(target.getString());
+ target.setString("foo");
+ assertFalse("foo".equals(source.getTarget().getString()));
+ Target target2 = (Target) targetComponent.getTargetInstance();
+ assertFalse("foo".equals(target2.getString()));
+ source.getTarget().setString("bar");
+ assertFalse("bar".equals(source.getTarget().getString()));
+ requestScope.onEvent(new RequestEnd(this));
+ requestScope.stop();
+ statelessScope.stop();
+ }
+
+
+ /**
+ * Tests a stateless-to-stateless scoped wire is setup properly by the runtime
+ */
+ public void testStatelessToStateless() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ ScopeContainer statelessScope = new StatelessScopeContainer(ctx, null);
+ statelessScope.start();
+
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class,
+ statelessScope, members, "target", Target.class, TargetImpl.class, statelessScope);
+
+ AtomicComponent sourceComponent = contexts.get("source");
+ AtomicComponent targetComponent = contexts.get("target");
+ Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = (Target) targetComponent.getTargetInstance();
+ assertTrue(Proxy.isProxyClass(source.getTarget().getClass()));
+ assertNull(source.getTarget().getString());
+ assertNull(target.getString());
+ target.setString("foo");
+ assertFalse("foo".equals(source.getTarget().getString()));
+ Target target2 = (Target) targetComponent.getTargetInstance();
+ assertFalse("foo".equals(target2.getString()));
+ source.getTarget().setString("bar");
+ assertFalse("bar".equals(source.getTarget().getString()));
+ statelessScope.stop();
+ }
+
+ /**
+ * Tests a stateless-to-request scoped wire is setup properly by the runtime
+ */
+ public void testStatelessToRequest() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ final ScopeContainer requestScope = new RequestScopeContainer(ctx, null);
+ requestScope.start();
+ ScopeContainer statelessScope = new StatelessScopeContainer(ctx, null);
+ statelessScope.start();
+
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class,
+ statelessScope, members, "target", Target.class, TargetImpl.class, requestScope);
+ requestScope.onEvent(new RequestStart(this));
+ AtomicComponent sourceComponent = contexts.get("source");
+ final AtomicComponent targetComponent = contexts.get("target");
+ final Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = (Target) targetComponent.getTargetInstance();
+ assertNull(source.getTarget().getString());
+ assertNull(target.getString());
+ target.setString("foo");
+ assertTrue(Proxy.isProxyClass(source.getTarget().getClass()));
+ assertEquals("foo", source.getTarget().getString());
+
+ // spin off another request
+ Executor executor = Executors.newSingleThreadExecutor();
+ FutureTask<Void> future = new FutureTask<Void>(new Runnable() {
+ public void run() {
+ requestScope.onEvent(new RequestStart(this));
+ Target target2 = null;
+ try {
+ target2 = (Target) targetComponent.getTargetInstance();
+ } catch (TargetException e) {
+ fail(e.getMessage());
+ }
+ assertFalse("foo".equals(target2.getString()));
+ assertFalse("foo".equals(source.getTarget().getString()));
+ source.getTarget().setString("bar");
+ assertEquals("bar", target2.getString());
+ assertEquals("bar", source.getTarget().getString());
+ requestScope.onEvent(new RequestEnd(this));
+ }
+ }, null);
+ executor.execute(future);
+ future.get();
+ requestScope.stop();
+ statelessScope.stop();
+ }
+
+ /**
+ * Tests a stateless-to-session scoped wire is setup properly by the runtime
+ */
+ public void testStatelessToSession() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ ScopeContainer statelessScope = new StatelessScopeContainer(ctx, null);
+ statelessScope.start();
+ ScopeContainer sessionScope = new HttpSessionScopeContainer(ctx, null);
+ sessionScope.start();
+
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class,
+ statelessScope, members, "target", Target.class, TargetImpl.class, sessionScope);
+ Object session1 = new Object();
+ ctx.setIdentifier(Scope.SESSION, session1);
+ sessionScope.onEvent(new HttpSessionStart(this, session1));
+ AtomicComponent sourceComponent = contexts.get("source");
+ AtomicComponent targetComponent = contexts.get("target");
+ Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = (Target) targetComponent.getTargetInstance();
+ assertNull(source.getTarget().getString());
+ assertNull(target.getString());
+ target.setString("foo");
+ assertTrue(Proxy.isProxyClass(source.getTarget().getClass()));
+ assertEquals("foo", source.getTarget().getString());
+ ctx.clearIdentifier(Scope.SESSION);
+ sessionScope.onEvent(new HttpSessionEnd(this, session1));
+
+ //second session
+ Object session2 = new Object();
+ ctx.setIdentifier(Scope.SESSION, session2);
+ sessionScope.onEvent(new HttpSessionStart(this, session2));
+
+ Target target2 = (Target) targetComponent.getTargetInstance();
+ assertFalse("foo".equals(target2.getString()));
+
+ assertFalse("foo".equals(source.getTarget().getString()));
+ source.getTarget().setString("bar");
+ assertEquals("bar", target2.getString());
+ assertEquals("bar", source.getTarget().getString());
+ sessionScope.onEvent(new HttpSessionEnd(this, session2));
+
+ ctx.clearIdentifier(Scope.SESSION);
+ sessionScope.stop();
+ statelessScope.stop();
+ }
+
+
+ /**
+ * Tests a stateless-to-composite scoped wire is setup properly by the runtime
+ */
+ public void testStatelessToComposite() throws Exception {
+ WorkContext ctx = new WorkContextImpl();
+ ScopeContainer statelessScope = new StatelessScopeContainer(ctx, null);
+ statelessScope.start();
+ ScopeContainer compositeScope = new CompositeScopeContainer(null);
+ compositeScope.start();
+
+ Map<String, AtomicComponent> contexts = MockFactory.createWiredComponents("source", SourceImpl.class,
+ statelessScope, members, "target", Target.class, TargetImpl.class, compositeScope);
+ compositeScope.onEvent(new CompositeStart(this, null));
+ AtomicComponent sourceComponent = contexts.get("source");
+ AtomicComponent targetComponent = contexts.get("target");
+ Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = (Target) targetComponent.getTargetInstance();
+ assertNull(source.getTarget().getString());
+ assertNull(target.getString());
+ target.setString("foo");
+ assertTrue(Proxy.isProxyClass(source.getTarget().getClass()));
+ assertEquals("foo", source.getTarget().getString());
+
+ //second session
+ Object session2 = new Object();
+ ctx.setIdentifier(Scope.SESSION, session2);
+ compositeScope.onEvent(new HttpSessionStart(this, session2));
+
+ Target target2 = (Target) targetComponent.getTargetInstance();
+ assertEquals("foo", target2.getString());
+
+ assertEquals("foo", source.getTarget().getString());
+ source.getTarget().setString("bar");
+ assertEquals("bar", target2.getString());
+ assertEquals("bar", source.getTarget().getString());
+
+ compositeScope.onEvent(new CompositeStop(this, null));
+ compositeScope.stop();
+ statelessScope.stop();
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ members = new HashMap<String, Member>();
+ Method[] methods = SourceImpl.class.getMethods();
+ for (Method method : methods) {
+ if (method.getName().startsWith("set")) {
+ members.put(JavaIntrospectionHelper.toPropertyName(method.getName()), method);
+ }
+ }
+ }
+
+
+}
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/wire/DifferentInterfaceWireTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/wire/DifferentInterfaceWireTestCase.java
new file mode 100644
index 0000000000..431f47b5bf
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/wire/DifferentInterfaceWireTestCase.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.integration.wire;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.TargetException;
+import org.apache.tuscany.spi.model.Scope;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.integration.mock.MockFactory;
+import org.apache.tuscany.core.mock.component.OtherTarget;
+import org.apache.tuscany.core.mock.component.OtherTargetImpl;
+import org.apache.tuscany.core.mock.component.Target;
+import org.apache.tuscany.core.mock.component.SourceImpl;
+import org.apache.tuscany.core.mock.component.Source;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+
+
+/**
+ * Tests wires that have different interfaces on the source and target side
+ *
+ * @version $Rev$ $Date$
+ */
+public class DifferentInterfaceWireTestCase extends TestCase {
+
+ public void testDifferentInterfaceInjection() throws Exception {
+ Map<String, Member> members = new HashMap<String, Member>();
+ Method m = SourceImpl.class.getMethod("setTarget", Target.class);
+ members.put("target", m);
+ ScopeContainer scope = createMock();
+ scope.start();
+ Map<String, AtomicComponent> contexts =
+ MockFactory.createWiredComponents("source",
+ SourceImpl.class,
+ Target.class,
+ scope,
+ null,
+ members,
+ "target",
+ OtherTarget.class,
+ OtherTargetImpl.class,
+ scope,
+ null);
+ AtomicComponent sourceComponent = contexts.get("source");
+ Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = source.getTarget();
+ assertTrue(Proxy.isProxyClass(target.getClass()));
+ assertNotNull(target);
+ scope.stop();
+ EasyMock.verify(scope);
+ }
+
+ public void testDifferentInterfaceMultiplicityInjection() throws Exception {
+ Map<String, Member> members = new HashMap<String, Member>();
+ Method m = SourceImpl.class.getMethod("setTargets", List.class);
+ members.put("target", m);
+ ScopeContainer scope = createMock();
+ scope.start();
+ Map<String, AtomicComponent> components = MockFactory.createWiredMultiplicity("source",
+ SourceImpl.class,
+ Target.class,
+ scope,
+ "target",
+ OtherTarget.class,
+ OtherTargetImpl.class,
+ members,
+ scope);
+ AtomicComponent sourceComponent = components.get("source");
+ Source source = (Source) sourceComponent.getTargetInstance();
+ List<Target> targets = source.getTargets();
+ assertEquals(1, targets.size());
+ Target target = targets.get(0);
+ target.setString("foo");
+ assertEquals("foo", target.getString());
+ assertTrue(Proxy.isProxyClass(target.getClass()));
+ scope.stop();
+ EasyMock.verify(scope);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ private ScopeContainer createMock() throws TargetException {
+ ScopeContainer scope = EasyMock.createMock(ScopeContainer.class);
+ scope.start();
+ scope.stop();
+ scope.register(EasyMock.isA(AtomicComponent.class));
+ EasyMock.expectLastCall().atLeastOnce();
+ EasyMock.expect(scope.getScope()).andReturn(Scope.COMPOSITE).atLeastOnce();
+ scope.getInstance(EasyMock.isA(AtomicComponent.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ private Map<AtomicComponent, Object> cache = new HashMap<AtomicComponent, Object>();
+
+ public Object answer() throws Throwable {
+ AtomicComponent component = (AtomicComponent) EasyMock.getCurrentArguments()[0];
+ Object instance = cache.get(component);
+ if (instance == null) {
+ instance = component.createInstance();
+ cache.put(component, instance);
+ }
+ return instance;
+ }
+ }).anyTimes();
+ EasyMock.replay(scope);
+ return scope;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/wire/ReferenceInjectionTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/wire/ReferenceInjectionTestCase.java
new file mode 100644
index 0000000000..603e334fe9
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/wire/ReferenceInjectionTestCase.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.integration.wire;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ScopeContainer;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.scope.CompositeScopeContainer;
+import org.apache.tuscany.core.integration.mock.MockFactory;
+import org.apache.tuscany.core.mock.component.Source;
+import org.apache.tuscany.core.mock.component.SourceImpl;
+import org.apache.tuscany.core.mock.component.TargetImpl;
+import org.apache.tuscany.core.mock.component.Target;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public class ReferenceInjectionTestCase extends TestCase {
+
+ private Map<String, Member> members;
+
+ public void testProxiedReferenceInjection() throws Exception {
+ ScopeContainer scope = new CompositeScopeContainer(null);
+ scope.start();
+ Map<String, AtomicComponent> components =
+ MockFactory.createWiredComponents("source", SourceImpl.class, scope,
+ members, "target", Target.class, TargetImpl.class, scope);
+ AtomicComponent sourceComponent = components.get("source");
+ Source source = (Source) sourceComponent.getTargetInstance();
+ Target target = source.getTarget();
+ assertTrue(Proxy.isProxyClass(target.getClass()));
+
+ assertNotNull(target);
+ scope.stop();
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ members = new HashMap<String, Member>();
+ Method m = SourceImpl.class.getMethod("setTarget", Target.class);
+ members.put("target", m);
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/wire/oneway/OneWayWireToJavaInvocationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/wire/oneway/OneWayWireToJavaInvocationTestCase.java
new file mode 100644
index 0000000000..78e349b788
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/integration/wire/oneway/OneWayWireToJavaInvocationTestCase.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.integration.wire.oneway;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.concurrent.CountDownLatch;
+
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.extension.ExecutionMonitor;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.services.work.WorkScheduler;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.implementation.java.JavaAtomicComponent;
+import org.apache.tuscany.core.implementation.java.JavaTargetInvoker;
+import org.apache.tuscany.core.services.work.jsr237.Jsr237WorkScheduler;
+import org.apache.tuscany.core.services.work.jsr237.workmanager.ThreadPoolWorkManager;
+import org.apache.tuscany.core.wire.InboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.InvokerInterceptor;
+import org.apache.tuscany.core.wire.NonBlockingBridgingInterceptor;
+import org.apache.tuscany.core.wire.OutboundInvocationChainImpl;
+import org.easymock.classextension.EasyMock;
+
+/**
+ * Verifies non-blocking invocations are properly made through a wire to a Java component
+ *
+ * @version $Rev$ $Date$
+ */
+public class OneWayWireToJavaInvocationTestCase extends TestCase {
+ private WorkScheduler scheduler;
+ private WorkContext context;
+ private CountDownLatch latch;
+ private OutboundInvocationChain ochain;
+ private JavaTargetInvoker invoker;
+ private JavaAtomicComponent component;
+ private AsyncTarget target;
+
+ public void testOneWay() throws Exception {
+ MessageImpl msg = new MessageImpl();
+ msg.setTargetInvoker(invoker);
+ ochain.getHeadInterceptor().invoke(msg);
+ latch.await();
+ EasyMock.verify(target);
+ EasyMock.verify(component);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ latch = new CountDownLatch(1);
+ context = new WorkContextImpl();
+ scheduler = new Jsr237WorkScheduler(new ThreadPoolWorkManager(1));
+ target = EasyMock.createMock(AsyncTarget.class);
+ target.invoke();
+ EasyMock.expectLastCall().once();
+ EasyMock.replay(target);
+ component = EasyMock.createMock(JavaAtomicComponent.class);
+ EasyMock.expect(component.getScope()).andReturn(Scope.COMPOSITE);
+ EasyMock.expect(component.getTargetInstance()).andReturn(target);
+ EasyMock.replay(component);
+ Method method = AsyncTarget.class.getMethod("invoke");
+ method.setAccessible(true);
+ InboundWire inboundWire = EasyMock.createMock(InboundWire.class);
+ ExecutionMonitor monitor = EasyMock.createNiceMock(ExecutionMonitor.class);
+ invoker = new JavaTargetInvoker(method, component, inboundWire, context, monitor);
+ Operation<Type> operation = new Operation<Type>("invoke", null, null, null, false, null, TargetInvoker.NONE);
+ ochain = new OutboundInvocationChainImpl(operation);
+ NonBlockingBridgingInterceptor bridgeInterceptor = new NonBlockingBridgingInterceptor(scheduler, context);
+ ochain.addInterceptor(bridgeInterceptor);
+ InboundInvocationChain ichain = new InboundInvocationChainImpl(operation);
+ WaitInterceptor waitInterceptor = new WaitInterceptor();
+ InvokerInterceptor invokerInterceptor = new InvokerInterceptor();
+ ichain.addInterceptor(waitInterceptor);
+ ichain.addInterceptor(invokerInterceptor);
+ bridgeInterceptor.setNext(waitInterceptor);
+ ochain.setTargetInvoker(invoker);
+ }
+
+ public interface AsyncTarget {
+ void invoke();
+ }
+
+
+ private class WaitInterceptor implements Interceptor {
+ private Interceptor next;
+
+ public Message invoke(Message msg) {
+ msg = next.invoke(msg);
+ latch.countDown();
+ return msg;
+ }
+
+ public Interceptor getNext() {
+ return next;
+ }
+
+ public void setNext(Interceptor next) {
+ this.next = next;
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderNoBindingTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderNoBindingTestCase.java
new file mode 100644
index 0000000000..3f6df22677
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderNoBindingTestCase.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamReader;
+
+import static org.osoa.sca.Constants.SCA_NS;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.Implementation;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.java.JavaImplementation;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ComponentLoaderNoBindingTestCase extends TestCase {
+ private static final QName COMPONENT = new QName(SCA_NS, "component");
+ private ComponentLoader loader;
+ private XMLStreamReader reader;
+ private ServiceDefinition service;
+ private ComponentTypeReferenceDefinition reference;
+
+ public void testNoServiceBinding() throws Exception {
+ loader.load(null, null, reader, null);
+ assert service.getBindings().isEmpty();
+ }
+
+ public void testNoReferenceBinding() throws Exception {
+ loader.load(null, null, reader, null);
+ assert reference.getBindings().isEmpty();
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ service = new ServiceDefinition();
+ reference = new ComponentTypeReferenceDefinition();
+ PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> type =
+ new PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ type.add(service);
+ type.add(reference);
+ JavaImplementation impl = new JavaImplementation(null, type);
+ LoaderRegistry registry = EasyMock.createMock(LoaderRegistry.class);
+ EasyMock.expect(registry.load((CompositeComponent) EasyMock.isNull(),
+ (ModelObject) EasyMock.isNull(),
+ EasyMock.isA(XMLStreamReader.class),
+ (DeploymentContext) EasyMock.isNull())).andReturn(impl);
+ registry.loadComponentType((CompositeComponent) EasyMock.isNull(),
+ EasyMock.isA(Implementation.class),
+ (DeploymentContext) EasyMock.isNull());
+ EasyMock.replay(registry);
+ loader = new ComponentLoader(registry, null);
+ reader = EasyMock.createMock(XMLStreamReader.class);
+ EasyMock.expect(reader.getName()).andReturn(COMPONENT).atLeastOnce();
+ EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT);
+ EasyMock.expect(reader.getAttributeValue(null, "name")).andReturn("foo");
+ EasyMock.expect(reader.getAttributeValue(null, "autowire")).andReturn("false");
+ EasyMock.expect(reader.getAttributeValue(null, "initLevel")).andReturn("0");
+ EasyMock.expect(reader.nextTag()).andReturn(1);
+ EasyMock.replay(reader);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderPropertyTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderPropertyTestCase.java
new file mode 100644
index 0000000000..5034e5114a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderPropertyTestCase.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import javax.xml.stream.XMLStreamException;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.implementation.java.JavaImplementation;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.MissingPropertyValueException;
+import org.apache.tuscany.spi.loader.PropertyObjectFactory;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.Implementation;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ComponentLoaderPropertyTestCase extends TestCase {
+
+ private TestLoader loader;
+
+ /**
+ * Verifies that an optional property not cofigured in an assembly will avoid having a PropertyValue created for it
+ * so that the runtime does not erroneously inject null values
+ */
+ public void testMissingPropertyValueException() throws LoaderException, XMLStreamException {
+ PojoComponentType<?, ?, Property<?>> type =
+ new PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ Property property = new Property();
+ property.setName("name");
+ property.setMustSupply(true);
+ type.add(property);
+
+ JavaImplementation impl = new JavaImplementation(null, type);
+ impl.setComponentType(type);
+ ComponentDefinition<Implementation<?>> defn = new ComponentDefinition<Implementation<?>>(impl);
+ assertTrue(defn.getPropertyValues().isEmpty());
+ try {
+ loader.populatePropertyValues(defn);
+ fail();
+ } catch (Exception e) {
+ assertTrue(e instanceof MissingPropertyValueException);
+ }
+
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ LoaderRegistry mockRegistry = EasyMock.createMock(LoaderRegistry.class);
+ PropertyObjectFactory mockPropertyFactory = EasyMock.createMock(PropertyObjectFactory.class);
+ loader = new TestLoader(mockRegistry, mockPropertyFactory);
+ }
+
+ private class TestLoader extends ComponentLoader {
+
+ public TestLoader(LoaderRegistry registry, PropertyObjectFactory propertyFactory) {
+ super(registry, propertyFactory);
+ }
+
+ @Override
+ public void populatePropertyValues(ComponentDefinition<Implementation<?>> componentDefinition)
+ throws MissingPropertyValueException, LoaderException {
+ super.populatePropertyValues(componentDefinition);
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderReferenceTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderReferenceTestCase.java
new file mode 100644
index 0000000000..3d73e53883
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderReferenceTestCase.java
@@ -0,0 +1,87 @@
+package org.apache.tuscany.core.loader;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import static org.osoa.sca.Constants.SCA_NS;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.UndefinedReferenceException;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.Implementation;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.java.JavaImplementation;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.isNull;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ComponentLoaderReferenceTestCase extends TestCase {
+ private static final QName COMPONENT = new QName(SCA_NS, "component");
+ private static final QName REFERENCE = new QName(SCA_NS, "reference");
+ private static final String NAME = "testComponent";
+ private ComponentLoader loader;
+ private XMLStreamReader reader;
+
+ /**
+ * Verifies an error is thrown when an attempt to configure a non-existent reference in SCDL is made
+ */
+ public void testNoReferenceOnComponentType() throws LoaderException, XMLStreamException {
+ try {
+ loader.load(null, null, reader, null);
+ fail();
+ } catch (UndefinedReferenceException e) {
+ // expected
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> type =
+ new PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ JavaImplementation impl = new JavaImplementation(null, type);
+ reader = EasyMock.createMock(XMLStreamReader.class);
+ EasyMock.expect(reader.getName()).andReturn(COMPONENT);
+ EasyMock.expect(reader.getAttributeValue((String) EasyMock.isNull(), EasyMock.isA(String.class)))
+ .andReturn(NAME);
+ EasyMock.expect(reader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("initLevel")))
+ .andReturn(null);
+ EasyMock.expect(reader.getAttributeValue((String) isNull(), EasyMock.eq("autowire")))
+ .andReturn("false");
+ EasyMock.expect(reader.getAttributeValue(EasyMock.isA(String.class), EasyMock.isA(String.class)))
+ .andReturn(null);
+ EasyMock.expect(reader.nextTag()).andReturn(0);
+ EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.START_ELEMENT);
+ EasyMock.expect(reader.getName()).andReturn(REFERENCE);
+ EasyMock.expect(reader.getAttributeValue((String) isNull(), EasyMock.eq("name")))
+ .andReturn("noreference");
+ EasyMock.expect(reader.getElementText()).andReturn("text");
+
+ EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT);
+ EasyMock.replay(reader);
+ LoaderRegistry mockRegistry = EasyMock.createMock(LoaderRegistry.class);
+ mockRegistry.loadComponentType((CompositeComponent) isNull(),
+ EasyMock.isA(Implementation.class),
+ (DeploymentContext) isNull());
+ EasyMock.expect(mockRegistry.load((CompositeComponent) isNull(),
+ (ModelObject) isNull(),
+ EasyMock.isA(XMLStreamReader.class),
+ (DeploymentContext) isNull())).andReturn(impl);
+ EasyMock.replay(mockRegistry);
+ loader = new ComponentLoader(mockRegistry, null);
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderTestCase.java
new file mode 100644
index 0000000000..f4421941fa
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderTestCase.java
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import static org.osoa.sca.Constants.SCA_NS;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.PropertyObjectFactory;
+import org.apache.tuscany.spi.loader.UnrecognizedElementException;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.Implementation;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.java.JavaImplementation;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isNull;
+import static org.easymock.EasyMock.replay;
+import org.easymock.IAnswer;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ComponentLoaderTestCase extends TestCase {
+ private static final QName COMPONENT = new QName(SCA_NS, "component");
+ private static final String NAME = "testComponent";
+ private JavaImplementation impl;
+
+ private XMLStreamReader mockReader;
+ private LoaderRegistry mockRegistry;
+ private PropertyObjectFactory mockPropertyFactory;
+ private ComponentLoader loader;
+
+ public void testEmptyComponent() throws LoaderException, XMLStreamException {
+ EasyMock.expect(mockReader.getName()).andReturn(COMPONENT).atLeastOnce();
+ EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.isA(String.class)))
+ .andReturn(NAME);
+ EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("initLevel")))
+ .andReturn(null);
+ EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("autowire")))
+ .andReturn("false");
+ EasyMock.expect(mockReader.getAttributeValue(EasyMock.isA(String.class), EasyMock.isA(String.class)))
+ .andReturn(null);
+ EasyMock.expect(mockReader.nextTag()).andReturn(0);
+ EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.END_ELEMENT);
+ EasyMock.replay(mockReader);
+ mockRegistry.loadComponentType(EasyMock.isA(CompositeComponent.class),
+ EasyMock.isA(Implementation.class),
+ EasyMock.isA(DeploymentContext.class));
+ EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ @SuppressWarnings("unchecked")
+ public Object answer() throws Throwable {
+ Implementation impl = (Implementation) EasyMock.getCurrentArguments()[1];
+ impl.setComponentType(new PojoComponentType());
+ return impl;
+ }
+ });
+
+ EasyMock.expect(mockRegistry.load(EasyMock.isA(CompositeComponent.class),
+ (ModelObject) isNull(),
+ EasyMock.eq(mockReader),
+ EasyMock.isA(DeploymentContext.class))).andReturn(impl);
+ EasyMock.replay(mockRegistry);
+ ComponentDefinition component = loader.load(EasyMock.createNiceMock(CompositeComponent.class),
+ null, mockReader,
+ EasyMock.createNiceMock(DeploymentContext.class));
+ assertEquals(NAME, component.getName());
+ assertNull(component.getInitLevel());
+ }
+
+ public void testInitValue20() throws LoaderException, XMLStreamException {
+ EasyMock.expect(mockReader.getName()).andReturn(COMPONENT).atLeastOnce();
+ EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.isA(String.class)))
+ .andReturn(NAME);
+ EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("initLevel")))
+ .andReturn("20");
+ EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("autowire")))
+ .andReturn("false");
+ EasyMock.expect(mockReader.nextTag()).andReturn(0);
+ EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.END_ELEMENT);
+ EasyMock.replay(mockReader);
+
+ mockRegistry.loadComponentType(EasyMock.isA(CompositeComponent.class),
+ EasyMock.isA(Implementation.class),
+ EasyMock.isA(DeploymentContext.class));
+
+ EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ @SuppressWarnings("unchecked")
+ public Object answer() throws Throwable {
+ Implementation impl = (Implementation) EasyMock.getCurrentArguments()[1];
+ impl.setComponentType(new PojoComponentType());
+ return impl;
+ }
+ });
+ EasyMock.expect(mockRegistry.load(EasyMock.isA(CompositeComponent.class),
+ (ModelObject) isNull(),
+ EasyMock.eq(mockReader),
+ EasyMock.isA(DeploymentContext.class))).andReturn(impl);
+ EasyMock.replay(mockRegistry);
+ ComponentDefinition component = loader.load(EasyMock.createNiceMock(CompositeComponent.class),
+ null, mockReader,
+ EasyMock.createNiceMock(DeploymentContext.class));
+ assertEquals(NAME, component.getName());
+ assertEquals(Integer.valueOf(20), component.getInitLevel());
+ }
+
+ public void testLoadPropertyWithSource() throws LoaderException, XMLStreamException {
+ PojoComponentType<?, ?, Property<?>> type =
+ new PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ Property property = new Property();
+ property.setName("name");
+ type.add(property);
+ JavaImplementation impl = new JavaImplementation();
+ impl.setComponentType(type);
+ ComponentDefinition<?> defn = new ComponentDefinition<JavaImplementation>(impl);
+ XMLStreamReader reader = createMock(XMLStreamReader.class);
+ expect(reader.getAttributeValue(null, "name")).andReturn("name");
+ expect(reader.getAttributeValue(null, "source")).andReturn("$source");
+ expect(reader.getAttributeValue(null, "type")).andReturn(null).anyTimes();
+ expect(reader.getAttributeValue(null, "element")).andReturn(null).anyTimes();
+ expect(reader.getAttributeValue(null, "file")).andReturn(null);
+ expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT);
+ replay(reader);
+ loader.loadProperty(reader, null, defn);
+ assertEquals("$source", defn.getPropertyValues().get("name").getSource());
+ EasyMock.verify(reader);
+ }
+
+ public void testUnrecognizedElement() throws LoaderException, XMLStreamException {
+ EasyMock.expect(mockReader.getName()).andReturn(COMPONENT);
+ EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.isA(String.class)))
+ .andReturn(NAME);
+ EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("initLevel")))
+ .andReturn(null);
+ EasyMock.expect(mockReader.getAttributeValue((String) EasyMock.isNull(), EasyMock.eq("autowire")))
+ .andReturn("false");
+ EasyMock.expect(mockReader.getAttributeValue(EasyMock.isA(String.class), EasyMock.isA(String.class)))
+ .andReturn(null);
+ EasyMock.expect(mockReader.nextTag()).andReturn(0);
+ EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.START_ELEMENT);
+ EasyMock.expect(mockReader.getName()).andReturn(new QName("foo", "bar"));
+ EasyMock.replay(mockReader);
+ mockRegistry.loadComponentType(EasyMock.isA(CompositeComponent.class),
+ EasyMock.isA(Implementation.class),
+ EasyMock.isA(DeploymentContext.class));
+
+ EasyMock.expect(mockRegistry.load(EasyMock.isA(CompositeComponent.class),
+ (ModelObject) isNull(),
+ EasyMock.eq(mockReader),
+ EasyMock.isA(DeploymentContext.class))).andReturn(impl);
+ EasyMock.replay(mockRegistry);
+ try {
+ loader.load(EasyMock.createNiceMock(CompositeComponent.class),
+ null, mockReader,
+ EasyMock.createNiceMock(DeploymentContext.class));
+ fail();
+ } catch (UnrecognizedElementException e) {
+ // expected
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ impl = new JavaImplementation();
+ mockReader = EasyMock.createMock(XMLStreamReader.class);
+ mockRegistry = EasyMock.createMock(LoaderRegistry.class);
+ mockPropertyFactory = EasyMock.createMock(PropertyObjectFactory.class);
+ loader = new ComponentLoader(mockRegistry, mockPropertyFactory);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderValidationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderValidationTestCase.java
new file mode 100644
index 0000000000..9c5ce0655c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentLoaderValidationTestCase.java
@@ -0,0 +1,170 @@
+package org.apache.tuscany.core.loader;
+
+import java.net.URI;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.loader.ReferenceMultiplicityViolationException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.MissingReferenceException;
+import org.apache.tuscany.spi.loader.PropertyObjectFactory;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.ComponentReferenceDefinition;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.Implementation;
+import org.apache.tuscany.spi.model.Multiplicity;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.apache.tuscany.spi.model.ReferenceTarget;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.implementation.java.JavaImplementation;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ComponentLoaderValidationTestCase extends TestCase {
+
+ private ComponentLoaderValidationTestCase.TestLoader loader;
+
+ public void testValidation() throws LoaderException, XMLStreamException {
+ PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> type =
+ new PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ ComponentTypeReferenceDefinition refDefinition = new ComponentTypeReferenceDefinition();
+ refDefinition.setName("name");
+ type.add(refDefinition);
+ JavaImplementation impl = new JavaImplementation(null, type);
+ ComponentDefinition<Implementation<?>> defn = new ComponentDefinition<Implementation<?>>(impl);
+ ComponentReferenceDefinition compRef = new ComponentReferenceDefinition(refDefinition);
+ compRef.addTarget(URI.create("uri"));
+ defn.add(compRef);
+ /*ReferenceTarget target = new ReferenceTarget();
+ target.setReferenceName("name");
+ defn.add(target);*/
+ loader.validate(defn);
+ }
+
+ /*public void testReferenceNotSet() throws LoaderException, XMLStreamException {
+ PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> type =
+ new PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ ComponentTypeReferenceDefinition refDefinition = new ComponentTypeReferenceDefinition();
+ refDefinition.setName("name");
+ type.add(refDefinition);
+ JavaImplementation impl = new JavaImplementation(null, type);
+ ComponentDefinition<Implementation<?>> defn = new ComponentDefinition<Implementation<?>>(impl);
+ try {
+ loader.validate(defn);
+ fail();
+ } catch (MissingReferenceException e) {
+ // expected
+ }
+ }*/
+
+ public void testNotRequiredReference() throws LoaderException, XMLStreamException {
+ PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> type =
+ new PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ ComponentTypeReferenceDefinition refDefinition = new ComponentTypeReferenceDefinition();
+ refDefinition.setName("name");
+ type.add(refDefinition);
+ JavaImplementation impl = new JavaImplementation(null, type);
+ ComponentDefinition<Implementation<?>> defn = new ComponentDefinition<Implementation<?>>(impl);
+ loader.validate(defn);
+ }
+
+ public void testReferenceMultiplicity() throws LoaderException, XMLStreamException {
+ PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> type =
+ new PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ ComponentTypeReferenceDefinition refDefinition = new ComponentTypeReferenceDefinition();
+ refDefinition.setName("r1");
+ refDefinition.setMultiplicity(Multiplicity.ONE_N);
+ type.add(refDefinition);
+ JavaImplementation impl = new JavaImplementation(null, type);
+ ComponentDefinition<Implementation<?>> defn = new ComponentDefinition<Implementation<?>>(impl);
+ ComponentReferenceDefinition compRef = new ComponentReferenceDefinition(type.getReferences().get("r1"));
+ compRef.addTarget(URI.create("c1"));
+ compRef.addTarget(URI.create("c2"));
+ defn.add(compRef);
+ /*ReferenceTarget target = new ReferenceTarget();
+ target.setReferenceName("r1");
+ target.addTarget(URI.create("c1"));
+ target.addTarget(URI.create("c2"));
+ defn.add(target);*/
+ loader.validate(defn);
+
+ refDefinition.setMultiplicity(Multiplicity.ZERO_ONE);
+ try {
+ loader.validate(defn);
+ fail();
+ } catch (ReferenceMultiplicityViolationException e) {
+ // Expected
+ }
+
+ refDefinition.setMultiplicity(Multiplicity.ZERO_N);
+ loader.validate(defn);
+
+ refDefinition.setMultiplicity(Multiplicity.ONE_ONE);
+ try {
+ loader.validate(defn);
+ fail();
+ } catch (ReferenceMultiplicityViolationException e) {
+ // Expected
+ }
+
+ defn = new ComponentDefinition<Implementation<?>>(impl);
+ compRef = new ComponentReferenceDefinition(type.getReferences().get("r1"));
+ defn.add(compRef);
+ refDefinition.setMultiplicity(Multiplicity.ONE_ONE);
+ try {
+ loader.validate(defn);
+ fail();
+ } catch (ReferenceMultiplicityViolationException e) {
+ // Expected
+ }
+ refDefinition.setMultiplicity(Multiplicity.ONE_N);
+ try {
+ loader.validate(defn);
+ fail();
+ } catch (ReferenceMultiplicityViolationException e) {
+ // Expected
+ }
+ refDefinition.setMultiplicity(Multiplicity.ZERO_N);
+ loader.validate(defn);
+ refDefinition.setMultiplicity(Multiplicity.ZERO_ONE);
+ loader.validate(defn);
+
+ }
+ public void testAutowire() throws LoaderException, XMLStreamException {
+ PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> type =
+ new PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ ComponentTypeReferenceDefinition refDefinition = new ComponentTypeReferenceDefinition();
+ refDefinition.setName("name");
+ refDefinition.setAutowire(true);
+ type.add(refDefinition);
+ JavaImplementation impl = new JavaImplementation(null, type);
+ ComponentDefinition<Implementation<?>> defn = new ComponentDefinition<Implementation<?>>(impl);
+ loader.validate(defn);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ LoaderRegistry mockRegistry = EasyMock.createMock(LoaderRegistry.class);
+ PropertyObjectFactory mockPropertyFactory = EasyMock.createMock(PropertyObjectFactory.class);
+ loader = new ComponentLoaderValidationTestCase.TestLoader(mockRegistry, mockPropertyFactory);
+ }
+
+ private class TestLoader extends ComponentLoader {
+
+ public TestLoader(LoaderRegistry registry, PropertyObjectFactory propertyFactory) {
+ super(registry, propertyFactory);
+ }
+
+ @Override
+ protected void validate(ComponentDefinition<Implementation<?>> definition) throws LoaderException {
+ super.validate(definition);
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentReferenceOverridingTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentReferenceOverridingTestCase.java
new file mode 100644
index 0000000000..ffc6ee7a03
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentReferenceOverridingTestCase.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import java.io.StringReader;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import junit.framework.Assert;
+
+import org.apache.tuscany.core.binding.local.LocalBindingDefinition;
+import org.apache.tuscany.core.implementation.java.JavaImplementation;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.implementation.java.PojoComponentType;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.ReferenceMultiplicityOverridingException;
+import org.apache.tuscany.spi.model.BindingDefinition;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.Implementation;
+import org.apache.tuscany.spi.model.Multiplicity;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+/**
+ * Tests to verify overriding of aspects of componenttype reference defintions
+ * by component definitions
+ */
+public class ComponentReferenceOverridingTestCase {
+ private static XMLInputFactory xmlFactory = XMLInputFactory.newInstance();;
+ private static LoaderRegistryImpl loaderRegistry;
+
+ public XMLStreamReader getReader(String xml) throws XMLStreamException {
+ XMLStreamReader reader = xmlFactory.createXMLStreamReader(new StringReader(xml));
+ reader.next();
+ return reader;
+ }
+
+
+ @Test
+ public void testRefDefNoOverriding() throws LoaderException,
+ XMLStreamException,
+ URISyntaxException {
+ String compDefXml =
+ "<tus:component name='TestComponent' xmlns:tus='http://www.osoa.org/xmlns/sca/1.0'>"
+ + "<tus:implementation.java class='mockedup'/>"
+ + "</tus:component>";
+
+ TestComponentLoader compLoader = new TestComponentLoader(EasyMock.createMock(LoaderRegistry.class));
+ ComponentDefinition<?> compDef = compLoader.load(null, null, getReader(compDefXml), null);
+
+ //verify if component inherits referece definitions from componentType
+ Assert.assertNotNull(compDef.getReferences().get("CTRefDef1"));
+ Assert.assertEquals(Multiplicity.ZERO_N.name(), compDef.getReferences().get("CTRefDef1").getMultiplicity().name());
+ Assert.assertEquals("TestComponent1/testService1",
+ compDef.getReferences().get("CTRefDef1").getTargets().get(1).toString());
+ Assert.assertTrue(
+ TestIfc1.class.isAssignableFrom(compDef.getReferences().get("CTRefDef1").getServiceContract().getInterfaceClass()));
+ Assert.assertTrue(compDef.getReferences().get("CTRefDef1").getBindings().get(0) instanceof LocalBindingDefinition);
+ }
+
+ @Test
+ public void testRefDefValidOverriding() throws LoaderException,
+ XMLStreamException,
+ URISyntaxException {
+ String overridenRef =
+ "<tus:component name='TestComponent' xmlns:tus='http://www.osoa.org/xmlns/sca/1.0'>"
+ + "<tus:implementation.java class='mockedup'/>"
+ + "<tus:reference name='CTRefDef1' target='OverridingTarget' multiplicity='0..1'>"
+ + "</tus:reference>"
+ + "</tus:component>";
+
+ TestComponentLoader compLoader = new TestComponentLoader(EasyMock.createMock(LoaderRegistry.class));
+
+ ComponentDefinition<?> compDef = compLoader.load(null, null, getReader(overridenRef), null);
+
+ //verify if component inherits referece definitions from componentType
+ Assert.assertNotNull(compDef.getReferences().get("CTRefDef1"));
+ Assert.assertEquals(Multiplicity.ZERO_ONE.name(),
+ compDef.getReferences().get("CTRefDef1").getMultiplicity().name());
+ Assert.assertEquals("OverridingTarget",
+ compDef.getReferences().get("CTRefDef1").getTargets().get(0).toString());
+ Assert.assertTrue(
+ TestIfc1.class.isAssignableFrom(compDef.getReferences().get("CTRefDef1").getServiceContract().getInterfaceClass()));
+ Assert.assertTrue(compDef.getReferences().get("CTRefDef1").getBindings().get(0) instanceof LocalBindingDefinition);
+ }
+
+ @Test
+ public void testRefDefInValidOverriding() throws LoaderException,
+ XMLStreamException,
+ URISyntaxException {
+ String overridenRef =
+ "<tus:component name='TestComponent' xmlns:tus='http://www.osoa.org/xmlns/sca/1.0'>"
+ + "<tus:implementation.java class='mockedup'/>"
+ + "<tus:reference name='CTRefDef1' target='OverridingTarget' multiplicity='1..1'/>"
+ + "</tus:component>";
+
+ TestComponentLoader compLoader = new TestComponentLoader(EasyMock.createMock(LoaderRegistry.class));
+
+ try {
+ ComponentDefinition<?> compDef = compLoader.load(null, null, getReader(overridenRef), null);
+ Assert.fail();
+ } catch ( ReferenceMultiplicityOverridingException e) {
+ //expected behaviour
+ }
+ }
+
+
+ public static interface TestIfc1 {
+ public String testMethod1();
+ }
+
+ public class TestComponentLoader extends ComponentLoader {
+
+ public TestComponentLoader(LoaderRegistry registry) {
+ super(registry, null);
+ }
+
+ @Override
+ protected Implementation<?> loadImplementation(CompositeComponent parent,
+ XMLStreamReader reader,
+ DeploymentContext deploymentContext) throws XMLStreamException,
+ LoaderException {
+ ComponentTypeReferenceDefinition ctRefDef = new ComponentTypeReferenceDefinition();
+
+ ctRefDef.setName("CTRefDef1");
+ try {
+ ctRefDef.addTarget(new URI("TestComponent1"));
+ ctRefDef.addTarget(new URI("TestComponent1/testService1"));
+
+ ctRefDef.setMultiplicity(Multiplicity.ZERO_N);
+
+ JavaServiceContract svcContract = new JavaServiceContract(TestIfc1.class);
+ ctRefDef.setServiceContract(svcContract);
+
+ BindingDefinition binding1 = new LocalBindingDefinition(new URI("localBindingUri"));
+ ctRefDef.addBinding(binding1);
+ } catch (URISyntaxException e) {
+ //do nothing... unlikely to happen
+ }
+
+ PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> ct =
+ new PojoComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ ct.add(ctRefDef);
+
+ JavaImplementation javaImpl = new JavaImplementation();
+ javaImpl.setComponentType(ct);
+ reader.next();
+ reader.next();
+ return javaImpl;
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentTypeElementLoaderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentTypeElementLoaderTestCase.java
new file mode 100644
index 0000000000..08272d98bc
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ComponentTypeElementLoaderTestCase.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.ComponentType;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.ModelObject;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ComponentTypeElementLoaderTestCase extends TestCase {
+
+ public void testSpecializedComponentTypePassedIn() throws Exception {
+ ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> type =
+ new ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ ComponentTypeElementLoader loader = new ComponentTypeElementLoader(null);
+ XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class);
+ EasyMock.expect(reader.getName()).andReturn(ComponentTypeElementLoader.COMPONENT_TYPE);
+ EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT);
+ EasyMock.replay(reader);
+ // verify that the exact component type instance is returned. Some StAXElementLoader implementations may chose
+ // to copy the original instance but ComponentTypeElementLoader does not since it has no knowledge of the
+ // specialized instance
+ ModelObject object = loader.load(null, type, reader, null);
+ assertEquals(object, type);
+ }
+
+ public void testComponentTypePassedAsContext() throws Exception {
+ ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> type =
+ new ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ LoaderRegistry registry = EasyMock.createMock(LoaderRegistry.class);
+ EasyMock.expect(registry.load((CompositeComponent) EasyMock.isNull(),
+ EasyMock.isA(ComponentType.class),
+ EasyMock.isA(XMLStreamReader.class),
+ (DeploymentContext) EasyMock.isNull())).andReturn(type);
+ EasyMock.replay(registry);
+ ComponentTypeElementLoader loader = new ComponentTypeElementLoader(registry);
+ XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class);
+ EasyMock.expect(reader.getName()).andReturn(ComponentTypeElementLoader.COMPONENT_TYPE);
+ EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.START_ELEMENT);
+ EasyMock.expect(reader.getName()).andReturn(new QName("foo", "foo"));
+ EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT);
+ EasyMock.replay(reader);
+
+ loader.load(null, type, reader, null);
+ EasyMock.verify(registry);
+ }
+
+ public void testNonSpecializedComponentTypePassedIn() throws Exception {
+ ComponentTypeElementLoader loader = new ComponentTypeElementLoader(null);
+ XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class);
+ EasyMock.expect(reader.getName()).andReturn(ComponentTypeElementLoader.COMPONENT_TYPE);
+ EasyMock.expect(reader.next()).andReturn(XMLStreamConstants.END_ELEMENT);
+ EasyMock.replay(reader);
+ ModelObject object = loader.load(null, null, reader, null);
+ assertEquals(ComponentType.class, object.getClass());
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/DependencyLoaderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/DependencyLoaderTestCase.java
new file mode 100644
index 0000000000..753289f4a6
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/DependencyLoaderTestCase.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.UnrecognizedElementException;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+import org.apache.tuscany.core.implementation.composite.Dependency;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class DependencyLoaderTestCase extends TestCase {
+ private static final String NS = "http://tuscany.apache.org/xmlns/1.0-SNAPSHOT";
+ private static final QName DEPENDENCY = new QName(NS, "dependency");
+ private static final QName GROUP = new QName(NS, "group");
+ private static final QName NAME = new QName(NS, "name");
+ private static final QName VERSION = new QName(NS, "version");
+ private static final QName CLASSIFIER = new QName(NS, "classifier");
+ private static final QName TYPE = new QName(NS, "type");
+
+ public void testLoad() throws Exception {
+ LoaderRegistry registry = EasyMock.createNiceMock(LoaderRegistry.class);
+ EasyMock.replay(registry);
+ XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class);
+ EasyMock.expect(reader.nextTag()).andReturn(XMLStreamConstants.START_ELEMENT);
+ EasyMock.expect(reader.getName()).andReturn(GROUP);
+ EasyMock.expect(reader.getElementText()).andReturn("group");
+ EasyMock.expect(reader.nextTag()).andReturn(XMLStreamConstants.START_ELEMENT);
+ EasyMock.expect(reader.getName()).andReturn(NAME);
+ EasyMock.expect(reader.getElementText()).andReturn("name");
+ EasyMock.expect(reader.nextTag()).andReturn(XMLStreamConstants.START_ELEMENT);
+ EasyMock.expect(reader.getName()).andReturn(VERSION);
+ EasyMock.expect(reader.getElementText()).andReturn("1");
+ EasyMock.expect(reader.nextTag()).andReturn(XMLStreamConstants.START_ELEMENT);
+ EasyMock.expect(reader.getName()).andReturn(CLASSIFIER);
+ EasyMock.expect(reader.getElementText()).andReturn("classifier");
+ EasyMock.expect(reader.nextTag()).andReturn(XMLStreamConstants.START_ELEMENT);
+ EasyMock.expect(reader.getName()).andReturn(TYPE);
+ EasyMock.expect(reader.getElementText()).andReturn("type");
+ EasyMock.expect(reader.nextTag()).andReturn(XMLStreamConstants.END_ELEMENT);
+ EasyMock.replay(reader);
+ DependencyLoader loader = new DependencyLoader(registry);
+ Dependency dependency = loader.load(null, null, reader, null);
+ assertEquals("group", dependency.getArtifact().getGroup());
+ assertEquals("name", dependency.getArtifact().getName());
+ assertEquals("1", dependency.getArtifact().getVersion());
+ assertEquals("classifier", dependency.getArtifact().getClassifier());
+ assertEquals("type", dependency.getArtifact().getType());
+ }
+
+ public void testLoaderRegister() {
+ LoaderRegistry registry = EasyMock.createMock(LoaderRegistry.class);
+ registry.registerLoader(EasyMock.eq(DEPENDENCY), EasyMock.isA(DependencyLoader.class));
+ EasyMock.replay(registry);
+ DependencyLoader loader = new DependencyLoader(registry);
+ loader.start();
+ EasyMock.verify(registry);
+ }
+
+ public void testUnrecognizedElement() throws Exception {
+ LoaderRegistry registry = EasyMock.createNiceMock(LoaderRegistry.class);
+ EasyMock.replay(registry);
+ XMLStreamReader reader = EasyMock.createMock(XMLStreamReader.class);
+ EasyMock.expect(reader.nextTag()).andReturn(XMLStreamConstants.START_ELEMENT);
+ EasyMock.expect(reader.getName()).andReturn(new QName("foo", "bar"));
+ EasyMock.expect(reader.getElementText()).andReturn("foo");
+ EasyMock.expect(reader.getLocation()).andReturn(new MockLocation());
+ EasyMock.replay(reader);
+ DependencyLoader loader = new DependencyLoader(registry);
+ try {
+ loader.load(null, null, reader, null);
+ fail();
+ } catch (UnrecognizedElementException e) {
+ // expected
+ }
+ }
+
+ private class MockLocation implements Location {
+
+ public int getLineNumber() {
+ return 0;
+ }
+
+ public int getColumnNumber() {
+ return 0;
+ }
+
+ public int getCharacterOffset() {
+ return 0;
+ }
+
+ public String getPublicId() {
+ return null;
+ }
+
+ public String getSystemId() {
+ return null;
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/IncludeLoaderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/IncludeLoaderTestCase.java
new file mode 100644
index 0000000000..ed2fde80d3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/IncludeLoaderTestCase.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import java.net.URL;
+import javax.xml.namespace.QName;
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.osoa.sca.Constants;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.MissingIncludeException;
+import org.apache.tuscany.spi.model.CompositeComponentType;
+import org.apache.tuscany.spi.model.Include;
+import org.apache.tuscany.spi.model.ModelObject;
+
+import junit.framework.TestCase;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.isNull;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class IncludeLoaderTestCase extends TestCase {
+ private static final QName INCLUDE = new QName(Constants.SCA_NS, "include");
+
+ private LoaderRegistry registry;
+ private IncludeLoader loader;
+ private XMLStreamReader reader;
+ private DeploymentContext context;
+ private URL base;
+ private URL includeURL;
+ private ClassLoader cl;
+
+ public void testNoLocation() throws LoaderException, XMLStreamException {
+ String name = "foo";
+ expect(reader.getName()).andReturn(INCLUDE);
+ expect(reader.getAttributeValue(null, "name")).andReturn(name);
+ expect(reader.getAttributeValue(null, "scdlLocation")).andReturn(null);
+ expect(reader.getAttributeValue(null, "scdlResource")).andReturn(null);
+ expect(reader.next()).andReturn(END_ELEMENT);
+
+ expect(context.getClassLoader()).andReturn(cl);
+ replay(registry, reader, context);
+
+ try {
+ loader.load(null, null, reader, context);
+ fail();
+ } catch (MissingIncludeException e) {
+ // OK expected
+ }
+ verify(registry, reader, context);
+ }
+
+ public void testWithAbsoluteScdlLocation() throws LoaderException, XMLStreamException {
+ String name = "foo";
+ expect(reader.getName()).andReturn(INCLUDE);
+ expect(reader.getAttributeValue(null, "name")).andReturn(name);
+ expect(reader.getAttributeValue(null, "scdlLocation")).andReturn("http://example.com/include.scdl");
+ expect(reader.getAttributeValue(null, "scdlResource")).andReturn(null);
+ expect(reader.next()).andReturn(END_ELEMENT);
+
+ expect(context.getScdlLocation()).andReturn(base);
+ expect(context.getClassLoader()).andReturn(cl);
+
+ expect(registry.load((CompositeComponent) isNull(),
+ (ModelObject) isNull(),
+ eq(includeURL),
+ eq(CompositeComponentType.class),
+ isA(DeploymentContext.class)))
+ .andReturn(null);
+ replay(registry, reader, context);
+
+ Include include = loader.load(null, null, reader, context);
+ assertEquals(name, include.getName());
+ assertEquals(includeURL, include.getScdlLocation());
+ verify(registry, reader, context);
+ }
+
+ public void testWithRelativeScdlLocation() throws LoaderException, XMLStreamException {
+ String name = "foo";
+ expect(reader.getName()).andReturn(INCLUDE);
+ expect(reader.getAttributeValue(null, "name")).andReturn(name);
+ expect(reader.getAttributeValue(null, "scdlLocation")).andReturn("include.scdl");
+ expect(reader.getAttributeValue(null, "scdlResource")).andReturn(null);
+ expect(reader.next()).andReturn(END_ELEMENT);
+
+ expect(context.getScdlLocation()).andReturn(base);
+ expect(context.getClassLoader()).andReturn(cl);
+
+ expect(registry.load((CompositeComponent) isNull(),
+ (ModelObject) isNull(),
+ eq(includeURL),
+ eq(CompositeComponentType.class),
+ isA(DeploymentContext.class)))
+ .andReturn(null);
+ replay(registry, reader, context);
+
+ Include include = loader.load(null, null, reader, context);
+ assertEquals(name, include.getName());
+ assertEquals(includeURL, include.getScdlLocation());
+ verify(registry, reader, context);
+ }
+
+ public void testWithScdlResource() throws LoaderException, XMLStreamException {
+ String name = "foo";
+ String resource = "org/apache/tuscany/core/loader/test-include.scdl";
+ includeURL = cl.getResource(resource);
+ assertNotNull(includeURL);
+
+ expect(reader.getName()).andReturn(INCLUDE);
+ expect(reader.getAttributeValue(null, "name")).andReturn(name);
+ expect(reader.getAttributeValue(null, "scdlLocation")).andReturn(null);
+ expect(reader.getAttributeValue(null, "scdlResource")).andReturn(resource);
+ expect(reader.next()).andReturn(END_ELEMENT);
+
+ expect(context.getClassLoader()).andReturn(cl);
+
+ expect(registry.load((CompositeComponent) isNull(),
+ (ModelObject) isNull(),
+ eq(includeURL),
+ eq(CompositeComponentType.class),
+ isA(DeploymentContext.class)))
+ .andReturn(null);
+ replay(registry, reader, context);
+
+ Include include = loader.load(null, null, reader, context);
+ assertEquals(name, include.getName());
+ assertEquals(includeURL, include.getScdlLocation());
+ verify(registry, reader, context);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ registry = createMock(LoaderRegistry.class);
+ reader = createMock(XMLStreamReader.class);
+ context = createMock(DeploymentContext.class);
+ cl = getClass().getClassLoader();
+ base = new URL("http://example.com/test.scdl");
+ includeURL = new URL("http://example.com/include.scdl");
+ loader = new IncludeLoader(registry);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/JNDIPropertyFactoryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/JNDIPropertyFactoryTestCase.java
new file mode 100644
index 0000000000..1c65ed42cc
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/JNDIPropertyFactoryTestCase.java
@@ -0,0 +1,66 @@
+package org.apache.tuscany.core.loader;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.spi.InitialContextFactory;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.injection.JNDIObjectFactory;
+import org.apache.tuscany.spi.model.PropertyValue;
+import org.easymock.EasyMock;
+import org.w3c.dom.Element;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JNDIPropertyFactoryTestCase extends TestCase {
+
+ public void testCreate() throws Exception {
+ String old = System.getProperty(Context.INITIAL_CONTEXT_FACTORY);
+ try {
+ System.setProperty(Context.INITIAL_CONTEXT_FACTORY, MockInitialContextFactory.class.getName());
+ JNDIPropertyFactory factory = new JNDIPropertyFactory();
+ Element element = EasyMock.createMock(Element.class);
+ EasyMock.expect(element.getTextContent()).andReturn("foo");
+ EasyMock.replay(element);
+ //Document doc = EasyMock.createMock(Document.class);
+ //EasyMock.expect(doc.getDocumentElement()).andReturn(element);
+ //EasyMock.replay(doc);
+ PropertyValue<?> value = new MockPropertyValue<Type>();
+ List<Element> docList = new ArrayList<Element>();
+ docList.add(element);
+ value.setValue(docList);
+ JNDIObjectFactory<?> jndiFactory = (JNDIObjectFactory<?>) factory.createObjectFactory(null, value);
+ assertEquals("bar", jndiFactory.getInstance());
+ } finally {
+ System.clearProperty(Context.INITIAL_CONTEXT_FACTORY);
+ if (old != null) {
+ System.setProperty(Context.INITIAL_CONTEXT_FACTORY, old);
+ }
+ }
+
+ }
+
+ private class MockPropertyValue<T> extends PropertyValue<T> {
+
+ }
+
+ public static class MockInitialContextFactory implements InitialContextFactory {
+ public MockInitialContextFactory() {
+ }
+
+ public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {
+ Context context = EasyMock.createMock(Context.class);
+ EasyMock.expect(context.lookup("foo")).andReturn("bar");
+ EasyMock.replay(context);
+ return context;
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/LoaderExceptionFormatterTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/LoaderExceptionFormatterTestCase.java
new file mode 100644
index 0000000000..49c53935dc
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/LoaderExceptionFormatterTestCase.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.apache.tuscany.spi.loader.LoaderException;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+import org.apache.tuscany.host.monitor.FormatterRegistry;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class LoaderExceptionFormatterTestCase extends TestCase {
+
+ public void testLog() {
+ FormatterRegistry registry = EasyMock.createNiceMock(FormatterRegistry.class);
+ LoaderExceptionFormatter formatter = new LoaderExceptionFormatter(registry);
+ LoaderException e = new LoaderException("test");
+ StringWriter writer = new StringWriter();
+ PrintWriter pw = new PrintWriter(writer);
+ formatter.write(pw, e);
+ pw.close();
+ assertTrue(!"message".equals(writer.toString()));
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/MultivaluePropertyLoadingTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/MultivaluePropertyLoadingTestCase.java
new file mode 100644
index 0000000000..a39ca52fd4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/MultivaluePropertyLoadingTestCase.java
@@ -0,0 +1,204 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.databinding.javabeans.JavaBean2DOMNodeTransformer;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.Property;
+import org.easymock.EasyMock;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * @version $Rev: 502055 $ $Date: 2007-02-01 05:37:32 +0530 (Thu, 01 Feb 2007) $
+ */
+public class MultivaluePropertyLoadingTestCase extends TestCase {
+ private PropertyLoader propertyLoader;
+ private XMLInputFactory xmlFactory;
+
+
+ public void testPropertyLoading_SimpleType() throws Exception {
+ String xml = "<tus:property xmlns:foo='http://foo.com' "
+ + "xmlns:tus='http://www.osoa.org/xmlns/sca/1.0' "
+ + "xmlns:xs='http://www.w3.org/2001/XMLSchema' "
+ + " name='TestProperty' type='xs:string' many='true'>"
+ + "<value>"
+ + "TestPropertyValue1"
+ + "</value>"
+ + "<value>"
+ + "TestPropertyValue2"
+ + "</value>"
+ + "</tus:property>";
+
+ XMLStreamReader reader = getReader(xml);
+ Property<?> aProperty = propertyLoader.load(null, null, reader, null);
+
+ assertEquals("TestProperty", aProperty.getName());
+ assertEquals(new QName("http://www.w3.org/2001/XMLSchema", "string", "xs"), aProperty.getXmlType());
+ assertEquals(false, aProperty.isMustSupply());
+ assertEquals(true, aProperty.isMany());
+
+ Element secondValue = aProperty.getDefaultValues().get(1);
+
+ NodeList childNodes = secondValue.getChildNodes();
+ assertEquals(1, childNodes.getLength());
+
+ Text t = (Text) childNodes.item(0);
+ assertEquals("TestPropertyValue2", t.getTextContent());
+ }
+
+ public void testPropertyLoading_Type() throws Exception {
+ String xml = "<tus:property xmlns:foo='http://foo.com' "
+ + "xmlns:tus='http://www.osoa.org/xmlns/sca/1.0' "
+ + "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
+ + " name='complexFoo' many='true' type='foo:MyComplexType'>"
+ + "<MyComplexPropertyValue1 xsi:type='foo:MyComplexType' attr='bar'>"
+ + "<foo:a>AValue</foo:a>"
+ + "<foo:b>InterestingURI</foo:b>"
+ + "</MyComplexPropertyValue1>"
+ + "<MyComplexPropertyValue2 xsi:type='foo:MyComplexType' attr='zing'>"
+ + "<foo:a>BValue</foo:a>"
+ + "<foo:b>BoringURI</foo:b>"
+ + "</MyComplexPropertyValue2>"
+ + "</tus:property>";
+
+
+
+ XMLStreamReader reader = getReader(xml);
+ Property<?> aProperty = propertyLoader.load(null, null, reader, null);
+
+ assertEquals("complexFoo", aProperty.getName());
+ assertEquals(new QName("http://foo.com", "MyComplexType", "foo"), aProperty.getXmlType());
+ assertEquals(false, aProperty.isMustSupply());
+ assertEquals(true, aProperty.isMany());
+
+ Element secondValue = aProperty.getDefaultValues().get(1);
+
+ NodeList childNodes = secondValue.getChildNodes();
+ assertEquals(2, childNodes.getLength());
+
+ Element e = (Element) childNodes.item(0);
+ assertEquals("http://foo.com", e.getNamespaceURI());
+ assertEquals("a", e.getLocalName());
+ assertEquals("BValue", e.getTextContent());
+ e = (Element) childNodes.item(1);
+ assertEquals("http://foo.com", e.getNamespaceURI());
+ assertEquals("b", e.getLocalName());
+ assertEquals("BoringURI", e.getTextContent());
+ }
+
+ public void testPropertyLoading_Element() throws Exception {
+ String xml =
+ "<tus:property xmlns:foo='http://foo.com' "
+ + "xmlns:tus='http://www.osoa.org/xmlns/sca/1.0'"
+ + " name='TestProperty' many='true' element='foo:TestElement'>\n"
+ + "<foo:TestElement>"
+ + "<foo:a>aValue1</foo:a>"
+ + "<foo:b>InterestingURI1</foo:b>"
+ + "</foo:TestElement>"
+ + "<foo:TestElement>"
+ + "<foo:a>aValue2</foo:a>"
+ + "<foo:b>InterestingURI2</foo:b>"
+ + "</foo:TestElement>"
+ + "</tus:property>";
+ XMLStreamReader reader = getReader(xml);
+ Property<?> aProperty = propertyLoader.load(null, null, reader, null);
+
+ Element secondElement = aProperty.getDefaultValues().get(1);
+
+ assertEquals(2, aProperty.getDefaultValues().size());
+ assertEquals("TestProperty", aProperty.getName());
+ assertEquals(new QName("http://foo.com", "TestElement", "foo"), aProperty.getXmlElement());
+ assertEquals(false, aProperty.isMustSupply());
+ assertEquals(true, aProperty.isMany());
+
+ NodeList childNodes = secondElement.getChildNodes();
+ assertEquals(2, childNodes.getLength());
+
+ Element e = (Element) childNodes.item(0);
+ assertEquals("http://foo.com", e.getNamespaceURI());
+ assertEquals("a", e.getLocalName());
+ assertEquals("aValue2", e.getTextContent());
+ e = (Element) childNodes.item(1);
+ assertEquals("http://foo.com", e.getNamespaceURI());
+ assertEquals("b", e.getLocalName());
+ assertEquals("InterestingURI2", e.getTextContent());
+ }
+
+ public void testManyValueException() throws Exception {
+ String xml =
+ "<tus:property xmlns:foo='http://foo.com' "
+ + "xmlns:tus='http://www.osoa.org/xmlns/sca/1.0'"
+ + " name='TestProperty' element='foo:TestElement'>\n"
+ + "<foo:TestElement>"
+ + "<foo:a>aValue1</foo:a>"
+ + "<foo:b>InterestingURI1</foo:b>"
+ + "</foo:TestElement>"
+ + "<foo:TestElement>"
+ + "<foo:a>aValue2</foo:a>"
+ + "<foo:b>InterestingURI2</foo:b>"
+ + "</foo:TestElement>"
+ + "</tus:property>";
+
+ XMLStreamReader reader = getReader(xml);
+
+ try {
+ propertyLoader.load(null, null, reader, null);
+ } catch (Exception e) {
+ assertTrue(e instanceof ManyPropertyValueLoaderException);
+ }
+ }
+
+ public XMLStreamReader getReader(String xml) throws XMLStreamException {
+ XMLStreamReader reader = xmlFactory.createXMLStreamReader(new StringReader(xml));
+ reader.next();
+ return reader;
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ xmlFactory = XMLInputFactory.newInstance();
+ propertyLoader = new PropertyLoader(EasyMock.createMock(LoaderRegistry.class));
+ }
+
+ private void printNode(Node node) throws Exception {
+ javax.xml.transform.Transformer transformer =
+ TransformerFactory.newInstance().newTransformer();
+ JavaBean2DOMNodeTransformer java2DomTransformer = new JavaBean2DOMNodeTransformer();
+ StringWriter sw = new StringWriter();
+ transformer.transform(new DOMSource(node), new StreamResult(sw));
+
+ System.out.println(sw.toString());
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/PolicySetLoaderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/PolicySetLoaderTestCase.java
new file mode 100644
index 0000000000..8e18c2ff0f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/PolicySetLoaderTestCase.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import java.util.Collection;
+import java.util.Iterator;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+import javax.xml.stream.XMLStreamReader;
+
+import static org.osoa.sca.Constants.SCA_NS;
+
+import org.apache.tuscany.spi.model.IntentMap;
+import org.apache.tuscany.spi.model.PolicySet;
+import org.apache.tuscany.spi.model.Qualifier;
+
+import junit.framework.TestCase;
+
+public class PolicySetLoaderTestCase extends TestCase {
+ private static final QName POLICYSET = new QName(SCA_NS, "policySet");
+
+ public void testLoader() throws Exception {
+ PolicySetLoader loader = new PolicySetLoader(null);
+ XMLInputFactory factory = XMLInputFactory.newInstance();
+ XMLStreamReader reader = factory.createXMLStreamReader(this.getClass().getResourceAsStream("TestPolicy.scdl"));
+ while (true) {
+ int state = reader.next();
+ if (START_ELEMENT == state && reader.getName().equals(POLICYSET)) {
+ break;
+ }
+ }
+ PolicySet policySet = loader.load(null, null, reader, null);
+ assertNotNull(policySet);
+ assertEquals(2, policySet.getAppliedArtifacts().size());
+ assertTrue(policySet.getAppliedArtifacts().contains(new QName(SCA_NS, "binding.ws")));
+ assertTrue(policySet.getAppliedArtifacts().contains(new QName(SCA_NS, "binding.jms")));
+ Collection<IntentMap> intentMaps = policySet.getIntentMaps();
+ assertEquals(1, intentMaps.size());
+ IntentMap intentMap = intentMaps.iterator().next();
+ assertEquals("transport", intentMap.getDefaultProvideIntent());
+ assertTrue(intentMap.getProvideIntents().contains("sec.confidentiality"));
+ Collection<Qualifier> qualifiers = intentMap.getQualifiers();
+ assertEquals(2, qualifiers.size());
+ Iterator qit = qualifiers.iterator();
+ Qualifier qualifier1 = (Qualifier) qit.next();
+ assertEquals(2, qualifier1.getWsPolicyAttachments().size());
+ assertEquals("transport", qualifier1.getName());
+ Qualifier qualifier2 = (Qualifier) qit.next();
+ assertEquals("message", qualifier2.getName());
+ IntentMap messageMap = qualifier2.getIntentMap();
+ assertEquals(2, messageMap.getQualifiers().size());
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/PropertyLoaderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/PropertyLoaderTestCase.java
new file mode 100644
index 0000000000..c357d9bc0a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/PropertyLoaderTestCase.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.databinding.javabeans.JavaBean2DOMNodeTransformer;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.Property;
+import org.easymock.EasyMock;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * @version $Rev: 502055 $ $Date: 2007-02-01 05:37:32 +0530 (Thu, 01 Feb 2007) $
+ */
+public class PropertyLoaderTestCase extends TestCase {
+ private PropertyLoader propertyLoader;
+ private XMLInputFactory xmlFactory;
+
+
+ public void testPropertyLoading_SimpleType() throws Exception {
+ String xml = "<tus:property xmlns:foo='http://foo.com' "
+ + "xmlns:tus='http://www.osoa.org/xmlns/sca/1.0' "
+ + "xmlns:xs='http://www.w3.org/2001/XMLSchema' "
+ + " name='TestProperty' type='xs:string'>"
+ + "TestPropertyValue"
+ + "</tus:property>";
+
+ XMLStreamReader reader = getReader(xml);
+ Property<?> aProperty = propertyLoader.load(null, null, reader, null);
+
+ assertEquals("TestProperty", aProperty.getName());
+ assertEquals(new QName("http://www.w3.org/2001/XMLSchema", "string", "xs"), aProperty.getXmlType());
+ assertEquals(false, aProperty.isMustSupply());
+ assertEquals(false, aProperty.isMany());
+
+ Element root = aProperty.getDefaultValues().get(0);
+
+ NodeList childNodes = root.getChildNodes();
+ assertEquals(1, childNodes.getLength());
+
+ Text t = (Text) childNodes.item(0);
+ assertEquals("TestPropertyValue", t.getTextContent());
+ }
+
+
+ public void testPropertyLoading_Type() throws Exception {
+ String xml = "<tus:property xmlns:foo='http://foo.com' "
+ + "xmlns:tus='http://www.osoa.org/xmlns/sca/1.0' "
+ + "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
+ + " name='complexFoo' type='foo:MyComplexType'>"
+ + "<MyComplexPropertyValue1 xsi:type='foo:MyComplexType' attr='bar'>"
+ + "<foo:a>AValue</foo:a>"
+ + "<foo:b>InterestingURI</foo:b>"
+ + "</MyComplexPropertyValue1>"
+ + "</tus:property>";
+
+ XMLStreamReader reader = getReader(xml);
+ Property<?> aProperty = propertyLoader.load(null, null, reader, null);
+ assertEquals("complexFoo", aProperty.getName());
+ assertEquals(new QName("http://foo.com", "MyComplexType", "foo"), aProperty.getXmlType());
+ assertEquals(false, aProperty.isMustSupply());
+ assertEquals(false, aProperty.isMany());
+
+ Element root = aProperty.getDefaultValues().get(0);
+
+ NodeList childNodes = root.getChildNodes();
+ assertEquals(2, childNodes.getLength());
+
+ Element e = (Element) childNodes.item(0);
+ assertEquals("http://foo.com", e.getNamespaceURI());
+ assertEquals("a", e.getLocalName());
+ assertEquals("AValue", e.getTextContent());
+ e = (Element) childNodes.item(1);
+ assertEquals("http://foo.com", e.getNamespaceURI());
+ assertEquals("b", e.getLocalName());
+ assertEquals("InterestingURI", e.getTextContent());
+ }
+
+ public void testPropertyLoading_Element() throws Exception {
+ String xml = "<tus:property xmlns:foo='http://foo.com' "
+ + "xmlns:tus='http://www.osoa.org/xmlns/sca/1.0'"
+ + " name='TestProperty' element='foo:TestElement'>\n"
+ + "<foo:TestElement>"
+ + "<foo:a>aValue</foo:a>"
+ + "<foo:b>InterestingURI</foo:b>"
+ + "</foo:TestElement>"
+ + "</tus:property>";
+ XMLStreamReader reader = getReader(xml);
+ Property<?> aProperty = propertyLoader.load(null, null, reader, null);
+
+ Element root = aProperty.getDefaultValues().get(0);
+
+ assertEquals("TestProperty", aProperty.getName());
+ assertEquals(new QName("http://foo.com", "TestElement", "foo"), aProperty.getXmlElement());
+ assertEquals(false, aProperty.isMustSupply());
+ assertEquals(false, aProperty.isMany());
+
+ NodeList childNodes = root.getChildNodes();
+ assertEquals(2, childNodes.getLength());
+
+ Element e = (Element) childNodes.item(0);
+ assertEquals("http://foo.com", e.getNamespaceURI());
+ assertEquals("a", e.getLocalName());
+ assertEquals("aValue", e.getTextContent());
+ e = (Element) childNodes.item(1);
+ assertEquals("http://foo.com", e.getNamespaceURI());
+ assertEquals("b", e.getLocalName());
+ assertEquals("InterestingURI", e.getTextContent());
+ }
+
+ public void testPropertyLoadingNoDefault() throws Exception {
+ String xml = "<tus:property xmlns:foo='http://foo.com' "
+ + "xmlns:tus='http://www.osoa.org/xmlns/sca/1.0'"
+ + " name='TestProperty' type='foo:TestType' mustSupply='true'>"
+ + "<foo:a>aValue</foo:a>"
+ + "<foo:b>InterestingURI</foo:b>"
+ + "</tus:property>";
+
+ XMLStreamReader reader = getReader(xml);
+
+ try {
+ propertyLoader.load(null, null, reader, null);
+ } catch (Exception e) {
+ assertTrue(e instanceof DefaultPropertyValueLoaderException);
+ }
+ }
+
+ public XMLStreamReader getReader(String xml) throws XMLStreamException {
+ XMLStreamReader reader = xmlFactory.createXMLStreamReader(new StringReader(xml));
+ reader.next();
+ return reader;
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ xmlFactory = XMLInputFactory.newInstance();
+ propertyLoader = new PropertyLoader(EasyMock.createMock(LoaderRegistry.class));
+ }
+
+ private void printNode(Node node) throws Exception {
+ javax.xml.transform.Transformer transformer =
+ TransformerFactory.newInstance().newTransformer();
+ JavaBean2DOMNodeTransformer java2DomTransformer = new JavaBean2DOMNodeTransformer();
+ StringWriter sw = new StringWriter();
+ transformer.transform(new DOMSource(node), new StreamResult(sw));
+
+ System.out.println(sw.toString());
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/PropertyParsingTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/PropertyParsingTestCase.java
new file mode 100644
index 0000000000..a82e5f6b72
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/PropertyParsingTestCase.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import java.io.StringReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.DocumentBuilder;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.spi.util.stax.StaxUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class PropertyParsingTestCase extends TestCase {
+ private XMLInputFactory xmlFactory;
+ private DocumentBuilder docBuilder;
+ private Element root;
+
+ public void testComplexProperty() throws XMLStreamException {
+ String xml = "<property xmlns:foo='http://foo.com'>"
+ + "<foo:a>aValue</foo:a>"
+ + "<foo:b>InterestingURI</foo:b>"
+ + "</property>";
+
+ XMLStreamReader reader = getReader(xml);
+ StaxUtil.loadPropertyValue(reader, root, root.getOwnerDocument());
+ NodeList childNodes = root.getChildNodes();
+ assertEquals(2, childNodes.getLength());
+
+ Element e = (Element) childNodes.item(0);
+ assertEquals("http://foo.com", e.getNamespaceURI());
+ assertEquals("a", e.getLocalName());
+ assertEquals("aValue", e.getTextContent());
+ e = (Element) childNodes.item(1);
+ assertEquals("http://foo.com", e.getNamespaceURI());
+ assertEquals("b", e.getLocalName());
+ assertEquals("InterestingURI", e.getTextContent());
+ }
+
+ public XMLStreamReader getReader(String xml) throws XMLStreamException {
+ XMLStreamReader reader = xmlFactory.createXMLStreamReader(new StringReader(xml));
+ reader.next();
+ return reader;
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ xmlFactory = XMLInputFactory.newInstance();
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+ docBuilder = docFactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+ root = doc.createElement("value");
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ReferenceLoaderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ReferenceLoaderTestCase.java
new file mode 100644
index 0000000000..6254835f13
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ReferenceLoaderTestCase.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.deployer.RootDeploymentContext;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.BindingDefinition;
+import org.apache.tuscany.spi.model.ComponentType;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.easymock.EasyMock;
+import org.osoa.sca.Constants;
+
+/**
+ * Verifies loading of a reference definition from an XML-based assembly
+ *
+ * @version $Rev$ $Date$
+ */
+public class ReferenceLoaderTestCase extends TestCase {
+ private static final QName REFERENCE = new QName(Constants.SCA_NS, "reference");
+
+ private ReferenceLoader loader;
+ private DeploymentContext deploymentContext;
+ private XMLStreamReader mockReader;
+ private LoaderRegistry mockRegistry;
+
+ public void testWithNoInterface() throws LoaderException, XMLStreamException {
+ String name = "referenceDefinition";
+ EasyMock.expect(mockReader.getName()).andReturn(REFERENCE).anyTimes();
+ EasyMock.expect(mockReader.getAttributeValue(null, "name")).andReturn(name);
+ EasyMock.expect(mockReader.getAttributeValue(null, "multiplicity")).andReturn("0..1");
+ EasyMock.expect(mockReader.getAttributeValue(null, "wiredByImpl")).andReturn("false");
+ EasyMock.expect(mockReader.getAttributeValue(null, "target")).andReturn(null);
+ EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.END_ELEMENT);
+ EasyMock.expect(mockReader.getName()).andReturn(REFERENCE).anyTimes();
+ EasyMock.replay(mockReader);
+ ComponentTypeReferenceDefinition referenceDefinition =
+ loader.load(null, new ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>(), mockReader, null);
+ assertNotNull(referenceDefinition);
+ assertEquals(name, referenceDefinition.getName());
+ }
+
+ public void testComponentTypeService() throws LoaderException, XMLStreamException {
+ String name = "reference";
+ EasyMock.expect(mockReader.getName()).andReturn(REFERENCE).anyTimes();
+ EasyMock.expect(mockReader.getAttributeValue(null, "name")).andReturn(name);
+ EasyMock.expect(mockReader.getAttributeValue(null, "multiplicity")).andReturn("0..1");
+ EasyMock.expect(mockReader.getAttributeValue(null, "wiredByImpl")).andReturn("false");
+ EasyMock.expect(mockReader.getAttributeValue(null, "target")).andReturn(null);
+ EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.END_ELEMENT);
+ EasyMock.expect(mockReader.getName()).andReturn(REFERENCE).anyTimes();
+ EasyMock.replay(mockReader);
+ ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> type =
+ new ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ ComponentTypeReferenceDefinition referenceDefinition = loader.load(null, type, mockReader, null);
+ assertTrue(ComponentTypeReferenceDefinition.class.equals(referenceDefinition.getClass()));
+ }
+
+ public void testMultipleBindings() throws LoaderException, XMLStreamException {
+ String name = "referenceDefinition";
+ EasyMock.expect(mockReader.getName()).andReturn(REFERENCE).anyTimes();
+ EasyMock.expect(mockReader.getAttributeValue(null, "name")).andReturn(name);
+ EasyMock.expect(mockReader.getAttributeValue(null, "multiplicity")).andReturn("0..1");
+ EasyMock.expect(mockReader.getAttributeValue(null, "wiredByImpl")).andReturn("false");
+ EasyMock.expect(mockReader.getAttributeValue(null, "target")).andReturn(null);
+ EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.START_ELEMENT).times(2);
+ EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.END_ELEMENT);
+ EasyMock.expect(mockReader.getName()).andReturn(REFERENCE).anyTimes();
+ EasyMock.replay(mockReader);
+
+ BindingDefinition binding = new BindingDefinition() {
+ public Object clone() {
+ return null;
+ }
+ };
+ EasyMock.expect(mockRegistry.load(null, null, mockReader, null)).andReturn(binding).times(2);
+ EasyMock.replay(mockRegistry);
+
+ ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> type =
+ new ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ ComponentTypeReferenceDefinition referenceDefinition = loader.load(null, type, mockReader, null);
+ assertEquals(2, referenceDefinition.getBindings().size());
+ }
+
+ public void testWithInterface() throws LoaderException, XMLStreamException {
+ String name = "referenceDefinition";
+ ServiceContract sc = new ServiceContract() {
+ };
+ EasyMock.expect(mockReader.getName()).andReturn(REFERENCE).anyTimes();
+ EasyMock.expect(mockReader.getAttributeValue(null, "name")).andReturn(name);
+ EasyMock.expect(mockReader.getAttributeValue(null, "multiplicity")).andReturn("0..1");
+ EasyMock.expect(mockReader.getAttributeValue(null, "wiredByImpl")).andReturn("false");
+ EasyMock.expect(mockReader.getAttributeValue(null, "target")).andReturn(null);
+ EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.START_ELEMENT);
+ EasyMock.expect(mockRegistry.load(null, null, mockReader, deploymentContext)).andReturn(sc);
+ EasyMock.expect(mockReader.next()).andReturn(XMLStreamConstants.END_ELEMENT);
+
+ EasyMock.replay(mockReader);
+ EasyMock.replay(mockRegistry);
+
+ ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> type =
+ new ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ ComponentTypeReferenceDefinition referenceDefinition = loader.load(null, type, mockReader, deploymentContext);
+ assertNotNull(referenceDefinition);
+ assertEquals(name, referenceDefinition.getName());
+ assertSame(sc, referenceDefinition.getServiceContract());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ mockReader = EasyMock.createStrictMock(XMLStreamReader.class);
+ mockRegistry = EasyMock.createMock(LoaderRegistry.class);
+ loader = new ReferenceLoader(mockRegistry);
+ deploymentContext = new RootDeploymentContext(null, null, null, null);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ServiceLoaderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ServiceLoaderTestCase.java
new file mode 100644
index 0000000000..6e13256440
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/ServiceLoaderTestCase.java
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import javax.xml.namespace.QName;
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import static org.osoa.sca.Constants.SCA_NS;
+
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.BindingDefinition;
+import org.apache.tuscany.spi.model.ComponentType;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.deployer.RootDeploymentContext;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+/**
+ * Verifies loading of a service definition from an XML-based assembly
+ *
+ * @version $Rev$ $Date$
+ */
+public class ServiceLoaderTestCase extends TestCase {
+ private static final QName SERVICE = new QName(SCA_NS, "service");
+ private static final QName BINDING = new QName(SCA_NS, "binding.foo");
+ private static final QName REFERENCE = new QName(SCA_NS, "reference");
+ private static final QName INTERFACE_JAVA = new QName(SCA_NS, "interface.java");
+
+ private ServiceLoader loader;
+ private DeploymentContext deploymentContext;
+ private XMLStreamReader mockReader;
+ private LoaderRegistry mockRegistry;
+
+ public void testWithNoInterface() throws LoaderException, XMLStreamException {
+ String name = "serviceDefinition";
+ expect(mockReader.getName()).andReturn(SERVICE).anyTimes();
+ expect(mockReader.getAttributeValue(null, "name")).andReturn(name);
+ expect(mockReader.next()).andReturn(END_ELEMENT);
+ expect(mockReader.getName()).andReturn(SERVICE).anyTimes();
+ replay(mockReader);
+ ServiceDefinition serviceDefinition = loader.load(null, null, mockReader, null);
+ assertNotNull(serviceDefinition);
+ assertEquals(name, serviceDefinition.getName());
+ }
+
+ public void testComponentTypeService() throws LoaderException, XMLStreamException {
+ String name = "service";
+ expect(mockReader.getName()).andReturn(SERVICE).anyTimes();
+ expect(mockReader.getAttributeValue(null, "name")).andReturn(name);
+ expect(mockReader.next()).andReturn(END_ELEMENT);
+ expect(mockReader.getName()).andReturn(SERVICE).anyTimes();
+ replay(mockReader);
+ ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> type =
+ new ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ ServiceDefinition serviceDefinition = loader.load(null, type, mockReader, null);
+ assertTrue(ServiceDefinition.class.equals(serviceDefinition.getClass()));
+ }
+
+ public void testMultipleBindings() throws LoaderException, XMLStreamException {
+ String name = "serviceDefinition";
+ expect(mockReader.getName()).andReturn(SERVICE).anyTimes();
+ expect(mockReader.getAttributeValue(null, "name")).andReturn(name);
+ expect(mockReader.next()).andReturn(START_ELEMENT);
+ expect(mockReader.getName()).andReturn(BINDING);
+ expect(mockReader.next()).andReturn(START_ELEMENT);
+ expect(mockReader.getName()).andReturn(BINDING);
+ expect(mockReader.next()).andReturn(END_ELEMENT);
+ expect(mockReader.getName()).andReturn(SERVICE).anyTimes();
+ replay(mockReader);
+
+ BindingDefinition binding = new BindingDefinition() {
+ public Object clone() {
+ return null;
+ }
+ };
+ expect(mockRegistry.load(null, null, mockReader, null)).andReturn(binding).times(2);
+ replay(mockRegistry);
+
+ ServiceDefinition serviceDefinition = loader.load(null, null, mockReader, null);
+ assertEquals(2, serviceDefinition.getBindings().size());
+ }
+
+ public void testWithInterface() throws LoaderException, XMLStreamException {
+ String name = "serviceDefinition";
+ String target = "target";
+ ServiceContract sc = new ServiceContract() {
+ };
+ expect(mockReader.getName()).andReturn(SERVICE).anyTimes();
+ expect(mockReader.getAttributeValue(null, "name")).andReturn(name);
+ expect(mockReader.next()).andReturn(START_ELEMENT);
+ expect(mockReader.getName()).andReturn(INTERFACE_JAVA);
+ expect(mockRegistry.load(null, null, mockReader, deploymentContext)).andReturn(sc);
+ expect(mockReader.next()).andReturn(START_ELEMENT);
+ expect(mockReader.getName()).andReturn(REFERENCE);
+ expect(mockReader.getElementText()).andReturn(target);
+ expect(mockReader.next()).andReturn(END_ELEMENT);
+ expect(mockReader.getName()).andReturn(REFERENCE);
+ expect(mockReader.next()).andReturn(END_ELEMENT);
+ expect(mockReader.getName()).andReturn(SERVICE);
+
+ replay(mockReader);
+ replay(mockRegistry);
+
+ ServiceDefinition serviceDefinition = loader.load(null, null, mockReader, deploymentContext);
+ assertNotNull(serviceDefinition);
+ assertEquals(name, serviceDefinition.getName());
+ assertSame(sc, serviceDefinition.getServiceContract());
+ }
+
+ public void testWithNoReference() throws LoaderException, XMLStreamException {
+ String name = "serviceDefinition";
+ ServiceContract sc = new ServiceContract() {
+ };
+ expect(mockReader.getName()).andReturn(SERVICE).anyTimes();
+ expect(mockReader.getAttributeValue(null, "name")).andReturn(name);
+ expect(mockReader.next()).andReturn(START_ELEMENT);
+ expect(mockReader.getName()).andReturn(INTERFACE_JAVA);
+ expect(mockRegistry.load(null, null, mockReader, deploymentContext)).andReturn(sc);
+ expect(mockReader.next()).andReturn(END_ELEMENT);
+ expect(mockReader.getName()).andReturn(SERVICE);
+
+ replay(mockReader);
+ replay(mockRegistry);
+
+ ServiceDefinition serviceDefinition = loader.load(null, null, mockReader, deploymentContext);
+ assertNotNull(serviceDefinition);
+ assertEquals(name, serviceDefinition.getName());
+ assertSame(sc, serviceDefinition.getServiceContract());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ mockReader = EasyMock.createStrictMock(XMLStreamReader.class);
+ mockRegistry = EasyMock.createMock(LoaderRegistry.class);
+ loader = new ServiceLoader(mockRegistry);
+ deploymentContext = new RootDeploymentContext(null, null, null, null);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/StAXLoaderRegistryImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/StAXLoaderRegistryImplTestCase.java
new file mode 100644
index 0000000000..74a40c80a9
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/StAXLoaderRegistryImplTestCase.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.StAXElementLoader;
+import org.apache.tuscany.spi.loader.UnrecognizedElementException;
+import org.apache.tuscany.spi.model.ModelObject;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.deployer.RootDeploymentContext;
+import static org.easymock.EasyMock.isNull;
+import org.easymock.classextension.EasyMock;
+
+/**
+ * Verifies the default loader registry
+ *
+ * @version $Rev$ $Date$
+ */
+public class StAXLoaderRegistryImplTestCase extends TestCase {
+ private LoaderRegistryImpl registry;
+ private QName name;
+ private LoaderRegistryImpl.Monitor mockMonitor;
+ private StAXElementLoader<ModelObject> mockLoader;
+ private XMLStreamReader mockReader;
+ private DeploymentContext deploymentContext;
+ private ModelObject modelObject;
+
+ public void testLoaderRegistration() {
+ mockMonitor.registeringLoader(EasyMock.eq(name));
+ EasyMock.replay(mockMonitor);
+ registry.registerLoader(name, mockLoader);
+ EasyMock.verify(mockMonitor);
+ }
+
+ public void testLoaderUnregistration() {
+ mockMonitor.unregisteringLoader(EasyMock.eq(name));
+ EasyMock.replay(mockMonitor);
+ registry.unregisterLoader(name, (StAXElementLoader<ModelObject>) mockLoader);
+ EasyMock.verify(mockMonitor);
+ }
+
+ public void testSuccessfulDispatch() throws LoaderException, XMLStreamException {
+ EasyMock.expect(mockReader.getName()).andReturn(name);
+ EasyMock.replay(mockReader);
+ mockMonitor.registeringLoader(EasyMock.eq(name));
+ mockMonitor.elementLoad(EasyMock.eq(name));
+ EasyMock.replay(mockMonitor);
+ EasyMock.expect(mockLoader.load(EasyMock.isA(CompositeComponent.class),
+ (ModelObject) isNull(),
+ EasyMock.eq(mockReader),
+ EasyMock.eq(deploymentContext))).andReturn(modelObject);
+ EasyMock.replay(mockLoader);
+ registry.registerLoader(name, (StAXElementLoader<ModelObject>) mockLoader);
+ CompositeComponent parent = EasyMock.createNiceMock(CompositeComponent.class);
+ assertSame(modelObject, registry.load(parent, null, mockReader, deploymentContext));
+ EasyMock.verify(mockLoader);
+ EasyMock.verify(mockMonitor);
+ EasyMock.verify(mockReader);
+
+ }
+
+ public void testUnsuccessfulDispatch() throws LoaderException, XMLStreamException {
+ EasyMock.expect(mockReader.getName()).andReturn(name);
+ EasyMock.replay(mockReader);
+ mockMonitor.elementLoad(EasyMock.eq(name));
+ EasyMock.replay(mockMonitor);
+ try {
+ registry.load(null, null, mockReader, deploymentContext);
+ fail();
+ } catch (UnrecognizedElementException e) {
+ assertSame(name, e.getElement());
+ }
+ EasyMock.verify(mockReader);
+ EasyMock.verify(mockMonitor);
+ }
+
+ public void testPregivenModelObject() throws Exception {
+ EasyMock.expect(mockReader.getName()).andReturn(name);
+ EasyMock.replay(mockReader);
+ mockMonitor.registeringLoader(EasyMock.eq(name));
+ mockMonitor.elementLoad(EasyMock.eq(name));
+ EasyMock.replay(mockMonitor);
+ EasyMock.expect(mockLoader.load(EasyMock.isA(CompositeComponent.class),
+ EasyMock.eq(modelObject),
+ EasyMock.eq(mockReader),
+ EasyMock.eq(deploymentContext))).andReturn(modelObject);
+ EasyMock.replay(mockLoader);
+ registry.registerLoader(name, (StAXElementLoader<ModelObject>) mockLoader);
+ CompositeComponent parent = EasyMock.createNiceMock(CompositeComponent.class);
+ assertSame(modelObject, registry.load(parent, modelObject, mockReader, deploymentContext));
+ EasyMock.verify(mockLoader);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void setUp() throws Exception {
+ super.setUp();
+ name = new QName("http://mock", "test");
+ deploymentContext = new RootDeploymentContext(null, null, null, null);
+ mockMonitor = EasyMock.createMock(LoaderRegistryImpl.Monitor.class);
+ registry = new LoaderRegistryImpl(mockMonitor);
+
+ mockLoader = EasyMock.createMock(StAXElementLoader.class);
+ mockReader = EasyMock.createMock(XMLStreamReader.class);
+ modelObject = new ModelObject() {
+ };
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/StringParserPropertyFactoryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/StringParserPropertyFactoryTestCase.java
new file mode 100644
index 0000000000..002eb6646e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/StringParserPropertyFactoryTestCase.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.PropertyValue;
+import org.easymock.EasyMock;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class StringParserPropertyFactoryTestCase extends TestCase {
+
+ private <T> PropertyValue<T> mock(String value) {
+ Document document = EasyMock.createMock(Document.class);
+ Element element = EasyMock.createMock(Element.class);
+ //EasyMock.expect(document.getDocumentElement()).andReturn(element);
+ EasyMock.expect(element.getTextContent()).andReturn(value);
+ EasyMock.replay(document, element);
+
+ List<Element> valueList = new ArrayList<Element>();
+ valueList.add(element);
+ return new PropertyValue<T>(null, valueList);
+ }
+
+ public void testInteger() throws Exception {
+
+ StringParserPropertyFactory factory = new StringParserPropertyFactory();
+ Property<Integer> property = new Property<Integer>();
+ property.setJavaType(Integer.class);
+ PropertyValue<Integer> propertyValue = mock("1");
+ ObjectFactory<Integer> oFactory = factory.createObjectFactory(property, propertyValue);
+ assertEquals(1, oFactory.getInstance().intValue());
+ }
+
+ public void testPrimitiveInt() throws Exception {
+ StringParserPropertyFactory factory = new StringParserPropertyFactory();
+ Property<Integer> property = new Property<Integer>();
+ property.setJavaType(Integer.TYPE);
+ PropertyValue<Integer> propertyValue = mock("1");
+ ObjectFactory<Integer> oFactory = factory.createObjectFactory(property, propertyValue);
+ assertEquals(1, oFactory.getInstance().intValue());
+ }
+
+ public void testString() throws Exception {
+ StringParserPropertyFactory factory = new StringParserPropertyFactory();
+ Property<String> property = new Property<String>();
+ property.setJavaType(String.class);
+ PropertyValue<String> propertyValue = mock("1");
+ ObjectFactory<String> oFactory = factory.createObjectFactory(property, propertyValue);
+ assertEquals("1", oFactory.getInstance());
+ }
+
+ public void testByteArray() throws Exception {
+ StringParserPropertyFactory factory = new StringParserPropertyFactory();
+ Property<byte[]> property = new Property<byte[]>();
+ property.setJavaType(byte[].class);
+ PropertyValue<byte[]> propertyValue = mock("1");
+ ObjectFactory<byte[]> oFactory = factory.createObjectFactory(property, propertyValue);
+ byte[] result = oFactory.getInstance();
+ byte[] expected = "1".getBytes();
+ for (int i = 0; i < result.length; i++) {
+ byte b = result[i];
+ if (b != expected[i]) {
+ fail();
+ }
+ }
+ }
+
+ public void testBoolean() throws Exception {
+ StringParserPropertyFactory factory = new StringParserPropertyFactory();
+ Property<Boolean> property = new Property<Boolean>();
+ property.setJavaType(Boolean.class);
+ PropertyValue<Boolean> propertyValue = mock("true");
+ ObjectFactory<Boolean> oFactory = factory.createObjectFactory(property, propertyValue);
+ assertTrue(oFactory.getInstance());
+ }
+
+ public void testPrimitiveBoolean() throws Exception {
+ StringParserPropertyFactory factory = new StringParserPropertyFactory();
+ Property<Boolean> property = new Property<Boolean>();
+ property.setJavaType(Boolean.TYPE);
+ PropertyValue<Boolean> propertyValue = mock("true");
+ ObjectFactory<Boolean> oFactory = factory.createObjectFactory(property, propertyValue);
+ assertTrue(oFactory.getInstance());
+ }
+
+ public void testStringConstructor() throws Exception {
+ StringParserPropertyFactory factory = new StringParserPropertyFactory();
+ Property<Foo> property = new Property<Foo>();
+ property.setJavaType(Foo.class);
+ PropertyValue<Foo> propertyValue = mock("test");
+ ObjectFactory<Foo> oFactory = factory.createObjectFactory(property, propertyValue);
+ assertEquals("test", oFactory.getInstance().getFoo());
+ }
+
+ private static class Foo {
+ private String foo;
+
+ public Foo(String foo) {
+ this.foo = foo;
+ }
+
+ public String getFoo() {
+ return foo;
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/WireLoaderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/WireLoaderTestCase.java
new file mode 100644
index 0000000000..2e42c0e70d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/loader/WireLoaderTestCase.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.loader;
+
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import org.easymock.EasyMock;
+
+import static org.osoa.sca.Constants.SCA_NS;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.Location;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.loader.InvalidWireException;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.model.WireDefinition;
+
+/**
+ * @version $Rev: 471504 $ $Date: 2006-11-06 01:10:40 +0530 (Mon, 06 Nov 2006) $
+ */
+public class WireLoaderTestCase extends TestCase {
+ private static final QName WIRE = new QName(SCA_NS, "wire");
+ private static final QName SOURCE_URI = new QName(SCA_NS, "source.uri");
+ private static final QName TARGET_URI = new QName(SCA_NS, "target.uri");
+
+ private LoaderRegistry registry;
+ private WireLoader loader;
+ private XMLStreamReader reader;
+ private DeploymentContext context;
+ private CompositeComponent composite;
+
+ public void testValidWire() throws LoaderException, XMLStreamException {
+ expect(reader.getName()).andReturn(WIRE);
+ expect(reader.next()).andReturn(START_ELEMENT);
+ expect(reader.getName()).andReturn(SOURCE_URI).times(1);
+ expect(reader.getElementText()).andReturn("source").times(1);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.next()).andReturn(START_ELEMENT);
+ expect(reader.getName()).andReturn(TARGET_URI).times(2);
+ expect(reader.getElementText()).andReturn("target").times(1);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.getName()).andReturn(WIRE).anyTimes();
+ replay(registry, reader, context);
+ WireDefinition wireDef = loader.load(composite, null, reader, context);
+ assertNotNull(wireDef);
+ verify(registry, reader, context);
+ }
+
+ public void testInValidWireNoSourceElement() throws LoaderException, XMLStreamException {
+ expect(reader.getName()).andReturn(WIRE).times(1);
+ expect(reader.next()).andReturn(START_ELEMENT);
+ expect(reader.getName()).andReturn(TARGET_URI).times(2);
+ expect(reader.getElementText()).andReturn("target").times(1);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.getName()).andReturn(WIRE).anyTimes();
+ replay(registry, reader, context);
+ try {
+ loader.load(composite, null, reader, context);
+ fail();
+ } catch (InvalidWireException e) {
+ //expected behaviour
+ }
+ verify(registry, reader, context);
+ }
+
+ public void testInValidWireNoTargetElement() throws LoaderException, XMLStreamException {
+ expect(reader.getName()).andReturn(WIRE).times(1);
+ expect(reader.next()).andReturn(START_ELEMENT);
+ expect(reader.getName()).andReturn(SOURCE_URI).times(1);
+ expect(reader.getElementText()).andReturn("source").times(1);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.getName()).andReturn(WIRE).anyTimes();
+ replay(registry, reader, context);
+ try {
+ loader.load(composite, null, reader, context);
+ fail();
+ } catch (InvalidWireException e) {
+ //expected behaviour
+ }
+ verify(registry, reader, context);
+ }
+
+ public void testInValidWireNoSourceSpecified() throws LoaderException, XMLStreamException {
+ expect(reader.getName()).andReturn(WIRE).times(1);
+ expect(reader.next()).andReturn(START_ELEMENT);
+ expect(reader.getName()).andReturn(SOURCE_URI).times(1);
+ expect(reader.getElementText()).andReturn("").times(1);
+ replay(registry, reader, context);
+ try {
+ loader.load(composite, null, reader, context);
+ fail();
+ } catch (InvalidWireException e) {
+ //expected behaviour
+ }
+ verify(registry, reader, context);
+ }
+
+ public void testInValidWireNoTargetSpecified() throws LoaderException, XMLStreamException {
+ expect(reader.getName()).andReturn(WIRE).times(1);
+ expect(reader.next()).andReturn(START_ELEMENT);
+ expect(reader.getName()).andReturn(SOURCE_URI).times(1);
+ expect(reader.getElementText()).andReturn("source").times(1);
+ expect(reader.next()).andReturn(END_ELEMENT);
+ expect(reader.next()).andReturn(START_ELEMENT);
+ expect(reader.getName()).andReturn(TARGET_URI).times(2);
+ expect(reader.getElementText()).andReturn("").times(1);
+ expect(reader.getName()).andReturn(WIRE).anyTimes();
+ replay(registry, reader, context);
+ try {
+ loader.load(composite, null, reader, context);
+ fail();
+ } catch (InvalidWireException e) {
+ //expected behaviour
+ }
+ verify(registry, reader, context);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ registry = createMock(LoaderRegistry.class);
+ reader = createMock(XMLStreamReader.class);
+ Location location = EasyMock.createNiceMock(Location.class);
+ EasyMock.replay(location);
+ EasyMock.expect(reader.getLocation()).andReturn(location).anyTimes();
+ context = createMock(DeploymentContext.class);
+ composite = createMock(CompositeComponent.class);
+ loader = new WireLoader(registry);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/binding/MockServiceBinding.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/binding/MockServiceBinding.java
new file mode 100644
index 0000000000..8a38665584
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/binding/MockServiceBinding.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.binding;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.component.AbstractSCAObject;
+import org.apache.tuscany.spi.component.Service;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.component.TargetInvokerCreationException;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MockServiceBinding extends AbstractSCAObject implements ServiceBinding {
+ private InboundWire inboundWire;
+ private OutboundWire outboundWire;
+ private ServiceContract<?> bindingServiceContract;
+
+
+ public MockServiceBinding() {
+ super("foo", null);
+ }
+
+ public QName getBindingType() {
+ return null;
+ }
+
+ public void setService(Service service) {
+ }
+
+ public ServiceContract<?> getBindingServiceContract() {
+ return bindingServiceContract;
+ }
+
+ public InboundWire getInboundWire() {
+ return inboundWire;
+ }
+
+ public void setInboundWire(InboundWire inboundWire) {
+ this.inboundWire = inboundWire;
+ }
+
+ public OutboundWire getOutboundWire() {
+ return outboundWire;
+ }
+
+ public void setOutboundWire(OutboundWire outboundWire) {
+ this.outboundWire = outboundWire;
+ }
+
+ public TargetInvoker createTargetInvoker(ServiceContract contract, Operation operation)
+ throws TargetInvokerCreationException {
+ return null;
+ }
+
+ public Scope getScope() {
+ return null;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/AsyncTarget.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/AsyncTarget.java
new file mode 100644
index 0000000000..653d5d7335
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/AsyncTarget.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.OneWay;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface AsyncTarget {
+ @OneWay
+ void invoke();
+
+ int getCount();
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/BadContextPojo.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/BadContextPojo.java
new file mode 100644
index 0000000000..066acc346d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/BadContextPojo.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Context;
+
+public class BadContextPojo {
+
+ @Context
+ String context;
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/BadNamePojo.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/BadNamePojo.java
new file mode 100644
index 0000000000..77ec37f9e4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/BadNamePojo.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.ComponentName;
+
+public class BadNamePojo {
+ @ComponentName
+ private int name;
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/BasicInterface.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/BasicInterface.java
new file mode 100644
index 0000000000..b7921c248f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/BasicInterface.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface BasicInterface {
+ String returnsProperty();
+
+ BasicInterface returnsReference();
+
+ int returnsInt();
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/BasicInterfaceImpl.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/BasicInterfaceImpl.java
new file mode 100644
index 0000000000..f7d7bb38cf
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/BasicInterfaceImpl.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Property;
+import org.osoa.sca.annotations.Reference;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class BasicInterfaceImpl implements BasicInterface {
+
+ @Property
+ public String publicProperty;
+
+ @Reference (required = false)
+ public BasicInterface publicReference;
+
+ @Property
+ protected String protectedProperty;
+
+ @Reference (required = false)
+ protected BasicInterface protectedReference;
+
+ private String privateProperty;
+
+ private BasicInterface privateReference;
+
+ @Property
+ public void setPrivateProperty(String privateProperty) {
+ this.privateProperty = privateProperty;
+ }
+
+ @Reference (required = false)
+ public void setPrivateReference(BasicInterface privateReference) {
+ this.privateReference = privateReference;
+ }
+
+ public String returnsProperty() {
+ return privateProperty;
+ }
+
+ public BasicInterface returnsReference() {
+ return privateReference;
+ }
+
+ public int returnsInt() {
+ return 0;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeComponent.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeComponent.java
new file mode 100644
index 0000000000..88b97216cd
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeComponent.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * @version $Rev$ $Date$
+ */
+@Scope("COMPOSITE")
+public interface CompositeScopeComponent {
+
+ //public boolean isInit();
+}
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeComponentImpl.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeComponentImpl.java
new file mode 100644
index 0000000000..93ee1f707a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeComponentImpl.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Scope;
+
+
+/**
+ * @version $Rev$ $Date$
+ */
+@Scope("COMPOSITE")
+public class CompositeScopeComponentImpl implements
+ CompositeScopeComponent {
+
+ private String foo;
+
+ public void setFoo(String foo) {
+ this.foo = foo;
+ }
+
+ public String getFoo() {
+ return foo;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeDestroyOnlyComponent.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeDestroyOnlyComponent.java
new file mode 100644
index 0000000000..16ce3b5569
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeDestroyOnlyComponent.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Destroy;
+
+public class CompositeScopeDestroyOnlyComponent extends CompositeScopeComponentImpl {
+
+ boolean destroyed;
+
+ public boolean isDestroyed() {
+ return destroyed;
+ }
+
+ @Destroy
+ public void destroy() {
+ destroyed = true;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeInitDestroyComponent.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeInitDestroyComponent.java
new file mode 100644
index 0000000000..05b938a87c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeInitDestroyComponent.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Destroy;
+
+public class CompositeScopeInitDestroyComponent extends CompositeScopeInitOnlyComponent {
+
+ boolean destroyed;
+
+ public boolean isDestroyed() {
+ return destroyed;
+ }
+
+ @Destroy
+ public void destroy() {
+ if (destroyed) {
+ throw new AssertionError("Destroy called more than once");
+ }
+ destroyed = true;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeInitOnlyComponent.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeInitOnlyComponent.java
new file mode 100644
index 0000000000..f9f80ca15c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/CompositeScopeInitOnlyComponent.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Init;
+
+public class CompositeScopeInitOnlyComponent extends CompositeScopeComponentImpl {
+
+ private boolean initialized;
+ // this value tests to ensure introspection can find the init() method even
+ // if a field is named the same. Ultimately, this should be in the introspection tests
+ private boolean init;
+
+ public boolean isInitialized() {
+ return initialized;
+ }
+
+ @Init
+ public void init() {
+ if (initialized) {
+ throw new AssertionError("Init called more than once");
+ }
+ initialized = true;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeComponent.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeComponent.java
new file mode 100644
index 0000000000..c71ac0586f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeComponent.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * @version $Rev: 430937 $ $Date: 2006-08-11 21:17:56 -0400 (Fri, 11 Aug 2006) $
+ */
+@Scope("CONVERSATION")
+public interface ConversationalScopeComponent {
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeComponentImpl.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeComponentImpl.java
new file mode 100644
index 0000000000..5ea7278e1f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeComponentImpl.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * @version $Rev: 430937 $ $Date: 2006-08-11 21:17:56 -0400 (Fri, 11 Aug 2006) $
+ */
+@Scope("CONVERSATION")
+public class ConversationalScopeComponentImpl implements ConversationalScopeComponent {
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeDestroyOnlyComponent.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeDestroyOnlyComponent.java
new file mode 100644
index 0000000000..8cea9efa49
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeDestroyOnlyComponent.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.Scope;
+
+@Scope("CONVERSATION")
+public class ConversationalScopeDestroyOnlyComponent extends ConversationalScopeComponentImpl {
+
+ boolean destroyed;
+
+ public boolean isDestroyed() {
+ return destroyed;
+ }
+
+ @Destroy
+ public void destroy() {
+ destroyed = true;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeInitDestroyComponent.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeInitDestroyComponent.java
new file mode 100644
index 0000000000..40dbfedf2c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeInitDestroyComponent.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.Scope;
+
+@Scope("CONVERSATION")
+public class ConversationalScopeInitDestroyComponent
+ extends ConversationalScopeInitOnlyComponent {
+
+ private boolean destroyed;
+
+ public boolean isDestroyed() {
+ return destroyed;
+ }
+
+ @Destroy
+ public void destroy() {
+ destroyed = true;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeInitOnlyComponent.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeInitOnlyComponent.java
new file mode 100644
index 0000000000..caaa0c39e7
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/ConversationalScopeInitOnlyComponent.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Scope;
+
+@Scope("CONVERSATION")
+public class ConversationalScopeInitOnlyComponent
+ extends ConversationalScopeComponentImpl {
+
+ private boolean initialized;
+
+ public boolean isInitialized() {
+ return initialized;
+ }
+
+ @Init
+ public void init() {
+ initialized = true;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderException.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderException.java
new file mode 100644
index 0000000000..af257c226d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderException.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+public class OrderException extends Exception {
+
+ public OrderException() {
+ super();
+ }
+
+ public OrderException(String message) {
+ super(message);
+ }
+
+ public OrderException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public OrderException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedDependentPojo.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedDependentPojo.java
new file mode 100644
index 0000000000..2033f0eca5
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedDependentPojo.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public interface OrderedDependentPojo extends OrderedInitPojo {
+
+ OrderedInitPojo getPojo();
+
+ void setPojo(OrderedInitPojo pojo);
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedDependentPojoImpl.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedDependentPojoImpl.java
new file mode 100644
index 0000000000..439c3d143c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedDependentPojoImpl.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public class OrderedDependentPojoImpl extends OrderedInitPojoImpl implements OrderedDependentPojo {
+
+ private OrderedInitPojo pojo;
+
+ public OrderedInitPojo getPojo() {
+ return pojo;
+ }
+
+ public void setPojo(OrderedInitPojo pojo) {
+ this.pojo = pojo;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedEagerInitPojo.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedEagerInitPojo.java
new file mode 100644
index 0000000000..1986952747
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedEagerInitPojo.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Scope;
+import org.osoa.sca.annotations.EagerInit;
+
+@Scope("COMPOSITE")
+@EagerInit
+public class OrderedEagerInitPojo {
+
+ private static final Object LOCK = new Object();
+ private static int numberInstantied;
+ private int initOrder;
+
+ @Init
+ public void init() {
+ synchronized (LOCK) {
+ ++numberInstantied;
+ initOrder = numberInstantied;
+ }
+ }
+
+ @Destroy
+ public void destroy() throws OrderException {
+ synchronized (LOCK) {
+ if (initOrder != numberInstantied) {
+ throw new OrderException("Instance shutdown done out of order");
+ }
+ --numberInstantied;
+ }
+ }
+
+ public int getNumberInstantiated() {
+ return numberInstantied;
+ }
+
+ public int getInitOrder() {
+ return initOrder;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedInitPojo.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedInitPojo.java
new file mode 100644
index 0000000000..0b891cfa42
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedInitPojo.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public interface OrderedInitPojo {
+ int getNumberInstantiated();
+
+ int getInitOrder();
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedInitPojoImpl.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedInitPojoImpl.java
new file mode 100644
index 0000000000..a7063f6353
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OrderedInitPojoImpl.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Scope;
+
+@Scope("COMPOSITE")
+public class OrderedInitPojoImpl implements OrderedInitPojo {
+
+ private static final Object LOCK = new Object();
+ private static int numberInstantied;
+ private int initOrder;
+
+ public OrderedInitPojoImpl() {
+ }
+
+ @Init
+ public void init() {
+ synchronized (LOCK) {
+ ++numberInstantied;
+ initOrder = numberInstantied;
+ }
+ }
+
+ @Destroy
+ public void destroy() throws OrderException {
+ synchronized (LOCK) {
+ if (initOrder != numberInstantied) {
+ throw new OrderException("Instance shutdown done out of order");
+ }
+ --numberInstantied;
+ }
+ }
+
+ public int getNumberInstantiated() {
+ return numberInstantied;
+ }
+
+ public int getInitOrder() {
+ return initOrder;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OtherTarget.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OtherTarget.java
new file mode 100644
index 0000000000..0b897daa40
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OtherTarget.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+/**
+ * Implementations are used in wiring tests
+ *
+ * @version $Rev$ $Date$
+ */
+public interface OtherTarget {
+
+ String getString();
+
+ void setString(String val);
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OtherTargetImpl.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OtherTargetImpl.java
new file mode 100644
index 0000000000..a3b2bbf098
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/OtherTargetImpl.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+/**
+ * A target used for testing wires with a different source and target interface
+ *
+ * @version $Rev$ $Date$
+ */
+public class OtherTargetImpl implements OtherTarget {
+
+ private String theString;
+
+ public String getString() {
+ return theString;
+ }
+
+ public void setString(String val) {
+ theString = val;
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeComponent.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeComponent.java
new file mode 100644
index 0000000000..8c7dc107ee
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeComponent.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * @version $Rev$ $Date$
+ */
+@Scope("REQUEST")
+public interface RequestScopeComponent {
+
+}
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeDestroyOnlyComponent.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeDestroyOnlyComponent.java
new file mode 100644
index 0000000000..5224ceda5f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeDestroyOnlyComponent.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.Scope;
+
+@Scope("REQUEST")
+public class RequestScopeDestroyOnlyComponent extends SessionScopeComponentImpl {
+
+ boolean destroyed;
+
+ public boolean isDestroyed() {
+ return destroyed;
+ }
+
+ @Destroy
+ public void destroy() {
+ destroyed = true;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeInitDestroyComponent.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeInitDestroyComponent.java
new file mode 100644
index 0000000000..38b188a4b5
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeInitDestroyComponent.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.Scope;
+
+@Scope("REQUEST")
+public class RequestScopeInitDestroyComponent extends SessionScopeInitOnlyComponent {
+
+ boolean destroyed;
+
+ public boolean isDestroyed() {
+ return destroyed;
+ }
+
+ @Destroy
+ public void destroy() {
+ destroyed = true;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeInitOnlyComponent.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeInitOnlyComponent.java
new file mode 100644
index 0000000000..707f8ab50f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/RequestScopeInitOnlyComponent.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Scope;
+
+@Scope("REQUEST")
+public class RequestScopeInitOnlyComponent extends SessionScopeComponentImpl {
+
+ private boolean initialized;
+
+ public boolean isInitialized() {
+ return initialized;
+ }
+
+ @Init
+ public void init() {
+ initialized = true;
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeComponent.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeComponent.java
new file mode 100644
index 0000000000..827ba804f2
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeComponent.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * @version $Rev$ $Date$
+ */
+@Scope("SESSION")
+public interface SessionScopeComponent {
+
+}
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeComponentImpl.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeComponentImpl.java
new file mode 100644
index 0000000000..e547bf6113
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeComponentImpl.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * @version $Rev$ $Date$
+ */
+@Scope("SESSION")
+public class SessionScopeComponentImpl implements
+ SessionScopeComponent {
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeInitDestroyComponent.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeInitDestroyComponent.java
new file mode 100644
index 0000000000..c11bd1bd49
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeInitDestroyComponent.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Destroy;
+
+public class SessionScopeInitDestroyComponent extends SessionScopeInitOnlyComponent {
+
+ private boolean destroyed;
+
+ public boolean isDestroyed() {
+ return destroyed;
+ }
+
+ @Destroy
+ public void destroy() {
+ destroyed = true;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeInitOnlyComponent.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeInitOnlyComponent.java
new file mode 100644
index 0000000000..095cc916ec
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SessionScopeInitOnlyComponent.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Init;
+
+public class SessionScopeInitOnlyComponent extends SessionScopeComponentImpl {
+
+ private boolean initialized;
+
+ public boolean isInitialized() {
+ return initialized;
+ }
+
+ @Init
+ public void init() {
+ initialized = true;
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SimpleTarget.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SimpleTarget.java
new file mode 100644
index 0000000000..c78ba00a7a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SimpleTarget.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+public interface SimpleTarget {
+
+ String hello(String message) throws Exception;
+
+ String goodbye(String message) throws Exception;
+
+ String echo(String message) throws Exception;
+
+}
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SimpleTargetImpl.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SimpleTargetImpl.java
new file mode 100644
index 0000000000..634a07a401
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SimpleTargetImpl.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+public class SimpleTargetImpl implements SimpleTarget {
+
+ public SimpleTargetImpl() {
+ super();
+ }
+
+ public String hello(String message) throws Exception {
+ return message;
+ }
+
+ public String goodbye(String message) throws Exception {
+ return message;
+ }
+
+ public String echo(String message) throws Exception {
+ return message;
+ }
+
+
+}
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/Source.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/Source.java
new file mode 100644
index 0000000000..f7969f748b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/Source.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import java.util.List;
+
+/**
+ * Implementations are used in wiring tests
+ *
+ * @version $Rev$ $Date$
+ */
+public interface Source {
+
+ Target getTarget();
+
+ List<Target> getTargets();
+
+ List<Target> getTargetsThroughField();
+
+}
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SourceImpl.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SourceImpl.java
new file mode 100644
index 0000000000..187e33b2bd
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/SourceImpl.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import java.util.List;
+
+/**
+ * Mock system component implementation used in wiring tests
+ *
+ * @version $Rev$ $Date$
+ */
+public class SourceImpl implements Source {
+
+ private Target target;
+ private List<Target> targets;
+ private List<Target> targetsThroughField;
+ private Target[] targetsArray;
+
+ public void setTarget(Target target) {
+ this.target = target;
+ }
+
+ public Target getTarget() {
+ return target;
+ }
+
+ public List<Target> getTargets() {
+ return targets;
+ }
+
+ public void setTargets(List<Target> targets) {
+ this.targets = targets;
+ }
+
+ public List<Target> getTargetsThroughField() {
+ return targetsThroughField;
+ }
+
+ public Target[] getArrayOfTargets() {
+ return targetsArray;
+ }
+
+ public void setArrayOfTargets(Target[] targets) {
+ targetsArray = targets;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/StatelessComponent.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/StatelessComponent.java
new file mode 100644
index 0000000000..c16ac942a3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/StatelessComponent.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * @version $Rev$ $Date$
+ */
+@Scope("STATELESS")
+public interface StatelessComponent {
+
+}
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/StatelessComponentImpl.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/StatelessComponentImpl.java
new file mode 100644
index 0000000000..64a23c12c8
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/StatelessComponentImpl.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class StatelessComponentImpl implements
+ StatelessComponent {
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/Target.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/Target.java
new file mode 100644
index 0000000000..778c14665d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/Target.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+/**
+ * Implementations are used in wiring tests
+ *
+ * @version $Rev$ $Date$
+ */
+public interface Target {
+
+ String getString();
+
+ void setString(String val);
+}
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/TargetImpl.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/TargetImpl.java
new file mode 100644
index 0000000000..037dd3a37c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/component/TargetImpl.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.component;
+
+/**
+ * Mock system component implementation used in wiring tests
+ *
+ * @version $Rev$ $Date$
+ */
+public class TargetImpl implements Target {
+
+ private String theString;
+
+ public String getString() {
+ return theString;
+ }
+
+ public void setString(String val) {
+ theString = val;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/wire/MockStaticInvoker.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/wire/MockStaticInvoker.java
new file mode 100644
index 0000000000..cdd0de7a6d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/wire/MockStaticInvoker.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.wire;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+/**
+ * Caches component instances that do not need to be resolved for every wire, e.g. an wire originating from a lesser
+ * scope intended for a target with a wider scope
+ *
+ * @version $Rev$ $Date$
+ */
+public class MockStaticInvoker implements TargetInvoker {
+
+ private Object instance;
+ private Method operation;
+ private boolean cacheable;
+
+
+ public MockStaticInvoker(Method operation, Object instance) {
+ this.operation = operation;
+ this.instance = instance;
+ }
+
+ public boolean isCacheable() {
+ return cacheable;
+ }
+
+ public void setCacheable(boolean cacheable) {
+ this.cacheable = cacheable;
+ }
+
+ public boolean isOptimizable() {
+ return isCacheable();
+ }
+
+ public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException {
+ try {
+ if (payload != null && !payload.getClass().isArray()) {
+ return operation.invoke(instance, payload);
+ } else {
+ return operation.invoke(instance, (Object[]) payload);
+ }
+ } catch (IllegalAccessException e) {
+ throw new InvocationRuntimeException(e);
+ }
+ }
+
+ public Message invoke(Message msg) throws InvocationRuntimeException {
+ try {
+ Object resp = invokeTarget(msg.getBody(), TargetInvoker.NONE);
+ msg.setBody(resp);
+ } catch (InvocationTargetException e) {
+ msg.setBodyWithFault(e.getCause());
+ } catch (Throwable e) {
+ msg.setBodyWithFault(e);
+ }
+ return msg;
+ }
+
+ public void setNext(Interceptor next) {
+ throw new IllegalStateException("This interceptor must be the last interceptor in an interceptor chain");
+ }
+
+ public Object clone() throws CloneNotSupportedException {
+ try {
+ MockStaticInvoker invoker = (MockStaticInvoker) super.clone();
+ invoker.instance = this.instance;
+ invoker.operation = this.operation;
+ return invoker;
+ } catch (CloneNotSupportedException e) {
+ return null; // will not happen
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/wire/MockSyncInterceptor.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/wire/MockSyncInterceptor.java
new file mode 100644
index 0000000000..1fe2c027ab
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/wire/MockSyncInterceptor.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.wire;
+
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+
+public class MockSyncInterceptor implements Interceptor {
+
+ private int count;
+
+ private Interceptor next;
+
+ public MockSyncInterceptor() {
+ }
+
+ public Message invoke(Message msg) {
+ ++count;
+ return next.invoke(msg);
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public void setNext(Interceptor next) {
+ this.next = next;
+ }
+
+ public Interceptor getNext() {
+ return next;
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+
+}
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/wire/MockTargetInvoker.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/wire/MockTargetInvoker.java
new file mode 100644
index 0000000000..3fcc75bdb4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/mock/wire/MockTargetInvoker.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.mock.wire;
+
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.Message;
+
+import org.apache.tuscany.core.binding.local.AbstractLocalTargetInvoker;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MockTargetInvoker extends AbstractLocalTargetInvoker {
+ public Message invoke(Message msg) throws InvocationRuntimeException {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/monitor/DefaultExceptionFormatterTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/monitor/DefaultExceptionFormatterTestCase.java
new file mode 100644
index 0000000000..2d3f01422d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/monitor/DefaultExceptionFormatterTestCase.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.monitor;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.api.TuscanyException;
+import org.apache.tuscany.api.TuscanyRuntimeException;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class DefaultExceptionFormatterTestCase extends TestCase {
+ private DefaultExceptionFormatter formatter = new DefaultExceptionFormatter();
+
+ public void testTuscanyExceptionFormat() throws Exception {
+ StringWriter writer = new StringWriter();
+ PrintWriter pw = new PrintWriter(writer);
+ TuscanyException e = new TuscanyException("somemessage") {
+ };
+ e.addContextName("somecontext");
+ formatter.write(pw, e);
+ assertTrue(writer.toString().indexOf("somemessage") >= 0);
+ assertTrue(writer.toString().indexOf("somecontext") >= 0);
+ }
+
+ public void testTuscanyRuntimeExceptionFormat() throws Exception {
+ StringWriter writer = new StringWriter();
+ PrintWriter pw = new PrintWriter(writer);
+ TuscanyRuntimeException e = new TuscanyRuntimeException("somemessage") {
+ };
+ e.addContextName("somecontext");
+ formatter.write(pw, e);
+ assertTrue(writer.toString().indexOf("somemessage") >= 0);
+ assertTrue(writer.toString().indexOf("somecontext") >= 0);
+ }
+
+ public void testNormalExceptionFormat() throws Exception {
+ StringWriter writer = new StringWriter();
+ PrintWriter pw = new PrintWriter(writer);
+ Exception e = new Exception();
+ formatter.write(pw, e); // just verify there are no errors since no formatting needs to be doen
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/monitor/JavaLoggingTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/monitor/JavaLoggingTestCase.java
new file mode 100644
index 0000000000..5fdf035c7a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/monitor/JavaLoggingTestCase.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.monitor;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import org.apache.tuscany.api.annotation.LogLevel;
+import org.apache.tuscany.host.MonitorFactory;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for the JavaLoggingMonitorFactory.
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaLoggingTestCase extends TestCase {
+ private static final Logger LOGGER = Logger.getLogger(Monitor.class.getName());
+ private static final MockHandler HANDLER = new MockHandler();
+
+ private MonitorFactory factory;
+
+ /**
+ * Smoke test to ensure the LOGGER is working.
+ */
+ public void testLogger() {
+ LOGGER.info("test");
+ assertEquals(1, HANDLER.logs.size());
+ }
+
+ /**
+ * Test that no record is logged.
+ */
+ public void testUnloggedEvent() {
+ Monitor mon = factory.getMonitor(Monitor.class);
+ mon.eventNotToLog();
+ assertEquals(0, HANDLER.logs.size());
+ }
+
+ /**
+ * Test the correct record is written for an event with no arguments.
+ */
+ public void testEventWithNoArgs() {
+ Monitor mon = factory.getMonitor(Monitor.class);
+ mon.eventWithNoArgs();
+ assertEquals(1, HANDLER.logs.size());
+ LogRecord record = HANDLER.logs.get(0);
+ assertEquals(Level.INFO, record.getLevel());
+ assertEquals(LOGGER.getName(), record.getLoggerName());
+ assertEquals(Monitor.class.getName() + "#eventWithNoArgs", record.getMessage());
+ }
+
+ /**
+ * Test the correct record is written for an event defined by annotation.
+ */
+ public void testEventWithAnnotation() {
+ Monitor mon = factory.getMonitor(Monitor.class);
+ mon.eventWithAnnotation();
+ assertEquals(1, HANDLER.logs.size());
+ LogRecord record = HANDLER.logs.get(0);
+ assertEquals(Level.INFO, record.getLevel());
+ assertEquals(LOGGER.getName(), record.getLoggerName());
+ assertEquals(Monitor.class.getName() + "#eventWithAnnotation", record.getMessage());
+ }
+
+ /**
+ * Test the argument is logged.
+ */
+ public void testEventWithOneArg() {
+ Monitor mon = factory.getMonitor(Monitor.class);
+ mon.eventWithOneArg("ARG");
+ assertEquals(1, HANDLER.logs.size());
+ LogRecord record = HANDLER.logs.get(0);
+ assertEquals(Monitor.class.getName() + "#eventWithOneArg", record.getMessage());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ LOGGER.setUseParentHandlers(false);
+ LOGGER.addHandler(HANDLER);
+ HANDLER.flush();
+
+ String sourceClass = Monitor.class.getName();
+ Properties levels = new Properties();
+ levels.setProperty(sourceClass + "#eventWithNoArgs", "INFO");
+ levels.setProperty(sourceClass + "#eventWithOneArg", "INFO");
+ levels.setProperty(sourceClass + "#eventWithThrowable", "WARNING");
+ factory = new JavaLoggingMonitorFactory(levels, Level.FINE, "TestMessages");
+ }
+
+ protected void tearDown() throws Exception {
+ LOGGER.removeHandler(HANDLER);
+ HANDLER.flush();
+ super.tearDown();
+ }
+
+ /**
+ * Mock log HANDLER to capture records.
+ */
+ public static class MockHandler extends Handler {
+ List<LogRecord> logs = new ArrayList<LogRecord>();
+
+ public void publish(LogRecord record) {
+ logs.add(record);
+ }
+
+ public void flush() {
+ logs.clear();
+ }
+
+ public void close() throws SecurityException {
+ }
+ }
+
+ @SuppressWarnings({"JavaDoc"})
+ public static interface Monitor {
+ void eventNotToLog();
+
+ @LogLevel("INFO")
+ void eventWithNoArgs();
+
+ @LogLevel("INFO")
+ void eventWithOneArg(String msg);
+
+ @LogLevel("WARNING")
+ void eventWithThrowable(Exception e);
+
+ @LogLevel("INFO")
+ void eventWithAnnotation();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/policy/IntentRegistryImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/policy/IntentRegistryImplTestCase.java
new file mode 100644
index 0000000000..de1c91b741
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/policy/IntentRegistryImplTestCase.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import javax.xml.namespace.QName;
+
+import static org.osoa.sca.Constants.SCA_NS;
+
+import org.apache.tuscany.spi.model.Intent;
+import org.apache.tuscany.spi.model.IntentName;
+import org.apache.tuscany.spi.policy.IntentRegistry;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class IntentRegistryImplTestCase extends TestCase {
+ private static final QName WS_BINDING = new QName(SCA_NS, "binding.ws");
+ private static final QName JMS_BINDING = new QName(SCA_NS, "binding.jms");
+ private IntentRegistry intentReg;
+
+ @Override
+ protected void setUp() throws Exception {
+ intentReg = new IntentRegistryImpl();
+
+ Intent bodyintent = new Intent(new IntentName("sec.confidentiality/message/body"), "test");
+ bodyintent.addAppliedArtifacts(WS_BINDING);
+ bodyintent.addAppliedArtifacts(JMS_BINDING);
+ intentReg.register(bodyintent);
+
+ Intent headintent = new Intent(new IntentName("sec.confidentiality/message/head"), "test");
+ headintent.addAppliedArtifacts(WS_BINDING);
+ headintent.addAppliedArtifacts(JMS_BINDING);
+ intentReg.register(headintent);
+
+ Intent confidentialityintent = new Intent(new IntentName("sec.confidentiality"), "test");
+ confidentialityintent.addAppliedArtifacts(WS_BINDING);
+ confidentialityintent.addAppliedArtifacts(JMS_BINDING);
+ intentReg.register(confidentialityintent);
+
+ Intent messageintent = new Intent(new IntentName("sec.confidentiality/message"), null);
+ messageintent.addAppliedArtifacts(WS_BINDING);
+ messageintent.addAppliedArtifacts(JMS_BINDING);
+ intentReg.register(messageintent);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ intentReg = null;
+ }
+
+// public void testGetQualifiedIntent() {
+// List<IntentName> intentNameList = new ArrayList<IntentName>();
+// intentReg.get
+// //intentReg.getConcretIntents(intentNameList, artifact)
+// }
+
+ public void testGetConcretIntents() {
+ Intent messageintent = new Intent(new IntentName("sec.confidentiality/transport"), null);
+ messageintent.addAppliedArtifacts(WS_BINDING);
+ messageintent.addAppliedArtifacts(JMS_BINDING);
+ intentReg.register(messageintent);
+
+ Intent allintent = new Intent(new IntentName("sec.confidentiality/all"), null);
+ allintent.addAppliedArtifacts(WS_BINDING);
+ allintent.addRequriedIntents(new IntentName("sec.confidentiality/message"));
+ allintent.addRequriedIntents(new IntentName("sec.confidentiality/transport"));
+
+
+ intentReg.register(allintent);
+ List<IntentName> intents = new ArrayList<IntentName>();
+ intents.add(new IntentName("sec.confidentiality/all"));
+ Collection<IntentName> concreteIntents = intentReg.inlineProfileIntent(intents, WS_BINDING);
+ assertEquals(2, concreteIntents.size());
+ assertTrue(concreteIntents.contains(new IntentName("sec.confidentiality/message")));
+ assertTrue(concreteIntents.contains(new IntentName("sec.confidentiality/transport")));
+ //fail("Not yet implemented");
+ }
+
+ public void testGetQualifiedIntents() {
+ IntentName message = new IntentName("sec.confidentiality/message");
+ Collection<IntentName> qualifiedIntents = intentReg.getQualifiedIntents(message, JMS_BINDING);
+ assertEquals(2, qualifiedIntents.size());
+ assertTrue(qualifiedIntents.contains(new IntentName("sec.confidentiality/message/body")));
+ assertTrue(qualifiedIntents.contains(new IntentName("sec.confidentiality/message/head")));
+ assertFalse(qualifiedIntents.contains(new IntentName("sec.confidentiality/message")));
+ assertFalse(qualifiedIntents.contains(new IntentName("sec.confidentiality")));
+ }
+
+ public void testIsApplicable() {
+ assertTrue(intentReg.isApplicable(new IntentName("sec.confidentiality/message"), WS_BINDING));
+ assertFalse(intentReg.isApplicable(new IntentName("sec.confidentiality/transport"), WS_BINDING));
+ assertFalse(intentReg.isApplicable(new IntentName("test.confidentiality/transport"), WS_BINDING));
+ }
+
+ public void testRegister() {
+ Intent messageintent = new Intent(new IntentName("sec.confidentiality/transport"), null);
+ messageintent.addAppliedArtifacts(WS_BINDING);
+ messageintent.addAppliedArtifacts(JMS_BINDING);
+ intentReg.register(messageintent);
+ assertTrue(intentReg.isApplicable(new IntentName("sec.confidentiality/transport"), WS_BINDING));
+ assertTrue(intentReg.isApplicable(new IntentName("sec.confidentiality/transport"), JMS_BINDING));
+
+ }
+
+ public void testIsQualifiedIntent() {
+ Intent messageintent = new Intent(new IntentName("sec.confidentiality/transport"), null);
+ messageintent.addAppliedArtifacts(WS_BINDING);
+ messageintent.addAppliedArtifacts(JMS_BINDING);
+ intentReg.register(messageintent);
+ Intent allintent = new Intent(new IntentName("sec.confidentiality/all"), null);
+ allintent.addAppliedArtifacts(WS_BINDING);
+
+ assertTrue(intentReg.isQualifiedIntent(new IntentName("sec.confidentiality/transport")));
+ assertTrue(intentReg.isQualifiedIntent(new IntentName("sec.confidentiality/message/body")));
+ assertTrue(intentReg.isQualifiedIntent(new IntentName("sec.confidentiality/message/body")));
+ assertFalse(intentReg.isQualifiedIntent(new IntentName("sec.confidentiality/message")));
+ assertFalse(intentReg.isQualifiedIntent(new IntentName("sec.confidentiality")));
+ }
+
+ public void testUnRegister() {
+ Intent messageintent = new Intent(new IntentName("sec.confidentiality/transport"), null);
+ messageintent.addAppliedArtifacts(WS_BINDING);
+ messageintent.addAppliedArtifacts(JMS_BINDING);
+ intentReg.register(messageintent);
+ intentReg.unRegister(messageintent);
+ assertFalse(intentReg.isApplicable(new IntentName("sec.confidentiality/transport"), WS_BINDING));
+ assertFalse(intentReg.isApplicable(new IntentName("sec.confidentiality/transport"), JMS_BINDING));
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/policy/PolicyEngineImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/policy/PolicyEngineImplTestCase.java
new file mode 100644
index 0000000000..afb8981951
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/policy/PolicyEngineImplTestCase.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.policy;
+
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamReader;
+
+import static org.osoa.sca.Constants.SCA_NS;
+
+import org.apache.tuscany.spi.model.Intent;
+import org.apache.tuscany.spi.model.IntentName;
+import org.apache.tuscany.spi.model.PolicyModel;
+import org.apache.tuscany.spi.model.PolicySet;
+import org.apache.tuscany.spi.policy.IntentRegistry;
+import org.apache.tuscany.spi.policy.PolicyEngine;
+import org.apache.tuscany.spi.policy.PolicySetContainer;
+import org.apache.tuscany.spi.policy.SCATypeManager;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.loader.PolicySetLoader;
+
+public class PolicyEngineImplTestCase extends TestCase {
+ private static final QName POLICYSET = new QName(SCA_NS, "policySet");
+ private static final QName WS_BINDING = new QName(SCA_NS, "binding.ws");
+ private IntentRegistry intentReg;
+ private PolicyEngine policyEngine;
+
+
+ public void testgetPolicy() throws Exception {
+ Collection<PolicyModel> policies =
+ policyEngine.getPolicy(new IntentName[]{new IntentName("sec.authentication/cert")}, null, WS_BINDING);
+ assertEquals(2, policies.size());
+ policies =
+ policyEngine.getPolicy(new IntentName[]{new IntentName("sec.authentication/basic")}, null, WS_BINDING);
+ assertEquals(1, policies.size());
+
+ //test for unqualified intent with default value on intentMap
+ policies = policyEngine.getPolicy(new IntentName[]{new IntentName("sec.authentication")}, null, WS_BINDING);
+ assertEquals(2, policies.size());
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ PolicySetLoader loader = new PolicySetLoader(null);
+ XMLInputFactory factory = XMLInputFactory.newInstance();
+ InputStream resourceAsStream = this.getClass().getResourceAsStream("PolicySet.scdl");
+ XMLStreamReader reader = factory.createXMLStreamReader(resourceAsStream);
+ PolicySetContainerImpl psc = new PolicySetContainerImpl();
+ while (true) {
+ int state = reader.next();
+ if (state == XMLStreamConstants.END_DOCUMENT) {
+ break;
+ }
+ if (XMLStreamConstants.START_ELEMENT == state && reader.getName().equals(POLICYSET)) {
+ psc.addPolicySet(loader.load(null, null, reader, null));
+ }
+
+ }
+ resourceAsStream.close();
+ intentReg = new IntentRegistryImpl();
+ policyEngine = new PolicyEngineImpl(intentReg, psc, new SCATypeManagerImpl());
+
+ Intent bodyintent = new Intent(new IntentName("sec.confidentiality/message/body"), "test");
+ bodyintent.addAppliedArtifacts(WS_BINDING);
+ intentReg.register(bodyintent);
+
+ Intent allintent = new Intent(new IntentName("sec.confidentiality/message/all"), "test");
+ allintent.addAppliedArtifacts(WS_BINDING);
+ intentReg.register(allintent);
+
+ Intent confidentialityintent = new Intent(new IntentName("sec.confidentiality"), "test");
+ confidentialityintent.addAppliedArtifacts(WS_BINDING);
+ intentReg.register(confidentialityintent);
+
+ Intent messageintent = new Intent(new IntentName("sec.confidentiality/message"), null);
+ messageintent.addAppliedArtifacts(WS_BINDING);
+ intentReg.register(messageintent);
+
+ Intent authintent = new Intent(new IntentName("sec.authentication"), null);
+ authintent.addAppliedArtifacts(WS_BINDING);
+ intentReg.register(authintent);
+
+ Intent certintent = new Intent(new IntentName("sec.authentication/cert"), null);
+ certintent.addAppliedArtifacts(WS_BINDING);
+ intentReg.register(certintent);
+
+ Intent basicintent = new Intent(new IntentName("sec.authentication/basic"), null);
+ basicintent.addAppliedArtifacts(WS_BINDING);
+ intentReg.register(basicintent);
+
+ }
+
+ private class PolicySetContainerImpl implements PolicySetContainer {
+
+ private Map<QName, PolicySet> sets = new HashMap<QName, PolicySet>();
+
+ public Collection<PolicySet> getAllPolicySet() {
+ return sets.values();
+ }
+
+ public PolicySet getPolicySet(QName name) {
+ return sets.get(name);
+ }
+
+ public void addPolicySet(PolicySet pset) {
+ sets.put(pset.getName(), pset);
+ }
+
+ }
+
+ private class SCATypeManagerImpl implements SCATypeManager {
+
+ public boolean isTypeOf(QName subType, QName type) {
+ return subType.equals(type);
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/property/PropertyHelperTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/property/PropertyHelperTestCase.java
new file mode 100644
index 0000000000..5ddd0b32ce
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/property/PropertyHelperTestCase.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.property;
+
+import java.net.URL;
+import javax.xml.namespace.NamespaceContext;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.databinding.xml.String2Node;
+import org.easymock.EasyMock;
+
+/**
+ *
+ */
+public class PropertyHelperTestCase extends TestCase {
+ private static final String IPO_XML =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<ipo:purchaseOrder"
+ + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
+ + " xmlns:ipo=\"http://www.example.com/IPO\""
+ + " xsi:schemaLocation=\"http://www.example.com/IPO ipo.xsd\""
+ + " orderDate=\"1999-12-01\">"
+ + " <shipTo exportCode=\"1\" xsi:type=\"ipo:UKAddress\">"
+ + " <name>Helen Zoe</name>"
+ + " <street>47 Eden Street</street>"
+ + " <city>Cambridge</city>"
+ + " <postcode>CB1 1JR</postcode>"
+ + " </shipTo>"
+ + " <billTo xsi:type=\"ipo:USAddress\">"
+ + " <name>Robert Smith</name>"
+ + " <street>8 Oak Avenue</street>"
+ + " <city>Old Town</city>"
+ + " <state>PA</state>"
+ + " <zip>95819</zip>"
+ + " </billTo>"
+ + " <items>"
+ + " <item partNum=\"833-AA\">"
+ + " <productName>Lapis necklace</productName>"
+ + " <quantity>1</quantity>"
+ + " <USPrice>99.95</USPrice>"
+ + " <ipo:comment>Want this for the holidays</ipo:comment>"
+ + " <shipDate>1999-12-05</shipDate>"
+ + " </item>"
+ + " </items>"
+ + "</ipo:purchaseOrder>";
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public void testXPath() throws Exception {
+ String2Node t = new String2Node();
+ Node node = t.transform(IPO_XML, null);
+
+ Document doc = PropertyHelper.evaluate(null, node, "/ipo:purchaseOrder/billTo");
+ assertNotNull(doc);
+
+ NamespaceContext context = EasyMock.createMock(NamespaceContext.class);
+ EasyMock.expect(context.getNamespaceURI("ipo")).andReturn("http://www.example.com/IPO").anyTimes();
+ EasyMock.replay(context);
+ doc = PropertyHelper.evaluate(context, node, "/ipo:purchaseOrder/items");
+ assertNotNull(doc);
+ doc = PropertyHelper.evaluate(context, node, "/ipo:purchaseOrder/billTo");
+ assertNotNull(doc);
+ doc = PropertyHelper.evaluate(context, node, "/");
+ assertNotNull(doc);
+ doc = PropertyHelper.evaluate(context, node, "/ipo:purchaseOrder/billTo1");
+ assertNull(doc);
+ }
+
+ public void testFile() throws Exception {
+ URL url = getClass().getResource("ipo.xml");
+ Document doc = PropertyHelper.loadFromFile(url.toExternalForm(), null);
+ assertNotNull(doc);
+
+ DeploymentContext context = EasyMock.createMock(DeploymentContext.class);
+ EasyMock.expect(context.getClassLoader()).andReturn(getClass().getClassLoader());
+ EasyMock.replay(context);
+ doc = PropertyHelper.loadFromFile("org/apache/tuscany/core/property/ipo.xml", context);
+ assertNotNull(doc);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/property/SimplePropertyObjectFactoryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/property/SimplePropertyObjectFactoryTestCase.java
new file mode 100644
index 0000000000..ef67533a0a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/property/SimplePropertyObjectFactoryTestCase.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.property;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.tuscany.spi.ObjectFactory;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.PropertyValue;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SimplePropertyObjectFactoryTestCase extends TestCase {
+
+ private <T> PropertyValue<T> mock(String value) {
+ Document document = EasyMock.createMock(Document.class);
+ Element element = EasyMock.createMock(Element.class);
+ //EasyMock.expect(document.getDocumentElement()).andReturn(element);
+ EasyMock.expect(element.getTextContent()).andReturn(value);
+ EasyMock.replay(document, element);
+
+ List<Element> valueList = new ArrayList<Element>();
+ valueList.add(element);
+ return new PropertyValue<T>(null, valueList);
+ }
+
+ public void testInteger() throws Exception {
+
+ PropertyObjectFactoryImpl factory = new PropertyObjectFactoryImpl();
+ Property<Integer> property = new Property<Integer>();
+ property.setJavaType(Integer.class);
+ PropertyValue<Integer> propertyValue = mock("1");
+ ObjectFactory<Integer> oFactory = factory.createObjectFactory(property, propertyValue);
+ assertEquals(1, oFactory.getInstance().intValue());
+ }
+
+ public void testPrimitiveInt() throws Exception {
+ PropertyObjectFactoryImpl factory = new PropertyObjectFactoryImpl();
+ Property<Integer> property = new Property<Integer>();
+ property.setJavaType(Integer.TYPE);
+ PropertyValue<Integer> propertyValue = mock("1");
+ ObjectFactory<Integer> oFactory = factory.createObjectFactory(property, propertyValue);
+ assertEquals(1, oFactory.getInstance().intValue());
+ }
+
+ public void testString() throws Exception {
+ PropertyObjectFactoryImpl factory = new PropertyObjectFactoryImpl();
+ Property<String> property = new Property<String>();
+ property.setJavaType(String.class);
+ PropertyValue<String> propertyValue = mock("1");
+ ObjectFactory<String> oFactory = factory.createObjectFactory(property, propertyValue);
+ assertEquals("1", oFactory.getInstance());
+ }
+
+ public void testByteArray() throws Exception {
+ PropertyObjectFactoryImpl factory = new PropertyObjectFactoryImpl();
+ Property<byte[]> property = new Property<byte[]>();
+ property.setJavaType(byte[].class);
+ PropertyValue<byte[]> propertyValue = mock("TWFu"); // BASE64 for "Man"
+ ObjectFactory<byte[]> oFactory = factory.createObjectFactory(property, propertyValue);
+ byte[] result = oFactory.getInstance();
+ byte[] expected = "Man".getBytes();
+ for (int i = 0; i < result.length; i++) {
+ byte b = result[i];
+ if (b != expected[i]) {
+ fail();
+ }
+ }
+ }
+
+ public void testBoolean() throws Exception {
+ PropertyObjectFactoryImpl factory = new PropertyObjectFactoryImpl();
+ Property<Boolean> property = new Property<Boolean>();
+ property.setJavaType(Boolean.class);
+ PropertyValue<Boolean> propertyValue = mock("true");
+ ObjectFactory<Boolean> oFactory = factory.createObjectFactory(property, propertyValue);
+ assertTrue(oFactory.getInstance());
+ }
+
+ public void testPrimitiveBoolean() throws Exception {
+ PropertyObjectFactoryImpl factory = new PropertyObjectFactoryImpl();
+ Property<Boolean> property = new Property<Boolean>();
+ property.setJavaType(Boolean.TYPE);
+ PropertyValue<Boolean> propertyValue = mock("true");
+ ObjectFactory<Boolean> oFactory = factory.createObjectFactory(property, propertyValue);
+ assertTrue(oFactory.getInstance());
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/artifact/LocalMavenRepositoryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/artifact/LocalMavenRepositoryTestCase.java
new file mode 100644
index 0000000000..0efecb9302
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/artifact/LocalMavenRepositoryTestCase.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.artifact;
+
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.spi.services.artifact.Artifact;
+
+/**
+ * This testcase assumes that there is a maven repo in the default location.
+ *
+ * @version $Rev$ $Date$
+ */
+public class LocalMavenRepositoryTestCase extends TestCase {
+ private static final String VERSION = "3.8.1";
+ private LocalMavenRepository repo;
+ private Artifact artifact;
+ private String path;
+
+ public void testPathWithNoClassifier() {
+ assertEquals(path, repo.getPath(artifact));
+ }
+
+ public void testPathWithClassifier() {
+ artifact.setClassifier("x86");
+ path = "junit/junit/" + VERSION + "/junit-" + VERSION + "-x86.jar";
+ assertEquals(path, repo.getPath(artifact));
+ }
+
+ public void testArtifactFoundInRepo() throws MalformedURLException, UnsupportedEncodingException {
+ String home = System.getProperty("user.home");
+ File file = new File(home + "/.m2/repository", path);
+ repo.resolve(artifact);
+ assertEquals(file.toURI().toURL(), artifact.getUrl());
+ }
+
+ public void testArtifactNotFoundInRepo() throws MalformedURLException {
+ artifact.setClassifier("x86");
+ repo.resolve(artifact);
+ assertNull(artifact.getUrl());
+ }
+
+ public void testNonNullURLIsUnmodified() throws MalformedURLException {
+ URL url = new URL("http://www.apache.org");
+ artifact.setUrl(url);
+ repo.resolve(artifact);
+ assertSame(url, artifact.getUrl());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ repo = new LocalMavenRepository(".m2/repository");
+
+ artifact = new Artifact();
+ artifact.setGroup("junit");
+ artifact.setName("junit");
+ artifact.setVersion(VERSION);
+ artifact.setType("jar");
+ path = "junit/junit/" + VERSION + "/junit-" + VERSION + ".jar";
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/AssemblyServiceImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/AssemblyServiceImplTestCase.java
new file mode 100644
index 0000000000..fb1daf7e5f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/AssemblyServiceImplTestCase.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.deployment;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+import junit.framework.TestCase;
+import org.easymock.classextension.EasyMock;
+
+import org.apache.tuscany.host.deployment.UnsupportedContentTypeException;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class AssemblyServiceImplTestCase extends TestCase {
+ private AssemblyServiceImpl service;
+
+ public void testApplyChangesWithNullURL() {
+ try {
+ service.applyChanges(null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ //ok
+ } catch (Throwable t) {
+ fail();
+ }
+ }
+
+ public void testApplyChangesWhenURLContentTypeIsNull() throws Exception {
+ final URLConnection urlConnection = EasyMock.createMock(URLConnection.class);
+ EasyMock.expect(urlConnection.getContentType()).andReturn(null);
+ EasyMock.replay(urlConnection);
+ URLStreamHandler handler = new MockURLStreamHandler(urlConnection);
+
+ URL url = new URL(null, "file:/tmp/foo.xml", handler);
+ try {
+ service.applyChanges(url);
+ } catch (UnsupportedContentTypeException e) {
+ assertNull(e.getMessage());
+ assertEquals(url.toString(), e.getIdentifier());
+ EasyMock.verify(urlConnection);
+ } catch (Throwable t) {
+ fail();
+ }
+ }
+
+ public void testApplyChangesWithNullStream() {
+ try {
+ service.applyChanges(null, "xxx/xxx");
+ fail();
+ } catch (IllegalArgumentException e) {
+ //ok
+ } catch (Throwable t) {
+ fail();
+ }
+ }
+
+ public void testApplyChangesWithNullContentType() {
+ InputStream is = EasyMock.createMock(InputStream.class);
+ EasyMock.replay(is);
+ try {
+ service.applyChanges(is, null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ EasyMock.verify(is);
+ } catch (Throwable t) {
+ fail();
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ service = new AssemblyServiceImpl(null, null);
+ }
+
+ private static class MockURLStreamHandler extends URLStreamHandler {
+ private final URLConnection urlConnection;
+
+ public MockURLStreamHandler(URLConnection urlConnection) {
+ this.urlConnection = urlConnection;
+ }
+
+ protected URLConnection openConnection(URL url) throws IOException {
+ return urlConnection;
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/ContentTypeDescriberImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/ContentTypeDescriberImplTestCase.java
new file mode 100644
index 0000000000..8bb800962f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/ContentTypeDescriberImplTestCase.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.deployment;
+
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.spi.deployer.ContentType;
+
+public class ContentTypeDescriberImplTestCase extends TestCase {
+ private ContentTypeDescriberImpl contentTypeBuilder;
+
+ public void testResolveContentType() throws Exception {
+ URL artifactURL = getClass().getResource("test.scdl");
+ assertEquals(ContentType.COMPOSITE, contentTypeBuilder.getContentType(artifactURL, null));
+ }
+
+
+ public void testUnknownResolveContentType() throws Exception {
+ URL artifactURL = getClass().getResource("test.ext");
+ assertNull(contentTypeBuilder.getContentType(artifactURL, null));
+ }
+
+ public void testDefaultContentType() throws Exception {
+ URL artifactURL = getClass().getResource("test.ext");
+ assertEquals("application/vnd.tuscany.ext",
+ contentTypeBuilder.getContentType(artifactURL, "application/vnd.tuscany.ext"));
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ contentTypeBuilder = new ContentTypeDescriberImpl();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionLoaderTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionLoaderTestCase.java
new file mode 100644
index 0000000000..85e959cb87
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionLoaderTestCase.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.services.deployment;
+
+import java.io.StringReader;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.loader.InvalidValueException;
+import org.apache.tuscany.spi.model.Contribution;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ContributionLoaderTestCase 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 factory;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ factory = XMLInputFactory.newInstance();
+ }
+
+ public void testLoad() throws Exception {
+ XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(VALID_XML));
+ ContributionLoader loader = new ContributionLoader(null);
+ Contribution contribution = loader.load(null, null, reader, null);
+ assertNotNull(contribution);
+ assertEquals(1, contribution.getImports().size());
+ assertEquals(1, contribution.getExports().size());
+ assertEquals(2, contribution.getDeployables().size());
+ }
+
+ public void testLoadInvalid() throws Exception {
+ XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(INVALID_XML));
+ ContributionLoader loader = new ContributionLoader(null);
+ try {
+ loader.load(null, null, reader, null);
+ fail("InvalidException should have been thrown");
+ } catch (InvalidValueException e) {
+ assertTrue(true);
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionRepositoryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionRepositoryTestCase.java
new file mode 100644
index 0000000000..0641520b3c
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionRepositoryTestCase.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.services.deployment;
+
+import java.io.File;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+
+import org.apache.tuscany.core.util.FileHelper;
+
+import junit.framework.TestCase;
+
+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";
+ URI contribution = URI.create("sample-calculator.jar");
+ InputStream contributionStream = getClass().getResourceAsStream(resourceLocation);
+ repository.store(contribution, contributionStream);
+
+ URL contributionURL = repository.find(contribution);
+ assertNotNull(contributionURL);
+ }
+
+ public void testRemove() throws Exception {
+ String resourceLocation = "/repository/sample-calculator.jar";
+ URI contribution = URI.create("sample-calculator.jar");
+ InputStream contributionStream = getClass().getResourceAsStream(resourceLocation);
+ repository.store(contribution, contributionStream);
+
+ repository.remove(contribution);
+ URL contributionURL = repository.find(contribution);
+ assertNull(contributionURL);
+ }
+
+ public void testList() throws Exception {
+ String resourceLocation = "/repository/sample-calculator.jar";
+ URI contribution = URI.create("sample-calculator.jar");
+ InputStream contributionStream = getClass().getResourceAsStream(resourceLocation);
+ repository.store(contribution, contributionStream);
+
+ assertEquals(1, repository.list().size());
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ FileHelper.deleteDirectory(new File("target/repository"));
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionServiceImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionServiceImplTestCase.java
new file mode 100644
index 0000000000..12c629f8a2
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/ContributionServiceImplTestCase.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.core.services.deployment;
+
+import java.net.URI;
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.services.deployment.contribution.JarContributionProcessor;
+import org.apache.tuscany.core.services.deployment.contribution.JavaContributionProcessor;
+import org.apache.tuscany.host.deployment.ContributionService;
+import org.apache.tuscany.spi.deployer.ContentTypeDescriber;
+import org.apache.tuscany.spi.deployer.ContributionProcessorRegistry;
+import org.apache.tuscany.spi.deployer.ContributionRepository;
+
+/**
+ * This is more intended to be a integration test then a unit test. *
+ */
+public class ContributionServiceImplTestCase extends TestCase {
+ private static final String JAR_CONTRIBUTION = "/repository/sample-calculator.jar";
+ private ContributionRepository repository;
+ private ContentTypeDescriber contentTypeDescriber;
+ private ContributionProcessorRegistry registry;
+ private ContributionService contributionService;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+// this.repository = new ContributionRepositoryImpl("target/repository");
+//
+// this.contentTypeDescriber = new ContentTypeDescriberImpl();
+//
+// this.registry = new ContributionProcessorRegistryImpl(contentTypeDescriber);
+//
+// JarContributionProcessor jarProcessor = new JarContributionProcessor();
+// jarProcessor.setContributionProcessorRegistry(this.registry);
+// this.registry.register(JarContributionProcessor.CONTENT_TYPE, jarProcessor);
+//
+// JavaContributionProcessor javaProcessor = new JavaContributionProcessor(null);
+// javaProcessor.setContributionProcessorRegistry(this.registry);
+// this.registry.register(JavaContributionProcessor.CONTENT_TYPE, javaProcessor);
+//
+//
+// contributionService = new ContributionServiceImpl(repository, registry);
+ }
+
+ public void testContributeURL() throws Exception {
+// URL contribution = getClass().getResource(JAR_CONTRIBUTION);
+//
+// URI contributionURI = contributionService.contribute(contribution);
+// assertNotNull(contributionURI);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/CompositeContributionProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/CompositeContributionProcessorTestCase.java
new file mode 100644
index 0000000000..5d0b3227e8
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/CompositeContributionProcessorTestCase.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.deployment.contribution;
+
+import java.net.URL;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.implementation.IntrospectionRegistryImpl;
+import org.apache.tuscany.core.implementation.processor.DestroyProcessor;
+import org.apache.tuscany.core.implementation.processor.ImplementationProcessorServiceImpl;
+import org.apache.tuscany.core.implementation.processor.InitProcessor;
+import org.apache.tuscany.core.implementation.processor.PropertyProcessor;
+import org.apache.tuscany.core.implementation.processor.ReferenceProcessor;
+import org.apache.tuscany.core.implementation.processor.ResourceProcessor;
+import org.apache.tuscany.core.implementation.processor.ScopeProcessor;
+import org.apache.tuscany.core.monitor.NullMonitorFactory;
+import org.apache.tuscany.spi.deployer.ContributionProcessor;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService;
+
+public class CompositeContributionProcessorTestCase extends TestCase {
+ private static final String CONTRIBUTION = "/repository/sample-calculator.jar";
+ private static final String ARTIFACT_URL = "/META-INF/sca/default.scdl";
+ private IntrospectionRegistryImpl registry;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ registry = new IntrospectionRegistryImpl();
+ registry.setMonitor(new NullMonitorFactory().getMonitor(IntrospectionRegistryImpl.Monitor.class));
+ registry.registerProcessor(new DestroyProcessor());
+ registry.registerProcessor(new InitProcessor());
+ registry.registerProcessor(new ScopeProcessor());
+ JavaInterfaceProcessorRegistryImpl interfaceProcessorRegistry = new JavaInterfaceProcessorRegistryImpl();
+ ImplementationProcessorService service = new ImplementationProcessorServiceImpl(interfaceProcessorRegistry);
+ registry.registerProcessor(new PropertyProcessor(service));
+ registry.registerProcessor(new ReferenceProcessor(interfaceProcessorRegistry));
+ registry.registerProcessor(new ResourceProcessor());
+ }
+
+ protected URL getArtifactURL() throws Exception {
+ URL jarURL = getClass().getResource(CONTRIBUTION);
+ JarInputStream jar = new JarInputStream(getClass().getResourceAsStream(CONTRIBUTION));
+ URL rootURL = new URL("jar:" + jarURL.toString() + "!/");
+ URL classURL = null;
+
+ try {
+ while (true) {
+ JarEntry entry = jar.getNextJarEntry();
+ if (entry.getName().endsWith(".class")) {
+ classURL = new URL(rootURL, entry.getName());
+ break;
+ }
+ }
+ } finally {
+ jar.close();
+ }
+ return classURL;
+ }
+
+ public final void testProcessScdl() throws Exception {
+ //ContributionProcessor scdlContributionProcessor = new scdlContributionProcessor(registry);
+ //URL jarURL = this.getClassURL();
+ //javaContributionProcessor.processContent(null, jarURL, jarURL.openStream());
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/FolderContributionProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/FolderContributionProcessorTestCase.java
new file mode 100644
index 0000000000..f6db2e8b7e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/FolderContributionProcessorTestCase.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.deployment.contribution;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.spi.deployer.ContributionProcessorRegistry;
+import org.apache.tuscany.spi.model.Contribution;
+import org.easymock.EasyMock;
+
+public class FolderContributionProcessorTestCase extends TestCase {
+ private static final String DIRECTORY_CONTRIBUTION = "//D:/DEV/Projects/Tuscany/source/java-sca-integration/samples/sca/calculator";
+
+ private File contributionRoot;
+
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.contributionRoot = new File(DIRECTORY_CONTRIBUTION);
+ }
+
+ public final void testProcessJarArtifacts() throws Exception {
+// FolderContributionProcessor folderContribution = new FolderContributionProcessor();
+// ContributionProcessorRegistry mockRegistry = EasyMock.createMock(ContributionProcessorRegistry.class);
+// mockRegistry.register(FolderContributionProcessor.CONTENT_TYPE, folderContribution);
+// EasyMock.expectLastCall().anyTimes();
+// EasyMock.replay(mockRegistry);
+// folderContribution.setContributionProcessorRegistry(mockRegistry);
+// folderContribution.start();
+// EasyMock.verify(mockRegistry);
+//
+// Contribution contribution = new Contribution(URI.create("sca://contributions/001"));
+// contribution.setLocation(this.contributionRoot.toURL());
+// folderContribution.processContent(contribution, contribution.getUri(), null);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/JarContributionProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/JarContributionProcessorTestCase.java
new file mode 100644
index 0000000000..06ccd6c3da
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/JarContributionProcessorTestCase.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.deployment.contribution;
+
+import java.net.URI;
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.spi.deployer.ContributionProcessorRegistry;
+import org.apache.tuscany.spi.model.Contribution;
+import org.easymock.EasyMock;
+
+public class JarContributionProcessorTestCase extends TestCase {
+ private static final String JAR_CONTRIBUTION = "/repository/sample-calculator.jar";
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public final void testProcessJarArtifacts() throws Exception {
+ /*
+ JarContributionProcessor jarContribution = new JarContributionProcessor();
+ ContributionProcessorRegistry mockRegistry = EasyMock.createMock(ContributionProcessorRegistry.class);
+ mockRegistry.register(JarContributionProcessor.CONTENT_TYPE, jarContribution);
+ EasyMock.expectLastCall().once();
+ EasyMock.replay(mockRegistry);
+ jarContribution.setContributionProcessorRegistry(mockRegistry);
+ jarContribution.start();
+ EasyMock.verify(mockRegistry);
+ URL jarURL = getClass().getResource(JarContributionProcessorTestCase.JAR_CONTRIBUTION);
+ Contribution contribution = new Contribution(URI.create("sca://contributions/001"));
+ contribution.setLocation(jarURL);
+ jarContribution.processContent(contribution, contribution.getUri(), jarURL.openStream());
+ */
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/JavaContributionProcessorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/JavaContributionProcessorTestCase.java
new file mode 100644
index 0000000000..269e2e6feb
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/deployment/contribution/JavaContributionProcessorTestCase.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.deployment.contribution;
+
+import java.net.URI;
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.implementation.IntrospectionRegistryImpl;
+import org.apache.tuscany.core.implementation.processor.DestroyProcessor;
+import org.apache.tuscany.core.implementation.processor.ImplementationProcessorServiceImpl;
+import org.apache.tuscany.core.implementation.processor.InitProcessor;
+import org.apache.tuscany.core.implementation.processor.PropertyProcessor;
+import org.apache.tuscany.core.implementation.processor.ReferenceProcessor;
+import org.apache.tuscany.core.implementation.processor.ResourceProcessor;
+import org.apache.tuscany.core.implementation.processor.ScopeProcessor;
+import org.apache.tuscany.core.monitor.NullMonitorFactory;
+import org.apache.tuscany.spi.deployer.ContributionProcessor;
+import org.apache.tuscany.spi.implementation.java.ImplementationProcessorService;
+import org.apache.tuscany.spi.model.Contribution;
+import org.apache.tuscany.spi.model.DeployedArtifact;
+
+public class JavaContributionProcessorTestCase extends TestCase {
+ private static final String CONTRIBUTION = "/repository/sample-calculator.jar";
+ private static final String JAVA_ARTIFACT = "calculator/AddService.class";
+ private IntrospectionRegistryImpl registry;
+ private URI contributionId;
+ private Contribution contribution;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ registry = new IntrospectionRegistryImpl();
+ registry.setMonitor(new NullMonitorFactory().getMonitor(IntrospectionRegistryImpl.Monitor.class));
+ registry.registerProcessor(new DestroyProcessor());
+ registry.registerProcessor(new InitProcessor());
+ registry.registerProcessor(new ScopeProcessor());
+ JavaInterfaceProcessorRegistryImpl interfaceProcessorRegistry = new JavaInterfaceProcessorRegistryImpl();
+ ImplementationProcessorService service = new ImplementationProcessorServiceImpl(interfaceProcessorRegistry);
+ registry.registerProcessor(new PropertyProcessor(service));
+ registry.registerProcessor(new ReferenceProcessor(interfaceProcessorRegistry));
+ registry.registerProcessor(new ResourceProcessor());
+
+ contributionId = new URI("sca://contribution/001");
+ contribution = new Contribution(contributionId);
+ contribution.setLocation(getClass().getResource(CONTRIBUTION));
+
+ DeployedArtifact classArtifact = new DeployedArtifact(contributionId);
+ classArtifact.setLocation(this.getArtifactURL());
+ }
+
+ protected URL getArtifactURL() throws Exception {
+ URL jarURL = getClass().getResource(CONTRIBUTION);
+ return new URL("jar:" + jarURL.toString() + "!/" + JAVA_ARTIFACT);
+ }
+
+ public final void testProcessJavaArtifact() throws Exception {
+ //ContributionProcessor javaContributionProcessor = new JavaContributionProcessor(registry);
+ //URL artifactURL = this.getArtifactURL();
+ //javaContributionProcessor.processContent(contribution, artifactURL.toURI(), artifactURL.openStream());
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/host/DelegatingResourceHostRegistryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/host/DelegatingResourceHostRegistryTestCase.java
new file mode 100644
index 0000000000..c3eb2fa1bf
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/host/DelegatingResourceHostRegistryTestCase.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.host;
+
+import org.apache.tuscany.spi.host.ResourceHost;
+import org.apache.tuscany.spi.host.ResourceResolutionException;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class DelegatingResourceHostRegistryTestCase extends TestCase {
+
+ public void testResolveByType() throws Exception {
+ Object ret = new Object();
+ DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry();
+ registry.registerResource(Object.class, ret);
+ assertEquals(ret, registry.resolveResource(Object.class));
+ }
+
+ public void testResolveByUri() throws Exception {
+ ResourceHost host = EasyMock.createMock(ResourceHost.class);
+ EasyMock.expect(host.resolveResource(String.class, "Foo://foo")).andReturn("result");
+ EasyMock.replay(host);
+ DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry();
+ registry.registerResourceHost("Foo://", host);
+ assertEquals("result", registry.resolveResource(String.class, "Foo://foo"));
+ EasyMock.verify(host);
+ }
+
+ public void testResolveBySCAUri() throws Exception {
+ ResourceHost host = EasyMock.createMock(ResourceHost.class);
+ EasyMock.replay(host);
+ DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry();
+ registry.registerResourceHost("Foo://", host);
+ Object ret = new Object();
+ registry.registerResource(Object.class, "foo", ret);
+ assertEquals(ret, registry.resolveResource(Object.class, "SCA://foo"));
+ EasyMock.verify(host);
+ }
+
+ public void testResolveByUriNotFound() throws Exception {
+ ResourceHost host = EasyMock.createMock(ResourceHost.class);
+ EasyMock.replay(host);
+ DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry();
+ registry.registerResourceHost("Foo://", host);
+ try {
+ assertEquals("result", registry.resolveResource(String.class, "Bar://bar"));
+ fail();
+ } catch (ResourceResolutionException e) {
+ //expected
+ }
+ EasyMock.verify(host);
+ }
+
+ public void testUnregisterHost() throws Exception {
+ ResourceHost host = EasyMock.createMock(ResourceHost.class);
+ EasyMock.replay(host);
+ DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry();
+ registry.registerResourceHost("Foo://", host);
+ registry.unregisterResourceHost("Foo://");
+ try {
+ registry.resolveResource(String.class, "Foo://foo");
+ fail();
+ } catch (ResourceResolutionException e) {
+ //expected
+ }
+ EasyMock.verify(host);
+ }
+
+ public void testUnregisterResource() throws Exception {
+ DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry();
+ registry.registerResource(Object.class, new Object());
+ registry.unregisterResource(Object.class);
+ assertNull(registry.resolveResource(Object.class));
+ }
+
+ public void testUnregisterMappedResource() throws Exception {
+ DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry();
+ registry.registerResource(Object.class, "foo", new Object());
+ registry.registerResource(Object.class, new Object());
+ registry.unregisterResource(Object.class);
+ assertNull(registry.resolveResource(Object.class));
+ assertNotNull(registry.resolveResource(Object.class, "foo"));
+ registry.unregisterResource(Object.class, "foo");
+ assertNull(registry.resolveResource(Object.class));
+ }
+
+ public void testReolvedByTypeToMappedResource() throws Exception {
+ DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry();
+ registry.registerResource(Object.class, "foo", new Object());
+ assertNull(registry.resolveResource(Object.class));
+ }
+
+ public void testDelegatingResolveResource() throws Exception {
+ Object ret = new Object();
+ ResourceHost host = EasyMock.createMock(ResourceHost.class);
+ EasyMock.expect(host.resolveResource(Object.class)).andReturn(ret);
+ EasyMock.replay(host);
+ DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry();
+ registry.registerResourceHost("Foo://", host);
+ assertEquals(ret, registry.resolveResource(Object.class));
+ EasyMock.verify(host);
+ }
+
+ public void testDelegatingResolveResourceByTypeandName() throws Exception {
+ Object ret = new Object();
+ ResourceHost host = EasyMock.createMock(ResourceHost.class);
+ EasyMock.expect(host.resolveResource(EasyMock.eq(Object.class), EasyMock.eq("Foo://bar"))).andReturn(ret);
+ EasyMock.replay(host);
+ DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry();
+ registry.registerResourceHost("Foo://", host);
+ assertEquals(ret, registry.resolveResource(Object.class, "Foo://bar"));
+ EasyMock.verify(host);
+ }
+
+ public void testResolveLocalResourceFirst() throws Exception {
+ Object local = new Object();
+ ResourceHost host = EasyMock.createMock(ResourceHost.class);
+ EasyMock.replay(host);
+ DelegatingResourceHostRegistry registry = new DelegatingResourceHostRegistry();
+ registry.registerResourceHost("Foo://", host);
+ registry.registerResource(Object.class, local);
+ assertEquals(local, registry.resolveResource(Object.class));
+ EasyMock.verify(host);
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/store/memory/MemoryStoreTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/store/memory/MemoryStoreTestCase.java
new file mode 100644
index 0000000000..5ec1643b47
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/store/memory/MemoryStoreTestCase.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.store.memory;
+
+import java.util.UUID;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+import org.apache.tuscany.spi.services.store.DuplicateRecordException;
+import org.apache.tuscany.spi.services.store.Store;
+import org.apache.tuscany.spi.services.store.StoreExpirationEvent;
+import org.apache.tuscany.spi.services.store.StoreMonitor;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MemoryStoreTestCase extends TestCase {
+ private StoreMonitor monitor;
+
+ public void testEviction() throws Exception {
+ MemoryStore store = new MemoryStore(monitor);
+ store.setReaperInterval(10);
+ store.init();
+ AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class);
+ EasyMock.replay(component);
+ String id = UUID.randomUUID().toString();
+ Object value = new Object();
+ store.insertRecord(component, id, value, 1);
+ Thread.sleep(100);
+ assertNull(store.readRecord(component, id));
+ store.destroy();
+ }
+
+ public void testNotifyOnEviction() throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ RuntimeEventListener listener = EasyMock.createMock(RuntimeEventListener.class);
+ listener.onEvent(EasyMock.isA(StoreExpirationEvent.class));
+ org.easymock.classextension.EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ latch.countDown();
+ return null;
+ }
+ });
+ EasyMock.replay(listener);
+ MemoryStore store = new MemoryStore(monitor);
+ store.addListener(listener);
+ store.setReaperInterval(10);
+ store.init();
+ AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class);
+ EasyMock.replay(component);
+ String id = UUID.randomUUID().toString();
+ Object value = new Object();
+ store.insertRecord(component, id, value, 1);
+ if (!latch.await(1000, TimeUnit.MILLISECONDS)) {
+ // failed to notify listener
+ fail();
+ }
+ EasyMock.verify(listener);
+ }
+
+ public void testNoEviction() throws Exception {
+ MemoryStore store = new MemoryStore(monitor);
+ store.setReaperInterval(10);
+ store.init();
+ AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class);
+ EasyMock.replay(component);
+ String id = UUID.randomUUID().toString();
+ Object value = new Object();
+ store.insertRecord(component, id, value, Store.NEVER);
+ Thread.sleep(100);
+ assertNotNull(store.readRecord(component, id));
+ store.destroy();
+ }
+
+ public void testInsertRecord() throws Exception {
+ MemoryStore store = new MemoryStore(monitor);
+ store.setReaperInterval(10);
+ store.init();
+ AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class);
+ EasyMock.replay(component);
+ String id = UUID.randomUUID().toString();
+ Object value = new Object();
+ store.insertRecord(component, id, value, Store.NEVER);
+ store.destroy();
+ }
+
+ public void testInsertAlreadyExists() throws Exception {
+ MemoryStore store = new MemoryStore(monitor);
+ store.setReaperInterval(10);
+ store.init();
+ AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class);
+ EasyMock.replay(component);
+ String id = UUID.randomUUID().toString();
+ Object value = new Object();
+ store.insertRecord(component, id, value, Store.NEVER);
+ try {
+ store.insertRecord(component, id, value, Store.NEVER);
+ fail();
+ } catch (DuplicateRecordException e) {
+ //expected
+ }
+ store.destroy();
+ }
+
+ public void testUpdateRecord() throws Exception {
+ MemoryStore store = new MemoryStore(monitor);
+ store.setReaperInterval(10);
+ store.init();
+ AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class);
+ EasyMock.replay(component);
+ String id = UUID.randomUUID().toString();
+ Object value = new Object();
+ Object newValue = new Object();
+
+ store.insertRecord(component, id, value, Store.NEVER);
+ store.updateRecord(component, id, newValue, 1L);
+ assertEquals(newValue, store.readRecord(component, id));
+ store.destroy();
+ }
+
+ public void testDeleteRecord() throws Exception {
+ MemoryStore store = new MemoryStore(monitor);
+ store.setReaperInterval(10);
+ store.init();
+ AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class);
+ EasyMock.replay(component);
+ String id = UUID.randomUUID().toString();
+ Object value = new Object();
+
+ store.insertRecord(component, id, value, Store.NEVER);
+ store.removeRecord(component, id);
+ assertNull(store.readRecord(component, id));
+ store.destroy();
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ monitor = EasyMock.createNiceMock(StoreMonitor.class);
+ EasyMock.replay(monitor);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkSchedulerTest.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkSchedulerTest.java
new file mode 100644
index 0000000000..1a5cb4ebe1
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkSchedulerTest.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.work.jsr237;
+
+import org.apache.tuscany.spi.services.work.NotificationListener;
+import org.apache.tuscany.spi.services.work.WorkScheduler;
+
+import commonj.work.WorkManager;
+import junit.framework.TestCase;
+import org.apache.tuscany.core.services.work.jsr237.workmanager.ThreadPoolWorkManager;
+
+public class Jsr237WorkSchedulerTest extends TestCase {
+
+ /*
+ * Test method for 'org.apache.tuscany.core.services.work.jsr237.Jsr237WorkScheduler.scheduleWork(T) <T>'
+ */
+ public void testScheduleWorkT() {
+
+
+ WorkManager workManager = new ThreadPoolWorkManager(1);
+ WorkScheduler workScheduler = new Jsr237WorkScheduler(workManager);
+
+ workScheduler.scheduleWork(new MyRunnable(), new MyNotificationListener());
+
+ }
+
+ /*
+ * Test method for 'org.apache.tuscany.core.services.work.jsr237.Jsr237WorkScheduler.scheduleWork(T,
+ * NotificationListener<T>) <T>'
+ */
+ public void testScheduleWorkTNotificationListenerOfT() {
+
+ }
+
+ private class MyRunnable implements Runnable {
+ public void run() {
+ System.err.println("Test executed");
+ }
+ }
+
+ private class MyNotificationListener implements NotificationListener<MyRunnable> {
+
+ public void workAccepted(MyRunnable work) {
+ System.err.println("Work accepted");
+ }
+
+ public void workCompleted(MyRunnable work) {
+ System.err.println("Work completed");
+ }
+
+ public void workStarted(MyRunnable work) {
+ System.err.println("Work started");
+ }
+
+ public void workRejected(MyRunnable work) {
+ System.err.println("Work rejected");
+ }
+
+ public void workFailed(MyRunnable work, Throwable error) {
+ System.err.println("Work failed");
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkSchedulerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkSchedulerTestCase.java
new file mode 100644
index 0000000000..3966f65683
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/Jsr237WorkSchedulerTestCase.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.work.jsr237;
+
+import org.apache.tuscany.spi.services.work.NotificationListener;
+import org.apache.tuscany.spi.services.work.WorkSchedulerException;
+
+import commonj.work.Work;
+import commonj.work.WorkItem;
+import commonj.work.WorkListener;
+import commonj.work.WorkManager;
+import commonj.work.WorkRejectedException;
+import junit.framework.TestCase;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class Jsr237WorkSchedulerTestCase extends TestCase {
+
+ public void testSchedule() throws Exception {
+ WorkItem item = createMock(WorkItem.class);
+ WorkManager mgr = createMock(WorkManager.class);
+ mgr.schedule(isA(Work.class));
+ expectLastCall().andReturn(item);
+ replay(mgr);
+ Jsr237WorkScheduler scheduler = new Jsr237WorkScheduler(mgr);
+ Work work = createMock(Work.class);
+ scheduler.scheduleWork(work);
+ verify(mgr);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testListener() throws Exception {
+ WorkItem item = createMock(WorkItem.class);
+ WorkManager mgr = createMock(WorkManager.class);
+ mgr.schedule(isA(Work.class), isA(WorkListener.class));
+ expectLastCall().andReturn(item);
+ replay(mgr);
+ Jsr237WorkScheduler scheduler = new Jsr237WorkScheduler(mgr);
+ Work work = createMock(Work.class);
+ NotificationListener<Runnable> listener = createMock(NotificationListener.class);
+ scheduler.scheduleWork(work, listener);
+ verify(mgr);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testWorkRejectedListener() throws Exception {
+ WorkManager mgr = createMock(WorkManager.class);
+ mgr.schedule(isA(Work.class), isA(WorkListener.class));
+ expectLastCall().andThrow(new WorkRejectedException());
+ replay(mgr);
+ Jsr237WorkScheduler scheduler = new Jsr237WorkScheduler(mgr);
+ Work work = createMock(Work.class);
+ NotificationListener<Runnable> listener = createMock(NotificationListener.class);
+ listener.workRejected(isA(Runnable.class));
+ expectLastCall();
+ replay(listener);
+ scheduler.scheduleWork(work, listener);
+ verify(mgr);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testWorkRejectedNoListener() throws Exception {
+ WorkManager mgr = createMock(WorkManager.class);
+ mgr.schedule(isA(Work.class));
+ expectLastCall().andThrow(new WorkRejectedException());
+ replay(mgr);
+ Jsr237WorkScheduler scheduler = new Jsr237WorkScheduler(mgr);
+ Work work = createMock(Work.class);
+ try {
+ scheduler.scheduleWork(work);
+ fail();
+ } catch (WorkSchedulerException e) {
+ // expected
+ }
+ verify(mgr);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/workmanager/ThreadPoolWorkManagerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/workmanager/ThreadPoolWorkManagerTestCase.java
new file mode 100644
index 0000000000..33ecd66fdc
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/services/work/jsr237/workmanager/ThreadPoolWorkManagerTestCase.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.services.work.jsr237.workmanager;
+
+import java.util.concurrent.CountDownLatch;
+
+import commonj.work.Work;
+import commonj.work.WorkEvent;
+import commonj.work.WorkListener;
+import junit.framework.TestCase;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createStrictMock;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import org.easymock.IAnswer;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ThreadPoolWorkManagerTestCase extends TestCase {
+
+ public void testSchedule() throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ Work work = createMock(Work.class);
+ work.run();
+ expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ latch.countDown();
+ return null;
+ }
+ });
+ replay(work);
+ ThreadPoolWorkManager mgr = new ThreadPoolWorkManager(1);
+ mgr.schedule(work);
+ latch.await();
+ verify(work);
+ }
+
+ public void testListener() throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ WorkListener listener = createStrictMock(WorkListener.class);
+ listener.workAccepted(isA(WorkEvent.class));
+ listener.workStarted(isA(WorkEvent.class));
+ listener.workCompleted(isA(WorkEvent.class));
+ expectLastCall();
+ replay(listener);
+ Work work = createMock(Work.class);
+ work.run();
+ expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ latch.countDown();
+ return null;
+ }
+ });
+ replay(work);
+ ThreadPoolWorkManager mgr = new ThreadPoolWorkManager(1);
+ mgr.schedule(work, listener);
+ latch.await();
+ verify(work);
+ }
+
+ public void testDelayListener() throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ final CountDownLatch latch2 = new CountDownLatch(1);
+ WorkListener listener = createStrictMock(WorkListener.class);
+ listener.workAccepted(isA(WorkEvent.class));
+ listener.workStarted(isA(WorkEvent.class));
+ listener.workCompleted(isA(WorkEvent.class));
+ expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ latch2.countDown();
+ return null;
+ }
+ });
+ replay(listener);
+ Work work = createMock(Work.class);
+ work.run();
+ expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ latch.await();
+ return null;
+ }
+ });
+ replay(work);
+ ThreadPoolWorkManager mgr = new ThreadPoolWorkManager(1);
+ mgr.schedule(work, listener);
+ latch.countDown();
+ verify(work);
+ }
+
+ public void testErrorListener() throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ WorkListener listener = createStrictMock(WorkListener.class);
+ listener.workAccepted(isA(WorkEvent.class));
+ listener.workStarted(isA(WorkEvent.class));
+ listener.workCompleted(isA(WorkEvent.class));
+ replay(listener);
+ Work work = createMock(Work.class);
+ work.run();
+ expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ latch.countDown();
+ throw new RuntimeException();
+ }
+ });
+ replay(work);
+ ThreadPoolWorkManager mgr = new ThreadPoolWorkManager(1);
+ mgr.schedule(work, listener);
+ latch.await();
+ verify(work);
+ }
+
+}
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/util/Bean1.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/util/Bean1.java
new file mode 100644
index 0000000000..79fad549aa
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/util/Bean1.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.util;
+
+
+public class Bean1 extends SuperBean {
+
+ public static final int ALL_BEAN1_FIELDS = 6 + ALL_SUPER_FIELDS;
+ public static final int ALL_BEAN1_PUBLIC_PROTECTED_FIELDS = 5 + ALL_SUPER_PUBLIC_PROTECTED_FIELDS;
+ public static final int ALL_BEAN1_METHODS = 4 + ALL_SUPER_METHODS - 1;
+ public String field3;
+ protected String field2;
+ private String field1;
+
+ public void setMethod1(String param) {
+ }
+
+ public void setMethod1(int param) {
+ }
+
+ public void override(String param) throws Exception {
+ }
+
+
+ public void noOverride(String param) throws Exception {
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/util/Bean2.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/util/Bean2.java
new file mode 100644
index 0000000000..7f7f03da9e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/util/Bean2.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.util;
+
+import java.util.List;
+
+import junit.framework.AssertionFailedError;
+
+public class Bean2 {
+
+ private List methodList;
+ private List fieldList;
+
+ public List getMethodList() {
+ return methodList;
+ }
+
+ public void setMethodList(List list) {
+ methodList = list;
+ }
+
+ public List getfieldList() {
+ return fieldList;
+ }
+
+ public void setfieldList(List list) {
+ throw new AssertionFailedError("setter inadvertantly called");
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/util/JavaIntrospectionHelperTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/util/JavaIntrospectionHelperTestCase.java
new file mode 100644
index 0000000000..797b147b54
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/util/JavaIntrospectionHelperTestCase.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.mock.component.Target;
+
+public class JavaIntrospectionHelperTestCase extends TestCase {
+
+ private List testNoGenericsList;
+ private List<String> testList;
+ private Map<String, Bean1> testMap;
+ private Target[] testArray;
+ private String[] testStringArray;
+
+ public JavaIntrospectionHelperTestCase() {
+ super();
+ }
+
+ public JavaIntrospectionHelperTestCase(String arg0) {
+ super(arg0);
+ }
+
+ public void testBean1AllPublicProtectedFields() throws Exception {
+ Set<Field> beanFields = JavaIntrospectionHelper.getAllPublicAndProtectedFields(Bean1.class);
+ assertEquals(4, beanFields.size()); //Bean1.ALL_BEAN1_PUBLIC_PROTECTED_FIELDS
+ }
+
+ public void testGetSuperAllMethods() throws Exception {
+ Set<Method> superBeanMethods = JavaIntrospectionHelper.getAllUniquePublicProtectedMethods(SuperBean.class);
+ assertEquals(SuperBean.ALL_SUPER_METHODS, superBeanMethods.size());
+ }
+
+ public void testGetBean1AllMethods() throws Exception {
+ Set<Method> beanMethods = JavaIntrospectionHelper.getAllUniquePublicProtectedMethods(Bean1.class);
+ assertEquals(Bean1.ALL_BEAN1_METHODS, beanMethods.size());
+ }
+
+ public void testOverrideMethod() throws Exception {
+ Set<Method> beanFields = JavaIntrospectionHelper.getAllUniquePublicProtectedMethods(Bean1.class);
+ boolean invoked = false;
+ for (Method method : beanFields) {
+ if (method.getName().equals("override")) {
+ method.invoke(new Bean1(), "foo");
+ invoked = true;
+ }
+ }
+ if (!invoked) {
+ throw new Exception("Override never invoked");
+ }
+ }
+
+ public void testNoOverrideMethod() throws Exception {
+ Set<Method> beanFields = JavaIntrospectionHelper.getAllUniquePublicProtectedMethods(Bean1.class);
+ boolean found = false;
+ for (Method method : beanFields) {
+ if (method.getName().equals("noOverride") && method.getParameterTypes().length == 0) {
+ found = true;
+ }
+ }
+ if (!found) {
+ throw new Exception("No override not found");
+ }
+ }
+
+ public void testDefaultConstructor() throws Exception {
+ Constructor ctr = JavaIntrospectionHelper.getDefaultConstructor(Bean2.class);
+ assertEquals(ctr, Bean2.class.getConstructor());
+ assertTrue(Bean2.class == ctr.newInstance((Object[]) null).getClass());
+ }
+
+
+ public void testGetAllInterfaces() {
+ Set<Class> interfaces = JavaIntrospectionHelper.getAllInterfaces(Z.class);
+ assertEquals(2, interfaces.size());
+ assertTrue(interfaces.contains(W.class));
+ assertTrue(interfaces.contains(W2.class));
+ }
+
+
+ public void testGetAllInterfacesObject() {
+ Set<Class> interfaces = JavaIntrospectionHelper.getAllInterfaces(Object.class);
+ assertEquals(0, interfaces.size());
+ }
+
+ public void testGetAllInterfacesNoInterfaces() {
+ Set<Class> interfaces = JavaIntrospectionHelper.getAllInterfaces(NoInterface.class);
+ assertEquals(0, interfaces.size());
+ }
+
+ /**
+ * Tests generics introspection capabilities
+ */
+ public void testGenerics() throws Exception {
+
+ List classes = JavaIntrospectionHelper.getGenerics(getClass().getDeclaredField("testList").getGenericType());
+ assertEquals(1, classes.size());
+ assertEquals(String.class, classes.get(0));
+
+ classes =
+ JavaIntrospectionHelper.getGenerics(getClass().getDeclaredField("testNoGenericsList").getGenericType());
+ assertEquals(0, classes.size());
+
+ classes = JavaIntrospectionHelper.getGenerics(getClass().getDeclaredField("testMap").getGenericType());
+ assertEquals(2, classes.size());
+ assertEquals(String.class, classes.get(0));
+ assertEquals(Bean1.class, classes.get(1));
+
+ classes = JavaIntrospectionHelper
+ .getGenerics(getClass().getDeclaredMethod("fooMethod", Map.class).getGenericParameterTypes()[0]);
+ assertEquals(2, classes.size());
+ assertEquals(String.class, classes.get(0));
+ assertEquals(Bean1.class, classes.get(1));
+
+ classes = JavaIntrospectionHelper
+ .getGenerics(getClass().getDeclaredMethod("fooMethod", List.class).getGenericParameterTypes()[0]);
+ assertEquals(1, classes.size());
+ assertEquals(String.class, classes.get(0));
+
+ }
+
+ private void fooMethod(List<String> foo) {
+
+ }
+
+ private void fooMethod(Map<String, Bean1> foo) {
+
+ }
+
+ public void setTestArray(Target[] array) {
+ }
+
+ private interface W {
+
+ }
+
+ private interface W2 {
+
+ }
+
+ private class X implements W {
+
+ }
+
+ private class Y extends X implements W, W2 {
+
+ }
+
+ private class Z extends Y {
+
+ }
+
+ private class NoInterface {
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/util/SuperBean.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/util/SuperBean.java
new file mode 100644
index 0000000000..83aef7fb5e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/util/SuperBean.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.util;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SuperBean {
+
+ public static final int ALL_SUPER_FIELDS = 6;
+ public static final int ALL_SUPER_PUBLIC_PROTECTED_FIELDS = 5;
+ public static final int ALL_SUPER_METHODS = 4;
+ public String superField2;
+
+ protected String superField3;
+
+ private String superField1;
+
+ public void setSuperMethod1(String param) {
+ }
+
+ public void setSuperMethod1(int param) {
+ }
+
+ public void override(String param) throws Exception {
+ throw new Exception("Override not handled");
+ }
+
+ public void noOverride() throws Exception {
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/BasicReferenceInvocationHandlerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/BasicReferenceInvocationHandlerTestCase.java
new file mode 100644
index 0000000000..b62741a7e7
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/BasicReferenceInvocationHandlerTestCase.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.mock.component.SimpleTarget;
+import org.apache.tuscany.core.mock.component.SimpleTargetImpl;
+import org.apache.tuscany.core.mock.wire.MockStaticInvoker;
+import org.apache.tuscany.core.mock.wire.MockSyncInterceptor;
+import org.apache.tuscany.core.wire.jdk.JDKOutboundInvocationHandler;
+
+/**
+ * @version $$Rev$$ $$Date$$
+ */
+public class BasicReferenceInvocationHandlerTestCase extends TestCase {
+
+ private Method echo;
+
+ public void testInterceptorInvoke() throws Throwable {
+ JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ ServiceContract<?> contract = registry.introspect(SimpleTarget.class);
+ Operation<?> operation = contract.getOperations().get("echo");
+ MockStaticInvoker invoker = new MockStaticInvoker(echo, new SimpleTargetImpl());
+ OutboundInvocationChain chain = new OutboundInvocationChainImpl(operation);
+ MockSyncInterceptor interceptor = new MockSyncInterceptor();
+ chain.addInterceptor(interceptor);
+ chain.setTargetInterceptor(new InvokerInterceptor());
+ chain.setTargetInvoker(invoker);
+ chain.prepare();
+ //chains.put(echo, chain);
+ OutboundWire wire = new OutboundWireImpl();
+ wire.addInvocationChain(operation, chain);
+ wire.setServiceContract(contract);
+ JDKOutboundInvocationHandler handler = new JDKOutboundInvocationHandler(SimpleTarget.class, wire, null);
+ assertEquals("foo", handler.invoke(null, echo, new String[]{"foo"}));
+ assertEquals(1, interceptor.getCount());
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+ echo = SimpleTarget.class.getMethod("echo", String.class);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/CallbackInterfaceInterceptorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/CallbackInterfaceInterceptorTestCase.java
new file mode 100644
index 0000000000..6c50cb406f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/CallbackInterfaceInterceptorTestCase.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import org.osoa.sca.NoRegisteredCallbackException;
+
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class CallbackInterfaceInterceptorTestCase extends TestCase {
+
+ public void testOptimize() throws Exception {
+ CallbackInterfaceInterceptor interceptor = new CallbackInterfaceInterceptor(true);
+ assertFalse(interceptor.isOptimizable());
+ }
+
+ public void testImplements() {
+ CallbackInterfaceInterceptor interceptor = new CallbackInterfaceInterceptor(true);
+ Interceptor next = EasyMock.createMock(Interceptor.class);
+ EasyMock.expect(next.invoke(EasyMock.isA(Message.class))).andReturn(null);
+ EasyMock.replay(next);
+ interceptor.setNext(next);
+ interceptor.invoke(new MessageImpl());
+ EasyMock.verify(next);
+ }
+
+ public void testDoesNotImplement() {
+ CallbackInterfaceInterceptor interceptor = new CallbackInterfaceInterceptor(false);
+ try {
+ interceptor.invoke(new MessageImpl());
+ fail();
+ } catch (NoRegisteredCallbackException e) {
+ // expected
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/ContractCompatibilityTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/ContractCompatibilityTestCase.java
new file mode 100644
index 0000000000..d200b983b3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/ContractCompatibilityTestCase.java
@@ -0,0 +1,401 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.DataType;
+import org.apache.tuscany.spi.model.Operation;
+import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.IncompatibleServiceContractException;
+import org.apache.tuscany.spi.wire.OutboundChainHolder;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.ProxyCreationException;
+import org.apache.tuscany.spi.wire.Wire;
+import org.apache.tuscany.spi.wire.WireInvocationHandler;
+import org.apache.tuscany.spi.wire.WireService;
+
+import junit.framework.TestCase;
+
+/**
+ * TODO some tests commented out due to DataType.equals() needing to be strict
+ *
+ * @version $Rev$ $Date$
+ */
+public class ContractCompatibilityTestCase extends TestCase {
+
+ private WireService wireService = new MockWireService();
+
+ public void testNoOperation() throws Exception {
+ ServiceContract source = new MockContract<Type>("FooContract");
+ ServiceContract target = new MockContract<Type>("FooContract");
+ wireService.checkCompatibility(source, target, false);
+ }
+
+ public void testBasic() throws Exception {
+ ServiceContract<Type> source = new MockContract<Type>("FooContract");
+ Operation<Type> opSource1 = new Operation<Type>("op1", null, null, null, false, null, NO_CONVERSATION);
+ Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>();
+ sourceOperations.put("op1", opSource1);
+ source.setOperations(sourceOperations);
+ ServiceContract<Type> target = new MockContract<Type>("FooContract");
+ Operation<Type> opSource2 = new Operation<Type>("op1", null, null, null, false, null, NO_CONVERSATION);
+ Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>();
+ targetOperations.put("op1", opSource2);
+ target.setOperations(targetOperations);
+ wireService.checkCompatibility(source, target, false);
+ }
+
+ public void testBasicIncompatibleOperationNames() throws Exception {
+ ServiceContract<Type> source = new MockContract<Type>("FooContract");
+ Operation<Type> opSource1 = new Operation<Type>("op1", null, null, null, false, null, NO_CONVERSATION);
+ Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>();
+ sourceOperations.put("op1", opSource1);
+ source.setOperations(sourceOperations);
+ ServiceContract<Type> target = new MockContract<Type>("FooContract");
+ Operation<Type> opSource2 = new Operation<Type>("op2", null, null, null, false, null, NO_CONVERSATION);
+ Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>();
+ targetOperations.put("op2", opSource2);
+ target.setOperations(targetOperations);
+ try {
+ wireService.checkCompatibility(source, target, false);
+ fail();
+ } catch (IncompatibleServiceContractException e) {
+ //expected
+ }
+ }
+
+ public void testInputTypes() throws Exception {
+ ServiceContract<Type> source = new MockContract<Type>("FooContract");
+ List<DataType<Type>> sourceInputTypes = new ArrayList<DataType<Type>>();
+ sourceInputTypes.add(new DataType<Type>(Object.class, Object.class));
+ DataType<List<DataType<Type>>> inputType = new DataType<List<DataType<Type>>>(String.class, sourceInputTypes);
+ Operation<Type> opSource1 = new Operation<Type>("op1", inputType, null, null, false, null, NO_CONVERSATION);
+ Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>();
+ sourceOperations.put("op1", opSource1);
+ source.setOperations(sourceOperations);
+
+ ServiceContract<Type> target = new MockContract<Type>("FooContract");
+ List<DataType<Type>> targetInputTypes = new ArrayList<DataType<Type>>();
+ targetInputTypes.add(new DataType<Type>(Object.class, Object.class));
+ DataType<List<DataType<Type>>> targetInputType =
+ new DataType<List<DataType<Type>>>(String.class, targetInputTypes);
+
+ Operation<Type> opTarget =
+ new Operation<Type>("op1", targetInputType, null, null, false, null, NO_CONVERSATION);
+ Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>();
+ targetOperations.put("op1", opTarget);
+ target.setOperations(targetOperations);
+ wireService.checkCompatibility(source, target, false);
+ }
+
+
+ public void testIncompatibleInputTypes() throws Exception {
+ ServiceContract<Type> source = new MockContract<Type>("FooContract");
+ List<DataType<Type>> sourceInputTypes = new ArrayList<DataType<Type>>();
+ sourceInputTypes.add(new DataType<Type>(Integer.class, Integer.class));
+ DataType<List<DataType<Type>>> inputType = new DataType<List<DataType<Type>>>(String.class, sourceInputTypes);
+ Operation<Type> opSource1 = new Operation<Type>("op1", inputType, null, null, false, null, NO_CONVERSATION);
+ Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>();
+ sourceOperations.put("op1", opSource1);
+ source.setOperations(sourceOperations);
+
+ ServiceContract<Type> target = new MockContract<Type>("FooContract");
+ List<DataType<Type>> targetInputTypes = new ArrayList<DataType<Type>>();
+ targetInputTypes.add(new DataType<Type>(String.class, String.class));
+ DataType<List<DataType<Type>>> targetInputType =
+ new DataType<List<DataType<Type>>>(String.class, targetInputTypes);
+
+ Operation<Type> opTarget =
+ new Operation<Type>("op1", targetInputType, null, null, false, null, NO_CONVERSATION);
+ Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>();
+ targetOperations.put("op1", opTarget);
+ target.setOperations(targetOperations);
+ try {
+ wireService.checkCompatibility(source, target, false);
+ fail();
+ } catch (IncompatibleServiceContractException e) {
+ //expected
+ }
+ }
+
+ /**
+ * Verfies source input types can be super types of the target
+ */
+ public void testSourceSuperTypeInputCompatibility() throws Exception {
+// ServiceContract<Type> source = new MockContract<Type>("FooContract");
+// List<DataType<Type>> sourceInputTypes = new ArrayList<DataType<Type>>();
+// sourceInputTypes.add(new DataType<Type>(Object.class, Object.class));
+// DataType<List<DataType<Type>>> inputType = new DataType<List<DataType<Type>>>(String.class, sourceInputTypes);
+// Operation<Type> opSource1 = new Operation<Type>("op1", inputType, null, null, false, null);
+// Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>();
+// sourceOperations.put("op1", opSource1);
+// source.setOperations(sourceOperations);
+//
+// ServiceContract<Type> target = new MockContract<Type>("FooContract");
+// List<DataType<Type>> targetInputTypes = new ArrayList<DataType<Type>>();
+// targetInputTypes.add(new DataType<Type>(String.class, String.class));
+// DataType<List<DataType<Type>>> targetInputType =
+// new DataType<List<DataType<Type>>>(String.class, targetInputTypes);
+//
+// Operation<Type> opTarget = new Operation<Type>("op1", targetInputType, null, null, false, null);
+// Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>();
+// targetOperations.put("op1", opTarget);
+// target.setOperations(targetOperations);
+// wireService.checkCompatibility(source, target, false);
+ }
+
+ public void testOutputTypes() throws Exception {
+ ServiceContract<Type> source = new MockContract<Type>("FooContract");
+ DataType<Type> sourceOutputType = new DataType<Type>(String.class, String.class);
+ Operation<Type> opSource1 =
+ new Operation<Type>("op1", null, sourceOutputType, null, false, null, NO_CONVERSATION);
+ Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>();
+ sourceOperations.put("op1", opSource1);
+ source.setOperations(sourceOperations);
+
+ ServiceContract<Type> target = new MockContract<Type>("FooContract");
+ DataType<Type> targetOutputType = new DataType<Type>(String.class, String.class);
+ Operation<Type> opTarget =
+ new Operation<Type>("op1", null, targetOutputType, null, false, null, NO_CONVERSATION);
+ Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>();
+ targetOperations.put("op1", opTarget);
+ target.setOperations(targetOperations);
+ wireService.checkCompatibility(source, target, false);
+ }
+
+ /**
+ * Verfies a return type that is a supertype of of the target is compatible
+ */
+ public void testSupertypeOutputTypes() throws Exception {
+// ServiceContract<Type> source = new MockContract<Type>("FooContract");
+// DataType<Type> sourceOutputType = new DataType<Type>(Object.class, Object.class);
+// Operation<Type> opSource1 = new Operation<Type>("op1", null, sourceOutputType, null, false, null);
+// Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>();
+// sourceOperations.put("op1", opSource1);
+// source.setOperations(sourceOperations);
+//
+// ServiceContract<Type> target = new MockContract<Type>("FooContract");
+// DataType<Type> targetOutputType = new DataType<Type>(String.class, String.class);
+// Operation<Type> opTarget = new Operation<Type>("op1", null, targetOutputType, null, false, null);
+// Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>();
+// targetOperations.put("op1", opTarget);
+// target.setOperations(targetOperations);
+// wireService.checkCompatibility(source, target, false);
+ }
+
+ public void testIncompatibleOutputTypes() throws Exception {
+ ServiceContract<Type> source = new MockContract<Type>("FooContract");
+ DataType<Type> sourceOutputType = new DataType<Type>(String.class, String.class);
+ Operation<Type> opSource1 =
+ new Operation<Type>("op1", null, sourceOutputType, null, false, null, NO_CONVERSATION);
+ Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>();
+ sourceOperations.put("op1", opSource1);
+ source.setOperations(sourceOperations);
+
+ ServiceContract<Type> target = new MockContract<Type>("FooContract");
+ DataType<Type> targetOutputType = new DataType<Type>(Integer.class, Integer.class);
+ Operation<Type> opTarget =
+ new Operation<Type>("op1", null, targetOutputType, null, false, null, NO_CONVERSATION);
+ Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>();
+ targetOperations.put("op1", opTarget);
+ target.setOperations(targetOperations);
+ try {
+ wireService.checkCompatibility(source, target, false);
+ fail();
+ } catch (IncompatibleServiceContractException e) {
+ //expected
+ }
+ }
+
+ public void testFaultTypes() throws Exception {
+ ServiceContract<Type> source = new MockContract<Type>("FooContract");
+ DataType<Type> sourceFaultType = new DataType<Type>(String.class, String.class);
+ List<DataType<Type>> sourceFaultTypes = new ArrayList<DataType<Type>>();
+ sourceFaultTypes.add(0, sourceFaultType);
+ Operation<Type> opSource1 =
+ new Operation<Type>("op1", null, null, sourceFaultTypes, false, null, NO_CONVERSATION);
+ Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>();
+ sourceOperations.put("op1", opSource1);
+ source.setOperations(sourceOperations);
+
+ ServiceContract<Type> target = new MockContract<Type>("FooContract");
+ DataType<Type> targetFaultType = new DataType<Type>(String.class, String.class);
+ List<DataType<Type>> targetFaultTypes = new ArrayList<DataType<Type>>();
+ targetFaultTypes.add(0, targetFaultType);
+
+ Operation<Type> opTarget =
+ new Operation<Type>("op1", null, null, targetFaultTypes, false, null, NO_CONVERSATION);
+ Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>();
+ targetOperations.put("op1", opTarget);
+ target.setOperations(targetOperations);
+ wireService.checkCompatibility(source, target, false);
+ }
+
+ public void testSourceFaultTargetNoFaultCompatibility() throws Exception {
+ ServiceContract<Type> source = new MockContract<Type>("FooContract");
+ DataType<Type> sourceFaultType = new DataType<Type>(String.class, String.class);
+ List<DataType<Type>> sourceFaultTypes = new ArrayList<DataType<Type>>();
+ sourceFaultTypes.add(0, sourceFaultType);
+ Operation<Type> opSource1 =
+ new Operation<Type>("op1", null, null, sourceFaultTypes, false, null, NO_CONVERSATION);
+ Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>();
+ sourceOperations.put("op1", opSource1);
+ source.setOperations(sourceOperations);
+
+ ServiceContract<Type> target = new MockContract<Type>("FooContract");
+ Operation<Type> opTarget = new Operation<Type>("op1", null, null, null, false, null, NO_CONVERSATION);
+ Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>();
+ targetOperations.put("op1", opTarget);
+ target.setOperations(targetOperations);
+ wireService.checkCompatibility(source, target, false);
+ }
+
+ /**
+ * Verifies a source's fault which is a supertype of the target's fault are compatibile
+ *
+ * @throws Exception
+ */
+ public void testFaultSuperTypes() throws Exception {
+// ServiceContract<Type> source = new MockContract<Type>("FooContract");
+// DataType<Type> sourceFaultType = new DataType<Type>(Exception.class, Exception.class);
+// List<DataType<Type>> sourceFaultTypes = new ArrayList<DataType<Type>>();
+// sourceFaultTypes.add(0, sourceFaultType);
+// Operation<Type> opSource1 = new Operation<Type>("op1", null, null, sourceFaultTypes, false, null);
+// Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>();
+// sourceOperations.put("op1", opSource1);
+// source.setOperations(sourceOperations);
+//
+// ServiceContract<Type> target = new MockContract<Type>("FooContract");
+// DataType<Type> targetFaultType = new DataType<Type>(TuscanyException.class, TuscanyException.class);
+// List<DataType<Type>> targetFaultTypes = new ArrayList<DataType<Type>>();
+// targetFaultTypes.add(0, targetFaultType);
+//
+// Operation<Type> opTarget = new Operation<Type>("op1", null, null, targetFaultTypes, false, null);
+// Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>();
+// targetOperations.put("op1", opTarget);
+// target.setOperations(targetOperations);
+// wireService.checkCompatibility(source, target, false);
+ }
+
+ /**
+ * Verifies a source's faults which are supertypes and a superset of the target's faults are compatibile
+ */
+ public void testFaultSuperTypesAndSuperset() throws Exception {
+// ServiceContract<Type> source = new MockContract<Type>("FooContract");
+// DataType<Type> sourceFaultType = new DataType<Type>(Exception.class, Exception.class);
+// DataType<Type> sourceFaultType2 = new DataType<Type>(RuntimeException.class, RuntimeException.class);
+// List<DataType<Type>> sourceFaultTypes = new ArrayList<DataType<Type>>();
+// sourceFaultTypes.add(0, sourceFaultType);
+// sourceFaultTypes.add(1, sourceFaultType2);
+// Operation<Type> opSource1 = new Operation<Type>("op1", null, null, sourceFaultTypes, false, null);
+// Map<String, Operation<Type>> sourceOperations = new HashMap<String, Operation<Type>>();
+// sourceOperations.put("op1", opSource1);
+// source.setOperations(sourceOperations);
+//
+// ServiceContract<Type> target = new MockContract<Type>("FooContract");
+// DataType<Type> targetFaultType = new DataType<Type>(TuscanyException.class, TuscanyException.class);
+// List<DataType<Type>> targetFaultTypes = new ArrayList<DataType<Type>>();
+// targetFaultTypes.add(0, targetFaultType);
+//
+// Operation<Type> opTarget = new Operation<Type>("op1", null, null, targetFaultTypes, false, null);
+// Map<String, Operation<Type>> targetOperations = new HashMap<String, Operation<Type>>();
+// targetOperations.put("op1", opTarget);
+// target.setOperations(targetOperations);
+// wireService.checkCompatibility(source, target, false);
+ }
+
+ private class MockContract<T> extends ServiceContract<T> {
+ public MockContract() {
+ }
+
+ public MockContract(Class interfaceClass) {
+ super(interfaceClass);
+ }
+
+ public MockContract(String interfaceName) {
+ super(interfaceName);
+ }
+ }
+
+ private class MockWireService extends WireServiceExtension {
+ public MockWireService() {
+ super(null, null);
+ }
+
+ public <T> T createProxy(Class<T> interfaze, Wire wire) throws ProxyCreationException {
+ throw new UnsupportedOperationException();
+ }
+
+ public <T> T createProxy(Class<T> interfaze, Wire wire, Map<Method, OutboundChainHolder> mapping)
+ throws ProxyCreationException {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object createCallbackProxy(Class<?> interfaze, InboundWire wire) throws ProxyCreationException {
+ throw new UnsupportedOperationException();
+ }
+
+
+ public WireInvocationHandler createHandler(Class<?> interfaze, Wire wire) {
+ throw new UnsupportedOperationException();
+ }
+
+ public OutboundInvocationChain createOutboundChain(Operation<?> operation) {
+ throw new UnsupportedOperationException();
+ }
+
+ public InboundInvocationChain createInboundChain(Operation<?> operation) {
+ throw new UnsupportedOperationException();
+ }
+
+ public InboundWire createWire(ServiceDefinition service) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void createWires(AtomicComponent component, ComponentDefinition<?> definition) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void createWires(ReferenceBinding referenceBinding, ServiceContract<?> contract,
+ QualifiedName targetName) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void createWires(ServiceBinding serviceBinding, ServiceContract<?> contract, String targetName) {
+ throw new UnsupportedOperationException();
+ }
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/InboundInvocationErrorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/InboundInvocationErrorTestCase.java
new file mode 100644
index 0000000000..39e1bf0b46
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/InboundInvocationErrorTestCase.java
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.model.Operation;
+import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.mock.wire.MockStaticInvoker;
+import org.apache.tuscany.core.mock.wire.MockSyncInterceptor;
+import org.apache.tuscany.core.wire.jdk.JDKInboundInvocationHandler;
+import org.easymock.classextension.EasyMock;
+
+/**
+ * Tests handling of exceptions thrown during an inbound wire invocation
+ *
+ * @version $Rev$ $Date$
+ */
+public class InboundInvocationErrorTestCase extends TestCase {
+ private Method checkedMethod;
+ private Method runtimeMethod;
+ private Operation checkedOperation;
+ private Operation runtimeOperation;
+
+ public InboundInvocationErrorTestCase() {
+ super();
+ }
+
+ public InboundInvocationErrorTestCase(String arg0) {
+ super(arg0);
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+ checkedMethod =
+ TestBean.class.getDeclaredMethod("checkedException", (Class[]) null);
+ runtimeMethod =
+ TestBean.class.getDeclaredMethod("runtimeException", (Class[]) null);
+ assertNotNull(checkedMethod);
+ assertNotNull(runtimeMethod);
+ JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ ServiceContract<?> contract;
+ try {
+ contract = registry.introspect(TestBean.class);
+ } catch (InvalidServiceContractException e) {
+ throw new AssertionError();
+ }
+
+ checkedOperation = contract.getOperations().get("checkedException");
+ runtimeOperation = contract.getOperations().get("runtimeException");
+ }
+
+ public void testCheckedException() throws Exception {
+ WorkContext workContext = EasyMock.createNiceMock(WorkContext.class);
+ EasyMock.replay(workContext);
+
+ Operation<Type> operation =
+ new Operation<Type>("checkedException", null, null, null, false, null, NO_CONVERSATION);
+ Map<Operation<?>, InboundInvocationChain> chains = new HashMap<Operation<?>, InboundInvocationChain>();
+ chains.put(operation, createChain(checkedMethod, checkedOperation));
+ InboundWire wire = new InboundWireImpl();
+ wire.addInvocationChains(chains);
+ wire.setServiceContract(new ServiceContract<TestBean>(TestBean.class) {
+ });
+
+ JDKInboundInvocationHandler handler = new JDKInboundInvocationHandler(TestBean.class, wire, workContext);
+ try {
+ ClassLoader ccl = Thread.currentThread().getContextClassLoader();
+ TestBean proxy = (TestBean) Proxy.newProxyInstance(ccl, new Class[]{TestBean.class}, handler);
+ proxy.checkedException();
+ } catch (InboundInvocationErrorTestCase.TestException e) {
+ return;
+ }
+ fail(InboundInvocationErrorTestCase.TestException.class.getName() + " should have been thrown");
+ }
+
+ public void testRuntimeException() throws Exception {
+ WorkContext workContext = EasyMock.createNiceMock(WorkContext.class);
+ EasyMock.replay(workContext);
+
+ Operation<Type> operation =
+ new Operation<Type>("runtimeException", null, null, null, false, null, NO_CONVERSATION);
+ Map<Operation<?>, InboundInvocationChain> chains = new HashMap<Operation<?>, InboundInvocationChain>();
+ chains.put(operation, createChain(runtimeMethod, runtimeOperation));
+ InboundWire wire = new InboundWireImpl();
+ wire.addInvocationChains(chains);
+ wire.setServiceContract(new ServiceContract<TestBean>(TestBean.class) {
+ });
+
+ JDKInboundInvocationHandler handler = new JDKInboundInvocationHandler(TestBean.class, wire, workContext);
+ try {
+ InboundInvocationErrorTestCase.TestBean proxy = (InboundInvocationErrorTestCase.TestBean) Proxy
+ .newProxyInstance(Thread.currentThread().getContextClassLoader(),
+ new Class[]{InboundInvocationErrorTestCase.TestBean.class}, handler);
+ proxy.runtimeException();
+ } catch (InboundInvocationErrorTestCase.TestRuntimeException e) {
+ return;
+ }
+ fail(InboundInvocationErrorTestCase.TestException.class.getName() + " should have been thrown");
+ }
+
+ private InboundInvocationChain createChain(Method m, Operation operation) {
+ MockStaticInvoker invoker = new MockStaticInvoker(m, new TestBeanImpl());
+ InboundInvocationChain chain = new InboundInvocationChainImpl(operation);
+ chain.addInterceptor(new MockSyncInterceptor());
+ chain.setTargetInvoker(invoker);
+ chain.addInterceptor(new InvokerInterceptor());
+ chain.prepare();
+ return chain;
+ }
+
+ public interface TestBean {
+
+ void checkedException() throws TestException;
+
+ void runtimeException() throws TestRuntimeException;
+
+ }
+
+ public class TestBeanImpl implements TestBean {
+
+ public void checkedException() throws InboundInvocationErrorTestCase.TestException {
+ throw new TestException();
+ }
+
+ public void runtimeException() throws TestRuntimeException {
+ throw new TestRuntimeException();
+ }
+ }
+
+ public class TestException extends Exception {
+ }
+
+ public class TestRuntimeException extends RuntimeException {
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/IncompatibleServiceContractExceptionFormatterTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/IncompatibleServiceContractExceptionFormatterTestCase.java
new file mode 100644
index 0000000000..a9f455bc62
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/IncompatibleServiceContractExceptionFormatterTestCase.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.IncompatibleServiceContractException;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.host.monitor.FormatterRegistry;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class IncompatibleServiceContractExceptionFormatterTestCase extends TestCase {
+ FormatterRegistry registry = EasyMock.createNiceMock(FormatterRegistry.class);
+ IncompatibleServiceContractExceptionFormatter formatter =
+ new IncompatibleServiceContractExceptionFormatter(registry);
+
+ public void testFormat() throws Exception {
+ ServiceContract<Object> source = new ServiceContract<Object>() {
+ };
+ source.setInterfaceName("sourceInterface");
+ ServiceContract<Object> target = new ServiceContract<Object>() {
+ };
+ target.setInterfaceName("targetInterface");
+ Operation<Object> sourceOp = new Operation<Object>("sourceOp", null, null, null);
+ Operation<Object> targetOp = new Operation<Object>("targetOp", null, null, null);
+
+ IncompatibleServiceContractException e =
+ new IncompatibleServiceContractException("message", source, target, sourceOp, targetOp);
+ StringWriter writer = new StringWriter();
+ PrintWriter pw = new PrintWriter(writer);
+ formatter.write(pw, e);
+ String buffer = writer.toString();
+ assertTrue(buffer.indexOf("message") >= 0);
+ assertTrue(buffer.indexOf("sourceInterface") >= 0);
+ assertTrue(buffer.indexOf("targetInterface") >= 0);
+ assertTrue(buffer.indexOf("sourceOp") >= 0);
+ assertTrue(buffer.indexOf("targetOp") >= 0);
+ }
+
+
+ public void testFormatNulls() throws Exception {
+ ServiceContract<Object> source = new ServiceContract<Object>() {
+ };
+ source.setInterfaceName("sourceInterface");
+ ServiceContract<Object> target = new ServiceContract<Object>() {
+ };
+ target.setInterfaceName("targetInterface");
+
+ IncompatibleServiceContractException e =
+ new IncompatibleServiceContractException("message", source, target);
+ StringWriter writer = new StringWriter();
+ PrintWriter pw = new PrintWriter(writer);
+ formatter.write(pw, e);
+ String buffer = writer.toString();
+ assertTrue(buffer.indexOf("message") >= 0);
+ assertTrue(buffer.indexOf("sourceInterface") >= 0);
+ assertTrue(buffer.indexOf("targetInterface") >= 0);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/InvocationChainImplTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/InvocationChainImplTestCase.java
new file mode 100644
index 0000000000..294e98997f
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/InvocationChainImplTestCase.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.lang.reflect.Type;
+
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class InvocationChainImplTestCase extends TestCase {
+
+ public void testInsertAtPos() throws Exception {
+ MockChain chain = new MockChain(new Operation<Type>("foo", null, null, null));
+ Interceptor inter3 = new MockInterceptor();
+ Interceptor inter2 = new MockInterceptor();
+ Interceptor inter1 = new MockInterceptor();
+ chain.addInterceptor(inter3);
+ chain.addInterceptor(0, inter1);
+ chain.addInterceptor(1, inter2);
+ Interceptor head = chain.getHeadInterceptor();
+ assertEquals(inter1, head);
+ assertEquals(inter2, head.getNext());
+ assertEquals(inter3, head.getNext().getNext());
+ }
+
+ public void testInsertAtEnd() throws Exception {
+ MockChain chain = new MockChain(new Operation<Type>("foo", null, null, null));
+ Interceptor inter2 = new MockInterceptor();
+ Interceptor inter1 = new MockInterceptor();
+ chain.addInterceptor(0, inter1);
+ chain.addInterceptor(1, inter2);
+ Interceptor head = chain.getHeadInterceptor();
+ assertEquals(inter1, head);
+ assertEquals(inter2, head.getNext());
+ assertEquals(inter2, chain.getTailInterceptor());
+
+ }
+
+ private class MockChain extends InvocationChainImpl {
+
+ public MockChain(Operation operation) {
+ super(operation);
+ }
+
+ public void prepare() {
+
+ }
+ }
+
+ private class MockInterceptor implements Interceptor {
+
+ private Interceptor next;
+
+ public Message invoke(Message msg) {
+ return null;
+ }
+
+ public void setNext(Interceptor next) {
+ this.next = next;
+ }
+
+ public Interceptor getNext() {
+ return next;
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationErrorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationErrorTestCase.java
new file mode 100644
index 0000000000..aca68a0f25
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationErrorTestCase.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.mock.component.SimpleTarget;
+import org.apache.tuscany.core.mock.component.SimpleTargetImpl;
+import org.apache.tuscany.core.mock.wire.MockStaticInvoker;
+import org.apache.tuscany.core.mock.wire.MockSyncInterceptor;
+
+/**
+ * Tests error propagation through an innvocation
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvocationConfigurationErrorTestCase extends TestCase {
+
+ private ServiceContract<?> contract;
+ private Method hello;
+
+ public InvocationConfigurationErrorTestCase() {
+ super();
+ }
+
+ public InvocationConfigurationErrorTestCase(String arg0) {
+ super(arg0);
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+ JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ contract = registry.introspect(SimpleTarget.class);
+ hello = SimpleTarget.class.getMethod("hello", String.class);
+ }
+
+ /**
+ * Tests basic wiring of a source to a target, including handlers and interceptors
+ */
+ public void testInvokeWithInterceptors() throws Exception {
+ Operation operation = contract.getOperations().get("hello");
+ OutboundInvocationChain source = new OutboundInvocationChainImpl(operation);
+ MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor();
+ source.addInterceptor(sourceInterceptor);
+
+ InboundInvocationChain target = new InboundInvocationChainImpl(operation);
+ MockSyncInterceptor targetInterceptor = new MockSyncInterceptor();
+ target.addInterceptor(targetInterceptor);
+ target.addInterceptor(new InvokerInterceptor());
+
+ // connect the source to the target
+ source.setTargetInterceptor(target.getHeadInterceptor());
+ source.prepare();
+ target.prepare();
+ MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl());
+ source.setTargetInvoker(invoker);
+
+ Message msg = new MessageImpl();
+ msg.setTargetInvoker(invoker);
+ Message response = source.getHeadInterceptor().invoke(msg);
+ assertTrue(response.isFault());
+ assertTrue(response.getBody() instanceof IllegalArgumentException);
+ assertEquals(1, sourceInterceptor.getCount());
+ assertEquals(1, targetInterceptor.getCount());
+
+ }
+
+}
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationTestCase.java
new file mode 100644
index 0000000000..62df732a9e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationTestCase.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.mock.component.SimpleTarget;
+import org.apache.tuscany.core.mock.component.SimpleTargetImpl;
+import org.apache.tuscany.core.mock.wire.MockStaticInvoker;
+import org.apache.tuscany.core.mock.wire.MockSyncInterceptor;
+
+public class InvocationConfigurationTestCase extends TestCase {
+
+ private Method hello;
+ private Operation operation;
+
+
+ public InvocationConfigurationTestCase() {
+ super();
+ }
+
+ public InvocationConfigurationTestCase(String arg0) {
+ super(arg0);
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+ JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ ServiceContract<?> contract;
+ try {
+ contract = registry.introspect(SimpleTarget.class);
+ } catch (InvalidServiceContractException e) {
+ throw new AssertionError();
+ }
+
+ operation = contract.getOperations().get("echo");
+ hello = SimpleTarget.class.getMethod("hello", String.class);
+ }
+
+ /**
+ * Tests basic wiring of a source to a target, including handlers and interceptors
+ */
+ public void testInvokeWithInterceptors() throws Exception {
+ OutboundInvocationChain source = new OutboundInvocationChainImpl(operation);
+ MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor();
+ source.addInterceptor(sourceInterceptor);
+
+ InboundInvocationChain target = new InboundInvocationChainImpl(operation);
+ MockSyncInterceptor targetInterceptor = new MockSyncInterceptor();
+ target.addInterceptor(targetInterceptor);
+ target.addInterceptor(new InvokerInterceptor());
+
+ // connect the source to the target
+ source.setTargetInterceptor(target.getHeadInterceptor());
+ source.prepare();
+ target.prepare();
+ MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl());
+ source.setTargetInvoker(invoker);
+
+ Message msg = new MessageImpl();
+ msg.setBody("foo");
+ msg.setTargetInvoker(invoker);
+ Message response = source.getHeadInterceptor().invoke(msg);
+ assertEquals("foo", response.getBody());
+ assertEquals(1, sourceInterceptor.getCount());
+ assertEquals(1, targetInterceptor.getCount());
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/NonBlockingBridgingInterceptorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/NonBlockingBridgingInterceptorTestCase.java
new file mode 100644
index 0000000000..1755fe9d15
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/NonBlockingBridgingInterceptorTestCase.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.services.work.WorkScheduler;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.getCurrentArguments;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import org.easymock.IAnswer;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class NonBlockingBridgingInterceptorTestCase extends TestCase {
+
+ public void testInvoke() throws Exception {
+ WorkScheduler scheduler = createMock(WorkScheduler.class);
+ scheduler.scheduleWork(isA(Runnable.class));
+ expectLastCall().andStubAnswer(new IAnswer<Object>() {
+ public Object answer() throws Throwable {
+ Runnable runnable = (Runnable) getCurrentArguments()[0];
+ runnable.run();
+ return null;
+ }
+ });
+ replay(scheduler);
+ WorkContext context = createMock(WorkContext.class);
+ String convID = "convID";
+ EasyMock.expect(context.getIdentifier(Scope.CONVERSATION)).andReturn(convID);
+ context.setCurrentCorrelationId(null);
+ context.setIdentifier(Scope.CONVERSATION, convID);
+ EasyMock.replay(context);
+ Message msg = new MessageImpl();
+ Interceptor next = EasyMock.createMock(Interceptor.class);
+ EasyMock.expect(next.invoke(EasyMock.eq(msg))).andReturn(msg);
+ EasyMock.replay(next);
+ Interceptor interceptor = new NonBlockingBridgingInterceptor(scheduler, context, next);
+ interceptor.invoke(msg);
+ verify(context);
+ verify(next);
+ }
+
+ public void testOptimizable() {
+ NonBlockingBridgingInterceptor interceptor = new NonBlockingBridgingInterceptor(null, null);
+ assertFalse(interceptor.isOptimizable());
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/OptimizedWireObjectFactoryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/OptimizedWireObjectFactoryTestCase.java
new file mode 100644
index 0000000000..e0f094a83e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/OptimizedWireObjectFactoryTestCase.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class OptimizedWireObjectFactoryTestCase extends TestCase {
+
+ public void testGetInstance() throws Exception {
+ Foo foo = new Foo();
+ OutboundWire wire = EasyMock.createMock(OutboundWire.class);
+ EasyMock.expect(wire.getTargetService()).andReturn(foo);
+ EasyMock.replay(wire);
+ OptimizedWireObjectFactory factory = new OptimizedWireObjectFactory(wire);
+ assertEquals(foo, factory.getInstance());
+ EasyMock.verify(wire);
+ }
+
+ private class Foo {
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/OutboundInvocationErrorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/OutboundInvocationErrorTestCase.java
new file mode 100644
index 0000000000..42caa6eed7
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/OutboundInvocationErrorTestCase.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.mock.wire.MockStaticInvoker;
+import org.apache.tuscany.core.mock.wire.MockSyncInterceptor;
+import org.apache.tuscany.core.wire.jdk.JDKOutboundInvocationHandler;
+
+/**
+ * Tests handling of exceptions thrown during an outbound wire invocation
+ *
+ * @version $Rev$ $Date$
+ */
+public class OutboundInvocationErrorTestCase extends TestCase {
+
+ private Method checkedMethod;
+ private Method runtimeMethod;
+ private JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+
+ public OutboundInvocationErrorTestCase() {
+ super();
+ }
+
+ public OutboundInvocationErrorTestCase(String arg0) {
+ super(arg0);
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+ checkedMethod = TestBean.class.getDeclaredMethod("checkedException", (Class[]) null);
+ runtimeMethod = TestBean.class.getDeclaredMethod("runtimeException", (Class[]) null);
+ assertNotNull(checkedMethod);
+ assertNotNull(runtimeMethod);
+ }
+
+ public void testCheckedException() throws Exception {
+ OutboundWire wire = new OutboundWireImpl();
+ ServiceContract<?> contract = registry.introspect(TestBean.class);
+ wire.setServiceContract(contract);
+ Operation operation = contract.getOperations().get("checkedException");
+ wire.addInvocationChain(operation, createChain(checkedMethod, operation));
+ JDKOutboundInvocationHandler handler = new JDKOutboundInvocationHandler(TestBean.class, wire, null);
+ try {
+ TestBean proxy = (TestBean) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
+ new Class[]{TestBean.class}, handler);
+ proxy.checkedException();
+ } catch (TestException e) {
+ return;
+ }
+ fail(TestException.class.getName() + " should have been thrown");
+ }
+
+ public void testRuntimeException() throws Exception {
+ OutboundWire wire = new OutboundWireImpl();
+ ServiceContract<?> contract = registry.introspect(TestBean.class);
+ wire.setServiceContract(contract);
+ Operation operation = contract.getOperations().get("runtimeException");
+ OutboundInvocationChain chain = createChain(runtimeMethod, operation);
+ wire.addInvocationChain(operation, chain);
+ JDKOutboundInvocationHandler handler = new JDKOutboundInvocationHandler(TestBean.class, wire, null);
+ try {
+ TestBean proxy = (TestBean) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
+ new Class[]{TestBean.class}, handler);
+ proxy.runtimeException();
+ } catch (TestRuntimeException e) {
+ return;
+ }
+ fail(TestException.class.getName() + " should have been thrown");
+ }
+
+ private OutboundInvocationChain createChain(Method m, Operation operation) {
+ MockStaticInvoker invoker = new MockStaticInvoker(m, new TestBeanImpl());
+ OutboundInvocationChain chain = new OutboundInvocationChainImpl(operation);
+ chain.addInterceptor(new MockSyncInterceptor());
+ chain.setTargetInvoker(invoker);
+ chain.setTargetInterceptor(new InvokerInterceptor());
+ chain.prepare();
+ return chain;
+ }
+
+ public interface TestBean {
+
+ void checkedException() throws TestException;
+
+ void runtimeException() throws TestRuntimeException;
+
+ }
+
+ public class TestBeanImpl implements TestBean {
+
+ public void checkedException() throws TestException {
+ throw new TestException();
+ }
+
+ public void runtimeException() throws TestRuntimeException {
+ throw new TestRuntimeException();
+ }
+ }
+
+ public class TestException extends Exception {
+ }
+
+ public class TestRuntimeException extends RuntimeException {
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/OutboundInvocationHandlerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/OutboundInvocationHandlerTestCase.java
new file mode 100644
index 0000000000..70d85445ed
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/OutboundInvocationHandlerTestCase.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.idl.java.JavaIDLUtils;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.mock.component.SimpleTarget;
+import org.apache.tuscany.core.mock.component.SimpleTargetImpl;
+import org.apache.tuscany.core.mock.wire.MockStaticInvoker;
+import org.apache.tuscany.core.mock.wire.MockSyncInterceptor;
+import org.apache.tuscany.core.wire.jdk.JDKOutboundInvocationHandler;
+
+public class OutboundInvocationHandlerTestCase extends TestCase {
+
+ private Method hello;
+ private ServiceContract<?> contract;
+
+ public OutboundInvocationHandlerTestCase() {
+ super();
+ }
+
+ public OutboundInvocationHandlerTestCase(String arg0) {
+ super(arg0);
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+ JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ contract = registry.introspect(SimpleTarget.class);
+ hello = SimpleTarget.class.getMethod("hello", String.class);
+ }
+
+ public void testBasicInvoke() throws Throwable {
+ OutboundWire wire = new OutboundWireImpl();
+ Operation operation = contract.getOperations().get("hello");
+ wire.addInvocationChain(operation, createChain(operation));
+ wire.setServiceContract(contract);
+ JDKOutboundInvocationHandler handler = new JDKOutboundInvocationHandler(SimpleTarget.class, wire, null);
+ assertEquals("foo", handler.invoke(hello, new Object[]{"foo"}));
+ }
+
+ public void testErrorInvoke() throws Throwable {
+ OutboundWire wire = new OutboundWireImpl();
+ Operation operation = contract.getOperations().get("hello");
+ wire.addInvocationChain(operation, createChain(operation));
+ wire.setServiceContract(contract);
+ JDKOutboundInvocationHandler handler = new JDKOutboundInvocationHandler(SimpleTarget.class, wire, null);
+ try {
+ handler.invoke(hello, new Object[]{});
+ fail("Expected " + IllegalArgumentException.class.getName());
+ } catch (IllegalArgumentException e) {
+ // should throw
+ }
+ }
+
+ public void testDirectErrorInvoke() throws Throwable {
+ Operation operation = contract.getOperations().get("hello");
+ OutboundInvocationChain source = new OutboundInvocationChainImpl(operation);
+ MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl());
+ source.setTargetInvoker(invoker);
+
+ OutboundWire wire = new OutboundWireImpl();
+ wire.setServiceContract(contract);
+ wire.addInvocationChain(operation, source);
+ JDKOutboundInvocationHandler handler = new JDKOutboundInvocationHandler(SimpleTarget.class, wire, null);
+ try {
+ assertEquals("foo", handler.invoke(hello, new Object[]{}));
+ fail("Expected " + IllegalArgumentException.class.getName());
+ } catch (IllegalArgumentException e) {
+ // should throw
+ }
+ }
+
+ public void testDirectInvoke() throws Throwable {
+ Operation operation = contract.getOperations().get("hello");
+ OutboundInvocationChain source = new OutboundInvocationChainImpl(operation);
+ MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl());
+ source.setTargetInvoker(invoker);
+
+ OutboundWire wire = new OutboundWireImpl();
+ wire.setServiceContract(contract);
+ wire.addInvocationChain(operation, source);
+ JDKOutboundInvocationHandler handler = new JDKOutboundInvocationHandler(SimpleTarget.class, wire, null);
+ assertEquals("foo", handler.invoke(hello, new Object[]{"foo"}));
+ }
+
+ private OutboundInvocationChain createChain(Operation operation) {
+ OutboundInvocationChain source = new OutboundInvocationChainImpl(operation);
+ MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor();
+ source.addInterceptor(sourceInterceptor);
+
+ InboundInvocationChain target = new InboundInvocationChainImpl(operation);
+ MockSyncInterceptor targetInterceptor = new MockSyncInterceptor();
+ target.addInterceptor(targetInterceptor);
+ target.addInterceptor(new InvokerInterceptor());
+
+ // connect the source to the target
+ source.setTargetInterceptor(targetInterceptor);
+ source.prepare();
+ target.prepare();
+ Method method = JavaIDLUtils.findMethod(operation, SimpleTarget.class.getMethods());
+ MockStaticInvoker invoker = new MockStaticInvoker(method, new SimpleTargetImpl());
+ source.setTargetInvoker(invoker);
+ return source;
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/OutboundWireTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/OutboundWireTestCase.java
new file mode 100644
index 0000000000..9d0de99ed2
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/OutboundWireTestCase.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class OutboundWireTestCase extends TestCase {
+
+ /**
+ * Tests that the target wire returns null if there is no connected wire. This behavior is needed for optional
+ * autowires.
+ */
+ public void testGetNonExistentTargetService() throws Exception {
+ OutboundWire wire = new OutboundWireImpl();
+ assertNull(wire.getTargetService());
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/SynchronousBridgingInterceptorTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/SynchronousBridgingInterceptorTestCase.java
new file mode 100644
index 0000000000..f1631fc555
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/SynchronousBridgingInterceptorTestCase.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.verify;
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SynchronousBridgingInterceptorTestCase extends TestCase {
+
+ public void testInvoke() throws Exception {
+ Message msg = new MessageImpl();
+ Interceptor next = EasyMock.createMock(Interceptor.class);
+ EasyMock.expect(next.invoke(EasyMock.eq(msg))).andReturn(msg);
+ EasyMock.replay(next);
+ Interceptor interceptor = new SynchronousBridgingInterceptor(next);
+ interceptor.invoke(msg);
+ verify(next);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/WireObjectFactoryTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/WireObjectFactoryTestCase.java
new file mode 100644
index 0000000000..537ca21656
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/WireObjectFactoryTestCase.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.WireService;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WireObjectFactoryTestCase extends TestCase {
+
+ @SuppressWarnings({"unchecked"})
+ public void testCreateInstance() throws Exception {
+ Operation<Type> op = new Operation<Type>("hello", null, null, null);
+ OutboundInvocationChain chain = new OutboundInvocationChainImpl(op);
+ OutboundWire wire = EasyMock.createMock(OutboundWire.class);
+ Map<Operation<?>, OutboundInvocationChain> chains = new HashMap<Operation<?>, OutboundInvocationChain>();
+ chains.put(op, chain);
+ EasyMock.expect(wire.getInvocationChains()).andReturn(chains);
+ EasyMock.expect(wire.isOptimizable()).andReturn(false);
+ EasyMock.replay(wire);
+ WireService service = EasyMock.createMock(WireService.class);
+ service.createProxy(EasyMock.eq(Foo.class), EasyMock.eq(wire), EasyMock.isA(Map.class));
+ EasyMock.expectLastCall().andReturn(new Foo() {
+ public void hello() {
+
+ }
+ });
+ EasyMock.replay(service);
+
+ WireObjectFactory<Foo> factory = new WireObjectFactory<Foo>(Foo.class, wire, service);
+ factory.getInstance();
+ EasyMock.verify(service);
+ EasyMock.verify(wire);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testOptimizedCreateInstance() throws Exception {
+ ServiceContract<?> contract = new JavaServiceContract(Foo.class);
+ OutboundWire wire = EasyMock.createMock(OutboundWire.class);
+ EasyMock.expect(wire.isOptimizable()).andReturn(true);
+ EasyMock.expect(wire.getServiceContract()).andReturn(contract).atLeastOnce();
+ EasyMock.expect(wire.getInvocationChains()).andReturn((Map) Collections.emptyMap());
+ EasyMock.expect(wire.getTargetService()).andReturn(new Foo() {
+ public void hello() {
+ }
+ });
+ EasyMock.replay(wire);
+ WireObjectFactory<Foo> factory = new WireObjectFactory<Foo>(Foo.class, wire, null);
+ factory.getInstance();
+ EasyMock.verify(wire);
+
+ }
+
+ /**
+ * Verifies that a proxy is created when the required client contract is different than the wire contract
+ */
+ @SuppressWarnings("unchecked")
+ public void testCannotOptimizeDifferentContractsCreateInstance() throws Exception {
+ ServiceContract<?> contract = new JavaServiceContract(Object.class);
+ OutboundWire wire = EasyMock.createMock(OutboundWire.class);
+ EasyMock.expect(wire.isOptimizable()).andReturn(true);
+ EasyMock.expect(wire.getServiceContract()).andReturn(contract).atLeastOnce();
+ EasyMock.expect(wire.getInvocationChains()).andReturn((Map) Collections.emptyMap());
+ EasyMock.replay(wire);
+ WireService service = EasyMock.createMock(WireService.class);
+ service.createProxy(EasyMock.eq(Foo.class), EasyMock.eq(wire), EasyMock.isA(Map.class));
+ EasyMock.expectLastCall().andReturn(new Foo() {
+ public void hello() {
+
+ }
+ });
+ EasyMock.replay(service);
+
+ WireObjectFactory<Foo> factory = new WireObjectFactory<Foo>(Foo.class, wire, service);
+ factory.getInstance();
+ EasyMock.verify(service);
+ EasyMock.verify(wire);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testNoJavaInterfaceCreateInstance() throws Exception {
+ ServiceContract<?> contract = new JavaServiceContract();
+ OutboundWire wire = EasyMock.createMock(OutboundWire.class);
+ EasyMock.expect(wire.isOptimizable()).andReturn(true);
+ EasyMock.expect(wire.getServiceContract()).andReturn(contract).atLeastOnce();
+ EasyMock.expect(wire.getInvocationChains()).andReturn((Map) Collections.emptyMap());
+ EasyMock.replay(wire);
+ WireService service = EasyMock.createMock(WireService.class);
+ service.createProxy(EasyMock.eq(Foo.class), EasyMock.eq(wire), EasyMock.isA(Map.class));
+ EasyMock.expectLastCall().andReturn(new Foo() {
+ public void hello() {
+
+ }
+ });
+ EasyMock.replay(service);
+
+ WireObjectFactory<Foo> factory = new WireObjectFactory<Foo>(Foo.class, wire, service);
+ factory.getInstance();
+ EasyMock.verify(service);
+ EasyMock.verify(wire);
+ }
+
+ private interface Foo {
+ void hello();
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/WireOptimizationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/WireOptimizationTestCase.java
new file mode 100644
index 0000000000..c0d40c6369
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/WireOptimizationTestCase.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.lang.reflect.Type;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.Component;
+import org.apache.tuscany.spi.model.Operation;
+import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * Verifies wire optimization analysis
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class WireOptimizationTestCase extends TestCase {
+ private Operation operation;
+
+ public void foo() {
+ }
+
+ public void testSourceWireInterceptorOptimization() throws Exception {
+ AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class);
+ EasyMock.replay(component);
+ OutboundWire wire = new OutboundWireImpl();
+ wire.setContainer(component);
+ OutboundInvocationChain chain = new OutboundInvocationChainImpl(operation);
+ chain.addInterceptor(new OptimizableInterceptor());
+ wire.addInvocationChain(operation, chain);
+ assertTrue(WireUtils.isOptimizable(wire));
+ }
+
+ public void testSourceWireNonInterceptorOptimization() throws Exception {
+ AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class);
+ EasyMock.replay(component);
+ OutboundWire wire = new OutboundWireImpl();
+ wire.setContainer(component);
+ OutboundInvocationChain chain = new OutboundInvocationChainImpl(operation);
+ chain.addInterceptor(new NonOptimizableInterceptor());
+ wire.addInvocationChain(operation, chain);
+ assertFalse(WireUtils.isOptimizable(wire));
+ }
+
+ public void testTargetWireInterceptorOptimization() throws Exception {
+ AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class);
+ EasyMock.expect(component.isOptimizable()).andReturn(true);
+ EasyMock.replay(component);
+ InboundWire wire = new InboundWireImpl();
+ wire.setContainer(component);
+ InboundInvocationChain chain = new InboundInvocationChainImpl(operation);
+ chain.addInterceptor(new OptimizableInterceptor());
+ wire.addInvocationChain(operation, chain);
+ assertTrue(WireUtils.isOptimizable(wire));
+
+ }
+
+ public void testTargetWireNoOptimizationNonAtomicContainer() throws Exception {
+ Component component = EasyMock.createNiceMock(Component.class);
+ EasyMock.expect(component.isOptimizable()).andReturn(true);
+ EasyMock.replay(component);
+ InboundWire wire = new InboundWireImpl();
+ wire.setContainer(component);
+ InboundInvocationChain chain = new InboundInvocationChainImpl(operation);
+ chain.addInterceptor(new OptimizableInterceptor());
+ wire.addInvocationChain(operation, chain);
+ assertTrue(WireUtils.isOptimizable(wire));
+ }
+
+ public void testTargetWireNonInterceptorOptimization() throws Exception {
+ AtomicComponent component = EasyMock.createNiceMock(AtomicComponent.class);
+ EasyMock.replay(component);
+ InboundWire wire = new InboundWireImpl();
+ wire.setContainer(component);
+ InboundInvocationChain chain = new InboundInvocationChainImpl(operation);
+ chain.addInterceptor(new NonOptimizableInterceptor());
+ wire.addInvocationChain(operation, chain);
+ assertFalse(WireUtils.isOptimizable(wire));
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ operation = new Operation<Type>("foo", null, null, null, false, null, NO_CONVERSATION);
+
+ }
+
+ private class OptimizableInterceptor implements Interceptor {
+
+ public Message invoke(Message msg) {
+ return null;
+ }
+
+ public void setNext(Interceptor next) {
+
+ }
+
+ public Interceptor getNext() {
+ return null;
+ }
+
+ public boolean isOptimizable() {
+ return true;
+ }
+ }
+
+ private class NonOptimizableInterceptor implements Interceptor {
+
+ public Message invoke(Message msg) {
+ return null;
+ }
+
+ public void setNext(Interceptor next) {
+
+ }
+
+ public Interceptor getNext() {
+ return null;
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/WireServiceExtensionTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/WireServiceExtensionTestCase.java
new file mode 100644
index 0000000000..1838fd35bd
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/WireServiceExtensionTestCase.java
@@ -0,0 +1,333 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.QualifiedName;
+import org.apache.tuscany.spi.component.AbstractSCAObject;
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.Reference;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.component.TargetInvokerCreationException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.ComponentDefinition;
+import org.apache.tuscany.spi.model.ComponentReferenceDefinition;
+import org.apache.tuscany.spi.model.ComponentType;
+import org.apache.tuscany.spi.model.ComponentTypeReferenceDefinition;
+import org.apache.tuscany.spi.model.Implementation;
+import org.apache.tuscany.spi.model.Multiplicity;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.Property;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ReferenceTarget;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundChainHolder;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.ProxyCreationException;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.apache.tuscany.spi.wire.Wire;
+import org.apache.tuscany.spi.wire.WireInvocationHandler;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.mock.binding.MockServiceBinding;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WireServiceExtensionTestCase extends TestCase {
+ private TestWireService wireService;
+ private Operation<Type> operation;
+ private ServiceContract<Type> contract;
+ private Operation<Type> callbackOperation;
+
+ public void testCreateInboundChain() throws Exception {
+ InboundInvocationChain chain = wireService.createInboundChain(operation);
+ assertEquals(operation, chain.getOperation());
+ }
+
+ public void testCreateOutboundChain() throws Exception {
+ OutboundInvocationChain chain = wireService.createOutboundChain(operation);
+ assertEquals(operation, chain.getOperation());
+ }
+
+ public void testCreateServiceWire() throws Exception {
+ ServiceDefinition definition = new ServiceDefinition("foo", contract, false);
+ TargetInvoker invoker = EasyMock.createMock(TargetInvoker.class);
+ MessageImpl resp = new MessageImpl();
+ EasyMock.expect(invoker.invoke(EasyMock.isA(Message.class))).andReturn(resp);
+ EasyMock.replay(invoker);
+ InboundWire wire = wireService.createWire(definition);
+ assertEquals("foo", wire.getServiceName());
+ assertEquals(1, wire.getInvocationChains().size());
+ assertEquals(contract, wire.getServiceContract());
+ InboundInvocationChain chain = wire.getInvocationChains().get(operation);
+ assertEquals(operation, chain.getOperation());
+ // verify the chain is invokable
+ MessageImpl msg = new MessageImpl();
+ msg.setTargetInvoker(invoker);
+ assertNotNull(chain.getHeadInterceptor().invoke(msg));
+ EasyMock.verify(invoker);
+ }
+
+ /*public void testCreateReferenceWire() throws Exception {
+ AbstractReferenceDefinition definition = new AbstractReferenceDefinition("foo", contract);
+ ReferenceTarget target = new ReferenceTarget();
+ target.addTarget(new URI("bar"));
+ target.setReferenceName("refName");
+
+ OutboundWire wire = wireService.createWire(target, definition).get(0);
+ assertEquals("refName", wire.getReferenceName());
+ assertEquals("bar", wire.getTargetName().toString());
+ assertFalse(wire.isAutowire());
+ assertEquals(1, wire.getInvocationChains().size());
+ assertEquals(contract, wire.getServiceContract());
+ OutboundInvocationChain chain = wire.getInvocationChains().get(operation);
+ assertEquals(operation, chain.getOperation());
+ assertNull(chain.getHeadInterceptor());
+ assertEquals(Callback.class, wire.getCallbackInterface());
+ assertEquals(1, wire.getTargetCallbackInvocationChains().size());
+ InboundInvocationChain callbackChain = wire.getTargetCallbackInvocationChains().get(callbackOperation);
+ assertEquals(callbackOperation, callbackChain.getOperation());
+
+ TargetInvoker invoker = EasyMock.createMock(TargetInvoker.class);
+ MessageImpl resp = new MessageImpl();
+ EasyMock.expect(invoker.invoke(EasyMock.isA(Message.class))).andReturn(resp);
+ EasyMock.replay(invoker);
+ // verify the callback chain is invokable
+ MessageImpl msg = new MessageImpl();
+ msg.setTargetInvoker(invoker);
+ assertNotNull(callbackChain.getHeadInterceptor().invoke(msg));
+ EasyMock.verify(invoker);
+ }*/
+
+ public void testCreateAutowireReferenceWire() throws Exception {
+ ComponentTypeReferenceDefinition definition = new ComponentTypeReferenceDefinition("foo", contract);
+ definition.setAutowire(true);
+ ComponentReferenceDefinition compRef = new ComponentReferenceDefinition(definition);
+ //ReferenceTarget target = new ReferenceTarget();
+ //target.setReferenceName("refName");
+ OutboundWire wire = wireService.createWire(new ArrayList<URI>(), compRef).get(0);
+ assertTrue(wire.isAutowire());
+ assertEquals("foo", wire.getReferenceName());
+ assertEquals(contract, wire.getServiceContract());
+ assertEquals(Callback.class, wire.getCallbackInterface());
+ }
+
+ public void testCreateReferenceMultipleWire() throws Exception {
+ ComponentTypeReferenceDefinition ctRefDef = new ComponentTypeReferenceDefinition("foo", contract);
+ ComponentReferenceDefinition definition = new ComponentReferenceDefinition(ctRefDef);
+ definition.setMultiplicity(Multiplicity.ONE_N);
+
+ //ReferenceTarget target = new ReferenceTarget();
+ List<URI> target = new ArrayList<URI>();
+ target.add(new URI("bar"));
+ target.add(new URI("bar2"));
+ //target.setReferenceName("refName");
+
+ List<OutboundWire> wires = wireService.createWire(target, definition);
+ assertEquals(2, wires.size());
+ }
+
+ public void testCreateComponentWires() throws Exception {
+ ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>> type =
+ new ComponentType<ServiceDefinition, ComponentTypeReferenceDefinition, Property<?>>();
+ ComponentTypeReferenceDefinition referenceDefinition = new ComponentTypeReferenceDefinition("refName", contract);
+ type.add(referenceDefinition);
+ ServiceDefinition serviceDefinition = new ServiceDefinition("foo", contract, false);
+ type.add(serviceDefinition);
+
+ Implementation<ComponentType> impl = new Implementation<ComponentType>() {
+ };
+ impl.setComponentType(type);
+
+ ComponentDefinition<Implementation<ComponentType>> definition =
+ new ComponentDefinition<Implementation<ComponentType>>("Foo", impl);
+ ComponentReferenceDefinition compRef =
+ new ComponentReferenceDefinition(type.getReferences().get("refName"));
+ compRef.addTarget(new URI("bar"));
+ definition.add(compRef);
+
+ /*ReferenceTarget target = new ReferenceTarget();
+ target.addTarget(new URI("bar"));
+ target.setReferenceName("refName");
+ definition.add(target);
+ */
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ component.addInboundWire(EasyMock.isA(InboundWire.class));
+ component.addOutboundWire(EasyMock.isA(OutboundWire.class));
+ EasyMock.replay(component);
+
+ wireService.createWires(component, definition);
+ EasyMock.verify(component);
+ }
+
+ public void testCreateReferenceBindingWire() throws Exception {
+ ReferenceBinding binding = new MockReferenceBinding();
+ QualifiedName qName = new QualifiedName("target");
+
+ wireService.createWires(binding, contract, qName);
+
+ InboundWire inboundWire = binding.getInboundWire();
+ assertEquals(1, inboundWire.getInvocationChains().size());
+ assertEquals(contract, inboundWire.getServiceContract());
+ assertEquals(binding, inboundWire.getContainer());
+
+ OutboundWire outboundWire = binding.getOutboundWire();
+ assertEquals("target", outboundWire.getTargetName().toString());
+ assertEquals(1, outboundWire.getInvocationChains().size());
+ assertEquals(contract, outboundWire.getServiceContract());
+ assertEquals(binding, outboundWire.getContainer());
+ }
+
+ public void testCreateServiceBindingWire() throws Exception {
+ ServiceBinding binding = new MockServiceBinding();
+
+ wireService.createWires(binding, contract, "target");
+
+ InboundWire inboundWire = binding.getInboundWire();
+ assertEquals(1, inboundWire.getInvocationChains().size());
+ assertEquals(contract, inboundWire.getServiceContract());
+ assertEquals(binding, inboundWire.getContainer());
+
+ OutboundWire outboundWire = binding.getOutboundWire();
+ assertEquals("target", outboundWire.getTargetName().toString());
+ assertEquals(1, outboundWire.getInvocationChains().size());
+ assertEquals(contract, outboundWire.getServiceContract());
+ assertEquals(binding, outboundWire.getContainer());
+ assertEquals(1, outboundWire.getTargetCallbackInvocationChains().size());
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ wireService = new TestWireService(new WorkContextImpl());
+
+ operation = new Operation<Type>("foo", null, null, null);
+ callbackOperation = new Operation<Type>("foo", null, null, null);
+ Map<String, Operation<Type>> operations = new HashMap<String, Operation<Type>>();
+ operations.put("foo", operation);
+ Map<String, Operation<Type>> callbackOperations = new HashMap<String, Operation<Type>>();
+ callbackOperations.put("foo", callbackOperation);
+ contract = new ServiceContract<Type>() {
+ };
+ contract.setOperations(operations);
+ contract.setCallbackClass(Callback.class);
+ contract.setCallbackName(Callback.class.getName());
+ contract.setCallbackOperations(callbackOperations);
+ }
+
+ private interface Callback {
+
+ }
+
+ private class TestWireService extends WireServiceExtension {
+ protected TestWireService(WorkContext context) {
+ super(context, null);
+ }
+
+ public <T> T createProxy(Class<T> interfaze, Wire wire) throws ProxyCreationException {
+ return null;
+ }
+
+ public <T> T createProxy(Class<T> interfaze, Wire wire, Map<Method, OutboundChainHolder> mapping)
+ throws ProxyCreationException {
+ return null;
+ }
+
+ public Object createCallbackProxy(Class<?> interfaze, InboundWire wire) throws ProxyCreationException {
+ return null;
+ }
+
+ public WireInvocationHandler createHandler(Class<?> interfaze, Wire wire) {
+ return null;
+ }
+
+
+ public List<OutboundWire> createWire(List<URI> refTargetURIs, ComponentReferenceDefinition def) {
+ return super.createWire(refTargetURIs, def);
+ }
+ }
+
+ private class MockReferenceBinding extends AbstractSCAObject implements ReferenceBinding {
+ private ServiceContract<?> bindingServiceContract;
+ private InboundWire inboundWire;
+ private OutboundWire outboundWire;
+
+ public MockReferenceBinding() {
+ super("foo", null);
+ }
+
+ public ServiceContract<?> getBindingServiceContract() {
+ return bindingServiceContract;
+ }
+
+ public QName getBindingType() {
+ return null;
+ }
+
+ public void setReference(Reference reference) {
+
+ }
+
+ public InboundWire getInboundWire() {
+ return inboundWire;
+ }
+
+ public void setInboundWire(InboundWire inboundWire) {
+ this.inboundWire = inboundWire;
+ }
+
+ public OutboundWire getOutboundWire() {
+ return outboundWire;
+ }
+
+ public void setOutboundWire(OutboundWire outboundWire) {
+ this.outboundWire = outboundWire;
+ }
+
+ public TargetInvoker createTargetInvoker(ServiceContract contract, Operation operation)
+ throws TargetInvokerCreationException {
+ return null;
+ }
+
+ public Scope getScope() {
+ return null;
+ }
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/WireUtilsTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/WireUtilsTestCase.java
new file mode 100644
index 0000000000..331c0760d9
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/WireUtilsTestCase.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Map;
+
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundChainHolder;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WireUtilsTestCase extends TestCase {
+ private Method m;
+
+ public void testCreateInterfaceToWireMapping() throws Exception {
+ OutboundWire wire = new OutboundWireImpl();
+ Operation<Type> op = new Operation<Type>("hello", null, null, null);
+ OutboundInvocationChain chain = new OutboundInvocationChainImpl(op);
+ wire.addInvocationChain(op, chain);
+ Map<Method, OutboundChainHolder> chains = WireUtils.createInterfaceToWireMapping(Foo.class, wire);
+ assertEquals(1, chains.size());
+ assertNotNull(chains.get(m));
+ }
+
+ public void testCreateInterfaceToWireMappingNoOperation() throws Exception {
+ OutboundWire wire = new OutboundWireImpl();
+ Operation<Type> op = new Operation<Type>("goodbye", null, null, null);
+ OutboundInvocationChain chain = new OutboundInvocationChainImpl(op);
+ wire.addInvocationChain(op, chain);
+ try {
+ WireUtils.createInterfaceToWireMapping(Foo.class, wire);
+ fail();
+ } catch (NoMethodForOperationException e) {
+ // expected
+ }
+ }
+
+ public void testCreateInboundMapping() throws Exception {
+ InboundWire wire = new InboundWireImpl();
+ Operation<Type> op = new Operation<Type>("hello", null, null, null);
+ InboundInvocationChain chain = new InboundInvocationChainImpl(op);
+ wire.addInvocationChain(op, chain);
+ Map<Method, InboundInvocationChain> chains = WireUtils.createInboundMapping(wire, new Method[]{m});
+ assertEquals(1, chains.size());
+ assertNotNull(chains.get(m));
+ }
+
+ public void testCreateInboundMappingNoOperation() throws Exception {
+ InboundWire wire = new InboundWireImpl();
+ Operation<Type> op = new Operation<Type>("goodbye", null, null, null);
+ InboundInvocationChain chain = new InboundInvocationChainImpl(op);
+ wire.addInvocationChain(op, chain);
+ try {
+ WireUtils.createInboundMapping(wire, new Method[]{m});
+ fail();
+ } catch (NoMethodForOperationException e) {
+ // expected
+ }
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ m = Foo.class.getMethod("hello");
+ }
+
+ private interface Foo {
+ void hello();
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandlerSerializationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandlerSerializationTestCase.java
new file mode 100644
index 0000000000..df4dc63ea4
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandlerSerializationTestCase.java
@@ -0,0 +1,54 @@
+package org.apache.tuscany.core.wire.jdk;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.SCAExternalizable;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JDKCallbackInvocationHandlerSerializationTestCase extends TestCase {
+ private InboundWire wire;
+ private WorkContext workContext;
+
+ public void testSerializeDeserialize() throws Exception {
+ JDKCallbackInvocationHandler handler = new JDKCallbackInvocationHandler(wire, workContext);
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ ObjectOutputStream ostream = new ObjectOutputStream(stream);
+ ostream.writeObject(handler);
+
+ ObjectInputStream istream = new ObjectInputStream(new ByteArrayInputStream(stream.toByteArray()));
+ SCAExternalizable externalizable = (SCAExternalizable) istream.readObject();
+
+ externalizable.setWorkContext(workContext);
+ externalizable.reactivate();
+ EasyMock.verify(wire);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ wire = EasyMock.createMock(InboundWire.class);
+ EasyMock.expect(wire.getServiceName()).andReturn("foo").atLeastOnce();
+ EasyMock.replay(wire);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getInboundWire(EasyMock.eq("foo"))).andReturn(wire);
+ EasyMock.replay(component);
+ workContext = new WorkContextImpl();
+ workContext.setCurrentAtomicComponent(component);
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ workContext.setCurrentAtomicComponent(null);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandlerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandlerTestCase.java
new file mode 100644
index 0000000000..b8cbde687d
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKCallbackInvocationHandlerTestCase.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire.jdk;
+
+import java.lang.reflect.Proxy;
+
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.wire.InboundWireImpl;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JDKCallbackInvocationHandlerTestCase extends TestCase {
+
+ public void testToString() {
+ InboundWireImpl wire = new InboundWireImpl();
+ wire.setServiceContract(new JavaServiceContract(Foo.class));
+ JDKCallbackInvocationHandler handler = new JDKCallbackInvocationHandler(wire, new WorkContextImpl());
+ Foo foo = (Foo) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Foo.class}, handler);
+ assertNotNull(foo.toString());
+ }
+
+ public void testHashCode() {
+ InboundWireImpl wire = new InboundWireImpl();
+ wire.setServiceContract(new JavaServiceContract(Foo.class));
+ JDKCallbackInvocationHandler handler = new JDKCallbackInvocationHandler(wire, new WorkContextImpl());
+ Foo foo = (Foo) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Foo.class}, handler);
+ assertNotNull(foo.hashCode());
+ }
+
+ private interface Foo {
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInboundInvocationHandlerSerializationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInboundInvocationHandlerSerializationTestCase.java
new file mode 100644
index 0000000000..a631982958
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInboundInvocationHandlerSerializationTestCase.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire.jdk;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.Operation;
+import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.wire.InboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.InvokerInterceptor;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JDKInboundInvocationHandlerSerializationTestCase extends TestCase {
+ private InboundWire wire;
+ private WorkContext workContext;
+ private TargetInvoker invoker;
+
+ public void testSerializeDeserialize() throws Throwable {
+ JDKInboundInvocationHandler handler = new JDKInboundInvocationHandler(Foo.class, wire, workContext);
+ handler.invoke(Foo.class.getMethod("invoke"), null);
+
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ ObjectOutputStream ostream = new ObjectOutputStream(stream);
+ ostream.writeObject(handler);
+
+ ObjectInputStream istream = new ObjectInputStream(new ByteArrayInputStream(stream.toByteArray()));
+ JDKInboundInvocationHandler externalizable = (JDKInboundInvocationHandler) istream.readObject();
+
+ externalizable.setWorkContext(workContext);
+ externalizable.reactivate();
+ externalizable.invoke(Foo.class.getMethod("invoke"), null);
+ EasyMock.verify(wire);
+ EasyMock.verify(invoker);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ wire = EasyMock.createMock(InboundWire.class);
+ Map<Operation<?>, InboundInvocationChain> map = new HashMap<Operation<?>, InboundInvocationChain>();
+ Operation<Object> operation = new Operation<Object>("invoke", null, null, null, false, null, NO_CONVERSATION);
+ map.put(operation, createChain(operation));
+
+ EasyMock.expect(wire.getServiceName()).andReturn("foo").atLeastOnce();
+ EasyMock.expect(wire.getInvocationChains()).andReturn(map).times(2);
+ EasyMock.replay(wire);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getInboundWire(EasyMock.eq("foo"))).andReturn(wire);
+ EasyMock.replay(component);
+ workContext = new WorkContextImpl();
+ workContext.setCurrentAtomicComponent(component);
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ workContext.setCurrentAtomicComponent(null);
+ }
+
+ private InboundInvocationChain createChain(Operation operation) {
+ invoker = EasyMock.createMock(TargetInvoker.class);
+ EasyMock.expect(invoker.invoke(EasyMock.isA(Message.class))).andReturn(new MessageImpl()).times(2);
+ EasyMock.expect(invoker.isCacheable()).andReturn(false).atLeastOnce();
+ EasyMock.replay(invoker);
+ InboundInvocationChain chain = new InboundInvocationChainImpl(operation);
+ chain.setTargetInvoker(invoker);
+ chain.addInterceptor(new InvokerInterceptor());
+ chain.prepare();
+ return chain;
+ }
+
+ public class Foo {
+ public void invoke() {
+ }
+ }
+
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInboundInvocationHandlerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInboundInvocationHandlerTestCase.java
new file mode 100644
index 0000000000..1a4238c589
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInboundInvocationHandlerTestCase.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire.jdk;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.model.DataType;
+import org.apache.tuscany.spi.model.Operation;
+import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.mock.component.SimpleTarget;
+import org.apache.tuscany.core.mock.component.SimpleTargetImpl;
+import org.apache.tuscany.core.mock.wire.MockStaticInvoker;
+import org.apache.tuscany.core.mock.wire.MockSyncInterceptor;
+import org.apache.tuscany.core.wire.InboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.InboundWireImpl;
+import org.apache.tuscany.core.wire.InvokerInterceptor;
+import org.easymock.classextension.EasyMock;
+
+/**
+ * Verifies invocations on inbound wires
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+public class JDKInboundInvocationHandlerTestCase extends TestCase {
+
+ private Method echo;
+ private Operation operation;
+
+ public void testInterceptorInvoke() throws Throwable {
+ MockStaticInvoker invoker = new MockStaticInvoker(echo, new SimpleTargetImpl());
+ InboundInvocationChain chain = new InboundInvocationChainImpl(operation);
+ MockSyncInterceptor interceptor = new MockSyncInterceptor();
+ chain.addInterceptor(interceptor);
+ chain.addInterceptor(new InvokerInterceptor());
+ chain.setTargetInvoker(invoker);
+ chain.prepare();
+ InboundWire wire = createWire(chain);
+
+ WorkContext workContext = EasyMock.createNiceMock(WorkContext.class);
+ EasyMock.replay(workContext);
+ JDKInboundInvocationHandler handler = new JDKInboundInvocationHandler(SimpleTarget.class, wire, workContext);
+ assertEquals("foo", handler.invoke(echo, new String[]{"foo"}));
+ assertEquals(1, interceptor.getCount());
+ }
+
+ public void testDirectErrorInvoke() throws Throwable {
+ InboundInvocationChain source = new InboundInvocationChainImpl(operation);
+ MockStaticInvoker invoker = new MockStaticInvoker(echo, new SimpleTargetImpl());
+ source.setTargetInvoker(invoker);
+ InboundWire wire = createWire(source);
+
+ WorkContext workContext = EasyMock.createNiceMock(WorkContext.class);
+ EasyMock.replay(workContext);
+ JDKInboundInvocationHandler handler = new JDKInboundInvocationHandler(SimpleTarget.class, wire, workContext);
+ try {
+ assertEquals("foo", handler.invoke(echo, new Object[]{}));
+ fail("Expected " + IllegalArgumentException.class.getName());
+ } catch (IllegalArgumentException e) {
+ // should throw
+ }
+ }
+
+ public void testDirectInvoke() throws Throwable {
+ InboundInvocationChain source = new InboundInvocationChainImpl(operation);
+ MockStaticInvoker invoker = new MockStaticInvoker(echo, new SimpleTargetImpl());
+ source.setTargetInvoker(invoker);
+ InboundWire wire = createWire(source);
+
+ WorkContext workContext = EasyMock.createNiceMock(WorkContext.class);
+ EasyMock.replay(workContext);
+ JDKInboundInvocationHandler handler = new JDKInboundInvocationHandler(SimpleTarget.class, wire, workContext);
+ assertEquals("foo", handler.invoke(echo, new Object[]{"foo"}));
+ }
+
+ public void testToString() {
+ WorkContext workContext = EasyMock.createNiceMock(WorkContext.class);
+ EasyMock.replay(workContext);
+ InboundWireImpl wire = new InboundWireImpl();
+ wire.setServiceContract(new ServiceContract<Foo>(Foo.class) {
+ });
+ JDKInboundInvocationHandler handler = new JDKInboundInvocationHandler(SimpleTarget.class, wire, workContext);
+ Foo foo = (Foo) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Foo.class}, handler);
+ assertNotNull(foo.toString());
+ }
+
+ public void testHashCode() {
+ WorkContext workContext = EasyMock.createNiceMock(WorkContext.class);
+ EasyMock.replay(workContext);
+ InboundWireImpl wire = new InboundWireImpl();
+ wire.setServiceContract(new ServiceContract<Foo>(Foo.class) {
+ });
+ JDKInboundInvocationHandler handler = new JDKInboundInvocationHandler(SimpleTarget.class, wire, workContext);
+ Foo foo = (Foo) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Foo.class}, handler);
+ assertNotNull(foo.hashCode());
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+ JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ ServiceContract<?> contract;
+ try {
+ contract = registry.introspect(SimpleTarget.class);
+ } catch (InvalidServiceContractException e) {
+ throw new AssertionError();
+ }
+ operation = contract.getOperations().get("echo");
+ echo = SimpleTarget.class.getMethod("echo", String.class);
+ }
+
+
+ private InboundWire createWire(InboundInvocationChain chain) {
+ DataType<Type> type = new DataType<Type>(String.class, String.class);
+ List<DataType<Type>> types = new ArrayList<DataType<Type>>();
+ types.add(type);
+ DataType<List<DataType<Type>>> inputType =
+ new DataType<List<DataType<Type>>>(Object[].class, types);
+ Operation<Type> operation = new Operation<Type>("echo", inputType, null, null, false, null, NO_CONVERSATION);
+ Map<Operation<?>, InboundInvocationChain> chains = new HashMap<Operation<?>, InboundInvocationChain>();
+ chains.put(operation, chain);
+ InboundWire wire = new InboundWireImpl();
+ wire.addInvocationChains(chains);
+ wire.setServiceContract(new ServiceContract<SimpleTarget>(SimpleTarget.class) {
+ });
+ return wire;
+ }
+
+ private interface Foo {
+
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKOutboundInvocationHandlerProxyTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKOutboundInvocationHandlerProxyTestCase.java
new file mode 100644
index 0000000000..39d8113584
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKOutboundInvocationHandlerProxyTestCase.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire.jdk;
+
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorRegistry;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl;
+import org.apache.tuscany.core.wire.OutboundInvocationChainImpl;
+import org.apache.tuscany.core.wire.OutboundWireImpl;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JDKOutboundInvocationHandlerProxyTestCase extends TestCase {
+
+ private JavaInterfaceProcessorRegistry registry = new JavaInterfaceProcessorRegistryImpl();
+ private OutboundWire wire;
+ private Method clientHello;
+ private TargetInvoker targetInvoker;
+
+ public void testDifferentInterface() throws Throwable {
+ JDKOutboundInvocationHandler handler = new JDKOutboundInvocationHandler(Client.class, wire, null);
+ handler.invoke(null, clientHello, null);
+ EasyMock.verify(targetInvoker);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ wire = new OutboundWireImpl();
+ JavaServiceContract contract = registry.introspect(Target.class);
+ for (Operation<?> operation : contract.getOperations().values()) {
+ OutboundInvocationChain chain = new OutboundInvocationChainImpl(operation);
+ wire.addInvocationChain(operation, chain);
+ targetInvoker = EasyMock.createMock(TargetInvoker.class);
+ EasyMock.expect(targetInvoker.invokeTarget(EasyMock.isNull(), EasyMock.eq(TargetInvoker.NONE)))
+ .andReturn(new MessageImpl());
+ EasyMock.expect(targetInvoker.isCacheable()).andReturn(false);
+ EasyMock.replay(targetInvoker);
+ chain.setTargetInvoker(targetInvoker);
+ }
+ wire.setServiceContract(contract);
+ clientHello = Client.class.getMethod("hello");
+
+ }
+
+ private interface Target {
+ String hello();
+ }
+
+ private interface Client {
+ String hello();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKOutboundInvocationHandlerSerializationTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKOutboundInvocationHandlerSerializationTestCase.java
new file mode 100644
index 0000000000..c6e449d291
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKOutboundInvocationHandlerSerializationTestCase.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire.jdk;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.spi.component.AtomicComponent;
+import org.apache.tuscany.spi.component.SCAObject;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.model.InteractionScope;
+import org.apache.tuscany.spi.model.Operation;
+import static org.apache.tuscany.spi.model.Operation.NO_CONVERSATION;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.wire.InvokerInterceptor;
+import org.apache.tuscany.core.wire.OutboundInvocationChainImpl;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JDKOutboundInvocationHandlerSerializationTestCase extends TestCase {
+ private OutboundWire wire;
+ private WorkContext workContext;
+ private TargetInvoker invoker;
+
+ public void testSerializeDeserialize() throws Throwable {
+ JDKOutboundInvocationHandler handler =
+ new JDKOutboundInvocationHandler(Foo.class, wire, workContext);
+ handler.invoke(Foo.class.getMethod("invoke"), null);
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ ObjectOutputStream ostream = new ObjectOutputStream(stream);
+ ostream.writeObject(handler);
+
+ ObjectInputStream istream = new ObjectInputStream(new ByteArrayInputStream(stream.toByteArray()));
+ JDKOutboundInvocationHandler externalizable = (JDKOutboundInvocationHandler) istream.readObject();
+
+ externalizable.setWorkContext(workContext);
+ externalizable.reactivate();
+ externalizable.invoke(Foo.class.getMethod("invoke"), null);
+ EasyMock.verify(invoker);
+ EasyMock.verify(wire);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ SCAObject container = EasyMock.createMock(SCAObject.class);
+ ServiceContract<Foo> contract = new ServiceContract<Foo>() {
+ };
+ contract.setInterfaceClass(Foo.class);
+ contract.setInteractionScope(InteractionScope.NONCONVERSATIONAL);
+ EasyMock.expect(container.getName()).andReturn("bar").atLeastOnce();
+ EasyMock.replay(container);
+ wire = EasyMock.createMock(OutboundWire.class);
+ Map<Operation<?>, OutboundInvocationChain> map = new HashMap<Operation<?>, OutboundInvocationChain>();
+ Operation<Object> operation = new Operation<Object>("invoke", null, null, null, false, null, NO_CONVERSATION);
+ ServiceContract<Object> opContract = new ServiceContract<Object>() {
+ };
+ contract.setInterfaceClass(Foo.class);
+ contract.setInteractionScope(InteractionScope.NONCONVERSATIONAL);
+ operation.setServiceContract(opContract);
+ map.put(operation, createChain(operation));
+ EasyMock.expect(wire.getContainer()).andReturn(container).atLeastOnce();
+ EasyMock.expect(wire.getServiceContract()).andReturn(contract).atLeastOnce();
+ EasyMock.expect(wire.getReferenceName()).andReturn("foo").atLeastOnce();
+ EasyMock.expect(wire.getInvocationChains()).andReturn(map).times(2);
+ EasyMock.replay(wire);
+ Map<String, List<OutboundWire>> wires = new HashMap<String, List<OutboundWire>>();
+ List<OutboundWire> list = new ArrayList<OutboundWire>();
+ list.add(wire);
+ wires.put("foo", list);
+ AtomicComponent component = EasyMock.createMock(AtomicComponent.class);
+ EasyMock.expect(component.getOutboundWires()).andReturn(wires);
+ EasyMock.replay(component);
+ workContext = new WorkContextImpl();
+ workContext.setCurrentAtomicComponent(component);
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ workContext.setCurrentAtomicComponent(null);
+ }
+
+ private OutboundInvocationChain createChain(Operation operation) {
+ invoker = EasyMock.createMock(TargetInvoker.class);
+ EasyMock.expect(invoker.invoke(EasyMock.isA(Message.class))).andReturn(new MessageImpl()).times(2);
+ EasyMock.expect(invoker.isCacheable()).andReturn(false).atLeastOnce();
+ EasyMock.replay(invoker);
+ OutboundInvocationChain chain = new OutboundInvocationChainImpl(operation);
+ chain.setTargetInvoker(invoker);
+ chain.addInterceptor(new InvokerInterceptor());
+ chain.prepare();
+ return chain;
+ }
+
+ public class Foo {
+
+ public void invoke() {
+ }
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKOutboundInvocationHandlerTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKOutboundInvocationHandlerTestCase.java
new file mode 100644
index 0000000000..4d2af8acf9
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKOutboundInvocationHandlerTestCase.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire.jdk;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.idl.java.JavaServiceContract;
+import org.apache.tuscany.spi.model.DataType;
+import org.apache.tuscany.spi.model.InteractionScope;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.OutboundWire;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.core.component.WorkContextImpl;
+import org.apache.tuscany.core.wire.OutboundWireImpl;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JDKOutboundInvocationHandlerTestCase extends TestCase {
+
+ public void testToString() {
+ OutboundWireImpl wire = new OutboundWireImpl();
+ ServiceContract contract = new JavaServiceContract(Foo.class);
+ contract.setInteractionScope(InteractionScope.NONCONVERSATIONAL);
+ wire.setServiceContract(contract);
+ JDKOutboundInvocationHandler handler = new JDKOutboundInvocationHandler(Foo.class, wire, null);
+ Foo foo = (Foo) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Foo.class}, handler);
+ assertNotNull(foo.toString());
+ }
+
+ public void testHashCode() {
+ OutboundWireImpl wire = new OutboundWireImpl();
+ ServiceContract contract = new JavaServiceContract(Foo.class);
+ contract.setInteractionScope(InteractionScope.NONCONVERSATIONAL);
+ wire.setServiceContract(contract);
+ JDKOutboundInvocationHandler handler = new JDKOutboundInvocationHandler(Foo.class, wire, null);
+ Foo foo = (Foo) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Foo.class}, handler);
+ assertNotNull(foo.hashCode());
+ }
+
+ public void testConversational() throws Throwable {
+ OutboundWire outboundWire = createMock(OutboundWire.class);
+ Map<Operation<?>, OutboundInvocationChain> outboundChains =
+ new HashMap<Operation<?>, OutboundInvocationChain>();
+ DataType<Type> type1 = new DataType<Type>(String.class, String.class);
+ List<DataType<Type>> types = new ArrayList<DataType<Type>>();
+ types.add(type1);
+ DataType<List<DataType<Type>>> inputType1 = new DataType<List<DataType<Type>>>(Object[].class, types);
+ DataType<Type> outputType1 = new DataType<Type>(String.class, String.class);
+ Operation<Type> op1 = new Operation<Type>("test", inputType1, outputType1, null);
+ ServiceContract<Type> outboundContract = new JavaServiceContract(Foo.class);
+ outboundContract.setInteractionScope(InteractionScope.CONVERSATIONAL);
+ op1.setServiceContract(outboundContract);
+
+ WorkContext wc = new WorkContextImpl();
+ MockInvoker invoker = new MockInvoker(wc);
+ OutboundInvocationChain outboundChain = createMock(OutboundInvocationChain.class);
+ expect(outboundChain.getTargetInvoker()).andReturn(invoker).anyTimes();
+ expect(outboundChain.getHeadInterceptor()).andReturn(null).anyTimes();
+ replay(outboundChain);
+ outboundChains.put(op1, outboundChain);
+ expect(outboundWire.getInvocationChains()).andReturn(outboundChains).anyTimes();
+ expect(outboundWire.getReferenceName()).andReturn("fooRef").atLeastOnce();
+ expect(outboundWire.getContainer()).andReturn(null).anyTimes();
+ expect(outboundWire.getServiceContract()).andReturn(outboundContract).anyTimes();
+ replay(outboundWire);
+
+ String convID = UUID.randomUUID().toString();
+ wc.setIdentifier(Scope.CONVERSATION, convID);
+ invoker.setCurrentConversationID(convID);
+
+ outboundContract.setRemotable(true);
+ invoker.setRemotableTest(true);
+ JDKOutboundInvocationHandler handler = new JDKOutboundInvocationHandler(Foo.class, outboundWire, wc);
+ handler.invoke(Foo.class.getMethod("test", String.class), new Object[]{"bar"});
+ String currentConvID = (String) wc.getIdentifier(Scope.CONVERSATION);
+ assertSame(convID, currentConvID);
+
+ outboundContract.setRemotable(false);
+ invoker.setRemotableTest(false);
+ JDKOutboundInvocationHandler handler2 = new JDKOutboundInvocationHandler(Foo.class, outboundWire, wc);
+ handler2.invoke(Foo.class.getMethod("test", String.class), new Object[]{"bar"});
+ currentConvID = (String) wc.getIdentifier(Scope.CONVERSATION);
+ assertSame(convID, currentConvID);
+ }
+
+ private interface Foo {
+ String test(String s);
+ }
+
+ private class MockInvoker implements TargetInvoker {
+
+ private WorkContext wc;
+ private String currentConversationID;
+ private boolean remotableTest;
+
+ public MockInvoker(WorkContext wc) {
+ this.wc = wc;
+ }
+
+ public void setCurrentConversationID(String id) {
+ currentConversationID = id;
+ }
+
+ public void setRemotableTest(boolean remotableTest) {
+ this.remotableTest = remotableTest;
+ }
+
+ public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException {
+ assertEquals("bar", Array.get(payload, 0));
+ String convID = (String) wc.getIdentifier(Scope.CONVERSATION);
+ if (remotableTest) {
+ assertNotSame(convID, currentConversationID);
+ } else {
+ assertSame(convID, currentConversationID);
+ }
+ return "response";
+ }
+
+ public Message invoke(Message msg) throws InvocationRuntimeException {
+ fail();
+ return null;
+ }
+
+ public boolean isCacheable() {
+ return false;
+ }
+
+ public void setCacheable(boolean cacheable) {
+
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKProxyTestCase.java b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKProxyTestCase.java
new file mode 100644
index 0000000000..994d944d98
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKProxyTestCase.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.core.wire.jdk;
+
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InboundInvocationChain;
+import org.apache.tuscany.spi.wire.InboundWire;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JDKProxyTestCase extends TestCase {
+ private JDKWireService wireService;
+ private InboundWire inboundWire;
+ private Map<Operation<?>, InboundInvocationChain> chains;
+
+ public void testCreateProxy() {
+ EasyMock.expect(inboundWire.getServiceName()).andReturn("service");
+ EasyMock.expect(inboundWire.getInvocationChains()).andReturn(chains);
+ EasyMock.replay(inboundWire);
+ TestInterface intf = wireService.createProxy(TestInterface.class, inboundWire);
+ assertTrue(Proxy.isProxyClass(intf.getClass()));
+ EasyMock.verify(inboundWire);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ wireService = new JDKWireService();
+ inboundWire = EasyMock.createMock(InboundWire.class);
+ chains = new HashMap<Operation<?>, InboundInvocationChain>();
+ }
+
+ public static interface TestInterface {
+ int primitives(int i);
+
+ String objects(String object);
+ }
+}
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/resources/deployables/sample-calculator.jar b/branches/sca-java-integration/sca/kernel/core/src/test/resources/deployables/sample-calculator.jar
new file mode 100644
index 0000000000..0ca3a1b781
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/resources/deployables/sample-calculator.jar
Binary files differ
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/databinding/impl/ipo.xsd b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/databinding/impl/ipo.xsd
new file mode 100644
index 0000000000..92a576fb98
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/databinding/impl/ipo.xsd
@@ -0,0 +1,136 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<schema targetNamespace="http://www.example.com/IPO"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:ipo="http://www.example.com/IPO">
+
+ <annotation>
+ <documentation xml:lang="en">
+ International Purchase order schema for Example.com
+ Copyright 2000 Example.com. All rights reserved.
+ </documentation>
+ </annotation>
+
+
+ <element name="purchaseOrder" type="ipo:PurchaseOrderType" />
+
+ <element name="comment" type="string" />
+
+ <complexType name="PurchaseOrderType">
+ <sequence>
+ <element name="shipTo" type="ipo:Address" />
+ <element name="billTo" type="ipo:Address" />
+ <element ref="ipo:comment" minOccurs="0" />
+ <element name="items" type="ipo:Items" />
+ </sequence>
+ <attribute name="orderDate" type="date" />
+ </complexType>
+
+ <complexType name="Items">
+ <sequence>
+ <element name="item" minOccurs="0" maxOccurs="unbounded">
+ <complexType>
+ <sequence>
+ <element name="productName" type="string" />
+ <element name="quantity">
+ <simpleType>
+ <restriction base="positiveInteger">
+ <maxExclusive value="100" />
+ </restriction>
+ </simpleType>
+ </element>
+ <element name="USPrice" type="decimal" />
+ <element ref="ipo:comment" minOccurs="0" />
+ <element name="shipDate" type="date"
+ minOccurs="0" />
+ </sequence>
+ <attribute name="partNum" type="ipo:SKU"
+ use="required" />
+ </complexType>
+ </element>
+ </sequence>
+ </complexType>
+
+ <simpleType name="SKU">
+ <restriction base="string">
+ <pattern value="\d{3}-[A-Z]{2}" />
+ </restriction>
+ </simpleType>
+
+ <complexType name="Address">
+ <sequence>
+ <element name="name" type="string" />
+ <element name="street" type="string" />
+ <element name="city" type="string" />
+ </sequence>
+ </complexType>
+
+ <complexType name="USAddress">
+ <complexContent>
+ <extension base="ipo:Address">
+ <sequence>
+ <element name="state" type="ipo:USState" />
+ <element name="zip" type="positiveInteger" />
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="UKAddress">
+ <complexContent>
+ <extension base="ipo:Address">
+ <sequence>
+ <element name="postcode" type="ipo:UKPostcode" />
+ </sequence>
+ <attribute name="exportCode" type="positiveInteger"
+ fixed="1" />
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- other Address derivations for more countries -->
+
+ <simpleType name="USState">
+ <restriction base="string">
+ <enumeration value="AK" />
+ <enumeration value="AL" />
+ <enumeration value="AR" />
+ <enumeration value="CA" />
+ <enumeration value="PA" />
+ <!-- and so on ... -->
+ </restriction>
+ </simpleType>
+
+ <simpleType name="Postcode">
+ <restriction base="string">
+ <length value="7" fixed="true" />
+ </restriction>
+ </simpleType>
+
+
+ <simpleType name="UKPostcode">
+ <restriction base="ipo:Postcode">
+ <pattern value="[A-Z]{2}\d\s\d[A-Z]{2}" />
+ </restriction>
+ </simpleType>
+
+
+
+</schema>
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/databinding/impl/order.wsdl b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/databinding/impl/order.wsdl
new file mode 100644
index 0000000000..100890e10b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/databinding/impl/order.wsdl
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<definitions name="StockQuote" targetNamespace="http://example.com/order.wsdl" xmlns:tns="http://example.com/order.wsdl"
+ xmlns:xsd1="http://example.com/order.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns="http://schemas.xmlsoap.org/wsdl/">
+
+ <types>
+ <schema targetNamespace="http://example.com/order.xsd" xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:ipo="http://www.example.com/IPO">
+ <import namespace="http://www.example.com/IPO" schemaLocation="ipo.xsd"/>
+ <element name="checkOrderStatus">
+ <complexType>
+ <sequence>
+ <element name="customerId" type="string" />
+ <element name="order" type="ipo:PurchaseOrderType" />
+ <element name="flag" type="int" />
+ </sequence>
+ </complexType>
+ </element>
+ <element name="checkOrderStatusResponse">
+ <complexType>
+ <sequence>
+ <element name="status" type="string" />
+ </sequence>
+ </complexType>
+ </element>
+ <element name="note" type="string" />
+ </schema>
+ </types>
+
+ <message name="CheckOrderStatusInput1">
+ <part name="body" element="xsd1:checkOrderStatus" />
+ </message>
+
+ <message name="CheckOrderStatusOutput1">
+ <part name="body" element="xsd1:checkOrderStatusResponse" />
+ </message>
+
+ <message name="CheckOrderStatusInput2">
+ <part name="p1" element="xsd1:checkOrderStatus" />
+ <part name="p2" element="xsd1:note" />
+ </message>
+
+ <message name="CheckOrderStatusOutput2">
+ <part name="p1" element="xsd1:checkOrderStatusResponse" />
+ </message>
+
+ <portType name="OrderPortType">
+ <operation name="checkOrderStatus">
+ <input message="tns:CheckOrderStatusInput1" />
+ <output message="tns:CheckOrderStatusOutput1" />
+ </operation>
+ <operation name="checkOrderStatus2">
+ <input message="tns:CheckOrderStatusInput2" />
+ <output message="tns:CheckOrderStatusOutput2" />
+ </operation>
+ </portType>
+
+</definitions> \ No newline at end of file
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/databinding/xml/foo.xml b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/databinding/xml/foo.xml
new file mode 100644
index 0000000000..0ba8ade1e0
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/databinding/xml/foo.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<f:foo xmlns:f="http://foo" name="foo">
+ <b:bar xmlns:b="http://bar">bar</b:bar>
+</f:foo> \ No newline at end of file
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/deployer/boot1-include.scdl b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/deployer/boot1-include.scdl
new file mode 100644
index 0000000000..5ffd69dc28
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/deployer/boot1-include.scdl
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="boot1-include">
+
+ <component name="component2">
+ <system:implementation.system class="org.apache.tuscany.core.mock.component.BasicInterfaceImpl"/>
+ </component>
+
+ <service name="service2" >
+ <interface.java interface="org.apache.tuscany.core.mock.component.BasicInterface"/>
+ <reference>component2</reference>
+ </service>
+
+</composite>
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/deployer/boot1.scdl b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/deployer/boot1.scdl
new file mode 100644
index 0000000000..3911e54e86
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/deployer/boot1.scdl
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="boot1">
+ <service name="service" >
+ <interface.java interface="org.apache.tuscany.core.mock.component.BasicInterface"/>
+ <reference>component</reference>
+ </service>
+
+ <component name="component">
+ <system:implementation.system class="org.apache.tuscany.core.mock.component.BasicInterfaceImpl"/>
+ <property name="publicProperty">propval</property>
+ <reference name="publicReference">component2</reference>
+ </component>
+
+ <include name="boot1-include" scdlLocation="boot1-include.scdl"/>
+</composite>
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/deployer/boot2.scdl b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/deployer/boot2.scdl
new file mode 100644
index 0000000000..66449f39c3
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/deployer/boot2.scdl
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<!--
+ A more complex example closer to a typical bootstrap configuration
+ $Rev$ $Date$
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="boot2">
+
+ <!-- expose Deployer API as a service -->
+ <service name="deployer" >
+ <interface.java interface="org.apache.tuscany.spi.deployer.Deployer"/>
+ <reference>deployerImpl</reference>
+ </service>
+
+ <!-- Component that provides the Deployer service -->
+ <component name="deployerImpl">
+ <system:implementation.system class="org.apache.tuscany.core.deployer.DeployerImpl"/>
+ </component>
+
+ <!-- Work management -->
+ <component name="workContext">
+ <system:implementation.system class="org.apache.tuscany.core.component.WorkContextImpl"/>
+ </component>
+
+ <!-- Scope infrastructure -->
+ <component name="scopeRegistry">
+ <system:implementation.system class="org.apache.tuscany.core.component.scope.ScopeRegistryImpl"/>
+ </component>
+
+ <!-- Builder and BuilderRegistry -->
+ <component name="builder">
+ <system:implementation.system class="org.apache.tuscany.core.builder.BuilderRegistryImpl"/>
+ </component>
+
+ <!-- Loader and LoaderRegistry -->
+ <component name="loader">
+ <system:implementation.system class="org.apache.tuscany.core.loader.LoaderRegistryImpl"/>
+ </component>
+
+ <!-- Introspector and IntrospectionRegistry -->
+ <component name="interfaceProcessorRegistry">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.IntrospectionRegistryImpl"/>
+ </component>
+
+ <!-- Connector infrastructure -->
+ <component name="connector">
+ <system:implementation.system class="org.apache.tuscany.core.builder.ConnectorImpl"/>
+ </component>
+
+ <!-- Resource host registry -->
+ <component name="resourceHostRegistry">
+ <system:implementation.system class="org.apache.tuscany.core.services.host.DelegatingResourceHostRegistry"/>
+ </component>
+
+ <!-- Foundation element loader implementations -->
+ <component name="elementLoader.component">
+ <system:implementation.system class="org.apache.tuscany.core.loader.ComponentLoader"/>
+ </component>
+ <component name="elementLoader.componentType">
+ <system:implementation.system class="org.apache.tuscany.core.loader.ComponentTypeElementLoader"/>
+ </component>
+ <component name="elementLoader.interface.java">
+ <system:implementation.system class="org.apache.tuscany.core.idl.java.InterfaceJavaLoader"/>
+ </component>
+ <component name="elementLoader.property">
+ <system:implementation.system class="org.apache.tuscany.core.loader.PropertyLoader"/>
+ </component>
+ <component name="elementLoader.reference">
+ <system:implementation.system class="org.apache.tuscany.core.loader.ReferenceLoader"/>
+ </component>
+ <component name="elementLoader.service">
+ <system:implementation.system class="org.apache.tuscany.core.loader.ServiceLoader"/>
+ </component>
+
+ <component name="wireService">
+ <system:implementation.system class="org.apache.tuscany.core.wire.jdk.JDKWireService"/>
+ </component>
+
+ <!-- Composite implementation type -->
+ <component name="composite.loader">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.composite.CompositeLoader"/>
+ </component>
+
+ <component name="interfaceJava.interfaceProcessorRegistry">
+ <system:implementation.system class="org.apache.tuscany.core.idl.java.JavaInterfaceProcessorRegistryImpl"/>
+ </component>
+
+ <component name="artifactRepository">
+ <system:implementation.system class="org.apache.tuscany.core.services.artifact.LocalMavenRepository"/>
+ <property name="repository">.m2/repository</property>
+ </component>
+
+ <!-- DataBinding registry -->
+ <component name="databinding.registry">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.DataBindingRegistryImpl" />
+ </component>
+
+ <!-- DataBinding registry -->
+ <component name="databinding.mediator">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.MediatorImpl" />
+ </component>
+
+ <!-- Transformer registry -->
+ <component name="databinding.transformerRegistry" initLevel="90">
+ <system:implementation.system class="org.apache.tuscany.core.databinding.impl.TransformerRegistryImpl" />
+ </component>
+
+ <component name="propertyFactory">
+ <system:implementation.system class="org.apache.tuscany.core.property.PropertyObjectFactoryImpl"/>
+ </component>
+
+ <component name="policyBuilderRegistry">
+ <system:implementation.system class="org.apache.tuscany.core.policy.PolicyBuilderRegistryImpl"/>
+ </component>
+
+
+</composite>
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/loader/TestPolicy.scdl b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/loader/TestPolicy.scdl
new file mode 100644
index 0000000000..2ec1a2ed0e
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/loader/TestPolicy.scdl
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<!--
+ Default system configuration for the launcher environment.
+
+ $Rev$ $Date$
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
+ name="org.apache.tuscany.core.policy.testCase">
+ <policySet name="BasicAuthMsgProtSecurity"
+ provides="sec.confidentiality" appliesTo="binding.ws binding.jms"
+ xmlns="http://www.osoa.org/xmlns/sca/1.0">
+ <wsp:PolicyAttachment/>
+ <intentMap provides="sec.confidentiality" default="transport">
+ <qualifier name="transport">
+ <wsp:PolicyAttachment/>
+ <wsp:PolicyAttachment/>
+ </qualifier>
+ <qualifier name="message">
+ <intentMap provides="sec.confidentiality/message"
+ default="all">
+ <qualifier name="all">
+ <wsp:PolicyAttachment/>
+ </qualifier>
+ <qualifier name="body">
+ <wsp:PolicyAttachment/>
+ </qualifier>
+ </intentMap>
+ </qualifier>
+ </intentMap>
+ </policySet>
+</composite> \ No newline at end of file
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/loader/test-include.scdl b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/loader/test-include.scdl
new file mode 100644
index 0000000000..584846504b
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/loader/test-include.scdl
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<composite>
+ This file just needs to exist
+</composite> \ No newline at end of file
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/policy/PolicySet.scdl b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/policy/PolicySet.scdl
new file mode 100644
index 0000000000..77c6b5edd9
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/policy/PolicySet.scdl
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<!--
+ Default system configuration for the launcher environment.
+
+ $Rev$ $Date$
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
+ name="org.apache.tuscany.core.policy.testCase">
+ <policySet name="BasicMsgProtSecurity"
+ provides="sec.confidentiality" appliesTo="binding.ws binding.jms"
+ xmlns="http://www.osoa.org/xmlns/sca/1.0">
+ <wsp:PolicyAttachment/>
+ <intentMap provides="sec.confidentiality" default="transport">
+ <qualifier name="transport">
+ <wsp:PolicyAttachment/>
+ <wsp:PolicyAttachment/>
+ </qualifier>
+ <qualifier name="message">
+ <intentMap provides="sec.confidentiality/message"
+ default="all">
+ <qualifier name="all">
+ <wsp:PolicyAttachment/>
+ </qualifier>
+ <qualifier name="body">
+ <wsp:PolicyAttachment/>
+ </qualifier>
+ </intentMap>
+ </qualifier>
+ </intentMap>
+ </policySet>
+
+ <policySet name="Authentication"
+ provides="sec.authentication" appliesTo="binding.ws binding.jms">
+ <wsp:PolicyAttachment/>
+ <intentMap provides="authentication" default="cert">
+ <qualifier name="cert">
+ <wsp:PolicyAttachment/>
+ <wsp:PolicyAttachment/>
+ </qualifier>
+ <qualifier name="basic">
+ <wsp:PolicyAttachment/>
+ </qualifier>
+ </intentMap>
+ </policySet>
+
+</composite> \ No newline at end of file
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/property/ipo.xml b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/property/ipo.xml
new file mode 100644
index 0000000000..58058dbe1a
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/property/ipo.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<ipo:purchaseOrder
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ipo="http://www.example.com/IPO"
+ xsi:schemaLocation="http://www.example.com/IPO ipo.xsd"
+ orderDate="1999-12-01">
+
+ <shipTo exportCode="1" xsi:type="ipo:UKAddress">
+ <name>Helen Zoe</name>
+ <street>47 Eden Street</street>
+ <city>Cambridge</city>
+ <postcode>CB1 1JR</postcode>
+ </shipTo>
+
+ <billTo xsi:type="ipo:USAddress">
+ <name>Robert Smith</name>
+ <street>8 Oak Avenue</street>
+ <city>Old Town</city>
+ <state>PA</state>
+ <zip>95819</zip>
+ </billTo>
+
+ <items>
+ <item partNum="833-AA">
+ <productName>Lapis necklace</productName>
+ <quantity>1</quantity>
+ <USPrice>99.95</USPrice>
+ <ipo:comment>Want this for the holidays</ipo:comment>
+ <shipDate>1999-12-05</shipDate>
+ </item>
+ </items>
+</ipo:purchaseOrder>
+
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/services/deployment/test.ext b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/services/deployment/test.ext
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/services/deployment/test.ext
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/services/deployment/test.scdl b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/services/deployment/test.scdl
new file mode 100644
index 0000000000..1e09549194
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/resources/org/apache/tuscany/core/services/deployment/test.scdl
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<composite>
+ This file just needs to exist
+</composite> \ No newline at end of file
diff --git a/branches/sca-java-integration/sca/kernel/core/src/test/resources/repository/sample-calculator.jar b/branches/sca-java-integration/sca/kernel/core/src/test/resources/repository/sample-calculator.jar
new file mode 100644
index 0000000000..0ca3a1b781
--- /dev/null
+++ b/branches/sca-java-integration/sca/kernel/core/src/test/resources/repository/sample-calculator.jar
Binary files differ