summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core')
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/AddressingConstants.java33
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/AddressingFactory.java37
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/EndpointReference.java120
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/impl/AddressingFactoryImpl.java50
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/impl/EndpointReferenceImpl.java182
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderConfigException.java26
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderException.java41
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderInitException.java39
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/ConfigurationException.java26
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextCreationException.java41
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/HierarchicalWireBuilder.java29
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/NoAccessorException.java39
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/ObjectFactory.java19
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/RuntimeConfiguration.java69
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/RuntimeConfigurationBuilder.java24
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/UnknownTypeException.java26
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/WireBuilder.java60
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/AssemblyVisitor.java62
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/BaseExternalServiceRuntimeConfiguration.java106
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/DefaultWireBuilder.java110
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/EntryPointRuntimeConfiguration.java104
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/HierarchicalBuilder.java58
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ProxyObjectFactory.java42
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/client/TuscanyRuntime.java204
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ComponentTypeIntrospector.java37
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ConfigurationException.java42
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ConfigurationLoadException.java47
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ImplementationCache.java46
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/InvalidRootElementException.java51
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/JavaIntrospectionHelper.java349
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/MissingResourceException.java43
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ModuleComponentConfigurationLoader.java74
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/impl/Java5ComponentTypeIntrospector.java423
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/impl/ModuleComponentConfigurationLoaderImpl.java142
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AbstractContext.java89
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AggregateContext.java85
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireContext.java35
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireResolutionException.java40
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ConfigurationContext.java66
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/Context.java106
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ContextInitException.java43
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ContextRuntimeException.java39
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/CoreRuntimeException.java27
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/DuplicateNameException.java39
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EntryPointContext.java57
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EventContext.java66
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EventException.java43
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ExternalServiceContext.java24
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/InstanceContext.java75
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/InvalidNameException.java43
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/LifecycleEventListener.java32
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/QualifiedName.java83
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/RuntimeEventListener.java36
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeAwareContext.java31
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java72
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeIdentifier.java33
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeInitializationException.java42
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeRuntimeException.java43
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeStrategy.java43
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ServiceNotFoundException.java42
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/SimpleComponentContext.java36
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/SystemAggregateContext.java36
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/TargetException.java42
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractAggregateContext.java652
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AggregateContextImpl.java222
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EntryPointContextImpl.java112
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EventContextImpl.java77
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/ExternalServiceContextImpl.java92
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java158
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeStrategy.java67
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AggregateScopeContext.java184
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/DefaultScopeStrategy.java52
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/HttpSessionScopeContext.java254
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java182
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java224
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java145
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/HTTPSessionExpirationListener.java62
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/LazyHTTPSessionId.java56
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/TuscanyRequestFilter.java107
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/TuscanyWebAppRuntime.java59
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/EventInvoker.java17
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/FactoryInitException.java27
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/FieldInjector.java45
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/InjectionRuntimeException.java29
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/Injector.java17
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/MethodEventInvoker.java39
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/MethodInjector.java30
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/NullEventInvoker.java14
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/ObjectCallbackException.java26
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/ObjectCreationException.java27
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/PojoObjectFactory.java75
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/ReferenceTargetFactory.java133
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/SDOObjectFactory.java37
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/SingletonObjectFactory.java29
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/Interceptor.java42
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/InvocationConfiguration.java279
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/InvocationException.java29
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/InvocationRuntimeException.java44
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/MessageChannel.java33
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/MessageHandler.java34
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/MethodHashMap.java53
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/ProxyConfiguration.java101
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/TargetInvoker.java44
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/InvokerInterceptor.java46
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/MessageChannelImpl.java68
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/MessageDispatcher.java46
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/NullProxyFactory.java57
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/OneWayInterceptor.java48
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/RequestResponseInterceptor.java73
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/jdk/JDKInvocationHandler.java143
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/jdk/JDKProxyFactory.java96
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/jdk/JDKProxyFactoryFactory.java52
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyCreationException.java43
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyException.java40
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyFactory.java79
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyFactoryFactory.java42
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyInitializationException.java43
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/loader/SCDLModelLoaderRegistry.java51
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/SCDLModelLoaderRegistryImpl.java49
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/message/Message.java182
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/message/MessageFactory.java31
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/message/impl/MessageFactoryImpl.java40
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/message/impl/MessageImpl.java249
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeContext.java83
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeContextImpl.java286
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeMonitor.java32
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeScopeStrategy.java46
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/Autowire.java21
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/ParentContext.java33
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemAssemblyFactory.java38
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemBinding.java37
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemImplementation.java38
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemAssemblyFactoryImpl.java41
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemBindingImpl.java41
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemImplementationImpl.java94
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemComponentContextBuilder.java383
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemEntryPointBuilder.java63
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemExternalServiceBuilder.java77
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemComponentRuntimeConfiguration.java140
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemEntryPointRuntimeConfiguration.java92
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemExternalServiceRuntimeConfiguration.java97
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemObjectRuntimeConfiguration.java92
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemAggregateContextImpl.java666
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemComponentContext.java198
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemEntryPointContext.java82
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemExternalServiceContext.java82
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemScopeStrategy.java56
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/injection/AutowireFactory.java50
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/loader/SystemSCDLModelLoader.java49
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/webapp/ContextBinder.java39
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/webapp/TuscanyRequestFilter.java97
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/webapp/TuscanyServletListener.java168
152 files changed, 12857 insertions, 0 deletions
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/AddressingConstants.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/AddressingConstants.java
new file mode 100644
index 0000000000..8154ad4709
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/AddressingConstants.java
@@ -0,0 +1,33 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.addressing;
+
+/**
+ */
+public interface AddressingConstants {
+
+ String NS_URI = "http://schemas.xmlsoap.org/ws/2004/08/addressing";
+ String TO_HEADER_NAME = NS_URI + "#To";
+ String FROM_HEADER_NAME = NS_URI + "#From";
+ String MESSAGE_ID_HEADER_NAME = NS_URI + "#MessageID";
+ String ACTION_HEADER_NAME = NS_URI + "#Action";
+ String REPLY_TO_HEADER_NAME = NS_URI + "#ReplyTo";
+ String RELATES_TO_HEADER_NAME = NS_URI + "#RelatesTo";
+ String FAULT_TO_HEADER_NAME = NS_URI + "#FaultTo";
+ String ENDPOINT_REFERENCE_HEADER_NAME = NS_URI + "#EndpointReference";
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/AddressingFactory.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/AddressingFactory.java
new file mode 100644
index 0000000000..878322bc6e
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/AddressingFactory.java
@@ -0,0 +1,37 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.addressing;
+
+
+/**
+ * The <b>Factory</b> for the model.
+ */
+public interface AddressingFactory {
+
+ /**
+ * Returns a new object of class '<em>Endpoint Reference</em>'.
+ */
+ EndpointReference createEndpointReference();
+
+ /**
+ * Create a new message ID
+ *
+ * @return
+ */
+ String createMessageID();
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/EndpointReference.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/EndpointReference.java
new file mode 100644
index 0000000000..f8ecd34354
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/EndpointReference.java
@@ -0,0 +1,120 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.addressing;
+
+import java.util.Map;
+
+import org.apache.tuscany.core.invocation.MessageHandler;
+import org.apache.tuscany.model.assembly.ConfiguredPort;
+
+/**
+ * A representation of the model object '<em><b>Endpoint Reference</b></em>'.
+ */
+public interface EndpointReference extends org.osoa.sca.ServiceReference, MessageHandler {
+
+ /**
+ * Returns the endpoint address.
+ *
+ * @return The address.
+ */
+ String getAddress();
+
+ /**
+ * Sets the endpoint address.
+ *
+ * @param address The address.
+ */
+ void setAddress(String address);
+
+ /**
+ * Returns the QName of the WSDL portType associated with this endpoint reference.
+ *
+ * @return The QName of the portType.
+ */
+ String getPortTypeName();
+
+ /**
+ * Sets the QName of the WSDL portType associated with this endpoint reference.
+ *
+ * @param qname The QName of the portType.
+ */
+ void setPortTypeName(String qname);
+
+ /**
+ * Returns the QName of the WSDL service associated with this endpoint reference.
+ *
+ * @return The QName of the service.
+ */
+ String getServiceName();
+
+ /**
+ * Sets the QName of the WSDL service associated with this endpoint reference.
+ *
+ * @param qname The QName of the service.
+ */
+ void setServiceName(String qname);
+
+ /**
+ * Returns the name of the WSDL port associated with this endpoint reference.
+ *
+ * @return The name of the port.
+ */
+ String getPortName();
+
+ /**
+ * Sets the name of the WSDL port associated with this endpoint reference.
+ *
+ * @param name The name of the port.
+ */
+ void setPortName(String name);
+
+ /**
+ * Returns the endpoint reference parameters..
+ *
+ * @return The collection of reference parameters.
+ */
+ Map<String, Object> getReferenceParameters();
+
+ /**
+ * Returns the configured port corresponding to this endpoint reference.
+ *
+ * @return
+ */
+ ConfiguredPort getConfiguredPort();
+
+ /**
+ * Returns the configured port corresponding to this endpoint reference.
+ *
+ * @return
+ */
+ void setConfiguredPort(ConfiguredPort configuredPort);
+
+ /**
+ * Returns the message handler associated with this endpoint reference
+ *
+ * @return
+ */
+ MessageHandler getMessageHandler();
+
+ /**
+ * Sets the message handler associated with this endpoint reference
+ *
+ * @param messageHandler
+ */
+ void setMessageHandler(MessageHandler messageHandler);
+
+} // EndpointReference
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/impl/AddressingFactoryImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/impl/AddressingFactoryImpl.java
new file mode 100644
index 0000000000..882e3157c2
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/impl/AddressingFactoryImpl.java
@@ -0,0 +1,50 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.addressing.impl;
+
+import org.eclipse.emf.ecore.util.EcoreUtil;
+
+import org.apache.tuscany.core.addressing.AddressingFactory;
+import org.apache.tuscany.core.addressing.EndpointReference;
+
+/**
+ * A factory for endpoint references.
+ *
+ */
+public class AddressingFactoryImpl implements AddressingFactory {
+
+ /**
+ * Constructor
+ */
+ public AddressingFactoryImpl() {
+ super();
+ }
+
+ /**
+ * @see org.apache.tuscany.core.addressing.AddressingFactory#createEndpointReference()
+ */
+ public EndpointReference createEndpointReference() {
+ return new EndpointReferenceImpl();
+ }
+
+ /**
+ * @see org.apache.tuscany.core.addressing.AddressingFactory#createMessageID()
+ */
+ public String createMessageID() {
+ return EcoreUtil.generateUUID();
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/impl/EndpointReferenceImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/impl/EndpointReferenceImpl.java
new file mode 100644
index 0000000000..f4fbd2036b
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/addressing/impl/EndpointReferenceImpl.java
@@ -0,0 +1,182 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.addressing.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.core.addressing.EndpointReference;
+import org.apache.tuscany.core.invocation.MessageHandler;
+import org.apache.tuscany.core.message.Message;
+import org.apache.tuscany.model.assembly.ConfiguredPort;
+
+/**
+ * An implementation of EndpointReference.
+ */
+public class EndpointReferenceImpl implements EndpointReference {
+
+ private ConfiguredPort configuredPort;
+ private MessageHandler messageHandler;
+ private String address;
+ private String portTypeName;
+ private String portName;
+ private String serviceName;
+ private Map<String, Object> referenceParameters;
+
+ /**
+ * @see org.apache.tuscany.core.addressing.EndpointReference#getAddress()
+ */
+ public String getAddress() {
+ return address;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.addressing.EndpointReference#setAddress(java.lang.String)
+ */
+ public void setAddress(String value) {
+ this.address=value;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.addressing.EndpointReference#getPortTypeName()
+ */
+ public String getPortTypeName() {
+ return portTypeName;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.addressing.EndpointReference#setPortTypeName(java.lang.String)
+ */
+ public void setPortTypeName(String value) {
+ this.portTypeName=value;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.addressing.EndpointReference#getServiceName()
+ */
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.addressing.EndpointReference#getPortName()
+ */
+ public String getPortName() {
+ return portName;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.addressing.EndpointReference#setServiceName(java.lang.String)
+ */
+ public void setServiceName(String value) {
+ this.serviceName=value;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.addressing.EndpointReference#setPortName(java.lang.String)
+ */
+ public void setPortName(String portName) {
+ this.portName=portName;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.addressing.EndpointReference#getReferenceParameters()
+ */
+ public Map<String, Object> getReferenceParameters() {
+ if (referenceParameters==null)
+ referenceParameters=new HashMap<String, Object>();
+ return referenceParameters;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.addressing.EndpointReference#getConfiguredPort()
+ */
+ public ConfiguredPort getConfiguredPort() {
+ return configuredPort;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.addressing.EndpointReference#setConfiguredPort(org.apache.tuscany.model.assembly.ConfiguredPort)
+ */
+ public void setConfiguredPort(ConfiguredPort configuredPort) {
+ this.configuredPort = configuredPort;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.addressing.EndpointReference#getMessageHandler()
+ */
+ public MessageHandler getMessageHandler() {
+ return messageHandler;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.addressing.EndpointReference#setMessageHandler(org.apache.tuscany.core.invocation.MessageHandler)
+ */
+ public void setMessageHandler(MessageHandler messageHandler) {
+ this.messageHandler = messageHandler;
+ }
+
+ /**
+ * @see org.osoa.sca.ServiceReference#getSessionID()
+ */
+ public Object getSessionID() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @see org.osoa.sca.ServiceReference#endSession()
+ */
+ public void endSession() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @see org.osoa.sca.ServiceReference#getCallbackID()
+ */
+ public Object getCallbackID() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @see org.osoa.sca.ServiceReference#setCallbackID(java.lang.Object)
+ */
+ public void setCallbackID(Object callbackID) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @see org.osoa.sca.ServiceReference#getCallback()
+ */
+ public Object getCallback() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @see org.osoa.sca.ServiceReference#setCallback(java.lang.Object)
+ */
+ public void setCallback(Object callback) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @see org.apache.tuscany.core.invocation.MessageHandler#processMessage(org.apache.tuscany.core.message.Message)
+ */
+ public boolean processMessage(Message message) {
+ return messageHandler.processMessage(message);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderConfigException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderConfigException.java
new file mode 100644
index 0000000000..04b7b69cf5
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderConfigException.java
@@ -0,0 +1,26 @@
+package org.apache.tuscany.core.builder;
+
+/**
+ * Represents an error processing a logical configuration model
+ *
+ * @version $Rev$ $Date$
+ */
+public class BuilderConfigException extends BuilderException {
+
+ public BuilderConfigException() {
+ super();
+ }
+
+ public BuilderConfigException(String message) {
+ super(message);
+ }
+
+ public BuilderConfigException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public BuilderConfigException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderException.java
new file mode 100644
index 0000000000..246f188988
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderException.java
@@ -0,0 +1,41 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.builder;
+
+import org.apache.tuscany.core.context.CoreRuntimeException;
+
+/**
+ * The root exception for the builder package. Builder exceptions denote a non-recoverable failure.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class BuilderException extends CoreRuntimeException {
+
+ public BuilderException() {
+ super();
+ }
+
+ public BuilderException(String message) {
+ super(message);
+ }
+
+ public BuilderException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public BuilderException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderInitException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderInitException.java
new file mode 100644
index 0000000000..cd57eaf7ab
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderInitException.java
@@ -0,0 +1,39 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.builder;
+
+/**
+ * Denotes an exception initializing a builder
+ *
+ * @version $Rev$ $Date$
+ */
+public class BuilderInitException extends BuilderException {
+
+ public BuilderInitException() {
+ super();
+ }
+
+ public BuilderInitException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public BuilderInitException(String message) {
+ super(message);
+ }
+
+ public BuilderInitException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/ConfigurationException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/ConfigurationException.java
new file mode 100644
index 0000000000..70a31c34c6
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/ConfigurationException.java
@@ -0,0 +1,26 @@
+package org.apache.tuscany.core.builder;
+
+/**
+ * Represents an error processing a logical configuration model
+ *
+ * @version $Rev$ $Date$
+ */
+public class ConfigurationException extends BuilderException {
+
+ public ConfigurationException() {
+ super();
+ }
+
+ public ConfigurationException(String message) {
+ super(message);
+ }
+
+ public ConfigurationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ConfigurationException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextCreationException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextCreationException.java
new file mode 100644
index 0000000000..24b526371d
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextCreationException.java
@@ -0,0 +1,41 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.builder;
+
+
+/**
+ * Denotes an exception creating an instance context
+ *
+ * @version $Rev$ $Date$
+ */
+public class ContextCreationException extends BuilderException {
+
+ public ContextCreationException() {
+ super();
+ }
+
+ public ContextCreationException(String message) {
+ super(message);
+ }
+
+ public ContextCreationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ContextCreationException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/HierarchicalWireBuilder.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/HierarchicalWireBuilder.java
new file mode 100644
index 0000000000..ace34a1ad5
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/HierarchicalWireBuilder.java
@@ -0,0 +1,29 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.builder;
+
+/**
+ * A wire builder that delegates to child wire builders
+ *
+ * @version $Rev$ $Date$
+ */
+public interface HierarchicalWireBuilder extends WireBuilder{
+
+ /**
+ * Registers a child wire builder
+ */
+ public void addWireBuilder(WireBuilder builder);
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/NoAccessorException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/NoAccessorException.java
new file mode 100644
index 0000000000..34b6294638
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/NoAccessorException.java
@@ -0,0 +1,39 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.builder;
+
+/**
+ * Denotes an attempt to access a non-existent field or method
+ *
+ * @version $Rev$ $Date$
+ */
+public class NoAccessorException extends BuilderException {
+
+ public NoAccessorException() {
+ super();
+ }
+
+ public NoAccessorException(String message) {
+ super(message);
+ }
+
+ public NoAccessorException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public NoAccessorException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/ObjectFactory.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/ObjectFactory.java
new file mode 100644
index 0000000000..7d27df4ebd
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/ObjectFactory.java
@@ -0,0 +1,19 @@
+package org.apache.tuscany.core.builder;
+
+import org.apache.tuscany.core.injection.ObjectCreationException;
+
+/**
+ * Implementations create new instances of a particular type
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ObjectFactory<T> {
+
+ /**
+ * Return a instance of the type that this factory creates.
+ *
+ * @return a instance from this factory
+ */
+ T getInstance() throws ObjectCreationException;
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/RuntimeConfiguration.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/RuntimeConfiguration.java
new file mode 100644
index 0000000000..79396e6052
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/RuntimeConfiguration.java
@@ -0,0 +1,69 @@
+package org.apache.tuscany.core.builder;
+
+import java.util.Map;
+
+import org.apache.tuscany.core.context.Context;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * Implementations create instances of {@link org.apache.tuscany.core.context.Context} based on a compiled
+ * configuration, such as a logical assembly model. For example, implementations of
+ * {@link org.apache.tuscany.core.builder.RuntimeConfigurationBuilder} analyze an
+ * {@link org.apache.tuscany.model.assembly.AssemblyModelObject} to create implementations of
+ * <tt>RuntimeConfiguration</tt>.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface RuntimeConfiguration<T extends Context> {
+
+ /**
+ * Creates an instance context based on the current runtime configuration
+ *
+ * @return a new instance context
+ * @throws ContextCreationException if an error occurs creating the context
+ */
+ public T createInstanceContext() throws ContextCreationException;
+
+ /**
+ * Returns the scope identifier associated with the type of contexts produced by the current configuration
+ */
+ public Scope getScope();
+
+ /**
+ * Returns the name of the contexts produced by the current configuration
+ */
+ public String getName();
+
+ public void prepare();
+
+ /**
+ * Adds a target-side proxy factory for the given service name to the configuration. Target-side proxy factories
+ * contain the invocation chains associated with the destination service of a wire and are responsible for
+ * generating proxies
+ */
+ public void addTargetProxyFactory(String serviceName, ProxyFactory factory);
+
+ /**
+ * Returns the target-side proxy factory associated with the given service name
+ */
+ public ProxyFactory getTargetProxyFactory(String serviceName);
+
+ /**
+ * Returns a collection of target-side proxy factories for the configuration keyed by service name
+ */
+ public Map<String, ProxyFactory> getTargetProxyFactories();
+
+ /**
+ * Adds a source-side proxy factory for the given reference. Source-side proxy factories contain the invocation
+ * chains for a reference in the component implementation associated with the instance context created by this
+ * configuration. Source-side proxy factories also produce proxies that are injected on a reference in a component
+ * implementation.
+ */
+ public void addSourceProxyFactory(String referenceName, ProxyFactory factory);
+
+ public ProxyFactory getSourceProxyFactory(String referenceName);
+
+ public Map<String, ProxyFactory> getSourceProxyFactories();
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/RuntimeConfigurationBuilder.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/RuntimeConfigurationBuilder.java
new file mode 100644
index 0000000000..d797253520
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/RuntimeConfigurationBuilder.java
@@ -0,0 +1,24 @@
+package org.apache.tuscany.core.builder;
+
+import org.apache.tuscany.core.context.Context;
+import org.apache.tuscany.model.assembly.AssemblyModelObject;
+
+/**
+ * Implementations are responsible for generating a runtime configuration model from a logical configuration model. The
+ * logical configuration model (LCM) is decorated with the runtime configuration model (RCM).
+ *
+ * @version $Rev$ $Date$
+ * @see RuntimeConfiguration
+ */
+public interface RuntimeConfigurationBuilder<Y extends Context> {
+
+ /**
+ * Builds a runtime configuration for the supplied model object for registration under the supplied context.
+ *
+ * @param object the logical configuration model node
+ * @param context the context that will be the parent of the built context
+ * @throws BuilderException
+ */
+ public void build(AssemblyModelObject object, Y context) throws BuilderException;
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/UnknownTypeException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/UnknownTypeException.java
new file mode 100644
index 0000000000..015b0ba342
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/UnknownTypeException.java
@@ -0,0 +1,26 @@
+package org.apache.tuscany.core.builder;
+
+/**
+ * Denotes an unknown configuration parameter type
+ *
+ * @version $Rev$ $Date$
+ */
+public class UnknownTypeException extends BuilderException {
+
+ public UnknownTypeException() {
+ super();
+ }
+
+ public UnknownTypeException(String message) {
+ super(message);
+ }
+
+ public UnknownTypeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public UnknownTypeException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/WireBuilder.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/WireBuilder.java
new file mode 100644
index 0000000000..6f0cf9ce14
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/WireBuilder.java
@@ -0,0 +1,60 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.builder;
+
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+
+/**
+ * Responsible for finalizing target-side proxy factories and bridging
+ * {@link org.apache.tuscany.core.invocation.InvocationConfiguration}s held by source- and target-side proxy factories.
+ * <p>
+ * Wire builders may optimize the invocation chains based on certain characteristics of th wire, such as source and
+ * target scopes.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface WireBuilder {
+
+ /**
+ * Connects invocation configurations of the source proxy factory to corresponding ones in the target proxy to
+ * factory
+ *
+ * @param sourceFactory the proxy factory used in constructing the source side of the invocation chain
+ * @param targetFactory the proxy factory used in constructing the target side of the invocation chain
+ * @param targetType the context type of the target. Used to determine if a paricular wire builder should construct
+ * the wire
+ * @param downScope true if the component containing the reference (source side) is of a lesser scope than the
+ * target service
+ * @param targetScopeContext the scope context responsible for managing intance contexts of the target component
+ * type
+ * @throws BuilderConfigException if an error occurs during the wire build process
+ */
+ public void connect(ProxyFactory sourceFactory, ProxyFactory targetFactory, Class targetType, boolean downScope,
+ ScopeContext targetScopeContext) throws BuilderConfigException;
+
+ /**
+ * Finishes processing the target side invocation chain. For example, a
+ * {@link org.apache.tuscany.core.invocation.TargetInvoker} used by target-side proxies is usually set during this
+ * phase.
+ *
+ * @param targetFactory the target-side proxy factory
+ * @param targetType the target context type
+ * @param targetScopeContext the target scope
+ * @throws BuilderConfigException if an error occurs during the wire build process
+ */
+ public void completeTargetChain(ProxyFactory targetFactory, Class targetType, ScopeContext targetScopeContext)
+ throws BuilderConfigException;
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/AssemblyVisitor.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/AssemblyVisitor.java
new file mode 100644
index 0000000000..20e9143537
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/AssemblyVisitor.java
@@ -0,0 +1,62 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.builder.impl;
+
+import java.util.List;
+
+import org.apache.tuscany.core.builder.RuntimeConfigurationBuilder;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.model.assembly.AssemblyModelObject;
+import org.apache.tuscany.model.assembly.AssemblyModelVisitor;
+
+/**
+ * Decorates an assembly object graph with runtime configurations using a set of builders
+ *
+ * @version $Rev$ $Date$
+ */
+public class AssemblyVisitor implements AssemblyModelVisitor {
+
+ private AggregateContext parent;
+
+ List<RuntimeConfigurationBuilder> builders;
+
+ /**
+ * Constructs a visitor
+ *
+ * @param parent the parent context for the object graph
+ * @param builders the collection of builders for creating runtime configurations
+ */
+ public AssemblyVisitor(AggregateContext parent, List<RuntimeConfigurationBuilder> builders) {
+ this.parent = parent;
+ this.builders = builders;
+ }
+
+ /**
+ * Initiate walking the object graph
+ */
+ public boolean start(AssemblyModelObject modelObject) {
+ return modelObject.accept(this);
+ }
+
+ /**
+ * Callback when walking the graph
+ */
+ public boolean visit(AssemblyModelObject modelObject) {
+ for (RuntimeConfigurationBuilder builder : builders) {
+ builder.build(modelObject, parent);
+ }
+ return true;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/BaseExternalServiceRuntimeConfiguration.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/BaseExternalServiceRuntimeConfiguration.java
new file mode 100644
index 0000000000..ce092a7d34
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/BaseExternalServiceRuntimeConfiguration.java
@@ -0,0 +1,106 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.builder.impl;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.core.builder.ContextCreationException;
+import org.apache.tuscany.core.builder.ObjectFactory;
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.ExternalServiceContext;
+import org.apache.tuscany.core.context.impl.ExternalServiceContextImpl;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * A template implementation that creates instances of {@link org.apache.tuscany.core.context.ExternalServiceContext}
+ * configured with the appropriate invocation chains and bindings. This class is intended to be subclassed when
+ * contributing new bindings to the runtime. The subclass serves as a marker so the binding {@link WireBuilder}
+ * responsible for setting the proper {@link org.apache.tuscany.core.invocation.TargetInvoker} on the invocation chains
+ * can be notified.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class BaseExternalServiceRuntimeConfiguration implements RuntimeConfiguration<ExternalServiceContext> {
+
+ private String name;
+
+ private ProxyFactory proxyFactory;
+
+ private ObjectFactory objectFactory;
+
+ private String targetServiceName;
+
+ private Map<String,ProxyFactory> targetProxyFactories;
+
+ public BaseExternalServiceRuntimeConfiguration(String name, ObjectFactory objectFactory) {
+ assert (name != null) : "Name was null";
+ assert (objectFactory != null) : "Object factory was null";
+ this.name = name;
+ this.objectFactory = objectFactory;
+ }
+
+ public ExternalServiceContext createInstanceContext() throws ContextCreationException {
+ return new ExternalServiceContextImpl(name, proxyFactory, objectFactory);
+ }
+
+ public Scope getScope() {
+ return Scope.MODULE;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void prepare() {
+ }
+
+ public void addTargetProxyFactory(String serviceName, ProxyFactory factory) {
+ assert (serviceName != null) : "No service name specified";
+ assert (factory != null) : "Proxy factory was null";
+ this.targetServiceName = serviceName; // external services are configured with only one service
+ this.proxyFactory = factory;
+ }
+
+ public ProxyFactory getTargetProxyFactory(String serviceName) {
+ if (this.targetServiceName.equals(serviceName)) {
+ return proxyFactory;
+ } else {
+ return null;
+ }
+ }
+
+ public Map<String,ProxyFactory> getTargetProxyFactories() {
+ if (targetProxyFactories == null) {
+ targetProxyFactories = new HashMap(1);
+ targetProxyFactories.put(targetServiceName, proxyFactory);
+ }
+ return targetProxyFactories;
+ }
+
+ public void addSourceProxyFactory(String referenceName, ProxyFactory factory) {
+ // no wires inside an aggregate from an external service
+ }
+
+ public ProxyFactory getSourceProxyFactory(String referenceName) {
+ return null;
+ }
+
+ public Map getSourceProxyFactories() {
+ return Collections.EMPTY_MAP;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/DefaultWireBuilder.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/DefaultWireBuilder.java
new file mode 100644
index 0000000000..6ed5472a64
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/DefaultWireBuilder.java
@@ -0,0 +1,110 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.builder.impl;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.core.builder.BuilderConfigException;
+import org.apache.tuscany.core.builder.HierarchicalWireBuilder;
+import org.apache.tuscany.core.builder.WireBuilder;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.core.invocation.InvocationConfiguration;
+import org.apache.tuscany.core.invocation.impl.InvokerInterceptor;
+import org.apache.tuscany.core.invocation.impl.MessageChannelImpl;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+
+/**
+ * The top-most wire builder configured in a runtime. Responsible for constructing wires from source and target chains,
+ * this implementation first bridges the chains and then delegates to any other wire builders.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefaultWireBuilder implements HierarchicalWireBuilder {
+
+ // collection configured wire builders
+ private List<WireBuilder> builders = new ArrayList();
+
+ public DefaultWireBuilder() {
+ }
+
+ /**
+ * Adds a wire builder to delegate to
+ */
+ public void addWireBuilder(WireBuilder builder) {
+ builders.add(builder);
+ }
+
+ public void setWireBuilders(List<WireBuilder> builders) {
+ builders.addAll(builders);
+ }
+
+ public void connect(ProxyFactory sourceFactory, ProxyFactory targetFactory, Class targetType, boolean downScope,
+ ScopeContext targetScopeContext) {
+ QualifiedName targetName = sourceFactory.getProxyConfiguration().getTargetName();
+ // get the proxy chain for the target
+ if (targetFactory != null) {
+ // if null, the target side has no interceptors or handlers
+ Map<Method, InvocationConfiguration> targetInvocationConfigs = targetFactory.getProxyConfiguration()
+ .getInvocationConfigurations();
+ for (InvocationConfiguration sourceInvocationConfig : sourceFactory.getProxyConfiguration()
+ .getInvocationConfigurations().values()) {
+ // match invocation chains
+ InvocationConfiguration targetInvocationConfig = targetInvocationConfigs.get(sourceInvocationConfig.getMethod());
+ // if handler is configured, add that
+ if (targetInvocationConfig.getRequestHandlers() != null) {
+ sourceInvocationConfig.setTargetRequestChannel(new MessageChannelImpl(targetInvocationConfig
+ .getRequestHandlers()));
+ sourceInvocationConfig.setTargetResponseChannel(new MessageChannelImpl(targetInvocationConfig
+ .getResponseHandlers()));
+ } else {
+ // no handlers, just connect interceptors
+ if (targetInvocationConfig.getTargetInterceptor() == null) {
+ BuilderConfigException e = new BuilderConfigException("No target handler or interceptor for operation");
+ e.setIdentifier(targetInvocationConfig.getMethod().getName());
+ throw e;
+ }
+ if (!(sourceInvocationConfig.getLastTargetInterceptor() instanceof InvokerInterceptor && targetInvocationConfig
+ .getTargetInterceptor() instanceof InvokerInterceptor)) {
+ // check that we do not have the case where the only interceptors are invokers since we just need one
+ sourceInvocationConfig.addTargetInterceptor(targetInvocationConfig.getTargetInterceptor());
+ }
+ }
+ }
+ }
+ // delegate to other wire builders
+ for (WireBuilder builder : builders) {
+ builder.connect(sourceFactory, targetFactory, targetType, downScope, targetScopeContext);
+ }
+ // signal that wire build process is complete
+ boolean optimizable = true;
+ for (InvocationConfiguration sourceInvocationConfig : sourceFactory.getProxyConfiguration().getInvocationConfigurations()
+ .values()) {
+ sourceInvocationConfig.build();
+ // TODO optimize if no proxy needed using NullProxyFactory
+ }
+ }
+
+ public void completeTargetChain(ProxyFactory targetFactory, Class targetType, ScopeContext targetScopeContext)
+ throws BuilderConfigException {
+ // delegate to other wire builders
+ for (WireBuilder builder : builders) {
+ builder.completeTargetChain(targetFactory, targetType, targetScopeContext);
+ }
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/EntryPointRuntimeConfiguration.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/EntryPointRuntimeConfiguration.java
new file mode 100644
index 0000000000..108cc2d366
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/EntryPointRuntimeConfiguration.java
@@ -0,0 +1,104 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.builder.impl;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.core.builder.ContextCreationException;
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.EntryPointContext;
+import org.apache.tuscany.core.context.impl.EntryPointContextImpl;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.message.MessageFactory;
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * Produces entry point contexts
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class EntryPointRuntimeConfiguration implements RuntimeConfiguration<EntryPointContext> {
+
+ private String name;
+
+ private ProxyFactory proxyFactory;
+
+ private String referenceName;
+
+ private MessageFactory msgFactory;
+
+ private Map<String, ProxyFactory> sourceProxyFactories;
+
+ public EntryPointRuntimeConfiguration(String name, String referenceName, MessageFactory msgFactory) {
+ assert (name != null) : "Entry point name was null";
+ assert (msgFactory != null) : "Message factory was null";
+ this.name = name;
+ this.referenceName = referenceName;
+ this.msgFactory = msgFactory;
+ }
+
+ public EntryPointContext createInstanceContext() throws ContextCreationException {
+ return new EntryPointContextImpl(name, proxyFactory, msgFactory);
+ }
+
+ public Scope getScope() {
+ return Scope.MODULE;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void prepare() {
+ }
+
+ public void addTargetProxyFactory(String serviceName, ProxyFactory factory) {
+ // no wires to an entry point from with an aggregate
+ }
+
+ public ProxyFactory getTargetProxyFactory(String serviceName) {
+ // no wires to an entry point from with an aggregate
+ return null;
+ }
+
+ public Map<String, ProxyFactory> getTargetProxyFactories() {
+ // no wires to an entry point from with an aggregate
+ return Collections.EMPTY_MAP;
+ }
+
+ public void addSourceProxyFactory(String refName, ProxyFactory factory) {
+ assert (refName != null) : "No reference name specified";
+ assert (factory != null) : "Proxy factory was null";
+ this.referenceName = refName; // entry points are configured with only one reference
+ this.proxyFactory = factory;
+ }
+
+ public ProxyFactory getSourceProxyFactory(String refName) {
+ if (this.referenceName.equals(refName)) {
+ return proxyFactory;
+ } else {
+ return null;
+ }
+ }
+
+ public Map<String, ProxyFactory> getSourceProxyFactories() {
+ if (sourceProxyFactories == null) {
+ sourceProxyFactories = new HashMap(1);
+ sourceProxyFactories.put(referenceName, proxyFactory);
+ }
+ return sourceProxyFactories;
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/HierarchicalBuilder.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/HierarchicalBuilder.java
new file mode 100644
index 0000000000..41f56c1bf0
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/HierarchicalBuilder.java
@@ -0,0 +1,58 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.builder.impl;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.tuscany.core.builder.BuilderException;
+import org.apache.tuscany.core.builder.RuntimeConfigurationBuilder;
+import org.apache.tuscany.core.context.Context;
+import org.apache.tuscany.model.assembly.AssemblyModelObject;
+
+/**
+ * A builder that contains nested builders. Used for synchronizing parts of the build process, such as references.
+ *
+ * @version $Rev$ $Date$
+ */
+public class HierarchicalBuilder implements RuntimeConfigurationBuilder {
+ private List<RuntimeConfigurationBuilder> builders = new CopyOnWriteArrayList();
+
+ private List<RuntimeConfigurationBuilder> readOnlyBuilders = Collections.unmodifiableList(builders);
+
+ public HierarchicalBuilder() {
+ }
+
+ public void addBuilder(RuntimeConfigurationBuilder builder) {
+ builders.add(builder);
+ }
+
+ public void removeBuilder(RuntimeConfigurationBuilder builder){
+ builders.remove(builder);
+ }
+
+ public List getBuilders(){
+ return readOnlyBuilders;
+ }
+
+ public void build(AssemblyModelObject object, Context context) throws BuilderException {
+ for (RuntimeConfigurationBuilder builder : builders) {
+ builder.build(object, context);
+ }
+
+ }
+
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ProxyObjectFactory.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ProxyObjectFactory.java
new file mode 100644
index 0000000000..c5d3b56034
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ProxyObjectFactory.java
@@ -0,0 +1,42 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.builder.impl;
+
+import org.apache.tuscany.core.builder.ObjectFactory;
+import org.apache.tuscany.core.injection.ObjectCreationException;
+import org.apache.tuscany.core.invocation.spi.ProxyCreationException;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+
+/**
+ * Uses a proxy factory to return an object instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class ProxyObjectFactory implements ObjectFactory {
+
+ private ProxyFactory factory;
+
+ public ProxyObjectFactory(ProxyFactory factory) {
+ this.factory = factory;
+ }
+
+ public Object getInstance() throws ObjectCreationException {
+ try {
+ return factory.createProxy();
+ } catch (ProxyCreationException e) {
+ throw new ObjectCreationException(e);
+ }
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/client/TuscanyRuntime.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/client/TuscanyRuntime.java
new file mode 100644
index 0000000000..629f3ac0c2
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/client/TuscanyRuntime.java
@@ -0,0 +1,204 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.client;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.common.monitor.MonitorFactory;
+import org.apache.tuscany.common.monitor.impl.NullMonitorFactory;
+import org.apache.tuscany.common.resource.ResourceLoader;
+import org.apache.tuscany.common.resource.impl.ResourceLoaderImpl;
+import org.apache.tuscany.core.builder.RuntimeConfigurationBuilder;
+import org.apache.tuscany.core.builder.impl.DefaultWireBuilder;
+import org.apache.tuscany.core.config.ConfigurationException;
+import org.apache.tuscany.core.config.ModuleComponentConfigurationLoader;
+import org.apache.tuscany.core.config.impl.ModuleComponentConfigurationLoaderImpl;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.runtime.RuntimeContext;
+import org.apache.tuscany.core.runtime.RuntimeContextImpl;
+import org.apache.tuscany.core.system.builder.SystemComponentContextBuilder;
+import org.apache.tuscany.core.system.builder.SystemEntryPointBuilder;
+import org.apache.tuscany.core.system.builder.SystemExternalServiceBuilder;
+import org.apache.tuscany.core.system.loader.SystemSCDLModelLoader;
+import org.apache.tuscany.model.assembly.AssemblyFactory;
+import org.apache.tuscany.model.assembly.AssemblyModelContext;
+import org.apache.tuscany.model.assembly.ModuleComponent;
+import org.apache.tuscany.model.assembly.impl.AssemblyFactoryImpl;
+import org.apache.tuscany.model.assembly.impl.AssemblyModelContextImpl;
+import org.apache.tuscany.model.assembly.loader.AssemblyModelLoader;
+import org.apache.tuscany.model.scdl.loader.SCDLModelLoader;
+import org.apache.tuscany.model.scdl.loader.impl.SCDLAssemblyModelLoaderImpl;
+import org.osoa.sca.ModuleContext;
+import org.osoa.sca.SCA;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * Create and initialize a Tuscany SCA runtime environment.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TuscanyRuntime extends SCA {
+ private final Monitor monitor;
+ private final Object sessionKey = new Object();
+
+ private final RuntimeContext runtimeContext;
+ private AggregateContext systemModuleComponentContext;
+ private AggregateContext moduleContext;
+
+ private final static String SYSTEM_MODULE_COMPONENT = "org.apache.tuscany.core.system";
+
+ /**
+ * Construct a runtime using a null MonitorFactory.
+ *
+ * @param name the name of the module component
+ * @param uri the URI to assign to the module component
+ * @throws ConfigurationException if there was a problem loading the SCA configuration
+ * @see TuscanyRuntime#TuscanyRuntime(String, String, org.apache.tuscany.common.monitor.MonitorFactory)
+ */
+ public TuscanyRuntime(String name, String uri) throws ConfigurationException {
+ this(name, uri, new NullMonitorFactory());
+ }
+
+ /**
+ * Construct a runtime containing a single module component with the
+ * specified name. The module definition is loaded from a "/sca.module"
+ * resource found on the classpath of the current Thread context classloader.
+ *
+ * @param name the name of the module component
+ * @param uri the URI to assign to the module component
+ * @param monitorFactory the MonitorFactory for this runtime
+ * @throws ConfigurationException if there was a problem loading the SCA configuration
+ */
+ public TuscanyRuntime(String name, String uri, MonitorFactory monitorFactory) throws ConfigurationException {
+ this.monitor = monitorFactory.getMonitor(Monitor.class);
+
+ // Create a resource loader from the current classloader
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ ResourceLoader resourceLoader = new ResourceLoaderImpl(classLoader);
+
+ // Create an assembly model factory
+ AssemblyFactory modelFactory=new AssemblyFactoryImpl();
+
+ // Create an assembly model loader
+ List<SCDLModelLoader> scdlLoaders=new ArrayList<SCDLModelLoader>();
+ scdlLoaders.add(new SystemSCDLModelLoader());
+ AssemblyModelLoader modelLoader=new SCDLAssemblyModelLoaderImpl(scdlLoaders);
+
+ // Create an assembly model context
+ AssemblyModelContext modelContext = new AssemblyModelContextImpl(modelFactory, modelLoader, resourceLoader);
+
+ // Create system configuration builders
+ List<RuntimeConfigurationBuilder> configBuilders = new ArrayList();
+ configBuilders.add((new SystemComponentContextBuilder()));
+ configBuilders.add(new SystemEntryPointBuilder());
+ configBuilders.add(new SystemExternalServiceBuilder());
+
+ // Create a runtime context and start it
+ runtimeContext = new RuntimeContextImpl(monitorFactory, scdlLoaders, configBuilders,new DefaultWireBuilder());
+ runtimeContext.start();
+ monitor.started(runtimeContext);
+
+ // Get the system context
+ AggregateContext systemContext = runtimeContext.getSystemContext();
+
+ // Load the system module component
+ ModuleComponentConfigurationLoader loader = new ModuleComponentConfigurationLoaderImpl(modelContext);
+ ModuleComponent systemModuleComponent = loader.loadSystemModuleComponent(SYSTEM_MODULE_COMPONENT, SYSTEM_MODULE_COMPONENT);
+
+ // Register it with the system context
+ systemContext.registerModelObject(systemModuleComponent);
+
+ // Get the aggregate context representing the system module component
+ systemModuleComponentContext = (AggregateContext) systemContext.getContext(SYSTEM_MODULE_COMPONENT);
+ systemModuleComponentContext.registerModelObject(systemModuleComponent.getComponentImplementation());
+ systemModuleComponentContext.fireEvent(EventContext.MODULE_START, null);
+
+ // Load the SCDL configuration of the application module
+ ModuleComponent moduleComponent = loader.loadModuleComponent(name, uri);
+
+ // Register it under the root application context
+ runtimeContext.getRootContext().registerModelObject(moduleComponent);
+ moduleContext=(AggregateContext)runtimeContext.getContext(moduleComponent.getName());
+ moduleContext.registerModelObject(moduleComponent.getComponentImplementation());
+
+ }
+
+ /**
+ * Start the runtime and associate the module context with the calling thread.
+ */
+ @Override
+ public void start() {
+ setModuleContext((ModuleContext)moduleContext);
+ try {
+ //moduleContext.start();
+ moduleContext.fireEvent(EventContext.MODULE_START, null);
+ moduleContext.fireEvent(EventContext.REQUEST_START, null);
+ moduleContext.fireEvent(EventContext.SESSION_NOTIFY, sessionKey);
+ monitor.started(moduleContext);
+ } catch (CoreRuntimeException e) {
+ setModuleContext(null);
+ monitor.startFailed(moduleContext, e);
+ //FIXME throw a better exception
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ /**
+ * Disassociate the module context from the current thread and shut down the runtime.
+ */
+ @Override
+ public void stop() {
+ setModuleContext(null);
+ moduleContext.fireEvent(EventContext.REQUEST_END, null);
+ moduleContext.fireEvent(EventContext.SESSION_END, sessionKey);
+ moduleContext.fireEvent(EventContext.MODULE_STOP, null);
+ moduleContext.stop();
+ monitor.stopped(moduleContext);
+ runtimeContext.stop();
+ monitor.stopped(runtimeContext);
+ }
+
+ /**
+ * Monitor interface for a TuscanyRuntime.
+ */
+ public static interface Monitor {
+ /**
+ * Event emitted after the runtime has been started.
+ *
+ * @param ctx the runtime's module component context
+ */
+ void started(AggregateContext ctx);
+
+ /**
+ * Event emitted when an attempt to start the runtime failed.
+ *
+ * @param ctx the runtime's module component context
+ * @param e the exception that caused the failure
+ */
+ void startFailed(AggregateContext ctx, CoreRuntimeException e);
+
+ /**
+ * Event emitted after the runtime has been stopped.
+ *
+ * @param ctx the runtime's module component context
+ */
+ void stopped(AggregateContext ctx);
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ComponentTypeIntrospector.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ComponentTypeIntrospector.java
new file mode 100644
index 0000000000..c80a8f31ba
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ComponentTypeIntrospector.java
@@ -0,0 +1,37 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.config;
+
+import org.apache.tuscany.model.assembly.ComponentType;
+
+/**
+ * Interface for implementations that are able create SCA definitions
+ * by inspecting Java classes.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ComponentTypeIntrospector {
+ /**
+ * Create a componentType definition by introspecting a Java Class.
+ *
+ * @param implClass the class to inspect
+ * @return a componentType definition
+ * @throws ConfigurationException if the Class does not define a valid component type
+ */
+ ComponentType introspect(Class<?> implClass) throws ConfigurationException;
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ConfigurationException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ConfigurationException.java
new file mode 100644
index 0000000000..96365311f2
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ConfigurationException.java
@@ -0,0 +1,42 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.config;
+
+import org.apache.tuscany.common.TuscanyException;
+
+
+/**
+ * Base class for exceptions that pertain to configuration.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ConfigurationException extends TuscanyException {
+ public ConfigurationException() {
+ }
+
+ public ConfigurationException(String message) {
+ super(message);
+ }
+
+ public ConfigurationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ConfigurationException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ConfigurationLoadException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ConfigurationLoadException.java
new file mode 100644
index 0000000000..3055dc2fd2
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ConfigurationLoadException.java
@@ -0,0 +1,47 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.config;
+
+import java.io.IOException;
+
+/**
+ * Exception indicating that there was a problem loading a configuration resource.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ConfigurationLoadException extends ConfigurationException {
+
+ /**
+ * Constructor specifying the resource that was being loaded and the IOException that resulted.
+ * These are returned as the message and cause respectively.
+ *
+ * @param resource the resource being loaded
+ * @param cause the IOException that occurred
+ */
+ public ConfigurationLoadException(String resource, IOException cause) {
+ super(resource, cause);
+ }
+
+ /**
+ * Constructor specifying the resource that was being loaded.
+ *
+ * @param resource the resource being loaded
+ */
+ public ConfigurationLoadException(String resource) {
+ super(resource);
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ImplementationCache.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ImplementationCache.java
new file mode 100644
index 0000000000..595f499797
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ImplementationCache.java
@@ -0,0 +1,46 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.config;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.model.assembly.ComponentImplementation;
+
+/**
+ * Cache of introspected implementations.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ImplementationCache {
+ /**
+ * Return an implementation from a given namespace.
+ *
+ * @param type the namespace that defines the type of implementation
+ * @param name the name of an implementation in that namespace
+ * @return the implementation or null if it is not present in the cache
+ */
+ ComponentImplementation get(QName type, String name);
+
+ /**
+ * Add an implementation to the cache
+ *
+ * @param type the namespace that defines the type of implementation
+ * @param name the name of an implementation in that namespace
+ * @param implementation the introspected implementation
+ */
+ void put(QName type, String name, ComponentImplementation implementation);
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/InvalidRootElementException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/InvalidRootElementException.java
new file mode 100644
index 0000000000..19df4784cd
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/InvalidRootElementException.java
@@ -0,0 +1,51 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.config;
+
+/**
+ * Configuration exception that indicates the root element in an XML file was not the one expected.
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidRootElementException extends ConfigurationException {
+ private final String resource;
+ private final String element;
+
+ /**
+ * Constructor specifying the location of the resource and the element that was expected.
+ *
+ * @param resource the resource
+ * @param element the expected root element
+ */
+ public InvalidRootElementException(String resource, String element) {
+ super();
+ this.resource = resource;
+ this.element = element;
+ }
+
+ public String getMessage() {
+ return "XML document element in resource " + resource + " is not a " + element;
+ }
+
+ public String getResource() {
+ return resource;
+ }
+
+ public String getElement() {
+ return element;
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/JavaIntrospectionHelper.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/JavaIntrospectionHelper.java
new file mode 100644
index 0000000000..c10ff82310
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/JavaIntrospectionHelper.java
@@ -0,0 +1,349 @@
+package org.apache.tuscany.core.config;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+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 class JavaIntrospectionHelper {
+
+ private static final Class[] EMPTY_CLASS_ARRY = new Class[0];
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ /**
+ * Hide the constructor
+ */
+ private JavaIntrospectionHelper() {
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ /**
+ * Returns a collection of public, private, protected, or default fields declared by a class or one of its
+ * supertypes
+ */
+ public static Set<Field> getAllFields(Class pClass) {
+ return getAllFields(pClass, new HashSet<Field>());
+ }
+
+ /**
+ * Recursively evaluates the type hierachy to return all fields on a given type
+ *
+ * @spec This raises an interesting issue - do we allow injection on private supertype fields in a subtype even if
+ * they are annotated?
+ */
+ private static Set<Field> getAllFields(Class pClass, Set<Field> fields) {
+ if (pClass == null || pClass.isArray() || Object.class.equals(pClass)) {
+ return fields;
+ }
+ fields = getAllFields(pClass.getSuperclass(), fields);
+ Field[] declaredFields = pClass.getDeclaredFields();
+ for (int i = 0; i < declaredFields.length; i++) {
+ declaredFields[i].setAccessible(true); // ignore Java accessibility
+ fields.add(declaredFields[i]);
+ }
+ return fields;
+ }
+
+ /**
+ * Returns a collection of public, private, protected, or default 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> getAllUniqueMethods(Class pClass) {
+ return getAllUniqueMethods(pClass, 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 (int i = 0; i < declaredMethods.length; i++) {
+ if (methods.size() == 0) {
+ methods.add(declaredMethods[i]);
+ } else {
+ List temp = new ArrayList();
+ 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(declaredMethods[i], method)) {
+ matched = true;
+ break;
+ }
+ }
+ if (!matched) {
+ // TODO ignore Java accessibility
+ declaredMethods[i].setAccessible(true);
+ temp.add(declaredMethods[i]);
+
+ }
+ 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
+ * @throws NoSuchFieldException if no field 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
+ * @throws NoSuchFieldException if no field 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;
+ }
+ }
+
+ /**
+ * Returns a field or method defined in the given class or its superclasses matching a literal name and parameter
+ * types <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.
+ *
+ * @param clazz the class to introspect
+ * @param propertName the literal name of the property (i.e. JavaBean conventions are not applied)
+ * @param paramTypes the parameter types for a method or null for fields or methods with no parameters
+ * @return the field, method or null
+ */
+ public static AccessibleObject getBeanProperty(Class clazz, String propertName, Class[] paramTypes) {
+
+ Set<Method> methods = getAllUniqueMethods(clazz);
+ for (Method method : methods) {
+ if (method.getName().equals(propertName)) {
+ Class[] types = method.getParameterTypes();
+ if (types.length == 0 && paramTypes == null) {
+ return method;
+ } else if (types.length != 0 && paramTypes == null) {
+ break;
+ } else if (types.length == paramTypes.length) {
+ for (int n = 0; n < types.length - 1; n++) {
+ if (!types[n].equals(paramTypes[n]) || !types[n].isAssignableFrom(paramTypes[n])) {
+ break;
+ }
+ }
+ return method;
+ }
+ }
+ }
+
+ Set<Field> fields = getAllFields(clazz);
+ for (Field field : fields) {
+ if (field.getName().equals(propertName)) {
+ return field;
+ }
+ }
+ 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 Constructor getDefaultConstructor(Class 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
+ * @return
+ */
+ 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) {
+ return name.substring(3, 4).toLowerCase() + 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 dtermine 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;
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/MissingResourceException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/MissingResourceException.java
new file mode 100644
index 0000000000..7b40ccbefa
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/MissingResourceException.java
@@ -0,0 +1,43 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.config;
+
+/**
+ * Exception that indicates an expected resource could not be found.
+ *
+ * @version $Rev$ $Date$
+ */
+public class MissingResourceException extends ConfigurationException {
+ /**
+ * Constructor that indicates which resource could not be found.
+ * The supplied parameter is also returned as the message.
+ *
+ * @param resource the resource that could not be found
+ */
+ public MissingResourceException(String resource) {
+ super(resource);
+ }
+
+ /**
+ * Return the name of the expected resource.
+ *
+ * @return the name of the expected resource
+ */
+ public String getResource() {
+ return getMessage();
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ModuleComponentConfigurationLoader.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ModuleComponentConfigurationLoader.java
new file mode 100644
index 0000000000..a8e2718222
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/ModuleComponentConfigurationLoader.java
@@ -0,0 +1,74 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.config;
+
+import java.util.Collection;
+
+import org.apache.tuscany.model.assembly.ModuleComponent;
+
+/**
+ * Interface for loading configuration information from some external
+ * form into a Tuscany logical model.
+ *
+ * @version $Rev: 368822 $ $Date: 2006-01-13 10:54:38 -0800 (Fri, 13 Jan 2006) $
+ */
+public interface ModuleComponentConfigurationLoader {
+
+ /**
+ * Load a SCDL module component.
+ *
+ * @param name the name of the module component
+ * @param uri
+ * @return a new module component definition
+ * @throws ConfigurationException if there was a problem loading the module component.
+ */
+ ModuleComponent loadModuleComponent(String name, String uri) throws ConfigurationLoadException;
+
+ /**
+ * Load a System SCDL module component.
+ *
+ * @param name the name of the module component
+ * @param uri
+ * @return a new module component definition
+ * @throws ConfigurationException if there was a problem loading the module component.
+ */
+ ModuleComponent loadSystemModuleComponent(String name, String uri) throws ConfigurationLoadException;
+
+ /**
+ * Load a SCDL module component.
+ *
+ * @param name the name of the module component
+ * @param uri
+ * @param url
+ * @return a new module component definition
+ * @throws ConfigurationException if there was a problem loading the module component.
+ */
+ ModuleComponent loadModuleComponent(String name, String uri, String url) throws ConfigurationLoadException;
+
+ /**
+ * Load a SCDL module component.
+ *
+ * @param name the name of the module component
+ * @param uri
+ * @param url
+ * @param urls
+ * @return a new module component definition
+ * @throws ConfigurationException if there was a problem loading the module component.
+ */
+ ModuleComponent loadModuleComponent(String name, String uri, String url, Collection<String> urls) throws ConfigurationLoadException;
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/impl/Java5ComponentTypeIntrospector.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/impl/Java5ComponentTypeIntrospector.java
new file mode 100644
index 0000000000..8799969028
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/impl/Java5ComponentTypeIntrospector.java
@@ -0,0 +1,423 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.config.impl;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.osoa.sca.annotations.Callback;
+import org.osoa.sca.annotations.Remotable;
+
+import org.apache.tuscany.core.config.ComponentTypeIntrospector;
+import org.apache.tuscany.core.config.ConfigurationException;
+import org.apache.tuscany.core.config.JavaIntrospectionHelper;
+import org.apache.tuscany.model.assembly.AssemblyFactory;
+import org.apache.tuscany.model.assembly.ComponentType;
+import org.apache.tuscany.model.assembly.Multiplicity;
+import org.apache.tuscany.model.assembly.Property;
+import org.apache.tuscany.model.assembly.Reference;
+import org.apache.tuscany.model.assembly.Scope;
+import org.apache.tuscany.model.assembly.Service;
+import org.apache.tuscany.model.assembly.ServiceContract;
+import org.apache.tuscany.model.types.java.JavaServiceContract;
+
+/**
+ * Introspects Java annotation-based metata data
+ *
+ * @version $Rev$ $Date$
+ */
+public class Java5ComponentTypeIntrospector implements ComponentTypeIntrospector {
+ private final AssemblyFactory factory;
+
+ public Java5ComponentTypeIntrospector(AssemblyFactory factory) {
+ this.factory = factory;
+ }
+
+ /**
+ * Returns a component type for the given class
+ *
+ * @throws ConfigurationException
+ */
+ public ComponentType introspect(Class<?> implClass) throws ConfigurationException {
+ ComponentType compType = factory.createComponentType();
+ introspectServices(compType, implClass);
+ introspectAnnotatedMembers(compType, implClass);
+
+ // if implementation is not annotated and no annotated members were found, add public fields and setters
+ if (!implClass.isAnnotationPresent(org.osoa.sca.annotations.Service.class) && compType.getProperties().isEmpty()
+ && compType.getReferences().isEmpty()) {
+ introspectMembers(compType, implClass);
+ }
+
+ // FIXME scopes should be handled at the interface level
+ if (compType != null) {
+ Scope scope = getScope(implClass);
+ for (Iterator<Service> i = compType.getServices().iterator(); i.hasNext();) {
+ ServiceContract intf = i.next().getServiceContract();
+ if (intf != null)
+ intf.setScope(scope);
+ }
+ }
+
+ return compType;
+ }
+
+ /**
+ * Returns the scope for a given class
+ *
+ */
+ private static Scope getScope(Class<?> implClass) {
+ org.osoa.sca.annotations.Scope scope = implClass.getAnnotation(org.osoa.sca.annotations.Scope.class);
+ if (scope == null) {
+ // scope was not defined on the implementation class, look for annotated interfaces
+ Class<?>[] interfaces = implClass.getInterfaces();
+ for (int i = 0; i < interfaces.length; i++) {
+ scope = interfaces[i].getAnnotation(org.osoa.sca.annotations.Scope.class);
+ }
+ }
+ if (scope == null) {
+ return Scope.INSTANCE;
+ }
+
+ if ("MODULE".equalsIgnoreCase(scope.value())) {
+ return (Scope.MODULE);
+ } else if ("SESSION".equalsIgnoreCase(scope.value())) {
+ return (Scope.SESSION);
+ } else if ("REQUEST".equalsIgnoreCase(scope.value())) {
+ return (Scope.REQUEST);
+ } else {
+ return (Scope.INSTANCE);
+ }
+ }
+
+ /**
+ * Adds the supported services for a component implementation type to its component type
+ *
+ * @param compType the component type being generated
+ * @param implClass the component implementation type class
+ * @throws ConfigurationException
+ */
+ protected void introspectServices(ComponentType compType, Class<?> implClass) throws ConfigurationException {
+ List<Service> services = compType.getServices();
+ assert services.isEmpty() : "componentType already has services defined";
+
+ // add services defined in an @Service annotation
+ org.osoa.sca.annotations.Service serviceAnnotation = implClass.getAnnotation(org.osoa.sca.annotations.Service.class);
+ if (serviceAnnotation != null) {
+ Class<?>[] interfaces = serviceAnnotation.interfaces();
+ Class<?> value = serviceAnnotation.value();
+ if (interfaces.length > 0) {
+ if (!Void.class.equals(value)) {
+ throw new IllegalArgumentException("Both interfaces and value specified in @Service on "
+ + implClass.getName());
+ }
+ for (int i = 0; i < interfaces.length; i++) {
+ Class<?> intf = interfaces[i];
+ addService(services, intf);
+ }
+ return;
+ } else if (!Void.class.equals(value)) {
+ addService(services, value);
+ return;
+ }
+ }
+
+ // no @Service annotation, add all implemented interfaces with an @Remotable annotation
+ Class[] interfaces = implClass.getInterfaces();
+ for (int i = 0; i < interfaces.length; i++) {
+ Class<?> intf = interfaces[i];
+ if (intf.isAnnotationPresent(Remotable.class)) {
+ addService(services, intf);
+ }
+ }
+
+ // if no Remotable interfaces were specified, the class itself is the service
+ if (services.isEmpty()) {
+ addService(services, implClass);
+ }
+ }
+
+ /**
+ * Recursively adds supported services to a component type by walking the class hierarchy
+ *
+ * @throws ConfigurationException
+ */
+ protected void addService(List<Service> services, Class<?> serviceClass) throws ConfigurationException {
+ JavaServiceContract javaInterface = factory.createJavaServiceContract();
+ javaInterface.setInterface(serviceClass);
+ Callback callback = serviceClass.getAnnotation(Callback.class);
+ if (callback != null && !Void.class.equals(callback.value())) {
+ javaInterface.setCallbackInterface(callback.value());
+ }
+
+ String name = JavaIntrospectionHelper.getBaseName(serviceClass);
+ Service service = factory.createService();
+ service.setName(name);
+ service.setServiceContract(javaInterface);
+ services.add(service);
+ }
+
+ /**
+ * Root method for determining public field and method metadata
+ *
+ * @throws ConfigurationException
+ */
+ protected void introspectAnnotatedMembers(ComponentType compType, Class<?> implClass) throws ConfigurationException {
+
+ introspectPublicFields(compType, implClass);
+ introspectPrivateFields(compType, implClass);
+
+ introspectPublicMethods(compType, implClass);
+ introspectPrivateMethods(compType, implClass);
+ }
+
+ /**
+ * Introspects metdata for all public fields and methods for a class hierarchy
+ *
+ * @throws ConfigurationException
+ */
+ protected void introspectMembers(ComponentType compType, Class<?> implClass) throws ConfigurationException {
+ List<Property> properties = compType.getProperties();
+ List<Reference> references = compType.getReferences();
+
+ // inspect public fields from class and all superclasses
+ Field[] fields = implClass.getFields();
+ for (int i = 0; i < fields.length; i++) {
+ Field field = fields[i];
+ if (field.getType().isAnnotationPresent(Remotable.class)) {
+ addReference(references, field);
+ } else {
+ addProperty(properties, field);
+ }
+ }
+
+ // add public methods from class and all superclasses
+ Method[] methods = implClass.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ if (Void.class.equals(method.getReturnType()) && method.getName().startsWith("set")
+ && method.getParameterTypes().length == 1
+ && !method.getParameterTypes()[0].isAnnotationPresent(Remotable.class)) {
+ String name = method.getName();
+ name = Character.toLowerCase(name.charAt(3)) + name.substring(4);
+ Class<?> type = method.getParameterTypes()[0];
+ if (type.isAnnotationPresent(Remotable.class)) {
+ addReference(references, name, type, false);
+ } else {
+ addProperty(properties, name, type, false);
+ }
+ }
+ }
+ }
+
+ private void introspectPublicFields(ComponentType compType, Class<?> implClass) throws ConfigurationException {
+ List<Property> properties = compType.getProperties();
+ List<Reference> references = compType.getReferences();
+
+ // inspect public fields from class and all superclasses
+ Field[] fields = implClass.getFields();
+ for (int i = 0; i < fields.length; i++) {
+ Field field = fields[i];
+ if (field.isAnnotationPresent(org.osoa.sca.annotations.Property.class)) {
+ addProperty(properties, field);
+ } else if (field.isAnnotationPresent(org.osoa.sca.annotations.Reference.class)) {
+ addReference(references, field);
+ }
+ }
+ }
+
+ private void introspectPrivateFields(ComponentType compType, Class<?> implClass) throws ConfigurationException {
+ List<Property> properties = compType.getProperties();
+ List<Reference> references = compType.getReferences();
+
+ // inspect private fields declared in class
+ Field[] fields = implClass.getDeclaredFields();
+ for (int i = 0; i < fields.length; i++) {
+ Field field = fields[i];
+ if (!Modifier.isPrivate(field.getModifiers())) {
+ continue;
+ }
+ if (field.isAnnotationPresent(org.osoa.sca.annotations.Property.class)) {
+ addProperty(properties, field);
+ } else if (field.isAnnotationPresent(org.osoa.sca.annotations.Reference.class)) {
+ addReference(references, field);
+ }
+ }
+ }
+
+ private void introspectPublicMethods(ComponentType compType, Class<?> implClass) throws ConfigurationException {
+ List<Property> properties = compType.getProperties();
+ List<Reference> references = compType.getReferences();
+
+ // add public methods from class and all superclasses
+ Method[] methods = implClass.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ if (method.isAnnotationPresent(org.osoa.sca.annotations.Property.class)) {
+ addProperty(properties, method);
+ } else if (method.isAnnotationPresent(org.osoa.sca.annotations.Reference.class)) {
+ addReference(references, method);
+ }
+ }
+ }
+
+ private void introspectPrivateMethods(ComponentType compType, Class<?> implClass) throws ConfigurationException {
+ List<Property> properties = compType.getProperties();
+ List<Reference> references = compType.getReferences();
+
+ // add private methods declared on class
+ Method[] methods = implClass.getDeclaredMethods();
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ if (!Modifier.isPrivate(method.getModifiers())) {
+ continue;
+ }
+ if (method.isAnnotationPresent(org.osoa.sca.annotations.Property.class)) {
+ addProperty(properties, method);
+ } else if (method.isAnnotationPresent(org.osoa.sca.annotations.Reference.class)) {
+ addReference(references, method);
+ }
+ }
+ }
+
+ protected void addProperty(List<Property> properties, Field field) throws ConfigurationException {
+ String name;
+ boolean required;
+ org.osoa.sca.annotations.Property annotation = field.getAnnotation(org.osoa.sca.annotations.Property.class);
+ if (annotation != null) {
+ name = annotation.name();
+ if (name.length() == 0) {
+ name = field.getName();
+ }
+ required = annotation.required();
+ } else {
+ name = field.getName();
+ required = false;
+ }
+ addProperty(properties, name, field.getType(), required);
+ }
+
+ protected void addProperty(List<Property> properties, Method method) throws ConfigurationException {
+ if (!Void.class.equals(method.getReturnType())) {
+ throw new ConfigurationException("Property setter method does not return void: " + method.toString());
+ }
+ Class<?>[] params = method.getParameterTypes();
+ if (params.length != 1) {
+ throw new ConfigurationException("Property setter method does not have 1 parameter: " + method.toString());
+ }
+
+ String name;
+ boolean required;
+ org.osoa.sca.annotations.Property annotation = method.getAnnotation(org.osoa.sca.annotations.Property.class);
+ if (annotation != null) {
+ name = annotation.name();
+ required = annotation.required();
+ } else {
+ name = "";
+ required = false;
+ }
+ if (name.length() == 0) {
+ name = method.getName();
+ if (name.length() > 3 && name.startsWith("set")) {
+ name = Character.toLowerCase(name.charAt(3)) + name.substring(4);
+ }
+ }
+ addProperty(properties, name, params[0], required);
+ }
+
+ protected void addProperty(List<Property> properties, String name, Class<?> type, boolean required)
+ throws ConfigurationException {
+ Property prop = factory.createProperty();
+ prop.setName(name);
+ prop.setType(type);
+ prop.setRequired(required);
+
+ // a java.util.Map is not a "many"
+ prop.setMany(type.isArray() || Collection.class.isAssignableFrom(type));
+
+ // todo how is the default specified using annotations?
+ prop.setDefaultValue(null);
+
+ properties.add(prop);
+ }
+
+ protected void addReference(List<Reference> references, Field field) throws ConfigurationException {
+ String name;
+ boolean required;
+ org.osoa.sca.annotations.Reference annotation = field.getAnnotation(org.osoa.sca.annotations.Reference.class);
+ if (annotation != null) {
+ name = annotation.name();
+ if (name.length() == 0) {
+ name = field.getName();
+ }
+ required = annotation.required();
+ } else {
+ name = field.getName();
+ required = false;
+ }
+ addReference(references, name, field.getType(), required);
+ }
+
+ protected void addReference(List<Reference> references, Method method) throws ConfigurationException {
+ if (!Void.TYPE.equals(method.getReturnType())) {
+ throw new ConfigurationException("Reference setter method does not return void: " + method.toString());
+ }
+ Class<?>[] params = method.getParameterTypes();
+ if (params.length != 1) {
+ throw new ConfigurationException("Reference setter method does not have 1 parameter: " + method.toString());
+ }
+
+ String name;
+ boolean required;
+ org.osoa.sca.annotations.Reference annotation = method.getAnnotation(org.osoa.sca.annotations.Reference.class);
+ if (annotation != null) {
+ name = annotation.name();
+ required = annotation.required();
+ } else {
+ name = "";
+ required = false;
+ }
+ if (name.length() == 0) {
+ name = method.getName();
+ if (name.length() > 3 && name.startsWith("set")) {
+ name = Character.toLowerCase(name.charAt(3)) + name.substring(4);
+ }
+ }
+ addReference(references, name, params[0], required);
+ }
+
+ protected void addReference(List<Reference> references, String name, Class<?> type, boolean required)
+ throws ConfigurationException {
+ Reference ref = factory.createReference();
+ ref.setName(name);
+ boolean many = type.isArray() || Collection.class.isAssignableFrom(type);
+ Multiplicity multiplicity;
+ if (required)
+ multiplicity = many ? Multiplicity.ONE_N : Multiplicity.ONE_ONE;
+ else
+ multiplicity = many ? Multiplicity.ZERO_N : Multiplicity.ZERO_ONE;
+ ref.setMultiplicity(multiplicity);
+ ServiceContract javaInterface = factory.createJavaServiceContract();
+ javaInterface.setInterface(type);
+ ref.setServiceContract(javaInterface);
+ references.add(ref);
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/impl/ModuleComponentConfigurationLoaderImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/impl/ModuleComponentConfigurationLoaderImpl.java
new file mode 100644
index 0000000000..bed4b0ac40
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/config/impl/ModuleComponentConfigurationLoaderImpl.java
@@ -0,0 +1,142 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.config.impl;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tuscany.common.resource.ResourceLoader;
+import org.apache.tuscany.core.config.ConfigurationLoadException;
+import org.apache.tuscany.core.config.ModuleComponentConfigurationLoader;
+import org.apache.tuscany.model.assembly.AssemblyFactory;
+import org.apache.tuscany.model.assembly.AssemblyModelContext;
+import org.apache.tuscany.model.assembly.Module;
+import org.apache.tuscany.model.assembly.ModuleComponent;
+import org.apache.tuscany.model.assembly.ModuleFragment;
+import org.apache.tuscany.model.assembly.loader.AssemblyModelLoader;
+
+/**
+ */
+public class ModuleComponentConfigurationLoaderImpl implements ModuleComponentConfigurationLoader {
+
+ private static final String SCA_MODULE_FILE_NAME = "sca.module";
+ //FIXME can fragments have a variable prefix name?
+ private static final String SCA_FRAGMENT_FILE_NAME = "sca.fragment";
+ private static final String SYSTEM_MODULE_FILE_NAME = "system.module";
+ //FIXME can fragments have a variable prefix name?
+ private static final String SYSTEM_FRAGMENT_FILE_NAME = "system.fragment";
+
+ private AssemblyModelContext modelContext;
+ private ResourceLoader resourceLoader;
+ private AssemblyFactory assemblyFactory;
+ private AssemblyModelLoader modelLoader;
+
+ /**
+ * Constructor
+ */
+ public ModuleComponentConfigurationLoaderImpl(AssemblyModelContext modelContext) {
+ this.modelContext=modelContext;
+ this.modelLoader=this.modelContext.getAssemblyLoader();
+ this.assemblyFactory=this.modelContext.getAssemblyFactory();
+ this.resourceLoader=this.modelContext.getApplicationResourceLoader();
+ }
+
+ /**
+ * @see org.apache.tuscany.model.assembly.loader.AssemblyModelLoader#loadModuleComponent(java.lang.String, java.lang.String)
+ */
+ public ModuleComponent loadSystemModuleComponent(String name, String uri) throws ConfigurationLoadException {
+ return loadModuleComponent(SYSTEM_MODULE_FILE_NAME, SYSTEM_FRAGMENT_FILE_NAME, name, uri);
+ }
+
+ /**
+ * @see org.apache.tuscany.model.assembly.loader.AssemblyModelLoader#loadModuleComponent(java.lang.String, java.lang.String)
+ */
+ public ModuleComponent loadModuleComponent(String name, String uri) throws ConfigurationLoadException {
+ return loadModuleComponent(SCA_MODULE_FILE_NAME, SCA_FRAGMENT_FILE_NAME, name, uri);
+ }
+
+ /**
+ * Load a module component.
+ */
+ private ModuleComponent loadModuleComponent(String moduleFileName, String fragmentFileName, String name, String uri) throws ConfigurationLoadException {
+
+ // Load the sca.module file
+ URL moduleUrl;
+ try {
+ moduleUrl = resourceLoader.getResource(moduleFileName);
+ } catch (IOException e) {
+ throw new ConfigurationLoadException(moduleFileName, e);
+ }
+ if (moduleUrl == null) {
+ throw new ConfigurationLoadException(moduleFileName);
+ }
+ String moduleUri=moduleUrl.toString();
+
+ // Load the sca.fragment files
+ Iterator<URL> i;
+ try {
+ i = resourceLoader.getAllResources(fragmentFileName);
+ } catch (IOException e) {
+ throw new ConfigurationLoadException(fragmentFileName, e);
+ }
+ List<String> moduleFragmentUris=new ArrayList<String>();
+ for (; i.hasNext(); ) {
+ URL url=i.next();
+ moduleFragmentUris.add(url.toString());
+ }
+
+ return loadModuleComponent(name, uri, moduleUri, moduleFragmentUris);
+ }
+
+ /**
+ * @see org.apache.tuscany.core.config.ModuleComponentConfigurationLoader#loadModuleComponent(java.lang.String, java.lang.String, java.lang.String)
+ */
+ public ModuleComponent loadModuleComponent(String name, String uri, String url) throws ConfigurationLoadException {
+ return loadModuleComponent( name, uri, url, (Collection)null);
+ }
+
+ /**
+ * @see org.apache.tuscany.core.config.ModuleComponentConfigurationLoader#loadModuleComponent(java.lang.String, java.lang.String, java.lang.String, java.util.Collection)
+ */
+ public ModuleComponent loadModuleComponent(String name, String uri, String moduleUri, Collection<String> moduleFragmentUris) throws ConfigurationLoadException {
+
+ // Load the module file
+ Module module=modelLoader.loadModule(moduleUri);
+
+ // Load the sca.fragment files
+ if (moduleFragmentUris!=null) {
+ for (String moduleFragmentUri : moduleFragmentUris) {
+ ModuleFragment moduleFragment=modelLoader.loadModuleFragment(moduleFragmentUri);
+ module.getModuleFragments().add(moduleFragment);
+ }
+ }
+
+ // Create the module component
+ ModuleComponent moduleComponent=assemblyFactory.createModuleComponent();
+ moduleComponent.setName(name);
+ moduleComponent.setURI(uri);
+ moduleComponent.setComponentImplementation(module);
+ moduleComponent.initialize(modelContext);
+
+ return moduleComponent;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AbstractContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AbstractContext.java
new file mode 100644
index 0000000000..c1abcb3c03
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AbstractContext.java
@@ -0,0 +1,89 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Functionality common to all <code>Context<code> implementations
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractContext implements Context {
+
+ public AbstractContext() {
+ }
+
+ public AbstractContext(String name) {
+ this.name = name;
+ }
+
+ protected String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ protected int lifecycleState = UNINITIALIZED;
+
+ public int getLifecycleState() {
+ return lifecycleState;
+ }
+
+ public void setLifecycleState(int state) {
+ lifecycleState = state;
+ }
+
+ protected List<LifecycleEventListener> contextListener = new CopyOnWriteArrayList();
+
+ public void addContextListener(LifecycleEventListener listener) {
+ contextListener.add(listener);
+ }
+
+ public void removeContextListener(LifecycleEventListener listener) {
+ contextListener.remove(listener);
+ }
+
+ public String toString() {
+ switch (lifecycleState) {
+ case (CONFIG_ERROR):
+ return "Context [" + name + "] in state [CONFIG_ERROR]";
+ case (ERROR):
+ return "Context [" + name + "] in state [ERROR]";
+ case (INITIALIZING):
+ return "Context [" + name + "] in state [INITIALIZING]";
+ case (INITIALIZED):
+ return "Context [" + name + "] in state [INITIALIZED]";
+ case (RUNNING):
+ return "Context [" + name + "] in state [RUNNING]";
+ case (STOPPING):
+ return "Context [" + name + "] in state [STOPPING]";
+ case (STOPPED):
+ return "Context [" + name + "] in state [STOPPED]";
+ case (UNINITIALIZED):
+ return "Context [" + name + "] in state [UNINITIALIZED]";
+ default:
+ return "Context [" + name + "] in state [UNKNOWN]";
+ }
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AggregateContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AggregateContext.java
new file mode 100644
index 0000000000..0fab87358f
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AggregateContext.java
@@ -0,0 +1,85 @@
+package org.apache.tuscany.core.context;
+
+import java.util.List;
+
+import org.apache.tuscany.core.config.ConfigurationException;
+import org.apache.tuscany.model.assembly.Aggregate;
+import org.apache.tuscany.model.assembly.Extensible;
+import org.apache.tuscany.model.assembly.AggregatePart;
+
+/**
+ * A context which contains child component contexts.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface AggregateContext extends InstanceContext {
+
+ /**
+ * Propagates an event to registered listeners. All lifecycle events will be propagated to children in the order
+ * that they were registered. Listeners are expected to be well-behaved and if an exception is thrown the
+ * notification process will be aborted.
+ *
+ * @param pEventType the type of event. Basic types are defined in {@link EventContext}
+ * @param pMessage the message associated with the event or null
+ * @throws EventException if an error occurs while sending the event
+ */
+ public void fireEvent(int pEventType, Object pMessage) throws EventException;
+
+ /**
+ * Registers a listener to receive notifications for the context
+ *
+ * @throws ContextRuntimeException if an error occurs during registration
+ */
+ public void registerListener(RuntimeEventListener listener) throws ContextRuntimeException;
+
+ /**
+ * Adds runtime artifacts represented by the set of model objects to the aggregate context by merging them with
+ * existing artifacts. Implementing classes may support only a subset of {@link AggregatePart} types.
+ *
+ * @see org.apache.tuscany.model.assembly.Component
+ * @see org.apache.tuscany.model.assembly.ModuleComponent
+ * @see org.apache.tuscany.model.assembly.SimpleComponent
+ * @see org.apache.tuscany.model.assembly.EntryPoint
+ * @see org.apache.tuscany.model.assembly.ExternalService
+ */
+ public void registerModelObjects(List<Extensible> models) throws ConfigurationException;
+
+ /**
+ * Adds a runtime artifact represented by the model object to the aggregate context by merging it with existing
+ * artifacts. Implementing classes may support only a subset of {@link AggregatePart} types.
+ *
+ * @see org.apache.tuscany.model.assembly.Component
+ * @see org.apache.tuscany.model.assembly.ModuleComponent
+ * @see org.apache.tuscany.model.assembly.SimpleComponent
+ * @see org.apache.tuscany.model.assembly.EntryPoint
+ * @see org.apache.tuscany.model.assembly.ExternalService
+ */
+ public void registerModelObject(Extensible model) throws ConfigurationException;
+
+ /**
+ * Returns the child context associated with a given name
+ */
+ public InstanceContext getContext(String name);
+
+ /**
+ * Returns the parent context, or null if the context does not have one
+ */
+ public AggregateContext getParent();
+
+ /**
+ * Intended for internal use by the runtime, returns an implementation instance for the given context name, which
+ * may be a compound component/service form. Unlike {@link InstanceContext#getInstance(QualifiedName)}, which for aggregate contexts only returns
+ * entry point proxies, this method will return any type of contained implementation instance.
+ *
+ * @throws TargetException if there was an error returning the instance
+ */
+ public Object locateInstance(String name) throws TargetException;
+
+ /**
+ * Returns the aggregate managed by this aggregate context
+ * @return
+ */
+ @Deprecated
+ public Aggregate getAggregate();
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireContext.java
new file mode 100644
index 0000000000..5f3973f358
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireContext.java
@@ -0,0 +1,35 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * A specialization of an AggregateContext that is able to automatically resolve references
+ * for its children using EntryPoint or Service interfaces exposed by it or, recursively, any
+ * of it parents.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface AutowireContext extends AggregateContext {
+
+ /**
+ * Returns an reference to the requested service.
+ *
+ * @param instanceInterface the type of service being requested
+ * @return a reference to the requested service or null if none can be found
+ * @throws AutowireResolutionException if an error occurs attempting to resolve an autowire
+ */
+ <T> T resolveInstance(Class<T> instanceInterface) throws AutowireResolutionException;
+
+ // todo add additional methods that allow other qualifications to be supplied
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireResolutionException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireResolutionException.java
new file mode 100644
index 0000000000..4da4206a94
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireResolutionException.java
@@ -0,0 +1,40 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * Denotes an exception while resolving an automatic wire
+ *
+ * @version $Rev$ $Date$
+ */
+public class AutowireResolutionException extends TargetException {
+
+ public AutowireResolutionException() {
+ super();
+ }
+
+ public AutowireResolutionException(String message) {
+ super(message);
+ }
+
+ public AutowireResolutionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public AutowireResolutionException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ConfigurationContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ConfigurationContext.java
new file mode 100644
index 0000000000..a57ed03ffd
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ConfigurationContext.java
@@ -0,0 +1,66 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+import org.apache.tuscany.core.builder.BuilderConfigException;
+import org.apache.tuscany.core.config.ConfigurationException;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.model.assembly.Extensible;
+
+/**
+ * Offers configuration services in the runtime. A ConfigurationContext is able to configure a model and then build the
+ * runtime representation corresponding to that model in the live system. <p/> Configuration contexts will typically be
+ * hierarchical, delegating to their parent <b>after</b> performing an operation. The parent ConfigurationContext will
+ * typically be injected into an implementation of this interface during registration.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ConfigurationContext {
+
+ /**
+ * Adds additional configuration information to a model object.
+ *
+ * @param model the model object to be configured
+ * @throws ConfigurationException
+ */
+ public void configure(Extensible model) throws ConfigurationException;
+
+ /**
+ * Decorates the supplied model object with a {@link org.apache.tuscany.core.builder.RuntimeConfiguration} that can
+ * be used to create the runtime context corresponding to the model.
+ *
+ * @param parent an AggregrateContext that will ultimately become the parent of the runtime context
+ * @param model the model object that defines the configuration to be built
+ * @throws BuilderConfigException
+ * @see org.apache.tuscany.core.builder.RuntimeConfiguration
+ */
+ public void build(AggregateContext parent, Extensible model) throws BuilderConfigException;
+
+ /**
+ * Constructs a wire from a source proxy factory to a corresponding target, potentially performing optimizations
+ *
+ * @param sourceFactory the proxy factory that will be used to create the injected proxy for a reference
+ * @param targetFactory the proxy factory that contains the invocation chains for the target side of the wire
+ * @param targetType the {@link org.apache.tuscany.core.builder.RuntimeConfiguration} implementation type for the
+ * wire target
+ * @param downScope whether the source is a shorter lived scope than the target. Used in optimization.
+ * @param targetScopeContext the scope context of the target service
+ * @throws BuilderConfigException
+ */
+ public void wire(ProxyFactory sourceFactory, ProxyFactory targetFactory, Class targetType, boolean downScope,
+ ScopeContext targetScopeContext) throws BuilderConfigException;
+
+ public void wire(ProxyFactory targetFactory, Class targetType, ScopeContext targetScopeContext) throws BuilderConfigException;
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/Context.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/Context.java
new file mode 100644
index 0000000000..2eb70e8711
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/Context.java
@@ -0,0 +1,106 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * An entity that provides an execution context for a runtime artifact
+ *
+ * @version $Rev$ $Date$
+ */
+public interface Context {
+
+ /* A configuration error state */
+ public static final int CONFIG_ERROR = -1;
+
+ /* Has not been initialized */
+ public static final int UNINITIALIZED = 0;
+
+ /* In the process of being configured and initialized */
+ public static final int INITIALIZING = 1;
+
+ /* Instantiated and configured */
+ public static final int INITIALIZED = 2;
+
+ /* Configured and initialized */
+ public static final int RUNNING = 4;
+
+ /* In the process of being shutdown */
+ public static final int STOPPING = 5;
+
+ /* Has been shutdown and removed from the module */
+ public static final int STOPPED = 6;
+
+ /* In an error state */
+ public static final int ERROR = 7;
+
+ /**
+ * Returns the name of the context
+ */
+ public String getName();
+
+ /**
+ * Sets the name of the context
+ */
+ public void setName(String name);
+
+ /**
+ * Returns the lifecycle state
+ *
+ * @see #UNINITIALIZED
+ * @see #INITIALIZING
+ * @see #INITIALIZED
+ * @see #RUNNING
+ * @see #STOPPING
+ * @see #STOPPED
+ */
+ public int getLifecycleState();
+
+ /**
+ * Sets the lifecycle state
+ *
+ * @see #UNINITIALIZED
+ * @see #INITIALIZING
+ * @see #INITIALIZED
+ * @see #RUNNING
+ * @see #STOPPING
+ * @see #STOPPED
+ */
+ public void setLifecycleState(int state);
+
+ /**
+ * Starts the container
+ *
+ * @throws CoreRuntimeException
+ */
+ public void start() throws CoreRuntimeException;
+
+ /**
+ * Stops the container
+ *
+ * @throws CoreRuntimeException
+ */
+ public void stop() throws CoreRuntimeException;
+
+ /**
+ * Registers a listener for context events
+ */
+ public void addContextListener(LifecycleEventListener listener);
+
+ /**
+ * Deregisters a context event listener
+ */
+ public void removeContextListener(LifecycleEventListener listener);
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ContextInitException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ContextInitException.java
new file mode 100644
index 0000000000..e024a98b0e
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ContextInitException.java
@@ -0,0 +1,43 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * Denotes an error encountered while initializing an instance context
+ *
+ * @version $Rev$ $Date$
+ */
+public class ContextInitException extends ContextRuntimeException {
+
+ public ContextInitException() {
+ super();
+ }
+
+ public ContextInitException(String message) {
+ super(message);
+ }
+
+ public ContextInitException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ContextInitException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ContextRuntimeException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ContextRuntimeException.java
new file mode 100644
index 0000000000..0d35f145dc
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ContextRuntimeException.java
@@ -0,0 +1,39 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * An unchecked exception encountered by an {@link org.apache.tuscany.core.context.Context}
+ *
+ * @version $Rev$ $Date$
+ */
+public class ContextRuntimeException extends CoreRuntimeException {
+
+ public ContextRuntimeException() {
+ super();
+ }
+
+ public ContextRuntimeException(String message) {
+ super(message);
+ }
+
+ public ContextRuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ContextRuntimeException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/CoreRuntimeException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/CoreRuntimeException.java
new file mode 100644
index 0000000000..a46d35c22c
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/CoreRuntimeException.java
@@ -0,0 +1,27 @@
+package org.apache.tuscany.core.context;
+
+import org.apache.tuscany.common.TuscanyRuntimeException;
+
+/**
+ * The root exception for the runtime package. Exceptions occurring in the runtime are generally non-recoverable
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class CoreRuntimeException extends TuscanyRuntimeException {
+
+ public CoreRuntimeException() {
+ super();
+ }
+
+ public CoreRuntimeException(String message) {
+ super(message);
+ }
+
+ public CoreRuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public CoreRuntimeException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/DuplicateNameException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/DuplicateNameException.java
new file mode 100644
index 0000000000..81a334d3c8
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/DuplicateNameException.java
@@ -0,0 +1,39 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * Denotes an attempt to add a context with a name equal to an existing context
+ *
+ * @version $Rev$ $Date$
+ */
+public class DuplicateNameException extends ContextRuntimeException {
+
+ public DuplicateNameException() {
+ super();
+ }
+
+ public DuplicateNameException(String message) {
+ super(message);
+ }
+
+ public DuplicateNameException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public DuplicateNameException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EntryPointContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EntryPointContext.java
new file mode 100644
index 0000000000..aef2840f9a
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EntryPointContext.java
@@ -0,0 +1,57 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * The runtime artifact representing an entry point, <code>EntryPointContext</code> manages invocation handler
+ * instances that expose service operations offered by a component in the parent aggregate. The invocation handler
+ * instance is responsible for dispatching the request down an invocation chain to the target instance. The invocation
+ * chain may contain {@link org.apache.tuscany.core.invocation.Interceptor}s and
+ * {@link org.apache.tuscany.core.invocation.MessageHandler}s that implement policies or perform mediations on the
+ * invocation.
+ * <p>
+ * Entry point contexts are used by transport binding artifacts to invoke an operation on a service. The transport
+ * binding uses an {@link java.lang.reflect.InvocationHandler} instance obtained from the <code>EntryPointContext</code>
+ * to perform the invocation as in:
+ *
+ * <pre>
+ * AggregateContext aggregateContext = ...
+ * EntryPointContext ctx = (EntryPointContext) aggregateContext.getContext(&quot;source&quot;);
+ * Assert.assertNotNull(ctx);
+ * InvocationHandler handler = (InvocationHandler) ctx.getImplementationInstance();
+ * Object response = handler.invoke(null, operation, new Object[] { param });
+ * </pre>
+ *
+ * The <code>Proxy</code> instance passed to <code>InvocationHandler</code> may be null as the client is invoking
+ * directly on the handler.
+ * <p>
+ * Alternatively, the following will return a proxy implementing the service interface exposed by the entry point:
+ *
+ * <pre>
+ * AggregateContext aggregateContext = ...
+ * EntryPointContext ctx = (EntryPointContext) aggregateContext.getContext(&quot;source&quot;);
+ * Assert.assertNotNull(ctx);
+ * HelloWorld proxy = (Helloworld) ctx.getInstance(null); // service name not necessary
+ * </pre>
+ *
+ * The proxy returned will be backed by the entry point invocation chain.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface EntryPointContext extends InstanceContext {
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EventContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EventContext.java
new file mode 100644
index 0000000000..9f7c98200a
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EventContext.java
@@ -0,0 +1,66 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * Implementations are responsible for tracking scope keys associated with the current request.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface EventContext {
+
+ /* An event type fired when a request is first serviced in the runtime */
+ public static final int REQUEST_START = 1;
+
+ /* An event type fired when the runtime finishes servicing a request */
+ public static final int REQUEST_END = 2;
+
+ /* An event type fired when a session is set for the current context */
+ public static final int SESSION_NOTIFY = 3;
+
+ /* An event type fired when a session is invalidated in the runtime */
+ public static final int SESSION_END = 4;
+
+ /* An event type fired when the current deployment unit is initialized */
+ public static final int MODULE_START = 5;
+
+ /* An event type fired when the current deployment unit is quiesced */
+ public static final int MODULE_STOP = 6;
+
+ public static final int SYSTEM_START = 7;
+
+ public static final int SYSTEM_STOP = 8;
+
+ /* An identifier type associated with an HTTP session */
+ public static final Object HTTP_SESSION = new Object();
+
+ /**
+ * Returns the unique key for the given identifier, e.g a session
+ */
+ public Object getIdentifier(Object type);
+
+ /**
+ * Sets the unique key for the given identifier, e.g a session
+ */
+ public void setIdentifier(Object type, Object identifier);
+
+ /**
+ * Clears the unique key for the given identifier, e.g a session
+ */
+ public void clearIdentifier(Object type);
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EventException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EventException.java
new file mode 100644
index 0000000000..aaf26aee69
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/EventException.java
@@ -0,0 +1,43 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * Denotes an error encountered while firing a module event
+ *
+ * @version $Rev$ $Date$
+ */
+public class EventException extends CoreRuntimeException {
+
+ public EventException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public EventException(String message) {
+ super(message);
+ }
+
+ public EventException(Throwable cause) {
+ super(cause);
+ }
+
+ public EventException() {
+ super();
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ExternalServiceContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ExternalServiceContext.java
new file mode 100644
index 0000000000..298246dc81
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ExternalServiceContext.java
@@ -0,0 +1,24 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * Manages an external service
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ExternalServiceContext extends InstanceContext {
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/InstanceContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/InstanceContext.java
new file mode 100644
index 0000000000..473762b6b0
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/InstanceContext.java
@@ -0,0 +1,75 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * Manages instances of a runtime artifact. An <code>InstanceContext</code> may contain child contexts which
+ * themselves manage implementation instances or it may be a leaf context.
+ *
+ * @see org.apache.tuscany.core.context.SimpleComponentContext
+ * @see org.apache.tuscany.core.context.AggregateContext
+ * @see org.apache.tuscany.core.context.EntryPointContext
+ * @see org.apache.tuscany.core.context.ExternalServiceContext
+ *
+ * @version $Rev$ $Date$
+ */
+public interface InstanceContext extends Context {
+
+ /**
+ * Returns the instance associated with the requested name, which may be in a simple or compound form. Simple (i.e.
+ * leaf) contexts will return an instance associated with the service name part of the compound name, which may be
+ * null.
+ * <p>
+ * Aggregate contexts will return an instance (likely a proxy) of a contained entry point context. In this case, the
+ * port name on the qualified name will correspond to the aggregate context name and the part name will be used to
+ * retrieve the contained entry point context. The latter may be null. If the contained context is not an entry
+ * point context, an exception will be thrown.
+ *
+ * @param qName a qualified name of the requested instance
+ * @return the implementation instance or a proxy to it
+ * @throws TargetException if an error occurs retrieving the instance or the requested component is not an entry
+ * point.
+ *
+ * @see AggregateContext
+ * @see org.apache.tuscany.model.assembly.EntryPoint
+ */
+ public Object getInstance(QualifiedName qName) throws TargetException;
+
+ /**
+ * Returns an instance associated with the requested name without notifying <code>ContextEventListener</code>s
+ * that may be registered with this context on instance creation. Note that {@link #getInstance(QualifiedName)}
+ * should generally be called and this method is only provided as an optimization for particular circumstances.
+ *
+ * @param qName a qualified name of the requested instance
+ * @param notify whether to notify <code>ContextEventListener</code>s
+ * @return the instance or a proxy to it
+ * @throws TargetException if an error occurs retrieving the instance or proxy
+ * @see LifecycleEventListener
+ */
+ public Object getInstance(QualifiedName qName, boolean notify) throws TargetException;
+
+ /**
+ * Returns the implementation instance associated witht he component. An implementation instance does not
+ * have a proxy invocation chainXXX
+ * @return
+ * @throws TargetException
+ */
+ public Object getImplementationInstance() throws TargetException;
+
+ public Object getImplementationInstance(boolean notify) throws TargetException;
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/InvalidNameException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/InvalidNameException.java
new file mode 100644
index 0000000000..65c709e569
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/InvalidNameException.java
@@ -0,0 +1,43 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * Denotes an invalid name
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidNameException extends ContextRuntimeException {
+
+ public InvalidNameException() {
+ super();
+ }
+
+ public InvalidNameException(String message) {
+ super(message);
+ }
+
+ public InvalidNameException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvalidNameException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/LifecycleEventListener.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/LifecycleEventListener.java
new file mode 100644
index 0000000000..78962b53b4
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/LifecycleEventListener.java
@@ -0,0 +1,32 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+import java.util.EventListener;
+
+/**
+ * Callback interface for receiving instance context lifecycle events
+ *
+ * @version $Rev$ $Date$
+ */
+public interface LifecycleEventListener extends EventListener {
+
+ /**
+ * Notifies the listener that a new component context was created
+ */
+ public void onInstanceCreate(Context component);
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/QualifiedName.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/QualifiedName.java
new file mode 100644
index 0000000000..ad71721b75
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/QualifiedName.java
@@ -0,0 +1,83 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * An evaluated name consisting of a part/port pair. In the runtime, a part generally 'contains' or 'provides' ports
+ * such as a module component/entry point or a component/service pair.
+ *
+ * @version $Rev$ $Date$
+ */
+public class QualifiedName {
+
+ private String qName;
+
+ private String partName;
+
+ private String portName;
+
+ public static final String NAME_SEPARATOR = "/";
+
+ /**
+ * Constructs a new qualified name
+ *
+ * @throws InvalidNameException if the name is in an invalid format
+ */
+ public QualifiedName(String qualifiedName) throws InvalidNameException {
+ assert (qualifiedName != null) : "Name was null";
+ int pos = qualifiedName.indexOf(QualifiedName.NAME_SEPARATOR);
+ switch (pos) {
+ case -1:
+ partName = qualifiedName;
+ break;
+ case 0:
+ throw new InvalidNameException(qualifiedName);
+ default:
+ partName = qualifiedName.substring(0, pos);
+ portName = qualifiedName.substring(pos + 1);
+ break;
+ }
+ qName = qualifiedName;
+ }
+
+ /**
+ * Returns the parsed part name
+ */
+ public String getPartName() {
+ return partName;
+ }
+
+ /**
+ * Returns the parsed port name if the original is of the compound for part/port
+ */
+ public String getPortName() {
+ return portName;
+ }
+
+ /**
+ * Returns the full part/port name pair
+ *
+ * @return
+ */
+ public String getQualifiedName() {
+ return qName;
+ }
+
+ public String toString() {
+ return qName;
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/RuntimeEventListener.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/RuntimeEventListener.java
new file mode 100644
index 0000000000..e90f30b9cc
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/RuntimeEventListener.java
@@ -0,0 +1,36 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+import java.util.EventListener;
+
+/**
+ * Listeners observe events fired in the SCA runtime.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface RuntimeEventListener extends EventListener {
+
+ /**
+ * A method called when an event for which the <tt>Listener</tt> class is registered to observe is fired in the runtime
+ *
+ * @param type the event type identifier
+ * @param message the event message
+ * @throws EventException if an error occurs processing the event
+ */
+ public void onEvent(int type, Object message) throws EventException;
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeAwareContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeAwareContext.java
new file mode 100644
index 0000000000..565d7b49a6
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeAwareContext.java
@@ -0,0 +1,31 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+import java.util.Map;
+
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * Denotes an aggregate context that supports scopes
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ScopeAwareContext extends AggregateContext {
+
+ /**
+ * Returns an immutable collection of scopes keyed by type for the aggregate context
+ */
+ public Map<Scope, ScopeContext> getScopeContexts();
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java
new file mode 100644
index 0000000000..abda942c88
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java
@@ -0,0 +1,72 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+import java.util.List;
+
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+
+/**
+ * Manages the lifecycle and visibility of <code>InstanceContext</code>s.
+ *
+ * @see org.apache.tuscany.core.context.InstanceContext
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ScopeContext extends InstanceContext, RuntimeEventListener {
+
+ /**
+ * Returns whether implementation instances may be held for the duration of an invocation
+ */
+ public boolean isCacheable();
+
+ /**
+ * Registers the runtime configurations used to construct instance contexts for the scope
+ */
+ public void registerConfigurations(List<RuntimeConfiguration<InstanceContext>> configurations);
+
+ /**
+ * Adds a runtime configuration to the scope
+ */
+ public void registerConfiguration(RuntimeConfiguration<InstanceContext> configuration);
+
+ /**
+ * Returns a context bound to the given name or null if the component does not exist. The returned context is bound
+ * to a key determined from the thread context.
+ */
+ public InstanceContext getContext(String name);
+
+ /**
+ * Returns a context bound to the given name and scoped to the given key or null if the context does not exist
+ */
+ public InstanceContext getContextByKey(String name, Object key);
+
+ /**
+ * Removes a context with the given name, determining the scope key from the thread context
+ *
+ * @throws ScopeRuntimeException
+ */
+ public void removeContext(String name) throws ScopeRuntimeException;
+
+ /**
+ * Removes a context bound to the given name and scope key
+ *
+ * @throws ScopeRuntimeException
+ */
+ public void removeContextByKey(String name, Object key) throws ScopeRuntimeException;
+
+} \ No newline at end of file
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeIdentifier.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeIdentifier.java
new file mode 100644
index 0000000000..38a847295c
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeIdentifier.java
@@ -0,0 +1,33 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * 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.container.module.EventContext
+ */
+public interface ScopeIdentifier {
+
+ /**
+ * Returns the scope id for the request.
+ */
+ public Object getIdentifier();
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeInitializationException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeInitializationException.java
new file mode 100644
index 0000000000..6ef5bfe9dd
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeInitializationException.java
@@ -0,0 +1,42 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * Denotes an initialization exception thrown by a scope container
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScopeInitializationException extends ScopeRuntimeException {
+
+ public ScopeInitializationException() {
+ super();
+ }
+
+ public ScopeInitializationException(String message) {
+ super(message);
+ }
+
+ public ScopeInitializationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ScopeInitializationException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeRuntimeException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeRuntimeException.java
new file mode 100644
index 0000000000..5022f7589d
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeRuntimeException.java
@@ -0,0 +1,43 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * Denotes a general runtime exception encountered by a scope container
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScopeRuntimeException extends CoreRuntimeException {
+
+ public ScopeRuntimeException() {
+ super();
+ }
+
+ public ScopeRuntimeException(String message) {
+ super(message);
+ }
+
+ public ScopeRuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ScopeRuntimeException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeStrategy.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeStrategy.java
new file mode 100644
index 0000000000..b648fc2dcc
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeStrategy.java
@@ -0,0 +1,43 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+import java.util.Map;
+
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * Implementations provide scope container creation facilities and scope semantics to the runtime
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ScopeStrategy {
+
+ /* Denotes an undefined scope */
+ public static final int SCOPE_NOT_FOUND = -3;
+
+ /**
+ * Creates and returns new instances of configured scope containers
+ */
+ public Map<Scope, ScopeContext> createScopes(EventContext eventContext);
+
+ /**
+ * Determines whether a wire proceeds from a source of higher scope to a target of lesser scope
+ */
+ public boolean downScopeReference(Scope sourceScope, Scope targetScope);
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ServiceNotFoundException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ServiceNotFoundException.java
new file mode 100644
index 0000000000..253909d7fa
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/ServiceNotFoundException.java
@@ -0,0 +1,42 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+import org.osoa.sca.ServiceUnavailableException;
+
+/**
+ * Denotes the specific case where a service was not found at runtime
+ *
+ * @version $Rev$ $Date$
+ */
+public class ServiceNotFoundException extends ServiceUnavailableException {
+
+ public ServiceNotFoundException() {
+ super();
+ }
+
+ public ServiceNotFoundException(String message) {
+ super(message);
+ }
+
+ public ServiceNotFoundException(Throwable cause) {
+ super(cause);
+ }
+
+ public ServiceNotFoundException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/SimpleComponentContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/SimpleComponentContext.java
new file mode 100644
index 0000000000..d35a3712a0
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/SimpleComponentContext.java
@@ -0,0 +1,36 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * A runtime entity that manages a non-aggregate (i.e. leaf-type) instance.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface SimpleComponentContext extends InstanceContext {
+
+ /**
+ * Returns whether a the context should be eagerly initialized
+ */
+ public boolean isEagerInit();
+
+ /**
+ * Returns whether a the context should be called back when its scope ends
+ */
+ public boolean isDestroyable();
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/SystemAggregateContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/SystemAggregateContext.java
new file mode 100644
index 0000000000..afb8499104
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/SystemAggregateContext.java
@@ -0,0 +1,36 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+import org.apache.tuscany.core.config.ConfigurationException;
+
+/**
+ * Marker type for system aggregate contexts
+ *
+ * @version $Rev$ $Date$
+ */
+public interface SystemAggregateContext extends AutowireContext, ScopeAwareContext, ConfigurationContext {
+
+ /**
+ * Register a simple Java Object as a system component.
+ * This is primarily intended for use by bootstrap code to create the initial
+ * configuration components.
+ *
+ * @param name the name of the resulting component
+ * @param instance the Object that will become the component's implementation
+ * @throws ConfigurationException
+ */
+ void registerJavaObject(String name, Object instance) throws ConfigurationException;
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/TargetException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/TargetException.java
new file mode 100644
index 0000000000..dd39d06aa1
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/TargetException.java
@@ -0,0 +1,42 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context;
+
+/**
+ * Denotes an error while performing an operation on a target component implementation instance or proxy
+ *
+ * @version $Rev$ $Date$
+ */
+public class TargetException extends CoreRuntimeException {
+
+ public TargetException() {
+ super();
+ }
+
+ public TargetException(String message) {
+ super(message);
+ }
+
+ public TargetException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public TargetException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractAggregateContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractAggregateContext.java
new file mode 100644
index 0000000000..9ee1878625
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractAggregateContext.java
@@ -0,0 +1,652 @@
+package org.apache.tuscany.core.context.impl;
+
+import static org.apache.tuscany.core.context.EventContext.HTTP_SESSION;
+import static org.apache.tuscany.core.context.EventContext.REQUEST_END;
+import static org.apache.tuscany.core.context.EventContext.SESSION_NOTIFY;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.wsdl.Part;
+
+import org.apache.tuscany.common.monitor.MonitorFactory;
+import org.apache.tuscany.core.builder.BuilderConfigException;
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.config.ConfigurationException;
+import org.apache.tuscany.core.context.AbstractContext;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.AutowireContext;
+import org.apache.tuscany.core.context.ConfigurationContext;
+import org.apache.tuscany.core.context.ContextInitException;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.DuplicateNameException;
+import org.apache.tuscany.core.context.EntryPointContext;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.EventException;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.RuntimeEventListener;
+import org.apache.tuscany.core.context.ScopeAwareContext;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.core.context.ScopeRuntimeException;
+import org.apache.tuscany.core.context.ScopeStrategy;
+import org.apache.tuscany.core.context.SimpleComponentContext;
+import org.apache.tuscany.core.context.TargetException;
+import org.apache.tuscany.core.context.scope.DefaultScopeStrategy;
+import org.apache.tuscany.core.invocation.InvocationConfiguration;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.invocation.spi.ProxyInitializationException;
+import org.apache.tuscany.core.system.annotation.Autowire;
+import org.apache.tuscany.core.system.annotation.ParentContext;
+import org.apache.tuscany.model.assembly.Aggregate;
+import org.apache.tuscany.model.assembly.Component;
+import org.apache.tuscany.model.assembly.EntryPoint;
+import org.apache.tuscany.model.assembly.Extensible;
+import org.apache.tuscany.model.assembly.ExternalService;
+import org.apache.tuscany.model.assembly.Module;
+import org.apache.tuscany.model.assembly.Scope;
+import org.apache.tuscany.model.assembly.ComponentImplementation;
+import org.apache.tuscany.model.assembly.impl.AssemblyFactoryImpl;
+
+/**
+ * The base implementation of an aggregate context
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractAggregateContext extends AbstractContext implements AutowireContext, ScopeAwareContext {
+
+ public static final int DEFAULT_WAIT = 1000 * 60;
+
+ // ----------------------------------
+ // Fields
+ // ----------------------------------
+
+ // The parent context, if one exists
+ @ParentContext
+ protected AggregateContext parentContext;
+
+ // The parent configuration context, if one exists
+ @Autowire(required = false)
+ protected ConfigurationContext configurationContext;
+
+ // The system monitor factory
+ @Autowire(required = false)
+ protected MonitorFactory monitorFactory;
+
+ // The logical model representing the module assembly
+ // protected ModuleComponent moduleComponent;
+ protected Module module;
+
+ protected Map<String, RuntimeConfiguration<InstanceContext>> configurations = new HashMap();
+
+ // Factory for scope contexts
+ @Autowire(required = false)
+ protected ScopeStrategy scopeStrategy;
+
+ // The event context for associating context events to threads
+ protected EventContext eventContext;
+
+ // The scopes for this context
+ protected Map<Scope, ScopeContext> scopeContexts;
+
+ protected Map<Scope, ScopeContext> immutableScopeContexts;
+
+ // A component context name to scope context index
+ protected Map<String, ScopeContext> scopeIndex;
+
+ // Listeners for context events
+ protected List<RuntimeEventListener> listeners = new CopyOnWriteArrayList();
+
+ // Blocking latch to ensure the module is initialized exactly once prior to servicing requests
+ protected CountDownLatch initializeLatch = new CountDownLatch(1);
+
+ // Indicates whether the module context has been initialized
+ protected boolean initialized;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public AbstractAggregateContext() {
+ scopeIndex = new ConcurrentHashMap();
+ // FIXME the factory should be injected
+ module = new AssemblyFactoryImpl().createModule();
+ }
+
+ public AbstractAggregateContext(String name, AggregateContext parent, ScopeStrategy strategy, EventContext ctx,
+ ConfigurationContext configCtx, MonitorFactory factory) {
+ super(name);
+ this.scopeStrategy = strategy;
+ this.eventContext = ctx;
+ this.configurationContext = configCtx;
+ this.monitorFactory = factory;
+ scopeIndex = new ConcurrentHashMap();
+ parentContext = parent;
+ // FIXME the factory should be injected
+ module = new AssemblyFactoryImpl().createModule();
+ }
+
+ // ----------------------------------
+ // Lifecycle methods
+ // ----------------------------------
+
+ public void start() {
+ synchronized (initializeLatch) {
+ try {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Context not in UNINITIALIZED state");
+ }
+ lifecycleState = INITIALIZING;
+ initializeScopes();
+
+ Map<Scope, List<RuntimeConfiguration<SimpleComponentContext>>> configurationsByScope = new HashMap();
+ if (configurations != null) {
+ for (RuntimeConfiguration source : configurations.values()) {
+ // FIXME scopes are defined at the interface level
+ Scope sourceScope = source.getScope();
+ wireSource(source);
+ buildTarget(source);
+ scopeIndex.put(source.getName(), scopeContexts.get(sourceScope));
+ List<RuntimeConfiguration<SimpleComponentContext>> list = configurationsByScope.get(sourceScope);
+ if (list == null) {
+ list = new ArrayList();
+ configurationsByScope.put(sourceScope, list);
+ }
+ list.add(source);
+ }
+ }
+ for (EntryPoint ep : module.getEntryPoints()) {
+ registerAutowire(ep);
+ }
+ for (Component component : module.getComponents()) {
+ registerAutowire(component);
+ }
+ for (ExternalService es : module.getExternalServices()) {
+ registerAutowire(es);
+ }
+ for (Map.Entry entries : configurationsByScope.entrySet()) {
+ // register configurations with scope contexts
+ ScopeContext scope = scopeContexts.get(entries.getKey());
+ scope.registerConfigurations((List<RuntimeConfiguration<InstanceContext>>) entries.getValue());
+ }
+ initializeProxies();
+ for (ScopeContext scope : scopeContexts.values()) {
+ // register scope contexts as a listeners for events in the aggregate context
+ registerListener(scope);
+ scope.start();
+ }
+ lifecycleState = RUNNING;
+ } catch (ProxyInitializationException e) {
+ lifecycleState = ERROR;
+ ContextInitException cie = new ContextInitException(e);
+ cie.addContextName(getName());
+ throw cie;
+ } catch (ConfigurationException e) {
+ lifecycleState = ERROR;
+ throw new ContextInitException(e);
+ } catch (CoreRuntimeException e) {
+ lifecycleState = ERROR;
+ e.addContextName(getName());
+ throw e;
+ } finally {
+ initialized = true;
+ // release the latch and allow requests to be processed
+ initializeLatch.countDown();
+ }
+ }
+ }
+
+ public void stop() {
+ if (lifecycleState == STOPPED) {
+ return;
+ }
+ // need to block a start until reset is complete
+ initializeLatch = new CountDownLatch(2);
+ lifecycleState = STOPPING;
+ initialized = false;
+ if (scopeContexts != null) {
+ for (ScopeContext scope : scopeContexts.values()) {
+ try {
+ if (scope.getLifecycleState() == ScopeContext.RUNNING) {
+ scope.stop();
+ }
+ } catch (ScopeRuntimeException e) {
+ // log.error("Error stopping scope container [" + scopeContainers[i].getName() + "]", e);
+ }
+ }
+ }
+ scopeContexts = null;
+ scopeIndex.clear();
+ // allow initialized to be called
+ initializeLatch.countDown();
+ lifecycleState = STOPPED;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public void setModule(Module module) {
+ assert (module != null) : "Module cannot be null";
+ name = module.getName();
+ this.module = module;
+ }
+
+ public void setScopeStrategy(ScopeStrategy scopeStrategy) {
+ this.scopeStrategy = scopeStrategy;
+ }
+
+ public void setEventContext(EventContext eventContext) {
+ this.eventContext = eventContext;
+ }
+
+ public void setMonitorFactory(MonitorFactory factory) {
+ this.monitorFactory = factory;
+ }
+
+ public AggregateContext getParent() {
+ return parentContext;
+ }
+
+ public void registerModelObjects(List<Extensible> models) throws ConfigurationException {
+ assert (models != null) : "Model object collection was null";
+ for (Extensible model : models) {
+ registerModelObject(model);
+ }
+ }
+
+ public void registerModelObject(Extensible model) throws ConfigurationException {
+ assert (model != null) : "Model object was null";
+ initializeScopes();
+ if (configurationContext != null) {
+ try {
+ configurationContext.configure(model);
+ configurationContext.build(this, model);
+ } catch (ConfigurationException e) {
+ e.addContextName(getName());
+ throw e;
+ } catch (BuilderConfigException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+ RuntimeConfiguration<InstanceContext> configuration = null;
+ if (model instanceof Module) {
+ // merge new module definition with the existing one
+ Module oldModule = module;
+ Module newModule = (Module) model;
+ module = newModule;
+ for (Component component : newModule.getComponents()) {
+ ComponentImplementation componentImplementation = component.getComponentImplementation();
+ if (componentImplementation == null) {
+ ConfigurationException e = new ConfigurationException("Component implementation not set");
+ e.addContextName(component.getName());
+ e.addContextName(getName());
+ throw e;
+ }
+ configuration = (RuntimeConfiguration<InstanceContext>) componentImplementation.getRuntimeConfiguration();
+ if (configuration == null) {
+ ConfigurationException e = new ConfigurationException("Runtime configuration not set");
+ e.addContextName(component.getName());
+ e.addContextName(getName());
+ throw e;
+ }
+ registerConfiguration(configuration);
+ registerAutowire(component);
+ }
+ for (EntryPoint ep : newModule.getEntryPoints()) {
+ configuration = (RuntimeConfiguration<InstanceContext>) ep.getConfiguredReference().getRuntimeConfiguration();
+ if (configuration == null) {
+ ConfigurationException e = new ConfigurationException("Runtime configuration not set");
+ e.setIdentifier(ep.getName());
+ e.addContextName(getName());
+ throw e;
+ }
+ registerConfiguration(configuration);
+ registerAutowire(ep);
+ }
+ for (ExternalService service : newModule.getExternalServices()) {
+ configuration = (RuntimeConfiguration<InstanceContext>) service.getConfiguredService().getRuntimeConfiguration();
+ if (configuration == null) {
+ ConfigurationException e = new ConfigurationException("Runtime configuration not set");
+ e.setIdentifier(service.getName());
+ e.addContextName(getName());
+ throw e;
+ }
+ registerConfiguration(configuration);
+ registerAutowire(service);
+ }
+ if (lifecycleState == RUNNING) {
+ for (Component component : newModule.getComponents()) {
+ RuntimeConfiguration<InstanceContext> config = (RuntimeConfiguration<InstanceContext>) component
+ .getComponentImplementation().getRuntimeConfiguration();
+ wireSource(config);
+ buildTarget(config);
+ try {
+ if (config.getSourceProxyFactories() != null) {
+ for (ProxyFactory sourceProxyFactory : (Collection<ProxyFactory>) config.getSourceProxyFactories()
+ .values()) {
+ sourceProxyFactory.initialize();
+ }
+ }
+ if (config.getTargetProxyFactories() != null) {
+ for (ProxyFactory targetProxyFactory : (Collection<ProxyFactory>) config.getTargetProxyFactories()
+ .values()) {
+ targetProxyFactory.initialize();
+ }
+ }
+ } catch (ProxyInitializationException e) {
+ throw new ConfigurationException(e);
+ }
+
+ }
+ for (EntryPoint ep : newModule.getEntryPoints()) {
+ RuntimeConfiguration<InstanceContext> config = (RuntimeConfiguration<InstanceContext>) ep
+ .getConfiguredReference().getRuntimeConfiguration();
+ wireSource(config);
+ buildTarget(config);
+ try {
+ if (config.getSourceProxyFactories() != null) {
+ for (ProxyFactory sourceProxyFactory : (Collection<ProxyFactory>) config.getSourceProxyFactories()
+ .values()) {
+ sourceProxyFactory.initialize();
+ }
+ }
+ if (config.getTargetProxyFactories() != null) {
+ for (ProxyFactory targetProxyFactory : (Collection<ProxyFactory>) config.getTargetProxyFactories()
+ .values()) {
+ targetProxyFactory.initialize();
+ }
+ }
+ } catch (ProxyInitializationException e) {
+ throw new ConfigurationException(e);
+ }
+
+ }
+ for (ExternalService es : newModule.getExternalServices()) {
+ RuntimeConfiguration<InstanceContext> config = (RuntimeConfiguration<InstanceContext>) es
+ .getConfiguredService().getRuntimeConfiguration();
+ buildTarget(config);
+ try {
+ if (config.getSourceProxyFactories() != null) {
+ for (ProxyFactory sourceProxyFactory : (Collection<ProxyFactory>) config.getSourceProxyFactories()
+ .values()) {
+ sourceProxyFactory.initialize();
+ }
+ }
+ if (config.getTargetProxyFactories() != null) {
+ for (ProxyFactory targetProxyFactory : (Collection<ProxyFactory>) config.getTargetProxyFactories()
+ .values()) {
+ targetProxyFactory.initialize();
+ }
+ }
+ } catch (ProxyInitializationException e) {
+ throw new ConfigurationException(e);
+ }
+
+ }
+
+ }
+ // merge existing module component assets
+ module.getComponents().addAll(oldModule.getComponents());
+ module.getEntryPoints().addAll(oldModule.getEntryPoints());
+ module.getExternalServices().addAll(oldModule.getExternalServices());
+ } else {
+ if (model instanceof Component) {
+ Component component = (Component) model;
+ module.getComponents().add(component);
+ configuration = (RuntimeConfiguration<InstanceContext>) component.getComponentImplementation()
+ .getRuntimeConfiguration();
+ } else if (model instanceof EntryPoint) {
+ EntryPoint ep = (EntryPoint) model;
+ module.getEntryPoints().add(ep);
+ configuration = (RuntimeConfiguration<InstanceContext>) ep.getConfiguredReference().getRuntimeConfiguration();
+ } else if (model instanceof ExternalService) {
+ ExternalService service = (ExternalService) model;
+ module.getExternalServices().add(service);
+ configuration = (RuntimeConfiguration<InstanceContext>) service.getConfiguredService().getRuntimeConfiguration();
+ } else {
+ BuilderConfigException e = new BuilderConfigException("Unknown model type");
+ e.setIdentifier(model.getClass().getName());
+ e.addContextName(getName());
+ throw e;
+ }
+ if (configuration == null) {
+ ConfigurationException e = new ConfigurationException("Runtime configuration not set");
+ if (model instanceof Part) {
+ e.setIdentifier(((Part) model).getName());
+ }
+ e.addContextName(getName());
+ throw e;
+ }
+ registerConfiguration(configuration);
+ registerAutowire(model);
+ }
+ }
+
+ protected void registerConfiguration(RuntimeConfiguration<InstanceContext> configuration) throws ConfigurationException {
+ if (lifecycleState == RUNNING) {
+ if (scopeIndex.get(configuration.getName()) != null) {
+ throw new DuplicateNameException(configuration.getName());
+ }
+ ScopeContext scope = scopeContexts.get(configuration.getScope());
+ if (scope == null) {
+ ConfigurationException e = new ConfigurationException("Component has an unknown scope");
+ e.addContextName(configuration.getName());
+ e.addContextName(getName());
+ throw e;
+ }
+ scope.registerConfiguration(configuration);
+ scopeIndex.put(configuration.getName(), scope);
+ configurations.put(configuration.getName(), configuration); // xcv
+ } else {
+ if (configurations.get(configuration.getName()) != null) {
+ throw new DuplicateNameException(configuration.getName());
+ }
+ configurations.put(configuration.getName(), configuration);
+ }
+
+ }
+
+ public void registerListener(RuntimeEventListener listener) {
+ assert (listener != null) : "Listener cannot be null";
+ listeners.add(listener);
+ }
+
+ public void fireEvent(int eventType, Object message) throws EventException {
+ checkInit();
+ if (eventType == SESSION_NOTIFY) {
+ // update context
+ eventContext.setIdentifier(HTTP_SESSION, message);
+ } else if (eventType == REQUEST_END) {
+ // be very careful with pooled threads, ensuring threadlocals are cleaned up
+ eventContext.clearIdentifier(HTTP_SESSION);
+ }
+ for (RuntimeEventListener listener : listeners) {
+ listener.onEvent(eventType, message);
+ }
+ }
+
+ public InstanceContext getContext(String componentName) {
+ checkInit();
+ assert (componentName != null) : "Name was null";
+ ScopeContext scope = scopeIndex.get(componentName);
+ if (scope == null) {
+ return null;
+ }
+ return scope.getContext(componentName);
+
+ }
+
+ public Object getInstance(QualifiedName qName) throws TargetException {
+ return getInstance(qName, true);
+ }
+
+ public Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ assert (qName != null) : "Name was null ";
+ // use the port name to get the context since entry points ports
+ ScopeContext scope = scopeIndex.get(qName.getPortName());
+ if (scope == null) {
+ return null;
+ }
+ InstanceContext ctx = scope.getContext(qName.getPortName());
+ if (!(ctx instanceof EntryPointContext)) {
+ TargetException e = new TargetException("Target not an entry point");
+ e.setIdentifier(qName.getQualifiedName());
+ e.addContextName(name);
+ throw e;
+ }
+ return ctx.getInstance(null, notify);
+ }
+
+ public Object locateInstance(String qualifiedName) throws TargetException {
+ checkInit();
+ QualifiedName qName = new QualifiedName(qualifiedName);
+ ScopeContext scope = scopeIndex.get(qName.getPartName());
+ if (scope == null) {
+ TargetException e = new TargetException("Component not found");
+ e.setIdentifier(qualifiedName);
+ e.addContextName(getName());
+ throw e;
+ }
+ InstanceContext ctx = scope.getContext(qName.getPartName());
+ try {
+ return ctx.getInstance(qName, true);
+ } catch (TargetException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+
+ public Map<Scope, ScopeContext> getScopeContexts() {
+ initializeScopes();
+ return immutableScopeContexts;
+ }
+
+ // ----------------------------------
+ // Abstract methods
+ // ----------------------------------
+
+ /**
+ * Registers a model object as autowirable
+ *
+ * @throws ContextInitException
+ */
+ protected abstract void registerAutowire(Extensible model) throws ConfigurationException;
+
+ // ----------------------------------
+ // Protected methods
+ // ----------------------------------
+
+ /**
+ * Blocks until the module context has been initialized
+ */
+ protected void checkInit() {
+ if (!initialized) {
+ try {
+ /* block until the module has initialized */
+ boolean success = initializeLatch.await(DEFAULT_WAIT, TimeUnit.MILLISECONDS);
+ if (!success) {
+ throw new ContextInitException("Timeout waiting for module context to initialize");
+ }
+ } catch (InterruptedException e) { // should not happen
+ }
+ }
+
+ }
+
+ protected void initializeScopes() {
+ if (scopeContexts == null) {
+ if (scopeStrategy == null) {
+ scopeStrategy = new DefaultScopeStrategy();
+ }
+ scopeContexts = scopeStrategy.createScopes(eventContext);
+ immutableScopeContexts = Collections.unmodifiableMap(scopeContexts);
+ }
+ }
+
+ /**
+ * Iterates through references and delegates to the configuration context to wire them to their targets
+ */
+ protected void wireSource(RuntimeConfiguration source) {
+ Scope sourceScope = source.getScope();
+ if (source.getSourceProxyFactories() != null) {
+ for (ProxyFactory sourceFactory : ((Map<String, ProxyFactory>) source.getSourceProxyFactories()).values()) {
+ QualifiedName targetName = sourceFactory.getProxyConfiguration().getTargetName();
+ RuntimeConfiguration target = configurations.get(targetName.getPartName());
+ if (target == null) {
+ ContextInitException e = new ContextInitException("Target not found");
+ e.setIdentifier(targetName.getPartName());
+ e.addContextName(source.getName());
+ e.addContextName(name);
+ throw e;
+ }
+ // get the proxy chain for the target
+ ProxyFactory targetFactory = target.getTargetProxyFactory(sourceFactory.getProxyConfiguration().getTargetName()
+ .getPortName());
+ if (targetFactory == null) {
+ ContextInitException e = new ContextInitException("No proxy factory found for service");
+ e.setIdentifier(sourceFactory.getProxyConfiguration().getTargetName().getPortName());
+ e.addContextName(target.getName());
+ e.addContextName(source.getName());
+ e.addContextName(name);
+ throw e;
+ }
+ boolean downScope = scopeStrategy.downScopeReference(sourceScope, target.getScope());
+ configurationContext.wire(sourceFactory, targetFactory, target.getClass(), downScope, scopeContexts.get(target
+ .getScope()));
+ }
+ }
+ // wire invokers when the proxy only contains the target chain
+ if (source.getTargetProxyFactories() != null) {
+ for (ProxyFactory targetFactory : ((Map<String, ProxyFactory>) source.getTargetProxyFactories()).values()) {
+ configurationContext.wire(targetFactory, source.getClass(), scopeContexts.get(sourceScope));
+ }
+ }
+ source.prepare();
+ }
+
+ /**
+ * Signals to target side of reference configurations to initialize
+ */
+ protected void buildTarget(RuntimeConfiguration target) {
+ if (target.getTargetProxyFactories() != null) {
+ for (ProxyFactory targetFactory : ((Map<String, ProxyFactory>) target.getTargetProxyFactories()).values()) {
+ for (InvocationConfiguration iConfig : (Collection<InvocationConfiguration>) targetFactory
+ .getProxyConfiguration().getInvocationConfigurations().values()) {
+ iConfig.build();
+ }
+ }
+ }
+ }
+
+ protected void initializeProxies() throws ProxyInitializationException {
+ for (RuntimeConfiguration config : configurations.values()) {
+ if (config.getSourceProxyFactories() != null) {
+ for (ProxyFactory sourceProxyFactory : (Collection<ProxyFactory>) config.getSourceProxyFactories().values()) {
+ sourceProxyFactory.initialize();
+ }
+ }
+ if (config.getSourceProxyFactories() != null) {
+ for (ProxyFactory targetProxyFactory : (Collection<ProxyFactory>) config.getTargetProxyFactories().values()) {
+ targetProxyFactory.initialize();
+ }
+ }
+ }
+ }
+
+ /**
+ * @see org.apache.tuscany.core.context.AggregateContext#getAggregate()
+ */
+ public Aggregate getAggregate() {
+ return module;
+ }
+} \ No newline at end of file
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AggregateContextImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AggregateContextImpl.java
new file mode 100644
index 0000000000..69e0b8edfc
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AggregateContextImpl.java
@@ -0,0 +1,222 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context.impl;
+
+import org.apache.tuscany.common.monitor.MonitorFactory;
+import org.apache.tuscany.core.builder.BuilderConfigException;
+import org.apache.tuscany.core.config.ConfigurationException;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.AutowireContext;
+import org.apache.tuscany.core.context.AutowireResolutionException;
+import org.apache.tuscany.core.context.ConfigurationContext;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.core.context.ScopeStrategy;
+import org.apache.tuscany.core.context.ServiceNotFoundException;
+import org.apache.tuscany.core.context.TargetException;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.system.annotation.Autowire;
+import org.apache.tuscany.model.assembly.Extensible;
+import org.osoa.sca.ModuleContext;
+import org.osoa.sca.RequestContext;
+import org.osoa.sca.ServiceReference;
+import org.osoa.sca.ServiceUnavailableException;
+
+/**
+ * The standard implementation of an aggregate context. Autowiring is performed by delegating to the parent context.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AggregateContextImpl extends AbstractAggregateContext implements ConfigurationContext, ModuleContext {
+
+ // ----------------------------------
+ // Fields
+ // ----------------------------------
+
+ @Autowire(required = false)
+ private AutowireContext autowireContext;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public AggregateContextImpl() {
+ super();
+ eventContext = new EventContextImpl();
+ }
+
+ public AggregateContextImpl(String name, AggregateContext parent, ScopeStrategy strategy, EventContext ctx,
+ ConfigurationContext configCtx, MonitorFactory factory) {
+ super(name, parent, strategy, ctx, configCtx, factory);
+ }
+
+ public AggregateContextImpl(String name, AggregateContext parent, AutowireContext autowireContext, ScopeStrategy strategy,
+ EventContext ctx, ConfigurationContext configCtx, MonitorFactory factory) {
+ super(name, parent, strategy, ctx, configCtx, factory);
+ this.autowireContext = autowireContext;
+ }
+
+ // ----------------------------------
+ // ModuleContext methods
+ // ----------------------------------
+
+ private String uri;
+
+ public String getURI() {
+ return uri;
+ }
+
+ public void setURI(String uri) {
+ this.uri = uri;
+ }
+
+ public Object locateService(String qualifiedName) throws ServiceUnavailableException {
+ checkInit();
+ QualifiedName qName = new QualifiedName(qualifiedName);
+ ScopeContext scope = scopeIndex.get(qName.getPartName());
+ if (scope == null) {
+ throw new ServiceNotFoundException(qualifiedName);
+ }
+ InstanceContext ctx = scope.getContext(qName.getPartName());
+ try {
+ Object o = ctx.getInstance(qName, true);
+ if (o == null) {
+ throw new ServiceUnavailableException(qualifiedName);
+ }
+ return o;
+ } catch (TargetException e) {
+ e.addContextName(getName());
+ throw new ServiceUnavailableException(e);
+ }
+ }
+
+ public ServiceReference createServiceReference(String serviceName) {
+ throw new UnsupportedOperationException();
+ }
+
+ public RequestContext getRequestContext() {
+ throw new UnsupportedOperationException();
+ }
+
+ public ServiceReference createServiceReferenceForSession(Object self) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ServiceReference createServiceReferenceForSession(Object self, String serviceName) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ServiceReference newSession(String serviceName) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ServiceReference newSession(String serviceName, Object sessionId) {
+ throw new UnsupportedOperationException();
+ }
+
+ // ----------------------------------
+ // AutowireContext methods
+ // ----------------------------------
+
+ public <T> T resolveInstance(Class<T> instanceInterface) throws AutowireResolutionException {
+ if (MonitorFactory.class.equals(instanceInterface)) {
+ return instanceInterface.cast(monitorFactory);
+ } else if (ConfigurationContext.class.equals(instanceInterface)) {
+ return instanceInterface.cast(this);
+ } else if (AutowireContext.class.equals(instanceInterface)) {
+ return instanceInterface.cast(this);
+ }
+ if (autowireContext != null) {
+ try {
+ return autowireContext.resolveInstance(instanceInterface);
+ } catch (AutowireResolutionException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected void registerAutowire(Extensible model) {
+ // this context only delegates autowiring
+ }
+
+ // ----------------------------------
+ // ConfigurationContext methods
+ // ----------------------------------
+
+ public void configure(Extensible model) throws ConfigurationException {
+ if (configurationContext != null) {
+ try {
+ configurationContext.configure(model);
+ } catch (ConfigurationException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+ }
+
+ public void build(AggregateContext parent, Extensible model) throws BuilderConfigException {
+ if (configurationContext != null) {
+ try {
+ configurationContext.build(parent, model);
+ } catch (BuilderConfigException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+ }
+
+ public void wire(ProxyFactory sourceFactory, ProxyFactory targetFactory, Class targetType, boolean downScope,
+ ScopeContext targetScopeContext) throws BuilderConfigException {
+ if (configurationContext != null) {
+ try {
+ configurationContext.wire(sourceFactory, targetFactory, targetType, downScope, targetScopeContext);
+ } catch (BuilderConfigException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+ }
+
+ public void wire(ProxyFactory targetFactory, Class targetType, ScopeContext targetScopeContext) throws BuilderConfigException {
+ if (configurationContext != null) {
+ try {
+ configurationContext.wire(targetFactory, targetType, targetScopeContext);
+ } catch (BuilderConfigException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+ }
+
+ // ----------------------------------
+ // InstanceContext methods
+ // ----------------------------------
+
+ public Object getImplementationInstance() throws TargetException {
+ return this;
+ }
+
+ public Object getImplementationInstance(boolean notify) throws TargetException {
+ return this;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EntryPointContextImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EntryPointContextImpl.java
new file mode 100644
index 0000000000..791ce6b8a5
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EntryPointContextImpl.java
@@ -0,0 +1,112 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context.impl;
+
+import java.lang.reflect.InvocationHandler;
+
+import org.apache.tuscany.core.context.AbstractContext;
+import org.apache.tuscany.core.context.ContextInitException;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.EntryPointContext;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.TargetException;
+import org.apache.tuscany.core.invocation.jdk.JDKInvocationHandler;
+import org.apache.tuscany.core.invocation.spi.ProxyCreationException;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.message.MessageFactory;
+
+/**
+ * The default implementation of an entry point context
+ *
+ * @version $Rev$ $Date$
+ */
+public class EntryPointContextImpl extends AbstractContext implements EntryPointContext {
+
+ private MessageFactory messageFactory;
+
+ private ProxyFactory proxyFactory;
+
+ private Object target;
+
+ private InvocationHandler invocationHandler;
+
+ // a proxy implementing the service exposed by the entry point backed by the invocation handler
+ private Object proxy;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ /**
+ * Creates a new entry point
+ *
+ * @param name the entry point name
+ * @param proxyFactory the proxy factory containing the invocation chains for the entry point
+ * @param parentContext the containing aggregate of the entry point
+ * @param messageFactory a factory for generating invocation messages
+ * @throws ContextInitException if an error occurs creating the entry point
+ */
+ public EntryPointContextImpl(String name, ProxyFactory proxyFactory, MessageFactory messageFactory)
+ throws ContextInitException {
+ super(name);
+ assert (proxyFactory != null) : "Proxy factory was null";
+ assert (messageFactory != null) : "Message factory was null";
+ this.proxyFactory = proxyFactory;
+ this.messageFactory = messageFactory;
+ invocationHandler = new JDKInvocationHandler(messageFactory, proxyFactory.getProxyConfiguration()
+ .getInvocationConfigurations());
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public Object getInstance(QualifiedName qName) throws TargetException {
+ if (proxy == null) {
+ try {
+ proxy = proxyFactory.createProxy();
+ } catch (ProxyCreationException e) {
+ TargetException te = new TargetException(e);
+ te.addContextName(getName());
+ throw te;
+ }
+ }
+ return proxy;
+ }
+
+ public Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ return getInstance(qName);
+ }
+
+ public void start() throws ContextInitException {
+ lifecycleState = RUNNING;
+ }
+
+ public void stop() throws CoreRuntimeException {
+ lifecycleState = STOPPED;
+ }
+
+ // ----------------------------------
+ // InstanceContext methods
+ // ----------------------------------
+
+ public Object getImplementationInstance() throws TargetException {
+ return invocationHandler;
+ }
+
+ public Object getImplementationInstance(boolean notify) throws TargetException {
+ return getImplementationInstance();
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EventContextImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EventContextImpl.java
new file mode 100644
index 0000000000..accf6b3030
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EventContextImpl.java
@@ -0,0 +1,77 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.ScopeIdentifier;
+
+/**
+ * An implementation of an {@link org.apache.tuscany.core.context.EventContext} that handles event-to-thread associations using an
+ * <code>InheritableThreadLocal</code>
+ *
+ * @version $Rev$ $Date$
+ */
+public class EventContextImpl implements EventContext {
+
+ // @TODO design a proper propagation strategy for creating new threads
+ /*
+ * a map ( associated with the current thread) of scope identifiers keyed on the event context id type. the scope identifier
+ * may be a {@link ScopeIdentifier} or an opaque id
+ */
+ private ThreadLocal<Map> eventContext = new InheritableThreadLocal();
+
+ public Object getIdentifier(Object type) {
+ Map map = eventContext.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 map = eventContext.get();
+ if (map == null) {
+ map = new HashMap();
+ eventContext.set(map);
+ }
+ map.put(type, identifier);
+ }
+
+ public void clearIdentifier(Object type) {
+ if (type == null) {
+ return;
+ }
+ Map map = eventContext.get();
+ if (map != null) {
+ map.remove(type);
+ }
+ }
+
+ public EventContextImpl() {
+ super();
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/ExternalServiceContextImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/ExternalServiceContextImpl.java
new file mode 100644
index 0000000000..a73081ef66
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/impl/ExternalServiceContextImpl.java
@@ -0,0 +1,92 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context.impl;
+
+import org.apache.tuscany.core.builder.ObjectFactory;
+import org.apache.tuscany.core.context.AbstractContext;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.ExternalServiceContext;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.TargetException;
+import org.apache.tuscany.core.invocation.spi.ProxyCreationException;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+
+/**
+ * The default implementation of an external service context
+ *
+ * @version $Rev$ $Date$
+ */
+public class ExternalServiceContextImpl extends AbstractContext implements ExternalServiceContext {
+
+ private ProxyFactory targetProxyFactory;
+
+ private ObjectFactory targetInstanceFactory;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ /**
+ * Creates an external service context
+ *
+ * @param name the name of the external service
+ * @param targetProxyFactory the factory which creates proxies implementing the configured service interface for the
+ * external service. There is always only one proxy factory as an external service is configured with one
+ * service
+ * @param targetInstanceFactory the object factory that creates an artifact capabile of communicating over the
+ * binding transport configured on the external service. The object factory may implement a caching strategy.
+ */
+ public ExternalServiceContextImpl(String name, ProxyFactory targetProxyFactory, ObjectFactory targetInstanceFactory) {
+ super(name);
+ assert (targetProxyFactory != null) : "Target proxy factory was null";
+ assert (targetInstanceFactory != null) : "Target instance factory was null";
+ this.targetProxyFactory = targetProxyFactory;
+ this.targetInstanceFactory = targetInstanceFactory;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public Object getInstance(QualifiedName qName) throws TargetException {
+ try {
+ return targetProxyFactory.createProxy();
+ // TODO do we cache the proxy, (assumes stateful capabilities will be provided in an interceptor)
+ } catch (ProxyCreationException e) {
+ TargetException te = new TargetException(e);
+ te.addContextName(getName());
+ throw te;
+ }
+ }
+
+ public Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ return getInstance(qName);
+ }
+
+ public void start() throws CoreRuntimeException {
+ lifecycleState = RUNNING;
+ }
+
+ public void stop() throws CoreRuntimeException {
+ lifecycleState = STOPPED;
+ }
+
+ public Object getImplementationInstance() throws TargetException {
+ return targetInstanceFactory.getInstance();
+ }
+
+ public Object getImplementationInstance(boolean notify) throws TargetException {
+ return getImplementationInstance();
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java
new file mode 100644
index 0000000000..449af4bdf8
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java
@@ -0,0 +1,158 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context.scope;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.AbstractContext;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.Context;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.core.context.TargetException;
+
+/**
+ * Implements functionality common to scope contexts.
+ * <p>
+ * <b>NB: </b>Minimal synchronization is performed, particularly for initializing and destroying scopes, and it is
+ * assumed the scope container will block requests until these operations have completed.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractScopeContext extends AbstractContext implements ScopeContext{
+ // ----------------------------------
+ // Fields
+ // ----------------------------------
+
+ // The collection of runtime configurations for the scope
+ protected Map<String, RuntimeConfiguration<InstanceContext>> runtimeConfigurations = new ConcurrentHashMap();
+
+ // The event context the scope container is associated with
+ protected EventContext eventContext;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public AbstractScopeContext(EventContext eventContext) {
+ assert (eventContext != null) : "Event context was null";
+ this.eventContext = eventContext;
+ }
+
+ // ----------------------------------
+ // Lifecycle methods
+ // --------------------------_--------
+
+ public synchronized void start() {
+ }
+
+ public synchronized void stop() {
+ }
+
+
+ // ----------------------------------
+ // Scope methods
+ // ----------------------------------
+
+ public void registerConfigurations(List<RuntimeConfiguration<InstanceContext>> configurations) {
+ for (RuntimeConfiguration<InstanceContext> configuration : configurations) {
+ runtimeConfigurations.put(configuration.getName(), configuration);
+ }
+ }
+
+ public Object getInstance(QualifiedName qName) throws TargetException {
+ Object instance = null;
+ InstanceContext context = getContext(qName.getPartName());
+ if (context == null) {
+ TargetException e = new TargetException("Target not found");
+ e.setIdentifier(qName.getQualifiedName());
+ throw e;
+ }
+ return context.getInstance(qName);
+ }
+
+ public Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ return getInstance(qName);
+ }
+
+ //----------------------------------
+ // InstanceContext methods
+ //----------------------------------
+
+ public Object getImplementationInstance() throws TargetException{
+ return this;
+ }
+
+ public Object getImplementationInstance(boolean notify) throws TargetException{
+ return this;
+ }
+
+ // ----------------------------------
+ // Protected methods
+ // ----------------------------------
+
+ protected EventContext getEventContext() {
+ return eventContext;
+ }
+
+ /**
+ * Notfies instances that are associated with a context and configured to receive callbacks that the context is
+ * being destroyed in reverse order
+ *
+ * @param key the context key
+ */
+ protected void notifyInstanceShutdown(Object key) {
+ InstanceContext[] contexts = getShutdownContexts(key);
+ if ((contexts == null) || (contexts.length < 1)) {
+ return;
+ }
+ // shutdown destroyable instances in reverse instantiation order
+ for (int i = contexts.length - 1; i >= 0; i--) {
+ InstanceContext context = contexts[i];
+
+ if (context.getLifecycleState() == Context.RUNNING) {
+ synchronized (context) {
+ context.setLifecycleState(Context.STOPPING);
+ removeContextByKey(context.getName(), key);
+ try {
+ context.stop();
+ } catch (TargetException e) {
+ // TODO send a monitoring event
+ // log.error("Error releasing instance [" + context.getName() + "]",e);
+ }
+ }
+ }
+ }
+ }
+
+ protected void checkInit() {
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Scope not running [" + lifecycleState + "]");
+ }
+ }
+
+ /**
+ * Returns an array of contexts that need to be notified of scope shutdown. The array must be in the order in which
+ * component contexts were created
+ */
+ protected abstract InstanceContext[] getShutdownContexts(Object key);
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeStrategy.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeStrategy.java
new file mode 100644
index 0000000000..f89d09196d
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeStrategy.java
@@ -0,0 +1,67 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context.scope;
+
+import org.apache.tuscany.core.context.ScopeStrategy;
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * Implements basic scope strategy functionality
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractScopeStrategy implements ScopeStrategy {
+
+ public AbstractScopeStrategy() {
+ }
+
+ /**
+ * Determines legal scope references according to standard SCA scope rules
+ *
+ * @param pReferrer the scope of the component making the reference
+ * @param pReferee the scope of the component being referred to
+ */
+ public boolean downScopeReference(Scope pReferrer, Scope pReferee) {
+ if (pReferrer == Scope.UNDEFINED || pReferee == Scope.UNDEFINED) {
+ return false;
+ }
+ if (pReferee == pReferrer){
+ return false;
+ }else if(pReferrer == Scope.INSTANCE){
+ return false;
+ }else if(pReferee == Scope.INSTANCE){
+ return true;
+ }else if (pReferrer == Scope.REQUEST && pReferee == Scope.SESSION){
+ return false;
+ }else if (pReferrer == Scope.REQUEST && pReferee == Scope.MODULE){
+ return false;
+// }else if (pReferrer == Scope.SESSION && pReferee == Scope.REQUEST){
+// return true;
+ }else if (pReferrer == Scope.SESSION && pReferee == Scope.MODULE){
+ return false;
+// }else if (pReferrer == Scope.MODULE){
+// return true;
+ }else{
+ return true;
+ }
+ //FIXME Jim this does not work with enumerations, what does it mean to have a scope <0?
+// } else if ((pReferrer < 0) || (pReferee < 0)) {
+// return false;
+// }
+//
+// return (pReferrer > pReferee);
+// return pReferrer != pReferee;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AggregateScopeContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AggregateScopeContext.java
new file mode 100644
index 0000000000..19f554a625
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AggregateScopeContext.java
@@ -0,0 +1,184 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context.scope;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.AbstractContext;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.EventException;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.core.context.ScopeInitializationException;
+import org.apache.tuscany.core.context.ScopeRuntimeException;
+import org.apache.tuscany.core.context.TargetException;
+
+/**
+ * Manages the lifecycle of aggregate component contexts, i.e. contexts which contain child contexts
+ *
+ * @see org.apache.tuscany.core.context.AggregateContext
+ * @version $Rev$ $Date$
+ */
+public class AggregateScopeContext extends AbstractContext implements ScopeContext {
+
+ // ----------------------------------
+ // Fields
+ // ----------------------------------
+
+ private EventContext eventContext;
+
+ private List<RuntimeConfiguration<InstanceContext>> configs = new ArrayList();
+
+ // Aggregate component contexts in this scope keyed by name
+ private Map<String, AggregateContext> contexts = new ConcurrentHashMap();
+
+ // indicates if a module start event has been previously propagated so child contexts added after can be notified
+ private boolean moduleScopeStarted;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public AggregateScopeContext(EventContext eventContext) {
+ assert (eventContext != null) : "Event context was null";
+ this.eventContext = eventContext;
+ name = "Aggregate Scope";
+ }
+
+ // ----------------------------------
+ // Lifecycle methods
+ // ----------------------------------
+
+ public void start() throws ScopeInitializationException {
+ for (RuntimeConfiguration<InstanceContext> configuration : configs) {
+ InstanceContext context = configuration.createInstanceContext();
+ if (!(context instanceof AggregateContext)) {
+ ScopeInitializationException e = new ScopeInitializationException("Context not an aggregate type");
+ e.addContextName(context.getName());
+ throw e;
+ }
+ AggregateContext aggregateCtx = (AggregateContext) context;
+ aggregateCtx.start();
+ contexts.put(aggregateCtx.getName(), aggregateCtx);
+ }
+ lifecycleState = RUNNING;
+ }
+
+ public void stop() throws ScopeRuntimeException {
+ for (AggregateContext context : contexts.values()) {
+ context.stop();
+ }
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public void registerConfigurations(List<RuntimeConfiguration<InstanceContext>> configurations) {
+ this.configs = configurations;
+ }
+
+ public void registerConfiguration(RuntimeConfiguration<InstanceContext> configuration) {
+ assert (configuration != null) : "Configuration was null";
+ configs.add(configuration);
+ if (lifecycleState == RUNNING) {
+ InstanceContext context = configuration.createInstanceContext();
+ if (!(context instanceof AggregateContext)) {
+ ScopeInitializationException e = new ScopeInitializationException("Context not an aggregate type");
+ e.setIdentifier(context.getName());
+ throw e;
+ }
+ AggregateContext aggregateCtx = (AggregateContext) context;
+ aggregateCtx.start();
+ if (moduleScopeStarted) {
+ aggregateCtx.fireEvent(EventContext.MODULE_START, null);
+ }
+ contexts.put(aggregateCtx.getName(), aggregateCtx);
+ }
+ }
+
+ public boolean isCacheable() {
+ return false;
+ }
+
+ public Object getInstance(QualifiedName qName) throws TargetException {
+ Object instance = null;
+ InstanceContext context = getContext(qName.getPartName());
+ if (context == null) {
+ TargetException e = new TargetException("Component not found");
+ e.setIdentifier(qName.getQualifiedName());
+ throw e;
+ }
+ return context.getInstance(qName);
+ }
+
+ public Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ return getInstance(qName);
+ }
+
+ public InstanceContext getContext(String ctxName) {
+ checkInit();
+ return contexts.get(ctxName);
+ }
+
+ public InstanceContext getContextByKey(String ctxName, Object key) {
+ return getContext(ctxName);
+ }
+
+ public void removeContext(String ctxName) throws ScopeRuntimeException {
+ InstanceContext context = contexts.remove(ctxName);
+ if (context != null) {
+ context.stop();
+ }
+ }
+
+ public void removeContextByKey(String ctxName, Object key) throws ScopeRuntimeException {
+ }
+
+ public void onEvent(int type, Object message) throws EventException {
+ if (type == EventContext.MODULE_START) {
+ // track module starting so that aggregate contexts registered after the event are notified properly
+ moduleScopeStarted = true;
+ } else if (type == EventContext.MODULE_STOP) {
+ moduleScopeStarted = false;
+ }
+ // propagate events to child contexts
+ for (AggregateContext context : contexts.values()) {
+ context.fireEvent(type, message);
+ }
+ }
+
+ public Object getImplementationInstance() throws TargetException{
+ return this;
+ }
+
+ public Object getImplementationInstance(boolean notify) throws TargetException{
+ return this;
+ }
+
+ private void checkInit() {
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Scope not running [" + lifecycleState + "]");
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/DefaultScopeStrategy.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/DefaultScopeStrategy.java
new file mode 100644
index 0000000000..509eb7941f
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/DefaultScopeStrategy.java
@@ -0,0 +1,52 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context.scope;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * Implements a {@link org.apache.tuscany.core.context.ScopeStrategy} for the default module scopes: stateless, request, session,
+ * and module.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefaultScopeStrategy extends AbstractScopeStrategy {
+
+ public DefaultScopeStrategy() {
+ }
+
+ public Map<Scope,ScopeContext> createScopes(EventContext eventContext) {
+ ScopeContext moduleScope = new ModuleScopeContext(eventContext);
+ ScopeContext sessionScope = new HttpSessionScopeContext(eventContext);
+ ScopeContext requestScope = new RequestScopeContext(eventContext);
+ ScopeContext statelessScope = new StatelessScopeContext(eventContext);
+ ScopeContext aggregrateScope = new AggregateScopeContext(eventContext);
+ Map<Scope,ScopeContext> scopes = new HashMap();
+ scopes.put(Scope.MODULE,moduleScope);
+ scopes.put(Scope.SESSION,sessionScope);
+ scopes.put(Scope.REQUEST,requestScope);
+ scopes.put(Scope.INSTANCE,statelessScope);
+ scopes.put(Scope.AGGREGATE,aggregrateScope);
+ return scopes;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/HttpSessionScopeContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/HttpSessionScopeContext.java
new file mode 100644
index 0000000000..e1fcc4ab70
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/HttpSessionScopeContext.java
@@ -0,0 +1,254 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context.scope;
+
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.Context;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.LifecycleEventListener;
+import org.apache.tuscany.core.context.RuntimeEventListener;
+import org.apache.tuscany.core.context.ScopeRuntimeException;
+import org.apache.tuscany.core.context.SimpleComponentContext;
+
+/**
+ * An implementation of an HTTP session-scoped component container where each HTTP session is mapped to a context in the scope
+ *
+ * @version $Rev$ $Date$
+ */
+public class HttpSessionScopeContext extends AbstractScopeContext implements RuntimeEventListener, LifecycleEventListener {
+
+ // The collection of service component contexts keyed by session
+ private Map<Object, Map<String, InstanceContext>> contexts;
+
+ // Stores ordered lists of contexts to shutdown keyed by session
+ private Map<Object, Queue<InstanceContext>> destroyableContexts;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public HttpSessionScopeContext(EventContext eventContext) {
+ super(eventContext);
+ setName("Http Session Scope");
+ }
+
+ // ----------------------------------
+ // Lifecycle methods
+ // ----------------------------------
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED) {
+ throw new IllegalStateException("Scope container must be in UNINITIALIZED state");
+ }
+ super.start();
+ contexts = new ConcurrentHashMap();
+ destroyableContexts = new ConcurrentHashMap();
+ lifecycleState = RUNNING;
+ }
+
+ public synchronized void stop() {
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Scope container in wrong state");
+ }
+ super.stop();
+ contexts = null;
+ contexts = null;
+ destroyableContexts = null;
+ lifecycleState = STOPPED;
+ }
+
+ // ----------------------------------
+ // Listener methods
+ // ----------------------------------
+
+ public void onEvent(int type, Object key) {
+ checkInit();
+ if (key == null) {
+ return;
+ }
+ if (type == EventContext.SESSION_END) {
+ notifyInstanceShutdown(key);
+ destroyComponentContext(key);
+ }
+ }
+
+ // ----------------------------------
+ // Scope methods
+ // ----------------------------------
+
+ public boolean isCacheable() {
+ return true;
+ }
+
+ public void registerConfiguration(RuntimeConfiguration<InstanceContext> configuration) {
+ runtimeConfigurations.put(configuration.getName(), configuration);
+ }
+
+ public InstanceContext getContext(String ctxName) {
+ checkInit();
+ if (ctxName == null) {
+ return null;
+ }
+ // try{
+ Map<String, InstanceContext> ctxs = getSessionContext();
+ if (ctxs == null) {
+ return null;
+ }
+ InstanceContext ctx = ctxs.get(ctxName);
+ if (ctx == null) {
+ // the configuration was added after the session had started, so create a context now and start it
+ RuntimeConfiguration<InstanceContext> configuration = runtimeConfigurations.get(ctxName);
+ if (configuration != null) {
+ ctx = configuration.createInstanceContext();
+ ctx.addContextListener(this);
+ ctx.start();
+ ctxs.put(ctx.getName(), ctx);
+ }
+ }
+ return ctx;
+ }
+
+ public InstanceContext getContextByKey(String ctxName, Object key) {
+ checkInit();
+ if (key == null && ctxName == null) {
+ return null;
+ }
+ Map components = (Map) contexts.get(key);
+ if (components == null) {
+ return null;
+ }
+ return (InstanceContext) components.get(ctxName);
+ }
+
+ public void removeContext(String ctxName) {
+ checkInit();
+ Object key = getEventContext().getIdentifier(EventContext.HTTP_SESSION);
+ removeContextByKey(ctxName, key);
+ }
+
+ public void removeContextByKey(String ctxName, Object key) {
+ checkInit();
+ if (key == null || ctxName == null) {
+ return;
+ }
+ Map components = (Map) contexts.get(key);
+ if (components == null) {
+ return;
+ }
+ components.remove(ctxName);
+ Map definitions = contexts.get(key);
+ InstanceContext meta = (InstanceContext) definitions.get(ctxName);
+ destroyableContexts.get(key).remove(meta);
+ definitions.remove(ctxName);
+ }
+
+ public void onInstanceCreate(Context context) throws ScopeRuntimeException {
+ checkInit();
+ if (context instanceof SimpleComponentContext) {
+ // if destroyable, queue the context to have its component implementation instance released
+ if (((SimpleComponentContext) context).isDestroyable()) {
+ Object key = getEventContext().getIdentifier(EventContext.HTTP_SESSION);
+ Queue comps = destroyableContexts.get(key);
+ if (comps == null) {
+ ScopeRuntimeException e = new ScopeRuntimeException("Shutdown queue not found for key");
+ e.setIdentifier(key.toString());
+ throw e;
+ }
+ comps.add(context);
+ }
+ }
+ }
+
+ /**
+ * Returns an array of {@link SimpleComponentContext}s representing components that need to be notified of scope shutdown or
+ * null if none found.
+ */
+ protected InstanceContext[] getShutdownContexts(Object key) {
+ /*
+ * This method will be called from the Listener which is associated with a different thread than the request. So, just
+ * grab the key directly
+ */
+ Queue queue = destroyableContexts.get(key);
+ if (queue != null) {
+ // create 0-length array since Queue.size() has O(n) traversal
+ return (InstanceContext[]) queue.toArray(new InstanceContext[0]);
+ } else {
+ return null;
+ }
+ }
+
+ // ----------------------------------
+ // Private methods
+ // ----------------------------------
+
+ /**
+ * Returns and, if necessary, creates a context for the current sesion
+ */
+ private Map<String, InstanceContext> getSessionContext() throws CoreRuntimeException {
+ Object key = getEventContext().getIdentifier(EventContext.HTTP_SESSION);
+ if (key == null) {
+ throw new ScopeRuntimeException("Session key not set in request context");
+ }
+ Map m = contexts.get(key);
+ if (m != null) {
+ return m; // already created, return
+ }
+ Map<String, InstanceContext> sessionContext = new ConcurrentHashMap(runtimeConfigurations.size());
+ for (RuntimeConfiguration<InstanceContext> config : runtimeConfigurations.values()) {
+ InstanceContext context = null;
+ context = config.createInstanceContext();
+ context.addContextListener(this);
+ context.start();
+ sessionContext.put(context.getName(), context);
+ }
+
+ Queue shutdownQueue = new ConcurrentLinkedQueue();
+ contexts.put(key, sessionContext);
+ destroyableContexts.put(key, shutdownQueue);
+ // initialize eager components. Note this cannot be done when we initially create each context since a component may
+ // contain a forward reference to a component which has not been instantiated
+ for (InstanceContext context : sessionContext.values()) {
+ if (context instanceof SimpleComponentContext) {
+ SimpleComponentContext simpleCtx = (SimpleComponentContext) context;
+ if (simpleCtx.isEagerInit()) {
+ // Get the instance and perform manual shutdown registration to avoid a map lookup
+ context.getInstance(null, false);
+ if (simpleCtx.isDestroyable()) {
+ shutdownQueue.add(context);
+ }
+ }
+ }
+ }
+ return sessionContext;
+ }
+
+ /**
+ * Removes the components associated with an expiring context
+ */
+ private void destroyComponentContext(Object key) {
+ contexts.remove(key);
+ destroyableContexts.remove(key);
+ }
+
+} \ No newline at end of file
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java
new file mode 100644
index 0000000000..00f2747fae
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java
@@ -0,0 +1,182 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context.scope;
+
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.Context;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.LifecycleEventListener;
+import org.apache.tuscany.core.context.RuntimeEventListener;
+import org.apache.tuscany.core.context.SimpleComponentContext;
+
+/**
+ * Manages component contexts whose implementations are module scoped
+ *
+ * @version $Rev$ $Date$
+ */
+public class ModuleScopeContext extends AbstractScopeContext implements RuntimeEventListener, LifecycleEventListener {
+
+ // ----------------------------------
+ // Fields
+ // ----------------------------------
+
+ // Component contexts in this scope keyed by name
+ private Map<String, InstanceContext> componentContexts;
+
+ private Queue<SimpleComponentContext> destroyableContexts;
+
+ // ----------------------------------
+ // Constructor
+ // ----------------------------------
+
+ public ModuleScopeContext(EventContext eventContext) {
+ super(eventContext);
+ setName("Module Scope");
+ }
+
+ // ----------------------------------
+ // Listener methods
+ // ----------------------------------
+
+ public void onEvent(int type, Object key) {
+ if (type == EventContext.MODULE_START) {
+ lifecycleState = RUNNING;
+ initComponentContexts();
+ } else if (type == EventContext.MODULE_STOP) {
+ notifyInstanceShutdown(key);
+ }
+ }
+
+ // ----------------------------------
+ // Lifecycle methods
+ // ----------------------------------
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED state [" + lifecycleState + "]");
+ }
+ }
+
+ public synchronized void stop() {
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Scope in wrong state [" + lifecycleState + "]");
+ }
+ super.stop();
+ componentContexts = null;
+ destroyableContexts = null;
+ lifecycleState = STOPPED;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public boolean isCacheable() {
+ return true;
+ }
+
+ public void registerConfiguration(RuntimeConfiguration<InstanceContext> configuration) {
+ runtimeConfigurations.put(configuration.getName(), configuration);
+ if (lifecycleState == RUNNING) {
+ componentContexts.put(configuration.getName(), configuration.createInstanceContext());
+ }
+ }
+
+ public InstanceContext getContext(String ctxName) {
+ checkInit();
+ return componentContexts.get(ctxName);
+ }
+
+ public InstanceContext getContextByKey(String ctxName, Object key) {
+ checkInit();
+ return componentContexts.get(ctxName);
+ }
+
+ public void removeContext(String ctxName) {
+ checkInit();
+ Object component = componentContexts.remove(ctxName);
+ if (component != null) {
+ destroyableContexts.remove(component);
+ }
+ }
+
+ public void removeContextByKey(String ctxName, Object key) {
+ checkInit();
+ removeContext(ctxName);
+ }
+
+ public void onInstanceCreate(Context context) {
+ checkInit();
+ if (context instanceof SimpleComponentContext) {
+ SimpleComponentContext serviceContext = (SimpleComponentContext) context;
+ // Queue the context to have its implementation instance released if destroyable
+ if (serviceContext.isDestroyable()) {
+ destroyableContexts.add(serviceContext);
+ }
+ }
+ }
+
+ /**
+ * Returns an array of {@link SimpleComponentContext}s representing components that need to be notified of scope shutdown.
+ */
+ protected InstanceContext[] getShutdownContexts(Object key) {
+ if (destroyableContexts != null) {
+ // create 0-length array since Queue.size() has O(n) traversal
+ return (InstanceContext[]) destroyableContexts.toArray(new InstanceContext[0]);
+ } else {
+ return null;
+ }
+ }
+
+ // ----------------------------------
+ // Private methods
+ // ----------------------------------
+
+ private synchronized void initComponentContexts() throws CoreRuntimeException {
+ if (componentContexts == null) {
+ componentContexts = new ConcurrentHashMap();
+ destroyableContexts = new ConcurrentLinkedQueue();
+ for (RuntimeConfiguration<InstanceContext> config : runtimeConfigurations.values()) {
+ InstanceContext context = config.createInstanceContext();
+ context.addContextListener(this);
+ context.start();
+ componentContexts.put(context.getName(), context);
+ }
+ // Initialize eager contexts. Note this cannot be done when we initially create each context since a component may
+ // contain a forward reference to a component which has not been instantiated
+ for (InstanceContext context : componentContexts.values()) {
+ if (context instanceof SimpleComponentContext) {
+ SimpleComponentContext simpleCtx = (SimpleComponentContext) context;
+ if (simpleCtx.isEagerInit()) {
+ // perform silent creation and manual shutdown registration
+ simpleCtx.getInstance(null, false);
+ if (simpleCtx.isDestroyable()) {
+ destroyableContexts.add(simpleCtx);
+ }
+ }
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java
new file mode 100644
index 0000000000..deed3e2dee
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java
@@ -0,0 +1,224 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context.scope;
+
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.Context;
+import org.apache.tuscany.core.context.LifecycleEventListener;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.RuntimeEventListener;
+import org.apache.tuscany.core.context.SimpleComponentContext;
+
+/**
+ * An implementation of a request-scoped component container.
+ *
+ * @version $Rev$ $Date$
+ */
+public class RequestScopeContext extends AbstractScopeContext implements RuntimeEventListener, LifecycleEventListener {
+
+ // ----------------------------------
+ // Fields
+ // ----------------------------------
+
+ // A collection of service component contexts keyed by thread. Note this could have been implemented with a ThreadLocal but
+ // using a Map allows finer-grained concurrency.
+ private Map<Object, Map<String, InstanceContext>> contextMap;
+
+ // stores ordered lists of contexts to shutdown for each thread.
+ private Map<Object, Queue> destroyComponents;
+
+ // ----------------------------------
+ // Constructor
+ // ----------------------------------
+
+ public RequestScopeContext(EventContext eventContext) {
+ super(eventContext);
+ setName("Request Scope");
+ }
+
+ // ----------------------------------
+ // Listener methods
+ // ----------------------------------
+
+ public void onEvent(int type, Object key) {
+ checkInit();
+ /* clean up current context for pooled threads */
+ if (type == EventContext.REQUEST_END) {
+ getEventContext().clearIdentifier(EventContext.HTTP_SESSION);
+ notifyInstanceShutdown(Thread.currentThread());
+ destroyContext();
+ }
+ }
+
+ // ----------------------------------
+ // Lifecycle methods
+ // ----------------------------------
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED state [" + lifecycleState + "]");
+ }
+ super.start();
+ contextMap = new ConcurrentHashMap();
+ destroyComponents = new ConcurrentHashMap();
+ lifecycleState = RUNNING;
+
+ }
+
+ public synchronized void stop() {
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Scope in wrong state [" + lifecycleState + "]");
+ }
+ super.stop();
+ contextMap = null;
+ destroyComponents = null;
+ lifecycleState = STOPPED;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public boolean isCacheable() {
+ return true;
+ }
+
+ public void registerConfiguration(RuntimeConfiguration<InstanceContext> configuration) {
+ runtimeConfigurations.put(configuration.getName(), configuration);
+ }
+
+ public InstanceContext getContext(String ctxName) {
+ checkInit();
+ Map<String, InstanceContext> contexts = getComponentContexts();
+ InstanceContext ctx = contexts.get(ctxName);
+ if (ctx == null){
+ // check to see if the configuration was added after the request was started
+ RuntimeConfiguration<InstanceContext> configuration = runtimeConfigurations.get(ctxName);
+ if (configuration != null) {
+ ctx = configuration.createInstanceContext();
+ ctx.addContextListener(this);
+ ctx.start();
+ contexts.put(ctx.getName(), ctx);
+ }
+ }
+ return ctx;
+ }
+
+ public InstanceContext getContextByKey(String ctxName, Object key) {
+ checkInit();
+ if (key == null) {
+ return null;
+ }
+ Map<String, InstanceContext> components = (Map) contextMap.get(key);
+ if (components == null) {
+ return null;
+ }
+ return components.get(ctxName);
+ }
+
+ public void removeContext(String ctxName) {
+ checkInit();
+ removeContextByKey(ctxName, Thread.currentThread());
+ }
+
+ public void removeContextByKey(String ctxName, Object key) {
+ checkInit();
+ if (key == null || ctxName == null) {
+ return;
+ }
+ Map components = (Map) contextMap.get(key);
+ if (components == null) {
+ return;
+ }
+ components.remove(ctxName);
+ Map<String, InstanceContext> contexts = (Map) contextMap.get(key);
+ // no synchronization for the following two operations since the request
+ // context will not be shutdown before the second call is processed
+ InstanceContext context = contexts.get(ctxName);
+ destroyComponents.get(key).remove(context);
+ }
+
+ public void onInstanceCreate(Context context) {
+ checkInit();
+ if (context instanceof SimpleComponentContext) {
+ // Queue the context to have its implementation instance released if destroyable
+ if (((SimpleComponentContext) context).isDestroyable()) {
+ Queue collection = destroyComponents.get(Thread.currentThread());
+ collection.add(context);
+ }
+ }
+ }
+
+ /**
+ * Returns an array of {@link SimpleComponentContext}s representing components that need to be notified of scope shutdown.
+ */
+ protected InstanceContext[] getShutdownContexts(Object key) {
+ checkInit();
+ Queue queue = destroyComponents.get(Thread.currentThread());
+ if (queue != null) {
+ // create 0-length array since Queue.size() has O(n) traversal
+ return (InstanceContext[]) queue.toArray(new InstanceContext[0]);
+ } else {
+ return null;
+ }
+ }
+
+ // ----------------------------------
+ // Private methods
+ // ----------------------------------
+
+ private void destroyContext() {
+ // TODO uninitialize all request-scoped components
+ contextMap.remove(Thread.currentThread());
+ destroyComponents.remove(Thread.currentThread());
+ }
+
+ /**
+ * Initializes ServiceComponentContexts for the current request.
+ * <p>
+ * TODO This eagerly creates all component contexts, even if the component is never accessed during the request. This method
+ * should be profiled to determine if lazy initialization is more performant
+ * <p>
+ * TODO Eager initialization is not performed for request-scoped components
+ */
+
+ private Map<String, InstanceContext> getComponentContexts() throws CoreRuntimeException {
+ Map contexts = (Map) contextMap.get(Thread.currentThread());
+ if (contexts == null) {
+ contexts = new ConcurrentHashMap();
+ Queue shutdownQueue = new ConcurrentLinkedQueue();
+ for (RuntimeConfiguration<InstanceContext> config : runtimeConfigurations.values()) {
+ InstanceContext context = null;
+ context = config.createInstanceContext();
+ context.addContextListener(this);
+ context.start();
+ contexts.put(context.getName(), context);
+ }
+ contextMap.put(Thread.currentThread(), contexts);
+ destroyComponents.put(Thread.currentThread(), shutdownQueue);
+ }
+ return contexts;
+ }
+
+} \ No newline at end of file
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java
new file mode 100644
index 0000000000..8b12f8b183
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java
@@ -0,0 +1,145 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context.scope;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.Context;
+import org.apache.tuscany.core.context.LifecycleEventListener;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.RuntimeEventListener;
+
+/**
+ * A container that manages stateless components.
+ *
+ * @version $Rev$ $Date$
+ */
+public class StatelessScopeContext extends AbstractScopeContext implements RuntimeEventListener, LifecycleEventListener {
+
+ // ----------------------------------
+ // Fields
+ // ----------------------------------
+
+ // Component contexts keyed by name
+ private Map<String, InstanceContext> contextMap;
+
+ // ----------------------------------
+ // Constructor
+ // ----------------------------------
+
+ public StatelessScopeContext(EventContext eventContext) {
+ super(eventContext);
+ setName("Stateless Scope");
+ }
+
+ // ----------------------------------
+ // Lifecycle methods
+ // ----------------------------------
+
+ public synchronized void start() {
+ if (lifecycleState != UNINITIALIZED) {
+ throw new IllegalStateException("Scope must be in UNINITIALIZED state [" + lifecycleState + "]");
+ }
+ super.start();
+ lifecycleState = RUNNING;
+ prepare();
+ }
+
+ public synchronized void stop() {
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Scope in wrong state [" + lifecycleState + "]");
+ }
+ super.stop();
+ contextMap = null;
+ lifecycleState = STOPPED;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public void registerConfiguration(RuntimeConfiguration<InstanceContext> configuration) {
+ runtimeConfigurations.put(configuration.getName(), configuration);
+ if (lifecycleState == RUNNING) {
+ contextMap.put(configuration.getName(), configuration.createInstanceContext());
+ }
+
+ }
+
+ public void onEvent(int type, Object key) {
+ // do nothing
+ }
+
+ public boolean isCacheable() {
+ return true;
+ }
+
+ public InstanceContext getContext(String ctxName) {
+ return contextMap.get(ctxName);
+ }
+
+ public InstanceContext getContextByKey(String ctxName, Object key) {
+ return getContext(ctxName);
+ }
+
+ public void removeContext(String ctxName) {
+ removeContextByKey(ctxName, null);
+ }
+
+ public void removeContextByKey(String ctxName, Object key) {
+ contextMap.remove(ctxName);
+ }
+
+ /**
+ * Always returns null since stateless components cannot be shutdown
+ */
+ protected InstanceContext[] getShutdownContexts(Object key) {
+ return null;
+ }
+
+ // ----------------------------------
+ // Private methods
+ // ----------------------------------
+
+ public void onInstanceCreate(Context component) {
+ // do nothing
+ }
+
+ private void prepare() throws CoreRuntimeException {
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Scope not in INITIALIZED state [" + lifecycleState + "]");
+ }
+ if (contextMap == null) {
+ contextMap = new ConcurrentHashMap();
+ for (RuntimeConfiguration<InstanceContext> config : runtimeConfigurations.values()) {
+ for (int i = 0; i < runtimeConfigurations.size(); i++) {
+ InstanceContext context = null;
+ context = config.createInstanceContext();
+ context.addContextListener(this);
+ context.start();
+ contextMap.put(context.getName(), context);
+ }
+
+ }
+ }
+ }
+
+} \ No newline at end of file
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/HTTPSessionExpirationListener.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/HTTPSessionExpirationListener.java
new file mode 100644
index 0000000000..923b9fb941
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/HTTPSessionExpirationListener.java
@@ -0,0 +1,62 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context.webapp;
+
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.EventContext;
+
+/**
+ * Cleans up resources used by expired sessions
+ *
+ * @version $Rev$ $Date$
+ */
+public class HTTPSessionExpirationListener implements HttpSessionListener {
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public HTTPSessionExpirationListener() {
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public void sessionCreated(HttpSessionEvent event) {
+ // do nothing since sessions are lazily created in {@link
+ // org.apache.tuscany.tomcat.webapp.listener.RequestFilter}
+ }
+
+ public void sessionDestroyed(HttpSessionEvent event) {
+ TuscanyWebAppRuntime tuscanyRuntime = null;
+ try {
+ tuscanyRuntime = (TuscanyWebAppRuntime) event.getSession().getServletContext().getAttribute(
+ TuscanyWebAppRuntime.class.getName());
+ tuscanyRuntime.start();
+
+ // End the session
+ AggregateContext context = tuscanyRuntime.getModuleComponentContext();
+ context.fireEvent(EventContext.SESSION_END, event.getSession());
+ } finally {
+ if (tuscanyRuntime != null)
+ tuscanyRuntime.stop();
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/LazyHTTPSessionId.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/LazyHTTPSessionId.java
new file mode 100644
index 0000000000..186f35df14
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/LazyHTTPSessionId.java
@@ -0,0 +1,56 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context.webapp;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.tuscany.core.context.ScopeIdentifier;
+
+/**
+ * Implements a <code>ScopeIdentifier</code> for a Servlet-based transport.
+ * Wraps an <code>HttpServletRequest</code> so that the session id associated
+ * with the current request may be lazily retrieved by the module context - i.e.
+ * if a session context or session-scoped component is not accessed, no session
+ * is created.
+ *
+ * @version $Rev$ $Date$
+ */
+public class LazyHTTPSessionId implements ScopeIdentifier {
+
+ private HttpServletRequest request;
+
+ //----------------------------------
+ // Constructors
+ //----------------------------------
+
+ public LazyHTTPSessionId(HttpServletRequest request) {
+ this.request = request;
+ }
+
+ //----------------------------------
+ // Methods
+ //----------------------------------
+
+ /**
+ * Returns the session identifier
+ *
+ * @see org.apache.tuscany.core.context.ScopeIdentifier#getIdentifier()
+ */
+ public Object getIdentifier() {
+ return request.getSession(true);
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/TuscanyRequestFilter.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/TuscanyRequestFilter.java
new file mode 100644
index 0000000000..8e92c9ebd4
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/TuscanyRequestFilter.java
@@ -0,0 +1,107 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context.webapp;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.EventContext;
+
+/**
+ * Notifies the {@link org.apache.tuscany.core.context.AggregateContext} of web request start and end events as well as setting up the
+ * current session context. The latter is done using lazy Servlet-based session retrieval. The filter fires a session
+ * start event, passing a <tt>LazyServletSessionId</tt> as the session id. The <tt>LazyServletSessionId</tt> is a
+ * wrapper for the servlet request which may be called by the <tt>ModuleContext</tt> to retrieve the session id
+ * lazily.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TuscanyRequestFilter implements Filter {
+ private TuscanyWebAppRuntime tuscanyRuntime;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public TuscanyRequestFilter() {
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public void init(FilterConfig filterConfig) throws ServletException {
+
+ // Get the Tuscany runtime from the servlet context
+ tuscanyRuntime = (TuscanyWebAppRuntime) filterConfig.getServletContext().getAttribute(
+ TuscanyWebAppRuntime.class.getName());
+ }
+
+ public void destroy() {
+ }
+
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException,
+ IOException {
+ // Get the module component context from the tuscany runtime
+ AggregateContext context = tuscanyRuntime.getModuleComponentContext();
+ try {
+
+ // Start the SCA implementation
+ tuscanyRuntime.start();
+
+ // Handle a request
+ if (request instanceof HttpServletRequest) {
+ if (((HttpServletRequest) request).getSession(false) != null) {
+
+ // A session is already active
+ context.fireEvent(EventContext.SESSION_NOTIFY, ((HttpServletRequest) request).getSession(true));
+ } else {
+ // Create a lazy wrapper since a session is not yet active
+ context.fireEvent(EventContext.SESSION_NOTIFY, new LazyHTTPSessionId((HttpServletRequest) request));
+ }
+ } else {
+ context.fireEvent(EventContext.SESSION_NOTIFY, request);
+ }
+ // Start processing the request
+ context.fireEvent(EventContext.REQUEST_START, request);
+ // Dispatch to the next filter
+ filterChain.doFilter(request, response);
+ } catch (Exception e) {
+ throw new ServletException(e);
+
+ } finally {
+ try {
+ // End processing the request
+ context.fireEvent(EventContext.REQUEST_END, request);
+ // Stop the SCA implementation
+ tuscanyRuntime.stop();
+ } catch (Exception e) {
+ throw new ServletException(e);
+ }
+ }
+
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/TuscanyWebAppRuntime.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/TuscanyWebAppRuntime.java
new file mode 100644
index 0000000000..3b9801a811
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/context/webapp/TuscanyWebAppRuntime.java
@@ -0,0 +1,59 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.context.webapp;
+
+import org.apache.tuscany.core.context.AggregateContext;
+import org.osoa.sca.ModuleContext;
+import org.osoa.sca.SCA;
+
+/**
+ * An implementation of the SCA runtime for use in a Web app
+ *
+ * @version $Rev$ $Date$
+ */
+public class TuscanyWebAppRuntime extends SCA {
+ private AggregateContext moduleComponentContext;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public TuscanyWebAppRuntime(AggregateContext moduleComponentContext) {
+ this.moduleComponentContext = moduleComponentContext;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ /**
+ * Returns the module component context associated with this runtime
+ */
+ public AggregateContext getModuleComponentContext() {
+ return moduleComponentContext;
+ }
+
+ public void start() {
+ // Associate it with the current thread
+ setModuleContext((ModuleContext) moduleComponentContext);
+ }
+
+ public void stop() {
+ setModuleContext(null);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/EventInvoker.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/EventInvoker.java
new file mode 100644
index 0000000000..d2b95ae70e
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/EventInvoker.java
@@ -0,0 +1,17 @@
+package org.apache.tuscany.core.injection;
+
+/**
+ * Performs an invocation on an instance
+ *
+ * @version $Rev$ $Date$
+ * @see MethodEventInvoker
+ */
+public interface EventInvoker<T> {
+
+ /**
+ * Performs the invocation on a given instance
+ *
+ * @throws ObjectCallbackException
+ */
+ void invokeEvent(T instance) throws ObjectCallbackException;
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/FactoryInitException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/FactoryInitException.java
new file mode 100644
index 0000000000..e9573d4a4e
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/FactoryInitException.java
@@ -0,0 +1,27 @@
+package org.apache.tuscany.core.injection;
+
+/**
+ * Denotes an exception initializing an object factory
+ *
+ * @version $Rev$ $Date$
+ */
+public class FactoryInitException extends InjectionRuntimeException {
+
+ public FactoryInitException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public FactoryInitException(String message) {
+ super(message);
+ }
+
+ public FactoryInitException(Throwable cause) {
+ super(cause);
+ }
+
+ public FactoryInitException() {
+ super();
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/FieldInjector.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/FieldInjector.java
new file mode 100644
index 0000000000..c48f620a3f
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/FieldInjector.java
@@ -0,0 +1,45 @@
+package org.apache.tuscany.core.injection;
+
+import java.lang.reflect.Field;
+
+import org.apache.tuscany.core.builder.ObjectFactory;
+
+/**
+ * Injects a value created by an {@link ObjectFactory} on a given field
+ *
+ * @version $Rev$ $Date$
+ */
+public class FieldInjector<T> implements Injector<T> {
+
+ private final Field field;
+
+ private final ObjectFactory<?> objectFactory;
+
+ // //----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ /**
+ * 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.objectFactory = objectFactory;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ /**
+ * Inject a new value on the given isntance
+ */
+ public void inject(T instance) throws ObjectCreationException {
+ try {
+ field.set(instance, objectFactory.getInstance());
+ } catch (IllegalAccessException e) {
+ throw new AssertionError("Field is not accessible [" + field + "]");
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/InjectionRuntimeException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/InjectionRuntimeException.java
new file mode 100644
index 0000000000..ac8b09eab2
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/InjectionRuntimeException.java
@@ -0,0 +1,29 @@
+package org.apache.tuscany.core.injection;
+
+import org.apache.tuscany.common.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);
+ }
+
+ public InjectionRuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InjectionRuntimeException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/Injector.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/Injector.java
new file mode 100644
index 0000000000..013b1c5874
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/Injector.java
@@ -0,0 +1,17 @@
+package org.apache.tuscany.core.injection;
+
+/**
+ * Implementations inject a pre-configured value on an instance
+ *
+ * @version $Rev$ $Date$
+ * @see MethodInjector
+ * @see FieldInjector
+ */
+public interface Injector<T> {
+
+ /**
+ * Inject a value on the given instance
+ */
+ void inject(T instance) throws ObjectCreationException;
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/MethodEventInvoker.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/MethodEventInvoker.java
new file mode 100644
index 0000000000..08dd4cd124
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/MethodEventInvoker.java
@@ -0,0 +1,39 @@
+package org.apache.tuscany.core.injection;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Performs an invocation on a method of a given instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class MethodEventInvoker<T> implements EventInvoker<T> {
+ private final Method method;
+
+ //----------------------------------
+ // Constructors
+ //----------------------------------
+
+ /**
+ * Intantiates an invoker for the given method
+ */
+ public MethodEventInvoker(Method method) {
+ this.method = method;
+ }
+
+ //----------------------------------
+ // Methods
+ //----------------------------------
+
+ public void invokeEvent(T instance) throws ObjectCallbackException {
+ try {
+ method.invoke(instance, (Object[]) null);
+ } catch (IllegalAccessException e) {
+ throw new AssertionError("Method is not accessible [" + method + "]");
+ } catch (InvocationTargetException e) {
+ throw new ObjectCallbackException("Exception thrown by callback method [" + method + "]", e);
+ }
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/MethodInjector.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/MethodInjector.java
new file mode 100644
index 0000000000..55ea7bae5f
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/MethodInjector.java
@@ -0,0 +1,30 @@
+package org.apache.tuscany.core.injection;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.core.builder.ObjectFactory;
+
+/**
+ * Injects a value created by an {@link 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) {
+ this.method = method;
+ this.objectFactory = objectFactory;
+ }
+
+ public void inject(T instance) throws ObjectCreationException {
+ try {
+ method.invoke(instance, new Object[]{objectFactory.getInstance()});
+ } catch (IllegalAccessException e) {
+ throw new AssertionError("Method is not accessible [" + method + "]");
+ } catch (InvocationTargetException e) {
+ throw new ObjectCreationException("Exception thrown by setter [" + method + "]", e);
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/NullEventInvoker.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/NullEventInvoker.java
new file mode 100644
index 0000000000..23599bae0e
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/NullEventInvoker.java
@@ -0,0 +1,14 @@
+package org.apache.tuscany.core.injection;
+
+/**
+ * A no-op invoker
+ *
+ * @version $Rev$ $Date$
+ */
+public final class NullEventInvoker<T> implements EventInvoker<T> {
+ public static final EventInvoker<?> NULL_INVOKER = new NullEventInvoker();
+
+ public void invokeEvent(T instance) {
+ // does nothing
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/ObjectCallbackException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/ObjectCallbackException.java
new file mode 100644
index 0000000000..b428c31f4f
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/ObjectCallbackException.java
@@ -0,0 +1,26 @@
+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, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ObjectCallbackException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/ObjectCreationException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/ObjectCreationException.java
new file mode 100644
index 0000000000..338b841c49
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/ObjectCreationException.java
@@ -0,0 +1,27 @@
+package org.apache.tuscany.core.injection;
+
+/**
+ * Denotes an error creating a new object instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class ObjectCreationException extends InjectionRuntimeException {
+
+ public ObjectCreationException() {
+ super();
+ }
+
+ public ObjectCreationException(String message) {
+ super(message);
+ }
+
+ public ObjectCreationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ObjectCreationException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/PojoObjectFactory.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/PojoObjectFactory.java
new file mode 100644
index 0000000000..e3e1874b1e
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/PojoObjectFactory.java
@@ -0,0 +1,75 @@
+package org.apache.tuscany.core.injection;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.tuscany.core.builder.ObjectFactory;
+
+/**
+ * Creates new instances of a Java class, calling a given set of injectors to configure the instance
+ *
+ * @version $Rev$ $Date$
+ * @see Injector
+ */
+public class PojoObjectFactory<T> implements ObjectFactory<T> {
+
+ // ----------------------------------
+ // Constants
+ // ----------------------------------
+
+ private static final ObjectFactory[] NO_INIT_PARAM = {};
+
+ private static final List<Injector> NO_SETTER_PARAM = Collections.EMPTY_LIST;
+
+ // ----------------------------------
+ // Fields
+ // ----------------------------------
+
+ private final Constructor<T> ctr;
+
+ private final ObjectFactory<?>[] initParamsArray;
+
+ private final List<Injector> setters;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public PojoObjectFactory(Constructor<T> ctr, List<ObjectFactory> initParams, List<Injector> setters) {
+ this.ctr = ctr;
+ if (initParams != null && initParams.size() > 0) {
+ initParamsArray = initParams.toArray(new ObjectFactory[initParams.size()]);
+ } else {
+ initParamsArray = NO_INIT_PARAM;
+ }
+ this.setters = setters != null ? setters : NO_SETTER_PARAM;
+ } // ----------------------------------
+
+ // Methods
+ // ----------------------------------
+
+ public T getInstance() throws ObjectCreationException {
+ Object[] initargs = new Object[initParamsArray.length];
+ // create the constructor arg array
+ for (int i = 0; i < initParamsArray.length; i++) {
+ ObjectFactory<?> objectFactory = initParamsArray[i];
+ initargs[i] = objectFactory.getInstance();
+ }
+ try {
+ T instance = ctr.newInstance(initargs);
+ // interate through the injectors and inject the instance
+ for (Injector setter : setters) {
+ setter.inject(instance);
+ }
+ return instance;
+ } catch (InstantiationException e) {
+ throw new AssertionError("Class is not instantiable [" + ctr.getDeclaringClass().getName() + "]");
+ } catch (IllegalAccessException e) {
+ throw new AssertionError("Constructor is not accessible [" + ctr + "]");
+ } catch (InvocationTargetException e) {
+ throw new ObjectCreationException("Exception thrown by constructor [" + ctr + "]", e);
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/ReferenceTargetFactory.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/ReferenceTargetFactory.java
new file mode 100644
index 0000000000..f84c5b7ed1
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/ReferenceTargetFactory.java
@@ -0,0 +1,133 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.injection;
+
+import org.apache.tuscany.core.builder.ObjectFactory;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.TargetException;
+import org.apache.tuscany.model.assembly.Component;
+import org.apache.tuscany.model.assembly.ConfiguredReference;
+import org.apache.tuscany.model.assembly.ConfiguredService;
+import org.apache.tuscany.model.assembly.EntryPoint;
+import org.apache.tuscany.model.assembly.ExternalService;
+
+/**
+ * Returns a direct reference to a target service, i.e. the factory avoids creating proxies and returns the actual
+ * target instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class ReferenceTargetFactory<T> implements ObjectFactory<T> {
+
+ private AggregateContext parentContext;
+
+ // the SCDL name of the target component/service for this reference
+ private String targetName;
+
+ private QualifiedName targetComponentName;
+
+ // the reference target is in another module
+ private boolean interModule;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ /**
+ * Constructs a reference object factory from a configured reference on a type
+ */
+ public ReferenceTargetFactory(ConfiguredReference reference, AggregateContext parentContext)
+ throws FactoryInitException {
+ // FIXME how to handle a reference that is a list - may take different proxy factories for each entry
+ assert (reference != null) : "Reference was null";
+ assert (parentContext != null) : "Parent context was null";
+
+ this.parentContext = parentContext;
+ // targetName = reference.getReference().getName();
+ ConfiguredService targetService = reference.getTargetConfiguredServices().get(0);
+ if (targetService.getAggregatePart() instanceof ExternalService) {
+ targetName = ((ExternalService) targetService.getAggregatePart()).getName();
+ } else if (targetService.getAggregatePart() instanceof Component) {
+ Component targetComponent = (Component) targetService.getAggregatePart();
+ targetName = targetComponent.getName();
+ } else if (targetService.getAggregatePart() instanceof EntryPoint) {
+ targetName = ((EntryPoint) targetService.getAggregatePart()).getName();
+ } else if (targetService.getAggregatePart() == null) {
+ // FIXME not correct
+ if (targetService.getService() == null) {
+ throw new FactoryInitException("No target service specified");
+ }
+ targetName = targetService.getService().getName();
+ } else {
+ FactoryInitException fie = new FactoryInitException("Unknown reference target type");
+ fie.setIdentifier(reference.getReference().getName());
+ throw fie;
+ }
+ }
+
+ /**
+ * Reference source is an external service, target is in another module
+ *
+ * @param service
+ * @param parentContext
+ * @throws FactoryInitException
+ */
+ public ReferenceTargetFactory(String targetName, AggregateContext parentContext) throws FactoryInitException {
+ //assert (service != null) : "Service was null";
+ assert (parentContext != null) : "Parent context was null";
+ interModule = true; // an external service with a reference target in another module
+ this.targetName = targetName;// service.getAggregatePart().getName();
+ targetComponentName = new QualifiedName(targetName);
+ this.parentContext = parentContext;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public T getInstance() throws ObjectCreationException {
+ if (interModule) {
+ // only return entry points since this is an inter-module wire
+ Object o = parentContext.getInstance(targetComponentName);
+ if (o != null) {
+ return (T) o;
+ } else {
+ // walk up the hierarchy of aggregate contexts
+ AggregateContext ctx = parentContext;
+ do {
+ if (ctx == null) {
+ break; // reached top of context hierarchy
+ }
+ InstanceContext compContext = ctx.getContext(targetComponentName.getPartName());
+ if (compContext != null) {
+ o = compContext.getInstance(targetComponentName);
+ if (o != null) {
+ return (T) o;
+ }
+ }
+ ctx = ctx.getParent();
+ } while (ctx != null);
+ TargetException e= new TargetException("Target reference not found");
+ e.setIdentifier(targetName);
+ throw e;
+ }
+ } else {
+ // the target is in the same module, so just locate it
+ return (T) parentContext.locateInstance(targetName);
+ }
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/SDOObjectFactory.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/SDOObjectFactory.java
new file mode 100644
index 0000000000..8147fa0d51
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/SDOObjectFactory.java
@@ -0,0 +1,37 @@
+package org.apache.tuscany.core.injection;
+
+import org.apache.tuscany.core.builder.ObjectFactory;
+
+import commonj.sdo.DataObject;
+import commonj.sdo.helper.CopyHelper;
+
+/**
+ * Creates new instances of an SDO
+ *
+ * @version $Rev$ $Date$
+ */
+public class SDOObjectFactory implements ObjectFactory<DataObject> {
+
+ private DataObject dataObject;
+
+ //----------------------------------
+ // Constructors
+ //----------------------------------
+
+ public SDOObjectFactory(DataObject dataObject) {
+ this.dataObject = dataObject;
+ }
+
+ //----------------------------------
+ // Methods
+ //----------------------------------
+
+ public DataObject getInstance() throws ObjectCreationException {
+ return CopyHelper.INSTANCE.copy(dataObject);
+ }
+
+ public void releaseInstance(DataObject instance) {
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/SingletonObjectFactory.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/SingletonObjectFactory.java
new file mode 100644
index 0000000000..9f46357086
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/injection/SingletonObjectFactory.java
@@ -0,0 +1,29 @@
+package org.apache.tuscany.core.injection;
+
+import org.apache.tuscany.core.builder.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;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public SingletonObjectFactory(T instance) {
+ this.instance = instance;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public T getInstance() {
+ return instance;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/Interceptor.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/Interceptor.java
new file mode 100644
index 0000000000..40137f9b10
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/Interceptor.java
@@ -0,0 +1,42 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation;
+
+import org.apache.tuscany.core.message.Message;
+
+/**
+ * Synchronous, around-style mediation associated with a client- or target- side invocation.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface Interceptor {
+
+ /**
+ * Process a synchronous invocation.
+ *
+ * @param msg the request Message for the invocation
+ * @return the response Message from the invocation
+ */
+ Message invoke(Message msg);
+
+ /**
+ * Sets the next interceptor.
+ *
+ * @param next
+ */
+ void setNext(Interceptor next);
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/InvocationConfiguration.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/InvocationConfiguration.java
new file mode 100644
index 0000000000..2c5e61a8a1
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/InvocationConfiguration.java
@@ -0,0 +1,279 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.core.invocation.impl.MessageChannelImpl;
+import org.apache.tuscany.core.invocation.impl.MessageDispatcher;
+import org.apache.tuscany.core.invocation.impl.RequestResponseInterceptor;
+
+/**
+ * Contains a source- or target-side invocation pipeline for a service operation. Source and target invocation pipelines
+ * are "bridged" together by a set of wire builders with the source-side holding references to the target.
+ * <p>
+ * A set of invocation configurations are used by a {@link org.apache.tuscany.core.invocation.spi.ProxyFactory} to
+ * create service proxies.
+ * <p>
+ * Invocation configurations must contain at least one interceptor and may have 0 to N handlers. Handlers process an
+ * invocation request or response in a one-way fashion. A typical invocation sequence where interceptors and handlers
+ * are configured for both the source and target-side will proceed as follows:
+ * <ol>
+ * <li>The first source interceptor will be called with a message, which will in turn invoke the next interceptor in
+ * the chain
+ * <li>The last source interceptor, which must be of type
+ * {@link org.apache.tuscany.core.invocation.impl.RequestResponseInterceptor} if there are handlers present, will be
+ * invoked. The RR interceptor will in turn pass the message to a
+ * {@link org.apache.tuscany.core.invocation.MessageChannel} which will invoke all source-side request handlers.
+ * <li> The RR interceptor will then invoke the target-side request <tt>MessageChannel</tt>.
+ * <li> The last source-side handler, an instance of
+ * {@link org.apache.tuscany.core.invocation.impl.MessageDispatcher}, will invoke the first source-side
+ * interceptor, which in turn will pass the message down the target-side interceptor chain.
+ * <li> If the target is a component instance the last target-side interceptor, an instance of
+ * {@link org.apache.tuscany.core.invocation.impl.InvokerInterceptor} will retrieve the
+ * {@link org.apache.tuscany.core.invocation.TargetInvoker} from the message and call it to invoke the operation on a
+ * target instance. <tt>TargetInvoker</tt>s are help by the source proxy to enable optimizations such as caching of
+ * target instances.
+ * <li> The response is returned up the invocation stack until it reaches the source-side
+ * <tt>RequestResponseInterceptor</tt>, which invokes the target and source-side response channels respectively.
+ * <li> The response is then passed back up the rest of the invocation stack.
+ * </ol>
+ * <p>
+ * The source-to-target bridge may be constructed in any of the following ways:
+ * <ul>
+ * <li>Source handler-to-target handler
+ * <li>Source handler-to-target interceptor
+ * <li>Source interceptor-to-target handler
+ * <li>Source interceptor-to-target interceptor
+ * </ul>
+ * <p>
+ * In some scenarios, a service proxy may only contain target-side invocaton chains, for example, when a service is
+ * resolved through a locate operation by a non-component client. In this case, there will be no source-side invocation
+ * chains and the target invoker will be held by the target-side and passed down the pipeline.
+ *
+ * @see org.apache.tuscany.core.builder.WireBuilder
+ * @see org.apache.tuscany.core.invocation.spi.ProxyFactory
+ * @see org.apache.tuscany.core.invocation.TargetInvoker
+ * @see org.apache.tuscany.core.invocation.impl.MessageDispatcher
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvocationConfiguration {
+
+ // the operation on the target that will utlimately be invoked
+ private Method operation;
+
+ // responsible for invoking a target instance
+ private TargetInvoker targetInvoker;
+
+ private Interceptor sourceInterceptorChainHead;
+
+ private Interceptor sourceInterceptorChainTail;
+
+ private Interceptor targetInterceptorChainHead;
+
+ private Interceptor targetInterceptorChainTail;
+
+ private List<MessageHandler> requestHandlers;
+
+ private List<MessageHandler> responseHandlers;
+
+ // a source-side pointer to target request handlers, if the exist
+ private MessageChannel targetRequestChannel;
+
+ // a source-side pointer to target response handlers, if the exist
+ private MessageChannel targetResponseChannel;
+
+ /**
+ * Creates an new invocation configuration for the given target operation
+ */
+ public InvocationConfiguration(Method operation) {
+ assert (operation != null) : "No operation type specified";
+ this.operation = operation;
+ }
+
+ /**
+ * Returns the target operation for the invocation configuration
+ */
+ public Method getMethod() {
+ return operation;
+ }
+
+ /**
+ * Used by source-side configurations, sets a pointer to the target-side request channel. This may be null when no
+ * target request handlers exist.
+ */
+ public void setTargetRequestChannel(MessageChannel channel) {
+ targetRequestChannel = channel;
+ }
+
+ /**
+ * Used by source-side configurations, sets a pointer to the target-side response channel. This may be null when no
+ * target response handlers exist.
+ */
+ public void setTargetResponseChannel(MessageChannel channel) {
+ targetResponseChannel = channel;
+ }
+
+ /**
+ * Adds an interceptor to the invocation chain for source-side configurations
+ */
+ public void addSourceInterceptor(Interceptor interceptor) {
+ if (sourceInterceptorChainHead == null) {
+ sourceInterceptorChainHead = interceptor;
+ } else {
+ sourceInterceptorChainTail.setNext(interceptor);
+ }
+ sourceInterceptorChainTail = interceptor;
+ }
+
+ /**
+ * Adds an interceptor to the invocation chain for target-side configurations
+ */
+ public void addTargetInterceptor(Interceptor interceptor) {
+ if (targetInterceptorChainHead == null) {
+ targetInterceptorChainHead = interceptor;
+ } else {
+ targetInterceptorChainTail.setNext(interceptor);
+ }
+ targetInterceptorChainTail = interceptor;
+ }
+
+ /**
+ * Adds an request handler to the invocation chain for either a source- or target-side configuration
+ */
+ public void addRequestHandler(MessageHandler handler) {
+ if (requestHandlers == null) {
+ requestHandlers = new ArrayList<MessageHandler>();
+ }
+ requestHandlers.add(handler);
+ }
+
+ /**
+ * Adds an response handler to the invocation chain for either a source- or target-side configuration
+ */
+ public void addResponseHandler(MessageHandler handler) {
+ if (responseHandlers == null) {
+ responseHandlers = new ArrayList<MessageHandler>();
+ }
+ responseHandlers.add(handler);
+ }
+
+ /**
+ * Returns the request handler chain for either a source- or target-side configuration
+ */
+ public List<MessageHandler> getRequestHandlers() {
+ return requestHandlers;
+ }
+
+ /**
+ * Returns the response handler chain for either a source- or target-side configuration
+ */
+ public List<MessageHandler> getResponseHandlers() {
+ return responseHandlers;
+ }
+
+ /**
+ * Returns the head source-side interceptor. This will be null for target-side configurations
+ */
+ public Interceptor getSourceInterceptor() {
+ return sourceInterceptorChainHead;
+ }
+
+ /**
+ * Returns the head target-side interceptor. On source-side configurations, this will be the head interceptor of the
+ * "bridged" target configuration.
+ */
+ public Interceptor getTargetInterceptor() {
+ return targetInterceptorChainHead;
+ }
+
+
+ public Interceptor getLastTargetInterceptor() {
+ return targetInterceptorChainTail;
+ }
+
+ /**
+ * Sets the target invoker to pass down the invocation pipeline. When a service proxy represents a wire,
+ * the target invoker is set on the source-side.
+ */
+ public void setTargetInvoker(TargetInvoker invoker) {
+ this.targetInvoker = invoker;
+ }
+
+ /**
+ * Returns the target invoker that is passed down the invocation pipeline. When a service proxy represents a wire,
+ * the target invoker is cached on the source-side.
+ */
+ public TargetInvoker getTargetInvoker() {
+ return targetInvoker;
+ }
+
+ /**
+ * Prepares the configuration by linking interceptors and handlers
+ */
+ public void build() {
+
+ if (requestHandlers != null && targetInterceptorChainHead != null) {
+ // on target-side, connect existing handlers and interceptors
+ MessageHandler messageDispatcher = new MessageDispatcher(targetInterceptorChainHead);
+ requestHandlers.add(messageDispatcher);
+ }
+
+ if (requestHandlers != null) {
+ MessageChannel requestChannel = new MessageChannelImpl(requestHandlers);
+ MessageChannel responseChannel = new MessageChannelImpl(responseHandlers);
+ Interceptor channelInterceptor = new RequestResponseInterceptor(requestChannel, targetRequestChannel,
+ responseChannel, targetResponseChannel);
+
+ if (sourceInterceptorChainHead != null) {
+ sourceInterceptorChainTail.setNext(channelInterceptor);
+ } else {
+ sourceInterceptorChainHead = channelInterceptor;
+ }
+
+ } else {
+ // no request handlers
+ if (sourceInterceptorChainHead != null) {
+ if (targetInterceptorChainHead != null) {
+ // Connect source interceptor chain directly to target interceptor chain
+ sourceInterceptorChainTail.setNext(targetInterceptorChainHead);
+ // sourceInterceptorChainTail = targetInterceptorChainHead;
+ } else {
+ // Connect source interceptor chain to the target request channel
+ Interceptor channelInterceptor = new RequestResponseInterceptor(null, targetRequestChannel, null,
+ targetResponseChannel);
+ sourceInterceptorChainTail.setNext(channelInterceptor);
+ }
+ } else {
+ // no source interceptor chain or source handlers, conntect to target interceptor chain or channel
+ if (targetInterceptorChainHead != null) {
+ sourceInterceptorChainHead = targetInterceptorChainHead;
+ sourceInterceptorChainTail = targetInterceptorChainHead;
+ } else {
+ Interceptor channelInterceptor = new RequestResponseInterceptor(null, targetRequestChannel, null,
+ targetResponseChannel);
+ sourceInterceptorChainHead = channelInterceptor;
+ sourceInterceptorChainTail = channelInterceptor;
+ }
+ }
+ }
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/InvocationException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/InvocationException.java
new file mode 100644
index 0000000000..d089b45d76
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/InvocationException.java
@@ -0,0 +1,29 @@
+package org.apache.tuscany.core.invocation;
+
+import org.apache.tuscany.common.TuscanyException;
+
+/**
+ * The root checked exception for the invocation framework
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class InvocationException extends TuscanyException {
+
+ public InvocationException() {
+ super();
+ }
+
+ public InvocationException(String message) {
+ super(message);
+ }
+
+ public InvocationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvocationException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/InvocationRuntimeException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/InvocationRuntimeException.java
new file mode 100644
index 0000000000..ddb7b5f74b
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/InvocationRuntimeException.java
@@ -0,0 +1,44 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation;
+
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * Denotes an exception thrown during invocation processing
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvocationRuntimeException extends ServiceRuntimeException {
+
+ public InvocationRuntimeException() {
+ super();
+ }
+
+ public InvocationRuntimeException(String message) {
+ super(message);
+ }
+
+ public InvocationRuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvocationRuntimeException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/MessageChannel.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/MessageChannel.java
new file mode 100644
index 0000000000..4a5e8a1f87
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/MessageChannel.java
@@ -0,0 +1,33 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation;
+
+import org.apache.tuscany.core.message.Message;
+
+/**
+ * Represents a one-way pipeline through which messages are sent during an invocation
+ *
+ * @see org.apache.tuscany.core.message.Message
+ */
+public interface MessageChannel {
+
+ /**
+ * Sends a message
+ */
+ void send(Message message);
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/MessageHandler.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/MessageHandler.java
new file mode 100644
index 0000000000..4719fbae81
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/MessageHandler.java
@@ -0,0 +1,34 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation;
+
+import org.apache.tuscany.core.message.Message;
+
+
+/**
+ * Performs a uni-directional mediation on a message
+ *
+ * @see org.apache.tuscany.core.message.Message
+ */
+public interface MessageHandler {
+
+ /**
+ * Process a message.
+ */
+ boolean processMessage(Message message);
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/MethodHashMap.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/MethodHashMap.java
new file mode 100644
index 0000000000..183cb5ecbb
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/MethodHashMap.java
@@ -0,0 +1,53 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+
+import org.apache.tuscany.core.config.JavaIntrospectionHelper;
+
+/**
+ * A HashMap keyed by method
+ */
+public class MethodHashMap extends HashMap {
+
+ /**
+ * Constructs a new MethodHashMap.
+ */
+ public MethodHashMap() {
+ super();
+ }
+
+ /**
+ * Constructs a new MethodHashMap.
+ */
+ public MethodHashMap(int size) {
+ super(size);
+ }
+
+ /**
+ * @see java.util.HashMap#get(java.lang.Object)
+ */
+ public Object get(Object key) {
+ Method method=(Method)key;
+ //FIXME find a more efficient way to find a matching method
+ Method closestMethod=JavaIntrospectionHelper.findClosestMatchingMethod(method.getName(), method.getParameterTypes(), super.keySet());
+ return super.get(closestMethod);
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/ProxyConfiguration.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/ProxyConfiguration.java
new file mode 100644
index 0000000000..11fc4768f3
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/ProxyConfiguration.java
@@ -0,0 +1,101 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.message.MessageFactory;
+
+/**
+ * Represents configuration information for creating a service proxy. When a client component implementation is injected
+ * with a service proxy representing a wire, source- and target-side proxy configurations are "bridged" together. This
+ * concatenated configuration may then be used to generate a proxy implemented a particular business interface required
+ * by the client.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ProxyConfiguration {
+
+ private Map<Method, InvocationConfiguration> configurations;
+
+ private ClassLoader proxyClassLoader;
+
+ private MessageFactory messageFactory;
+
+ private QualifiedName serviceName;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ /**
+ * Creates a configuration used to generate proxies representing a service.
+ *
+ * @param serviceName the qualified name of the service represented by this configuration
+ * @param invocationConfigs a collection of operation-to-invocation configuration mappings for the service
+ * @param proxyClassLoader the classloader to use when creating a proxy
+ * @param messageFactory the factory used to create invocation messages
+ */
+ public ProxyConfiguration(QualifiedName serviceName, Map<Method, InvocationConfiguration> invocationConfigs,
+ ClassLoader proxyClassLoader, MessageFactory messageFactory) {
+ assert (invocationConfigs != null) : "No invocation configuration map specified";
+ this.serviceName = serviceName;
+ configurations = invocationConfigs;
+ this.messageFactory = messageFactory;
+ if (proxyClassLoader == null) {
+ this.proxyClassLoader = Thread.currentThread().getContextClassLoader();
+ } else {
+ this.proxyClassLoader = proxyClassLoader;
+ }
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ /**
+ * Returns the qualified service name the configuration is associated with
+ */
+ public QualifiedName getTargetName() {
+ return serviceName;
+ }
+
+ /**
+ * Returns a collection of operation types to {@link InvocationConfiguration} mappings that represent the specific
+ * proxy configuration information for particular operations
+ */
+ public Map<Method, InvocationConfiguration> getInvocationConfigurations() {
+ return configurations;
+ }
+
+ /**
+ * Returns the classloader to use in creating proxies
+ */
+ public ClassLoader getProxyClassLoader() {
+ return proxyClassLoader;
+ }
+
+ /**
+ * Returns the factory used to create invocation messages
+ */
+ public MessageFactory getMessageFactory() {
+ return messageFactory;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/TargetInvoker.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/TargetInvoker.java
new file mode 100644
index 0000000000..e0a85d0b6e
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/TargetInvoker.java
@@ -0,0 +1,44 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Implementations are responsible for resolving a target and performing the actual invocation on it, for example, a
+ * service component implementation instance or an external service client.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface TargetInvoker extends Interceptor, Cloneable{
+
+ /**
+ * Responsible for invoking an operation on a target with the given payload
+ *
+ * @param payload the parameters of the target operation or null
+ * @throws InvocationTargetException if the target operation itself throws an exception. The root cause will be set
+ * to that exception
+ */
+ public Object invokeTarget(Object payload) throws InvocationTargetException;
+
+ /**
+ * Determines whether the proxy can be cached on the client/source side
+ */
+ public boolean isCacheable();
+
+ public Object clone();
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/InvokerInterceptor.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/InvokerInterceptor.java
new file mode 100644
index 0000000000..7b9dc1c86f
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/InvokerInterceptor.java
@@ -0,0 +1,46 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation.impl;
+
+import org.apache.tuscany.core.invocation.Interceptor;
+import org.apache.tuscany.core.invocation.InvocationRuntimeException;
+import org.apache.tuscany.core.invocation.TargetInvoker;
+import org.apache.tuscany.core.message.Message;
+
+/**
+ * Serves as a tail interceptor on a target invocation chain. This implementation dispatches to the target invoker
+ * passed inside the invocation message. Target invokers are passed from the source in order to allow for caching of
+ * target instances.
+ *
+ * @see org.apache.tuscany.core.invocation.TargetInvoker
+ * @version $Rev$ $Date$
+ */
+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");
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/MessageChannelImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/MessageChannelImpl.java
new file mode 100644
index 0000000000..6c0b15a823
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/MessageChannelImpl.java
@@ -0,0 +1,68 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation.impl;
+
+import java.util.List;
+
+import org.apache.tuscany.core.invocation.MessageChannel;
+import org.apache.tuscany.core.invocation.MessageHandler;
+import org.apache.tuscany.core.message.Message;
+
+/**
+ * A channel comprising an ordered collection of message handlers.
+ *
+ *@see org.apache.tuscany.core.message.Message
+ * @version $Rev$ $Date$
+ */
+public class MessageChannelImpl implements MessageChannel {
+
+ private final List<MessageHandler> pipeline;
+
+ //----------------------------------
+ // Constructors
+ //----------------------------------
+
+ /**
+ * Construct a new channel comprising the supplied list of handlers.
+ *
+ * @param pipeline the Handlers in the channel
+ */
+ public MessageChannelImpl(List<MessageHandler> pipeline) {
+ this.pipeline = pipeline;
+ }
+
+ //----------------------------------
+ // Methods
+ //----------------------------------
+
+ /**
+ * Send a message down the channel. The message will be processed by all handlers
+ * in order until one returns false to indicate processing is complete or all
+ * handlers have been called.
+ *
+ * @param msg a Message to send down the channel
+ */
+ public void send(Message msg) {
+ if (pipeline!=null) {
+ for (MessageHandler handler : pipeline) {
+ if (!handler.processMessage(msg)) {
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/MessageDispatcher.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/MessageDispatcher.java
new file mode 100644
index 0000000000..a162962717
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/MessageDispatcher.java
@@ -0,0 +1,46 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation.impl;
+
+import org.apache.tuscany.core.invocation.Interceptor;
+import org.apache.tuscany.core.invocation.MessageHandler;
+import org.apache.tuscany.core.message.Message;
+
+/**
+ * A message handler that dispatches the message through an interceptor stack and the uses the response channel to
+ * return the invocation result.
+ *
+ * @version $Rev$ $Date$
+ */
+public class MessageDispatcher implements MessageHandler {
+ private final Interceptor head;
+
+ /**
+ * Construct a handler that dispatches messages to an Interceptor stack.
+ *
+ * @param head the interceptor at the head of the stack
+ */
+ public MessageDispatcher(Interceptor head) {
+ this.head = head;
+ }
+
+ public boolean processMessage(Message msg) {
+ Message resp = head.invoke(msg);
+ msg.getCallbackChannel().send(resp);
+ return false;
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/NullProxyFactory.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/NullProxyFactory.java
new file mode 100644
index 0000000000..fa4297ef00
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/NullProxyFactory.java
@@ -0,0 +1,57 @@
+package org.apache.tuscany.core.invocation.impl;
+
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.invocation.ProxyConfiguration;
+import org.apache.tuscany.core.invocation.spi.ProxyCreationException;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.invocation.spi.ProxyInitializationException;
+
+/**
+ * Returns an actual implementation instance as opposed to a proxy. Used in cases where proxying may be optimized away.
+ *
+ * @version $Rev: 379957 $ $Date: 2006-02-22 14:58:24 -0800 (Wed, 22 Feb 2006) $
+ */
+public class NullProxyFactory implements ProxyFactory {
+
+ private AggregateContext parentContext;
+
+ private String targetName;
+
+ public NullProxyFactory(String componentName, AggregateContext parentContext) {
+ assert (parentContext != null) : "Parent context was null";
+ this.targetName = componentName;
+ this.parentContext = parentContext;
+ }
+
+ public void initialize(Class businessInterface, ProxyConfiguration config) throws ProxyInitializationException {
+ }
+
+ public Object createProxy() throws ProxyCreationException {
+ return parentContext.getContext(targetName);
+ }
+
+ public void initialize() throws ProxyInitializationException {
+ }
+
+ public ProxyConfiguration getProxyConfiguration() {
+ return null;
+ }
+
+ public void setProxyConfiguration(ProxyConfiguration config) {
+ }
+
+ public void setBusinessInterface(Class interfaze) {
+ }
+
+ public Class getBusinessInterface() {
+ return null;
+ }
+
+ public void addInterface(Class claz) {
+ }
+
+ public Class[] getImplementatedInterfaces() {
+ return null;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/OneWayInterceptor.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/OneWayInterceptor.java
new file mode 100644
index 0000000000..71d324e032
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/OneWayInterceptor.java
@@ -0,0 +1,48 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation.impl;
+
+import org.apache.tuscany.core.invocation.Interceptor;
+import org.apache.tuscany.core.invocation.MessageChannel;
+import org.apache.tuscany.core.message.Message;
+
+/**
+ * An interceptor that sends the invocation Message down its request channel and does not expect a response.
+ *
+ * @version $Rev$ $Date$
+ */
+public class OneWayInterceptor implements Interceptor {
+ private MessageChannel requestChannel;
+
+ /**
+ * Construct an interceptor that sends messages down the supplied channel.
+ *
+ * @param requestChannel the channel to send messages down
+ */
+ public OneWayInterceptor(MessageChannel requestChannel) {
+ this.requestChannel = requestChannel;
+ }
+
+ public Message invoke(Message message) {
+ requestChannel.send(message);
+ return null;
+ }
+
+ public void setNext(Interceptor next) {
+ throw new IllegalStateException("This interceptor must be the last one in an interceptor chain");
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/RequestResponseInterceptor.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/RequestResponseInterceptor.java
new file mode 100644
index 0000000000..03122f0992
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/impl/RequestResponseInterceptor.java
@@ -0,0 +1,73 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation.impl;
+
+import org.apache.tuscany.core.invocation.Interceptor;
+import org.apache.tuscany.core.invocation.MessageChannel;
+import org.apache.tuscany.core.message.Message;
+
+/**
+ * An interceptor that first sends the invocation Message down its request channel then extracts the response from the
+ * message and sends it down the response channel before returning it up the interceptor stack.
+ *
+ * @version $Rev$ $Date$
+ */
+public class RequestResponseInterceptor implements Interceptor {
+
+ private MessageChannel sourceRequestChannel;
+
+ private MessageChannel sourceResponseChannel;
+
+ private MessageChannel targetRequestChannel;
+
+ private MessageChannel targetResponseChannel;
+
+ /**
+ * Construct an interceptor that sends messages down the supplied channels.
+ *
+ * @param targetRequestChannel the channel to send request messages down
+ * @param targetResponseChannel the channel to sent response messages down
+ */
+ public RequestResponseInterceptor(MessageChannel sourceRequestChannel, MessageChannel targetRequestChannel,
+ MessageChannel sourceResponseChannel, MessageChannel targetResponseChannel) {
+ this.sourceRequestChannel = sourceRequestChannel;
+ this.sourceResponseChannel = sourceResponseChannel;
+ this.targetRequestChannel = targetRequestChannel;
+ this.targetResponseChannel = targetResponseChannel;
+ }
+
+ public Message invoke(Message requestMessage) {
+ if (sourceRequestChannel != null) {
+ sourceRequestChannel.send(requestMessage);
+ }
+ if (targetRequestChannel != null) {
+ targetRequestChannel.send(requestMessage);
+ }
+ Message responseMessage = requestMessage.getRelatedCallbackMessage();
+ if (targetResponseChannel != null) {
+ targetResponseChannel.send(responseMessage);
+ }
+ if (sourceResponseChannel != null) {
+ sourceResponseChannel.send(responseMessage);
+ }
+ return responseMessage;
+ }
+
+ public void setNext(Interceptor next) {
+ throw new IllegalStateException("This interceptor must be the last one in an interceptor chain");
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/jdk/JDKInvocationHandler.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/jdk/JDKInvocationHandler.java
new file mode 100644
index 0000000000..2f27698d6b
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/jdk/JDKInvocationHandler.java
@@ -0,0 +1,143 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation.jdk;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.core.context.TargetException;
+import org.apache.tuscany.core.invocation.Interceptor;
+import org.apache.tuscany.core.invocation.InvocationConfiguration;
+import org.apache.tuscany.core.invocation.TargetInvoker;
+import org.apache.tuscany.core.message.Message;
+import org.apache.tuscany.core.message.MessageFactory;
+
+/**
+ * Receives a request from a JDK proxy and dispatches it to a target invoker or source interceptor stack
+ *
+ * @version $Rev$ $Date$
+ */
+public class JDKInvocationHandler implements InvocationHandler {
+
+ private MessageFactory messageFactory;
+
+ /*
+ * an association of an operation to configuration holder. The holder contains the master invocation configuration
+ * and a locale 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 invocation configuration will be used.
+ */
+ private Map<Method, ConfigHolder> configuration;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public JDKInvocationHandler(MessageFactory messageFactory, Map<Method, InvocationConfiguration> configuration) {
+ assert (configuration != null) : "Configuration not specified";
+ this.configuration = new HashMap(configuration.size());
+ for (Map.Entry<Method, InvocationConfiguration> entry : configuration.entrySet()) {
+ this.configuration.put(entry.getKey(), new ConfigHolder(entry.getValue()));
+ }
+ // this.configuration = configuration;
+ this.messageFactory = messageFactory;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ /**
+ * Dispatches a client request made on a proxy
+ */
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ Interceptor headInterceptor = null;
+ ConfigHolder holder = configuration.get(method);
+ if (holder == null) {
+ TargetException e = new TargetException("Operation not configured");
+ e.setIdentifier(method.getName());
+ throw e;
+ }
+ InvocationConfiguration config = holder.config;
+ if (config != null) {
+ headInterceptor = config.getSourceInterceptor();
+ }
+
+ TargetInvoker invoker = null;
+
+ if (holder.cachedInvoker == null) {
+ if(config.getTargetInvoker() == null){
+ TargetException e= new TargetException("No target invoker configured for operation");
+ e.setIdentifier(config.getMethod().getName());
+ throw e;
+ }
+ if (config.getTargetInvoker().isCacheable()) {
+ // clone and store the invoker locally
+ holder.cachedInvoker = (TargetInvoker) config.getTargetInvoker().clone();
+ invoker = holder.cachedInvoker;
+ } else {
+ invoker = config.getTargetInvoker();
+ }
+ } else {
+ invoker = config.getTargetInvoker();
+ }
+ if (headInterceptor == null) {
+ try {
+ // short-circuit the dispatch and invoke the target directly
+ if (config.getTargetInvoker() == null) {
+ throw new AssertionError("No target invoker [" + method.getName() + "]");
+ }
+ return config.getTargetInvoker().invokeTarget(args);
+ } catch (InvocationTargetException e) {
+ // the cause was thrown by the target so throw it
+ throw e.getCause();
+ }
+ } else {
+ Message msg = messageFactory.createMessage();
+ msg.setTargetInvoker(invoker);// config.getTargetInvoker());
+ msg.setBody(args);
+ // dispatch the invocation down the chain and get the response
+ Message resp = headInterceptor.invoke(msg);
+
+ Object body = resp.getBody();
+ if (body instanceof Throwable) {
+ throw (Throwable) body;
+ }
+ return body;
+ }
+ }
+
+ /**
+ * A holder used to associate an invocation configuration with a local copy of a target invoker that was previously
+ * cloned from the configuration master
+ */
+ private class ConfigHolder {
+
+ public ConfigHolder(InvocationConfiguration config) {
+ this.config = config;
+ }
+
+ InvocationConfiguration config;
+
+ TargetInvoker cachedInvoker;
+ }
+
+} \ No newline at end of file
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/jdk/JDKProxyFactory.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/jdk/JDKProxyFactory.java
new file mode 100644
index 0000000000..75137ffa36
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/jdk/JDKProxyFactory.java
@@ -0,0 +1,96 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation.jdk;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Map;
+
+import org.apache.tuscany.core.invocation.InvocationConfiguration;
+import org.apache.tuscany.core.invocation.MethodHashMap;
+import org.apache.tuscany.core.invocation.ProxyConfiguration;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.invocation.spi.ProxyInitializationException;
+
+/**
+ * Creates proxies for handling invocations using JDK dynamic proxies
+ *
+ * @version $Rev$ $Date$
+ */
+public class JDKProxyFactory implements ProxyFactory {
+
+ private static final int UNINITIALIZED = 0;
+
+ private static final int INITIALIZED = 1;
+
+ private static final int ERROR = -1;
+
+ private int state = UNINITIALIZED;
+
+ private Class[] businessInterfaceArray;
+
+ private Map<Method, InvocationConfiguration> methodToInvocationConfig;
+
+ private ProxyConfiguration configuration;
+
+ public void initialize() throws ProxyInitializationException {
+ if (state != UNINITIALIZED) {
+ throw new IllegalStateException("Proxy factory in wrong state [" + state + "]");
+ }
+ Map<Method, InvocationConfiguration> invocationConfigs = configuration.getInvocationConfigurations();
+ methodToInvocationConfig = new MethodHashMap(invocationConfigs.size());
+ for (Map.Entry entry : invocationConfigs.entrySet()) {
+ Method method = (Method) entry.getKey();
+ methodToInvocationConfig.put(method, (InvocationConfiguration) entry.getValue());
+ }
+ state = INITIALIZED;
+ }
+
+ public Object createProxy() {
+ if (state != INITIALIZED) {
+ throw new IllegalStateException("Proxy factory not INITIALIZED [" + state + "]");
+ }
+ InvocationHandler handler = new JDKInvocationHandler(configuration.getMessageFactory(), methodToInvocationConfig);
+ return Proxy.newProxyInstance(configuration.getProxyClassLoader(), businessInterfaceArray, handler);
+ }
+
+ public ProxyConfiguration getProxyConfiguration() {
+ return configuration;
+ }
+
+ public void setProxyConfiguration(ProxyConfiguration config) {
+ configuration = config;
+ }
+
+ public void setBusinessInterface(Class interfaze) {
+ businessInterfaceArray = new Class[] { interfaze };
+ }
+
+ public Class getBusinessInterface() {
+ return businessInterfaceArray[0];
+ }
+
+ public void addInterface(Class claz) {
+ throw new UnsupportedOperationException("Additional proxy interfaces not yet supported");
+ }
+
+ public Class[] getImplementatedInterfaces() {
+ return businessInterfaceArray;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/jdk/JDKProxyFactoryFactory.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/jdk/JDKProxyFactoryFactory.java
new file mode 100644
index 0000000000..81458e4178
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/jdk/JDKProxyFactoryFactory.java
@@ -0,0 +1,52 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation.jdk;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.invocation.spi.ProxyFactoryFactory;
+
+/**
+ * Creates JDK Dynamic Proxy-based proxy factories
+ *
+ * @version $Rev$ $Date$
+ */
+public class JDKProxyFactoryFactory implements ProxyFactoryFactory {
+
+ public JDKProxyFactoryFactory() {
+ }
+
+ public ProxyFactory createProxyFactory() {
+ return new JDKProxyFactory();
+ }
+
+ public boolean isProxy(Object object) {
+ if (object == null) {
+ return false;
+ } else {
+ return Proxy.isProxyClass(object.getClass());
+ }
+ }
+
+ public InvocationHandler getHandler(Object proxy) {
+ if (proxy == null) {
+ return null;
+ } else {
+ return Proxy.getInvocationHandler(proxy);
+ }
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyCreationException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyCreationException.java
new file mode 100644
index 0000000000..2a97975bf9
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyCreationException.java
@@ -0,0 +1,43 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation.spi;
+
+/**
+ * Denotes an error creating a proxy instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class ProxyCreationException extends ProxyException {
+
+ public ProxyCreationException() {
+ super();
+ }
+
+ public ProxyCreationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ProxyCreationException(String message) {
+ super(message);
+ }
+
+ public ProxyCreationException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyException.java
new file mode 100644
index 0000000000..843a90d341
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyException.java
@@ -0,0 +1,40 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation.spi;
+
+import org.apache.tuscany.core.invocation.InvocationException;
+
+public class ProxyException extends InvocationException {
+
+ public ProxyException() {
+ super();
+ }
+
+ public ProxyException(String message) {
+ super(message);
+ }
+
+ public ProxyException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ProxyException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyFactory.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyFactory.java
new file mode 100644
index 0000000000..aef98a0b4c
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyFactory.java
@@ -0,0 +1,79 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation.spi;
+
+import org.apache.tuscany.core.invocation.ProxyConfiguration;
+
+/**
+ * Implementations are responsible for creating service proxies using a particular proxy strategy. Service proxies may
+ * represent a wire between two components or a reference to a service resolved through a locate operation. When
+ * representing a wire, a proxy is injected on reference in a component implementation. In this case the proxy will
+ * implement the interface required by the reference and pass invocation messages down source- and target-side
+ * invocation chains for processing. These source- and target-side invocation chains will be derived from metadata
+ * decorating the source reference and target service definition and implementation respectively.
+ * <p>
+ * The second type of proxy will be generated when non-component client code (such as a JSP) locates a service. In this
+ * case, the proxy will implement the requested service interface but will only contain a target-side invocation chain.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ProxyFactory<T> {
+
+ /**
+ * Prepares the factory for generating the proxy of a particular reference type. This will typically be called when
+ * construction of the proxy configuration is complete, including linking of source and target invocation chains.
+ *
+ * @throws ProxyInitializationException if an error is encountered during initialization
+ */
+ public void initialize() throws ProxyInitializationException;
+
+ /**
+ * Returns a proxy for a service reference
+ */
+ public T createProxy() throws ProxyCreationException;
+
+ /**
+ * Returns the configuration information used to create a proxy
+ */
+ public ProxyConfiguration getProxyConfiguration();
+
+ /**
+ * Sets the configuration information used to create a proxy
+ */
+ public void setProxyConfiguration(ProxyConfiguration config);
+
+ /**
+ * Sets the primary interface type generated proxies should implement
+ */
+ public void setBusinessInterface(Class interfaze);
+
+ /**
+ * Returns the primary interface type implemented by generated proxies
+ */
+ public Class getBusinessInterface();
+
+ /**
+ * Adds an interface type generated proxies should implement
+ */
+ public void addInterface(Class claz);
+
+ /**
+ * Returns an array of all interfaces implemented by generated proxies
+ */
+ public Class[] getImplementatedInterfaces();
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyFactoryFactory.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyFactoryFactory.java
new file mode 100644
index 0000000000..8e4c2ee589
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyFactoryFactory.java
@@ -0,0 +1,42 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation.spi;
+
+import java.lang.reflect.InvocationHandler;
+
+/**
+ * Creates proxy factories which may be subsequently configured to generate proxies
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ProxyFactoryFactory {
+
+ /**
+ * Returns a new proxy factory
+ */
+ public ProxyFactory createProxyFactory();
+
+ /**
+ * Determines whether the given object is a proxy
+ */
+ public boolean isProxy(Object object);
+
+ /**
+ * Returns an invocation handler fronting the invocation chains used by the proxy. Note that should SCA define a
+ * DII, this could return such an interface.
+ *
+ * @throws IllegalArgumentException if the class is not a proxy
+ */
+ public InvocationHandler getHandler(Object proxy) throws IllegalArgumentException;
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyInitializationException.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyInitializationException.java
new file mode 100644
index 0000000000..d8c8e64614
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/invocation/spi/ProxyInitializationException.java
@@ -0,0 +1,43 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.invocation.spi;
+
+/**
+ * Denotes an error initializing a proxy factory
+ *
+ * @version $Rev$ $Date$
+ */
+public class ProxyInitializationException extends ProxyException {
+
+ public ProxyInitializationException() {
+ super();
+ }
+
+ public ProxyInitializationException(String message) {
+ super(message);
+ }
+
+ public ProxyInitializationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ProxyInitializationException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/loader/SCDLModelLoaderRegistry.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/loader/SCDLModelLoaderRegistry.java
new file mode 100644
index 0000000000..0205c1350e
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/loader/SCDLModelLoaderRegistry.java
@@ -0,0 +1,51 @@
+/**
+ *
+ * Copyright 2005 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.loader;
+
+import java.util.List;
+
+import org.apache.tuscany.model.scdl.loader.SCDLModelLoader;
+
+/**
+ * A ModelLoaderRegistry maintains a list of SCDLModelLoaders that have been contributed
+ * to the system by various extension components (such as implementations or bindings).
+ *
+ *
+ * @version $Rev$ $Date$
+ */
+public interface SCDLModelLoaderRegistry {
+ /**
+ * Returns the list of registered model loaders.
+ *
+ * @return the list of registered model loaders
+ */
+ List<SCDLModelLoader> getLoaders();
+
+ /**
+ * Register a model loader.
+ *
+ * @param loader the loader being contributed by the extension component
+ */
+ void registerLoader(SCDLModelLoader loader);
+
+ /**
+ * Unregister a model loader.
+ *
+ * @param loader the loader previously contributed by the extension component
+ */
+ void unregisterLoader(SCDLModelLoader loader);
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/SCDLModelLoaderRegistryImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/SCDLModelLoaderRegistryImpl.java
new file mode 100644
index 0000000000..2f0ba73252
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/SCDLModelLoaderRegistryImpl.java
@@ -0,0 +1,49 @@
+/**
+ *
+ * Copyright 2005 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.loader.impl;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+
+import org.apache.tuscany.core.loader.SCDLModelLoaderRegistry;
+import org.apache.tuscany.model.scdl.loader.SCDLModelLoader;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SCDLModelLoaderRegistryImpl implements SCDLModelLoaderRegistry {
+ private final List<SCDLModelLoader> loaders;
+ private final List<SCDLModelLoader> registry;
+
+ public SCDLModelLoaderRegistryImpl() {
+ registry = new ArrayList<SCDLModelLoader>();
+ loaders = Collections.unmodifiableList(registry);
+ }
+
+ public List<SCDLModelLoader> getLoaders() {
+ return loaders;
+ }
+
+ public void registerLoader(SCDLModelLoader loader) {
+ registry.add(loader);
+ }
+
+ public void unregisterLoader(SCDLModelLoader loader) {
+ registry.remove(loader);
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/message/Message.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/message/Message.java
new file mode 100644
index 0000000000..e316050511
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/message/Message.java
@@ -0,0 +1,182 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.message;
+
+import java.util.Map;
+
+import org.apache.tuscany.core.addressing.EndpointReference;
+import org.apache.tuscany.core.invocation.MessageChannel;
+import org.apache.tuscany.core.invocation.TargetInvoker;
+
+/**
+ * Represents a request, response, or exception for an invocation
+ */
+public interface Message {
+
+ /**
+ * Return any message headers associated with the invocation.
+ */
+ Map<String, Object> getHeaders();
+
+ /**
+ * Returns the body of the message, which will be the payload or parameters
+ * associated with the invocation
+ * FIXME what is different w/ getPayload()?
+ */
+ Object getBody();
+
+ /**
+ * Sets the body of the message.
+ */
+ void setBody(Object body);
+
+ /**
+ * Returns true if the message is a request message
+ * FIXME is this still used?
+ */
+ boolean isRequest();
+
+ /**
+ * Returns true if the message is an inbound message
+ * FIXME is this still used?
+ */
+ boolean isResponse();
+
+ /**
+ * Sets the To header
+ * FIXME Javadoc
+ */
+ void setTo(EndpointReference to);
+
+ /**
+ * Returns the To header
+ * FIXME Javadoc
+ */
+ EndpointReference getTo();
+
+ /**
+ * Sets the From header
+ * FIXME Javadoc
+ */
+ void setFrom(EndpointReference from);
+
+ /**
+ * Returns the From header
+ * FIXME Javadoc
+ */
+ EndpointReference getFrom();
+
+ /**
+ * Sets the message ID
+ */
+ void setMessageID(String messageID);
+
+ /**
+ * Returns the message ID
+ */
+ String getMessageID();
+
+ /**
+ * Sets the Action header
+ * FIXME Javadoc
+ */
+ void setAction(String action);
+
+ /**
+ * Returns the Action header
+ * FIXME Javadoc
+ */
+ String getAction();
+
+ /**
+ * Sets the ReplyTo header
+ * FIXME Javadoc
+ */
+ void setReplyTo(EndpointReference replyTo);
+
+ /**
+ * Returns the ReplyTo header
+ * FIXME Javadoc
+ */
+ EndpointReference getReplyTo();
+
+ /**
+ * Sets the RelatesTo header
+ * FIXME Javadoc
+ */
+ void setRelatesTo(String relatesTo);
+
+ /**
+ * Returns the RelatesTo header
+ * FIXME Javadoc
+ */
+ String getRelatesTo();
+
+ /**
+ * Sets the FaultTo header
+ * FIXME Javadoc
+ */
+ void setFaultTo(EndpointReference faultTo);
+
+ /**
+ * Returns the FaultTo header
+ * FIXME Javadoc
+ */
+ EndpointReference getFaultTo();
+
+ /**
+ * Sets the EndpointReference header
+ * FIXME Javadoc
+ */
+ void setEndpointReference(EndpointReference endpointReference);
+
+ /**
+ * Returns the EndpointReference header
+ * FIXME Javadoc
+ */
+ EndpointReference getEndpointReference();
+
+ /**
+ * Sets the operation name
+ * FIXME Javadoc
+ */
+ void setOperationName(String operationName);
+
+ /**
+ * Returns the operation name
+ * FIXME Javadoc
+ */
+ String getOperationName();
+
+ /**
+ * Returns the callback channel
+ * FIXME Javadoc
+ */
+ MessageChannel getCallbackChannel();
+
+ /**
+ * Returns the related callback message
+ * FIXME Javadoc
+ */
+ Message getRelatedCallbackMessage();
+
+ //ADDED
+ public void setTargetInvoker(TargetInvoker invoker);
+
+ public TargetInvoker getTargetInvoker();
+
+} // Message
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/message/MessageFactory.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/message/MessageFactory.java
new file mode 100644
index 0000000000..74b0e85848
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/message/MessageFactory.java
@@ -0,0 +1,31 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.message;
+
+/**
+ * The <b>Factory</b> for messages
+ *
+ * @see org.apache.tuscany.core.message.Message
+ */
+public interface MessageFactory {
+
+ /**
+ * Returns a new message.
+ */
+ Message createMessage();
+
+} // MessageFactory
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/message/impl/MessageFactoryImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/message/impl/MessageFactoryImpl.java
new file mode 100644
index 0000000000..43787bbe67
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/message/impl/MessageFactoryImpl.java
@@ -0,0 +1,40 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.message.impl;
+
+import org.apache.tuscany.core.message.Message;
+import org.apache.tuscany.core.message.MessageFactory;
+
+/**
+ * The default message factory
+ *
+ * @version $Rev$ $Date$
+ */
+public class MessageFactoryImpl implements MessageFactory {
+
+ /**
+ * Constructor
+ */
+ public MessageFactoryImpl() {
+ super();
+ }
+
+ public Message createMessage() {
+ return new MessageImpl();
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/message/impl/MessageImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/message/impl/MessageImpl.java
new file mode 100644
index 0000000000..b67c7e227e
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/message/impl/MessageImpl.java
@@ -0,0 +1,249 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.message.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.core.addressing.EndpointReference;
+import org.apache.tuscany.core.invocation.MessageChannel;
+import org.apache.tuscany.core.invocation.TargetInvoker;
+import org.apache.tuscany.core.message.Message;
+
+/**
+ */
+public class MessageImpl implements Message, MessageChannel {
+
+ private String action;
+ private Object body;
+ private EndpointReference endpointReference;
+ private EndpointReference faultTo;
+ private EndpointReference from;
+ private Map<String, Object> headers;
+ private String messageID;
+ private String operationName;
+ private Message relatedCallbackMessage;
+ private String relatesTo;
+ private EndpointReference replyTo;
+ private TargetInvoker invoker;
+ private EndpointReference to;
+
+ /**
+ * Constructor
+ */
+ protected MessageImpl() {
+ super();
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#getAction()
+ */
+ public String getAction() {
+ return action;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#getBody()
+ */
+ public Object getBody() {
+ return body;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#getEndpointReference()
+ */
+ public EndpointReference getEndpointReference() {
+ return endpointReference;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#getFaultTo()
+ */
+ public EndpointReference getFaultTo() {
+ return faultTo;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#getFrom()
+ */
+ public EndpointReference getFrom() {
+ return from;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#getHeaders()
+ */
+ public Map<String, Object> getHeaders() {
+ if (headers==null)
+ headers=new HashMap<String, Object>();
+ return headers;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#getMessageID()
+ */
+ public String getMessageID() {
+ return messageID;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#getOperationName()
+ */
+ public String getOperationName() {
+ return operationName;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#getRelatesTo()
+ */
+ public String getRelatesTo() {
+ return relatesTo;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#getReplyTo()
+ */
+ public EndpointReference getReplyTo() {
+ return replyTo;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#getTo()
+ */
+ public EndpointReference getTo() {
+ return to;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#isRequest()
+ */
+ public boolean isRequest() {
+ return relatesTo==null;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#isResponse()
+ */
+ public boolean isResponse() {
+ return relatesTo!=null;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#setAction(java.lang.String)
+ */
+ public void setAction(String action) {
+ this.action=action;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#setBody(java.lang.Object)
+ */
+ public void setBody(Object body) {
+ this.body=body;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#setEndpointReference(org.apache.tuscany.core.client.runtime.addressing.sdo.EndpointReference)
+ */
+ public void setEndpointReference(EndpointReference endpointReference) {
+ this.endpointReference=endpointReference;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#setFaultTo(org.apache.tuscany.core.client.runtime.addressing.sdo.EndpointReference)
+ */
+ public void setFaultTo(EndpointReference faultTo) {
+ this.faultTo=faultTo;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#setFrom(org.apache.tuscany.core.client.runtime.addressing.sdo.EndpointReference)
+ */
+ public void setFrom(EndpointReference from) {
+ this.from=from;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#setMessageID(java.lang.String)
+ */
+ public void setMessageID(String messageID) {
+ this.messageID=messageID;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#setOperationName(java.lang.String)
+ */
+ public void setOperationName(String operationName) {
+ this.operationName=operationName;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#setRelatesTo(java.lang.String)
+ */
+ public void setRelatesTo(String relatesTo) {
+ this.relatesTo=relatesTo;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#setReplyTo(org.apache.tuscany.core.client.runtime.addressing.sdo.EndpointReference)
+ */
+ public void setReplyTo(EndpointReference replyTo) {
+ this.replyTo=replyTo;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#setTo(org.apache.tuscany.core.client.runtime.addressing.sdo.EndpointReference)
+ */
+ public void setTo(EndpointReference to) {
+ this.to=to;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#getCallbackChannel()
+ */
+ public MessageChannel getCallbackChannel() {
+ return this;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.invocation.MessageChannel#send(org.apache.tuscany.core.message.Message)
+ */
+ public void send(Message message) {
+ relatedCallbackMessage = message;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#getRelatedCallbackMessage()
+ */
+ public Message getRelatedCallbackMessage() {
+ return relatedCallbackMessage;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#setTargetInvoker(org.apache.tuscany.core.invocation.TargetInvoker)
+ */
+ public void setTargetInvoker(TargetInvoker invoker){
+ this.invoker = invoker;
+ }
+
+ /**
+ * @see org.apache.tuscany.core.message.Message#getTargetInvoker()
+ */
+ public TargetInvoker getTargetInvoker(){
+ return invoker;
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeContext.java
new file mode 100644
index 0000000000..5bf71a09f9
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeContext.java
@@ -0,0 +1,83 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.runtime;
+
+import org.apache.tuscany.common.monitor.MonitorFactory;
+import org.apache.tuscany.core.builder.RuntimeConfigurationBuilder;
+import org.apache.tuscany.core.builder.WireBuilder;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.AutowireContext;
+import org.apache.tuscany.core.context.ConfigurationContext;
+import org.apache.tuscany.core.context.SystemAggregateContext;
+import org.apache.tuscany.model.scdl.loader.SCDLModelLoader;
+
+/**
+ * Represents a top-level component context in the runtime, that is the bootstrap context.
+ * This context serves as the ultimate root of the context hierarchy. Under it are two
+ * separate trees: the rootContext for user components and the systemContext for
+ * system components (those that comprise the runtime itself).
+ *
+ * @version $Rev$ $Date$
+ */
+public interface RuntimeContext extends AutowireContext, ConfigurationContext {
+
+ /* the symbolic name of the runtime bootstrap context */
+ public static final String RUNTIME = "tuscany.runtime";
+
+ /* the symbolic name of the aggregate context containing all system components in the runtime */
+ public static final String SYSTEM = "tuscany.system";
+
+ /* the symbolic name of the aggregate context containing all user components in the runtime */
+ public static final String ROOT = "tuscany.root";
+
+ /**
+ * Returns the context that forms the root of the user component tree.
+ * All user components will managed by contexts that are children of this root.
+ * @return the root of the user component tree
+ */
+ public AggregateContext getRootContext();
+
+ /**
+ * Returns the context that forms the root of the system component tree.
+ * All system components, components that provide system services needed by the
+ * Tuscany runtime itself, will be managed by contexts that are children of this root.
+ * @return the root of the system component tree
+ */
+ public SystemAggregateContext getSystemContext();
+
+ /**
+ * Adds a configuration builder to the runtime
+ */
+ @Deprecated
+ public void addBuilder(RuntimeConfigurationBuilder builder);
+
+ /**
+ * Adds a wire builder to the runtime
+ */
+ @Deprecated
+ public void addBuilder(WireBuilder builder);
+
+ /**
+ * Adds an SCDL model loader to the runtime
+ */
+ @Deprecated
+ public void addLoader(SCDLModelLoader loader);
+
+ /**
+ * Returns the monitor factory in use by the runtime
+ */
+ @Deprecated
+ public MonitorFactory getMonitorFactory();
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeContextImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeContextImpl.java
new file mode 100644
index 0000000000..044958b9bf
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeContextImpl.java
@@ -0,0 +1,286 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.runtime;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.common.monitor.MonitorFactory;
+import org.apache.tuscany.common.monitor.impl.NullMonitorFactory;
+import org.apache.tuscany.core.builder.BuilderConfigException;
+import org.apache.tuscany.core.builder.HierarchicalWireBuilder;
+import org.apache.tuscany.core.builder.RuntimeConfigurationBuilder;
+import org.apache.tuscany.core.builder.WireBuilder;
+import org.apache.tuscany.core.builder.impl.AssemblyVisitor;
+import org.apache.tuscany.core.builder.impl.DefaultWireBuilder;
+import org.apache.tuscany.core.config.ConfigurationException;
+import org.apache.tuscany.core.context.AbstractContext;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.AutowireContext;
+import org.apache.tuscany.core.context.AutowireResolutionException;
+import org.apache.tuscany.core.context.ConfigurationContext;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.EventException;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.RuntimeEventListener;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.core.context.SystemAggregateContext;
+import org.apache.tuscany.core.context.TargetException;
+import org.apache.tuscany.core.context.impl.AggregateContextImpl;
+import org.apache.tuscany.core.context.impl.EventContextImpl;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.system.context.SystemAggregateContextImpl;
+import org.apache.tuscany.core.system.context.SystemScopeStrategy;
+import org.apache.tuscany.model.assembly.Aggregate;
+import org.apache.tuscany.model.assembly.Extensible;
+import org.apache.tuscany.model.scdl.loader.SCDLModelLoader;
+
+/**
+ * Implementation of a RuntimeContext that forms the foundation for a Tuscany environment.
+ *
+ * @version $Rev$ $Date$
+ */
+public class RuntimeContextImpl extends AbstractContext implements RuntimeContext {
+
+ private final List<RuntimeConfigurationBuilder> builders;
+
+ private final List<SCDLModelLoader> loaders;
+
+ // the top-level wire builder in the runtime
+ private final HierarchicalWireBuilder wireBuilder;
+
+ private final List<RuntimeEventListener> listeners = new ArrayList(1);
+
+ private final AggregateContext rootContext;
+
+ private final SystemAggregateContext systemContext;
+
+ private final MonitorFactory monitorFactory;
+
+ /**
+ * Default constructor that creates a runtime with a NullMonitorFactory and no builders.
+ */
+ public RuntimeContextImpl() {
+ this(new NullMonitorFactory(), null, null, null);
+ }
+
+ /**
+ * Constructor for creating a runtime with a specified MonitorFactory and pre-defined builders.
+ *
+ * @param monitorFactory the default {@link MonitorFactory} for this runtime
+ * @param builders a list of builders automatically made available; may be null
+ * @param wireBuilder the top-level hierarchical wire builder for the runtime; if not specified, a default
+ * implementation will be used
+ */
+ public RuntimeContextImpl(MonitorFactory monitorFactory, List<SCDLModelLoader> loaders,
+ List<RuntimeConfigurationBuilder> builders, HierarchicalWireBuilder wireBuilder) {
+ super(RUNTIME);
+ this.monitorFactory = monitorFactory;
+ this.builders = (builders == null) ? new ArrayList(1) : builders;
+ this.loaders = (loaders == null) ? new ArrayList(1) : loaders;
+ this.wireBuilder = (wireBuilder == null) ? new DefaultWireBuilder() : wireBuilder;
+
+ rootContext = new AggregateContextImpl(ROOT, this, this, new RuntimeScopeStrategy(), new EventContextImpl(), this, monitorFactory);
+ systemContext = new SystemAggregateContextImpl(SYSTEM, this, this, new SystemScopeStrategy(), new EventContextImpl(), this, monitorFactory);
+ }
+
+ /**
+ * Specialized constructor that allows the default implementations of the root and system contexts to be
+ * overridden.
+ *
+ * @param monitorFactory the default {@link MonitorFactory} for this runtime
+ * @param rootContext the context to use for the root of the user context tree
+ * @param systemContext the context to use for the root of the system context tree
+ * @param builders a list of builders automatically made available; may be null
+ * @param wireBuilder the top-level hierarchical wire builder for the runtime; if not specified, a default
+ * implementation will be used
+ */
+ public RuntimeContextImpl(MonitorFactory monitorFactory, AggregateContext rootContext, SystemAggregateContext systemContext,
+ List<SCDLModelLoader> loaders, List<RuntimeConfigurationBuilder> builders, HierarchicalWireBuilder wireBuilder) {
+ super(RUNTIME);
+ this.rootContext = rootContext;
+ this.systemContext = systemContext;
+ this.monitorFactory = monitorFactory;
+ this.loaders = (loaders == null) ? new ArrayList(1) : loaders;
+ this.builders = (builders == null) ? new ArrayList(1) : builders;
+ this.wireBuilder = (wireBuilder == null) ? new DefaultWireBuilder() : wireBuilder;
+ }
+
+ public void start() throws CoreRuntimeException {
+ if (lifecycleState == RUNNING) {
+ return;
+ }
+ systemContext.start();
+ rootContext.start();
+ lifecycleState = RUNNING;
+ }
+
+ public void stop() throws CoreRuntimeException {
+ if (lifecycleState == STOPPED) {
+ return;
+ }
+ rootContext.stop();
+ systemContext.stop();
+ lifecycleState = STOPPED;
+ }
+
+ public void addBuilder(RuntimeConfigurationBuilder builder) {
+ assert (builder != null) : "Builder was null";
+ builders.add(builder);
+ }
+
+ public void addBuilder(WireBuilder builder) {
+ assert (builder != null) : "Builder was null";
+ wireBuilder.addWireBuilder(builder);
+ }
+
+ public void addLoader(SCDLModelLoader loader) {
+ assert (loader != null) : "Loader was null";
+ loaders.add(loader);
+ }
+
+ public AggregateContext getContext(String ctxName) {
+ checkRunning();
+ if (ROOT.equals(ctxName)) {
+ return rootContext;
+ } else if (SYSTEM.equals(ctxName)) {
+ return systemContext;
+ }
+ return (AggregateContext) rootContext.getContext(ctxName);
+ }
+
+ public AggregateContext getRootContext() {
+ checkRunning();
+ return rootContext;
+ }
+
+ public SystemAggregateContext getSystemContext() {
+ checkRunning();
+ return systemContext;
+ }
+
+ public MonitorFactory getMonitorFactory() {
+ return monitorFactory;
+ }
+
+ public void registerModelObject(Extensible model) throws ConfigurationException {
+ assert (model != null) : "Model was null";
+ // note do not configure or build model object since the root context will perform a call back
+ rootContext.registerModelObject(model);
+ }
+
+ public void registerModelObjects(List<Extensible> models) throws ConfigurationException {
+ for (Extensible model : models) {
+ registerModelObject(model);
+ }
+ }
+
+ public void registerListener(RuntimeEventListener listener) {
+ assert (listener != null) : "Listener cannot be null";
+ listeners.add(listener);
+ }
+
+ public void fireEvent(int eventType, Object message) throws EventException {
+ checkRunning();
+ for (RuntimeEventListener listener : listeners) {
+ listener.onEvent(eventType, message);
+ }
+ }
+
+ public AggregateContext getParent() {
+ return null; // there is no parent
+ }
+
+ public Object locateService(String serviceName) {
+ return null;
+ }
+
+ public Object locateInstance(String serviceName) {
+ return null;
+ }
+
+ public Object getInstance(QualifiedName qName) throws TargetException {
+ return getSystemContext().getInstance(qName);
+ }
+
+ public Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ return getInstance(qName);
+ }
+
+ // ----------------------------------
+ // ConfigurationContext methods
+ // ----------------------------------
+
+ public synchronized void build(AggregateContext parent, Extensible model) throws BuilderConfigException {
+ AssemblyVisitor visitor = new AssemblyVisitor(parent, builders);
+ visitor.start(model);
+ }
+
+ public void configure(Extensible model) throws ConfigurationException {
+ }
+
+ public void wire(ProxyFactory sourceFactory, ProxyFactory targetFactory, Class targetType, boolean downScope,
+ ScopeContext targetScopeContext) throws BuilderConfigException {
+ wireBuilder.connect(sourceFactory, targetFactory, targetType, downScope, targetScopeContext);
+ }
+
+ public void wire(ProxyFactory targetFactory, Class targetType, ScopeContext targetScopeContext) throws BuilderConfigException {
+ wireBuilder.completeTargetChain(targetFactory, targetType, targetScopeContext);
+ }
+
+ // ----------------------------------
+ // AutowireContext methods
+ // ----------------------------------
+
+ public <T> T resolveInstance(Class<T> instanceInterface) throws AutowireResolutionException {
+ if (MonitorFactory.class.equals(instanceInterface)) {
+ return instanceInterface.cast(monitorFactory);
+ } else if (ConfigurationContext.class.equals(instanceInterface)) {
+ return instanceInterface.cast(this);
+ } else if (AutowireContext.class.equals(instanceInterface)) {
+ return instanceInterface.cast(this);
+ } else if (RuntimeContext.class.equals(instanceInterface)) {
+ return instanceInterface.cast(this);
+ } else {
+ // autowire to system components
+ return instanceInterface.cast(getSystemContext().resolveInstance(instanceInterface));
+ }
+ }
+
+ // ----------------------------------
+ // InstanceContext methods
+ // ----------------------------------
+
+ public Object getImplementationInstance() throws TargetException {
+ return this;
+ }
+
+ public Object getImplementationInstance(boolean notify) throws TargetException {
+ return this;
+ }
+
+ public Aggregate getAggregate() {
+ return systemContext.getAggregate();
+ }
+
+ // ----------------------------------
+ // Private methods
+ // ----------------------------------
+
+ private void checkRunning() {
+ if (lifecycleState != RUNNING) {
+ throw new IllegalStateException("Context must be in RUNNING state");
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeMonitor.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeMonitor.java
new file mode 100644
index 0000000000..c1b87d6a13
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeMonitor.java
@@ -0,0 +1,32 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.runtime;
+
+import org.apache.tuscany.common.TuscanyException;
+import org.apache.tuscany.common.TuscanyRuntimeException;
+
+
+/**
+ * Serves as a top-level error logging monitor
+ *
+ * @version $Rev$ $Date$
+ */
+public interface RuntimeMonitor {
+
+ public void log(TuscanyRuntimeException e);
+
+ public void log(TuscanyException e);
+
+}
+
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeScopeStrategy.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeScopeStrategy.java
new file mode 100644
index 0000000000..77ddd78d15
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeScopeStrategy.java
@@ -0,0 +1,46 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.runtime;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.core.context.scope.AbstractScopeStrategy;
+import org.apache.tuscany.core.context.scope.AggregateScopeContext;
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * Implements a {@link org.apache.tuscany.core.context.ScopeStrategy} for a runtime context. Specifically, a runtime
+ * context has only one scope, {@link org.apache.tuscany.model.assembly.Scope#AGGREGATE}
+ *
+ * @version $Rev$ $Date$
+ */
+public class RuntimeScopeStrategy extends AbstractScopeStrategy {
+
+ public RuntimeScopeStrategy() {
+ }
+
+ public Map<Scope, ScopeContext> createScopes(EventContext eventContext) {
+ ScopeContext aggregrateScope = new AggregateScopeContext(eventContext);
+ Map<Scope, ScopeContext> scopes = new HashMap();
+ scopes.put(Scope.AGGREGATE, aggregrateScope);
+ return scopes;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/Autowire.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/Autowire.java
new file mode 100644
index 0000000000..bcb06812e8
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/Autowire.java
@@ -0,0 +1,21 @@
+package org.apache.tuscany.core.system.annotation;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * A system annotation to inject an autowired instance
+ *
+ * @version $Rev$ $Date$
+ */
+@Target( { METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface Autowire {
+
+ public boolean required() default true;
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/ParentContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/ParentContext.java
new file mode 100644
index 0000000000..f3d2c0216b
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/ParentContext.java
@@ -0,0 +1,33 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.annotation;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * A system annotation to inject the parent context
+ *
+ * @version $Rev$ $Date$
+ */
+
+@Target( { METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface ParentContext {
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemAssemblyFactory.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemAssemblyFactory.java
new file mode 100644
index 0000000000..d230df8dd7
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemAssemblyFactory.java
@@ -0,0 +1,38 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.assembly;
+
+import org.apache.tuscany.model.assembly.AssemblyFactory;
+
+/**
+ * A factory for building system assembly model artifacts
+ *
+ * @version $Rev$ $Date$
+ */
+public interface SystemAssemblyFactory extends AssemblyFactory {
+
+ /**
+ * Returns an assembly model artifact representing a system component implementation
+ */
+ SystemImplementation createSystemImplementation();
+
+ /**
+ * Returns an assembly model artifact representing a system binding
+ */
+ SystemBinding createSystemBinding();
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemBinding.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemBinding.java
new file mode 100644
index 0000000000..edc7c87c85
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemBinding.java
@@ -0,0 +1,37 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.assembly;
+
+import org.apache.tuscany.model.assembly.Binding;
+
+/**
+ * Represents a system binding
+ *
+ * @version $Rev$ $Date$
+ */
+public interface SystemBinding extends Binding {
+
+ /**
+ * Returns the qualified name of the wire target the binding is associated with in component/service form
+ */
+ public String getTargetName();
+
+ /**
+ * Sets the qualified name of the wire target the binding is associated with in component/service form
+ */
+ public void setTargetName(String name);
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemImplementation.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemImplementation.java
new file mode 100644
index 0000000000..7fae0ebad3
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemImplementation.java
@@ -0,0 +1,38 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.assembly;
+
+import org.apache.tuscany.model.assembly.ComponentImplementation;
+
+/**
+ * Represents a system component implementation
+ *
+ * @version $Rev$ $Date$
+ */
+public interface SystemImplementation extends ComponentImplementation {
+
+ /**
+ * Returns the implementation class of the system component
+ */
+ Class getImplementationClass();
+
+ /**
+ * Sets the implementation class of the system component
+ */
+ void setImplementationClass(Class value);
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemAssemblyFactoryImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemAssemblyFactoryImpl.java
new file mode 100644
index 0000000000..668b7dd8b1
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemAssemblyFactoryImpl.java
@@ -0,0 +1,41 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.assembly.impl;
+
+import org.apache.tuscany.core.system.assembly.SystemAssemblyFactory;
+import org.apache.tuscany.core.system.assembly.SystemBinding;
+import org.apache.tuscany.core.system.assembly.SystemImplementation;
+import org.apache.tuscany.model.assembly.impl.AssemblyFactoryImpl;
+
+/**
+ * The default implementation of the system assembly factory
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemAssemblyFactoryImpl extends AssemblyFactoryImpl implements SystemAssemblyFactory {
+
+ public SystemAssemblyFactoryImpl() {
+ }
+
+ public SystemImplementation createSystemImplementation() {
+ return new SystemImplementationImpl();
+ }
+
+ public SystemBinding createSystemBinding() {
+ return new SystemBindingImpl();
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemBindingImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemBindingImpl.java
new file mode 100644
index 0000000000..a9996065e2
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemBindingImpl.java
@@ -0,0 +1,41 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.assembly.impl;
+
+import org.apache.tuscany.core.system.assembly.SystemBinding;
+import org.apache.tuscany.model.assembly.impl.BindingImpl;
+
+/**
+ * The default implementation of the system binding assembly artifact
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemBindingImpl extends BindingImpl implements SystemBinding {
+
+ protected SystemBindingImpl() {
+ }
+
+ private String name;
+
+ public String getTargetName() {
+ return name;
+ }
+
+ public void setTargetName(String name) {
+ this.name = name;
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemImplementationImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemImplementationImpl.java
new file mode 100644
index 0000000000..5d54132464
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemImplementationImpl.java
@@ -0,0 +1,94 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.assembly.impl;
+
+import java.net.URL;
+
+import org.apache.tuscany.core.config.ComponentTypeIntrospector;
+import org.apache.tuscany.core.config.ConfigurationException;
+import org.apache.tuscany.core.config.JavaIntrospectionHelper;
+import org.apache.tuscany.core.config.impl.Java5ComponentTypeIntrospector;
+import org.apache.tuscany.core.system.assembly.SystemImplementation;
+import org.apache.tuscany.model.assembly.AssemblyFactory;
+import org.apache.tuscany.model.assembly.AssemblyModelContext;
+import org.apache.tuscany.model.assembly.ComponentType;
+import org.apache.tuscany.model.assembly.Scope;
+import org.apache.tuscany.model.assembly.Service;
+import org.apache.tuscany.model.assembly.impl.AssemblyFactoryImpl;
+import org.apache.tuscany.model.assembly.impl.ComponentImplementationImpl;
+
+/**
+ * The default implementation of the system implementation assembly artifact
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemImplementationImpl extends ComponentImplementationImpl implements SystemImplementation {
+
+ private Class<?> implementationClass;
+
+ private AssemblyModelContext modelContext;
+
+ protected SystemImplementationImpl() {
+ }
+
+ public Class getImplementationClass() {
+ return implementationClass;
+ }
+
+ public void setImplementationClass(Class value) {
+ checkNotFrozen();
+ implementationClass = value;
+ }
+
+ public void initialize(AssemblyModelContext context) {
+ if (isInitialized())
+ return;
+ this.modelContext = context;
+ // Initialize the component type
+ ComponentType componentType = getComponentType();
+ if (componentType == null) {
+ componentType = createComponentType(implementationClass);
+ setComponentType(componentType);
+ }
+ super.initialize(modelContext);
+ }
+
+ /**
+ * Creates the component type
+ */
+ private ComponentType createComponentType(Class<?> implClass) {
+ ComponentType componentType;
+ String baseName = JavaIntrospectionHelper.getBaseName(implClass);
+ URL componentTypeFile = implClass.getResource(baseName + ".componentType");
+ if (componentTypeFile != null) {
+ componentType = modelContext.getAssemblyLoader().loadComponentType(componentTypeFile.toString());
+ // FIXME workaround for TUSCANY-46 where the scope is not read - default system implementations to MODULE scope
+ for (Service service : componentType.getServices()) {
+ service.getServiceContract().setScope(Scope.MODULE);
+ }
+ } else {
+ AssemblyFactory factory = new AssemblyFactoryImpl();
+ ComponentTypeIntrospector introspector = new Java5ComponentTypeIntrospector(factory);
+ try {
+ componentType = introspector.introspect(implClass);
+ } catch (ConfigurationException e) {
+ throw new IllegalArgumentException("Unable to introspect implementation class: " + implClass.getName(), e);
+ }
+ }
+ return componentType;
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemComponentContextBuilder.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemComponentContextBuilder.java
new file mode 100644
index 0000000000..ac65a3de49
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemComponentContextBuilder.java
@@ -0,0 +1,383 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.builder;
+
+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.common.monitor.MonitorFactory;
+import org.apache.tuscany.core.builder.BuilderConfigException;
+import org.apache.tuscany.core.builder.BuilderException;
+import org.apache.tuscany.core.builder.NoAccessorException;
+import org.apache.tuscany.core.builder.RuntimeConfigurationBuilder;
+import org.apache.tuscany.core.builder.UnknownTypeException;
+import org.apache.tuscany.core.config.JavaIntrospectionHelper;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.AutowireContext;
+import org.apache.tuscany.core.context.ConfigurationContext;
+import org.apache.tuscany.core.context.SystemAggregateContext;
+import org.apache.tuscany.core.context.impl.AggregateContextImpl;
+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.MethodEventInvoker;
+import org.apache.tuscany.core.injection.MethodInjector;
+import org.apache.tuscany.core.injection.ObjectCreationException;
+import org.apache.tuscany.core.injection.ReferenceTargetFactory;
+import org.apache.tuscany.core.injection.SDOObjectFactory;
+import org.apache.tuscany.core.injection.SingletonObjectFactory;
+import org.apache.tuscany.core.runtime.RuntimeContext;
+import org.apache.tuscany.core.system.annotation.Autowire;
+import org.apache.tuscany.core.system.annotation.ParentContext;
+import org.apache.tuscany.core.system.assembly.SystemImplementation;
+import org.apache.tuscany.core.system.config.SystemComponentRuntimeConfiguration;
+import org.apache.tuscany.core.system.context.SystemAggregateContextImpl;
+import org.apache.tuscany.model.assembly.AssemblyModelObject;
+import org.apache.tuscany.model.assembly.Component;
+import org.apache.tuscany.model.assembly.ComponentImplementation;
+import org.apache.tuscany.model.assembly.ConfiguredProperty;
+import org.apache.tuscany.model.assembly.ConfiguredReference;
+import org.apache.tuscany.model.assembly.ConfiguredService;
+import org.apache.tuscany.model.assembly.Module;
+import org.apache.tuscany.model.assembly.Scope;
+import org.osoa.sca.annotations.ComponentName;
+import org.osoa.sca.annotations.Context;
+import org.osoa.sca.annotations.Destroy;
+import org.osoa.sca.annotations.Init;
+
+import commonj.sdo.DataObject;
+
+/**
+ * Decorates components whose implementation type is a
+ * {@link org.apache.tuscany.core.system.assembly.SystemImplementation} with the appropriate runtime configuration.
+ * System components are not proxied.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemComponentContextBuilder implements RuntimeConfigurationBuilder<AggregateContext> {
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public SystemComponentContextBuilder() {
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public void build(AssemblyModelObject modelObject, AggregateContext parentContext) throws BuilderException {
+ if (!(modelObject instanceof Component)) {
+ return;
+ }
+ Component component = (Component) modelObject;
+
+ Class implClass = null;
+ Scope scope = null;
+
+ // Get the component implementation
+ ComponentImplementation componentImplementation = component.getComponentImplementation();
+ if (componentImplementation instanceof SystemImplementation
+ && componentImplementation.getRuntimeConfiguration() == null) {
+
+ // The component is a system component, implemented by a Java class
+ SystemImplementation javaImpl = (SystemImplementation) componentImplementation;
+ scope = componentImplementation.getComponentType().getServices().get(0).getServiceContract().getScope();
+ implClass = javaImpl.getImplementationClass();
+
+ } else if (componentImplementation instanceof Module) {
+ if (((Module)componentImplementation).getName().startsWith("org.apache.tuscany.core.system")) {
+
+ // The component is a system module component, fix the implementation class to our implementation
+ // of system module component context
+ implClass=SystemAggregateContextImpl.class;
+ scope = Scope.AGGREGATE;
+
+ } else {
+
+ // The component is an app module component, fix the implementation class to our implementation
+ // of app module component context
+ implClass=AggregateContextImpl.class;
+ scope = Scope.AGGREGATE;
+
+ }
+
+ } else {
+ return;
+ }
+
+ // FIXME scope
+ Set<Field> fields;
+ Set<Method> methods;
+ try {
+ fields = JavaIntrospectionHelper.getAllFields(implClass);
+ methods = JavaIntrospectionHelper.getAllUniqueMethods(implClass);
+ String name = component.getName();
+ Constructor ctr = implClass.getConstructor((Class[]) null);
+
+ List<Injector> injectors = new ArrayList();
+
+ // handle properties
+ List<ConfiguredProperty> configuredProperties = component.getConfiguredProperties();
+ if (configuredProperties != null) {
+ for (ConfiguredProperty property : configuredProperties) {
+ Injector injector = createPropertyInjector(property, fields, methods);
+ injectors.add(injector);
+ }
+ }
+
+ //FIXME do not inject references on an application module yet
+ if (implClass!=AggregateContextImpl.class) {
+ // handle references
+ List<ConfiguredReference> configuredReferences = component.getConfiguredReferences();
+ if (configuredReferences != null) {
+ for (ConfiguredReference reference : configuredReferences) {
+ Injector injector = createReferenceInjector(parentContext.getName(), component.getName(), parentContext,
+ reference, fields, methods);
+ injectors.add(injector);
+ }
+ }
+ }
+
+ // create factory for the component implementation type
+ EventInvoker initInvoker = null;
+ boolean eagerInit = false;
+ EventInvoker destroyInvoker = null;
+ for (Field field : fields) {
+ ComponentName compName = field.getAnnotation(ComponentName.class);
+ if (compName != null) {
+ Injector injector = new FieldInjector(field, new SingletonObjectFactory(name));
+ injectors.add(injector);
+ }
+ Context context = field.getAnnotation(Context.class);
+ if (context != null) {
+ Injector injector = new FieldInjector(field, new SingletonObjectFactory(parentContext));
+ injectors.add(injector);
+ }
+ ParentContext parentField = field.getAnnotation(ParentContext.class);
+ if (parentField != null) {
+ if (!(parentContext instanceof AggregateContext)) {
+ BuilderConfigException e = new BuilderConfigException("Component must be a child of");
+ e.setIdentifier(AggregateContext.class.getName());
+ throw e;
+ }
+ Injector injector = new FieldInjector(field, new SingletonObjectFactory((parentContext)));
+ injectors.add(injector);
+ }
+ Autowire autowire = field.getAnnotation(Autowire.class);
+ if (autowire != null) {
+ if (!(parentContext instanceof AutowireContext)) {
+ BuilderConfigException e = new BuilderConfigException("Parent context must implement");
+ e.setIdentifier(AutowireContext.class.getName());
+ throw e;
+ }
+ AutowireContext ctx = (AutowireContext) parentContext;
+ // for system aggregate context types, only allow autowire of certain types, otherwise we have a
+ // chicken-and-egg problem
+ if (SystemAggregateContext.class.isAssignableFrom(implClass)
+ && !(field.getType().equals(ConfigurationContext.class)
+ || field.getType().equals(MonitorFactory.class)
+ || field.getType().equals(RuntimeContext.class) || field.getType().equals(
+ AutowireContext.class))) {
+ BuilderConfigException e = new BuilderConfigException("Illegal autowire type for system context");
+ e.setIdentifier(field.getType().getName());
+ throw e;
+ }
+
+ Object o = ctx.resolveInstance(field.getType());
+ if (autowire.required() && o == null) {
+ BuilderConfigException e = new BuilderConfigException("No autowire found for field");
+ e.setIdentifier(field.getName());
+ throw e;
+ }
+ Injector injector = new FieldInjector(field, new SingletonObjectFactory(o));
+ injectors.add(injector);
+ }
+ }
+ for (Method method : methods) {
+ Init init = method.getAnnotation(Init.class);
+ if (init != null && initInvoker == null) {
+ initInvoker = new MethodEventInvoker(method);
+ eagerInit = init.eager();
+ continue;
+ }
+ Destroy destroy = method.getAnnotation(Destroy.class);
+ if (destroy != null && destroyInvoker == null) {
+ destroyInvoker = new MethodEventInvoker(method);
+ continue;
+ }
+ ComponentName compName = method.getAnnotation(ComponentName.class);
+ if (compName != null) {
+ Injector injector = new MethodInjector(method, new SingletonObjectFactory(name));
+ injectors.add(injector);
+ }
+ Context context = method.getAnnotation(Context.class);
+ if (context != null) {
+ Injector injector = new MethodInjector(method, new SingletonObjectFactory(parentContext));
+ injectors.add(injector);
+ }
+ ParentContext parentMethod = method.getAnnotation(ParentContext.class);
+ if (parentMethod != null) {
+ if (!(parentContext instanceof AggregateContext)) {
+ BuilderConfigException e = new BuilderConfigException("Component must be a child of ");
+ e.setIdentifier(AggregateContext.class.getName());
+ throw e;
+ }
+ Injector injector = new MethodInjector(method, new SingletonObjectFactory((parentContext)));
+ injectors.add(injector);
+ }
+ Autowire autowire = method.getAnnotation(Autowire.class);
+ if (autowire != null) {
+ if (!(parentContext instanceof AutowireContext)) {
+ BuilderConfigException e = new BuilderConfigException("Parent context must implement)");
+ e.setIdentifier(AutowireContext.class.getName());
+ throw e;
+ }
+ if (method.getParameterTypes() == null || method.getParameterTypes().length != 1) {
+ BuilderConfigException e = new BuilderConfigException(
+ "Autowire setter methods must take one parameter");
+ e.setIdentifier(method.getName());
+ throw e;
+ }
+ AutowireContext ctx = (AutowireContext) parentContext;
+ Class paramType = method.getParameterTypes()[0];
+ // for system aggregate context types, only allow autowire of certain types, otherwise we have a
+ // chicken-and-egg problem
+ if (SystemAggregateContext.class.isAssignableFrom(implClass)
+ && !(paramType.equals(ConfigurationContext.class) || paramType.equals(MonitorFactory.class)
+ || paramType.equals(RuntimeContext.class) || paramType.equals(AutowireContext.class))) {
+ BuilderConfigException e = new BuilderConfigException("Illegal autowire type for system context");
+ e.setIdentifier(paramType.getName());
+ throw e;
+ }
+ Object o = ctx.resolveInstance(paramType);
+ if (autowire.required() && o == null) {
+ BuilderConfigException e = new BuilderConfigException("No autowire found for method ");
+ e.setIdentifier(method.getName());
+ throw e;
+ }
+
+ Injector injector = new MethodInjector(method, new SingletonObjectFactory(o));
+ injectors.add(injector);
+ }
+ }
+ // decorate the logical model
+ SystemComponentRuntimeConfiguration config = new SystemComponentRuntimeConfiguration(name,
+ JavaIntrospectionHelper.getDefaultConstructor(implClass), injectors, eagerInit, initInvoker,
+ destroyInvoker, scope);
+ componentImplementation.setRuntimeConfiguration(config);
+ } catch (BuilderConfigException e) {
+ e.addContextName(component.getName());
+ e.addContextName(parentContext.getName());
+ throw e;
+ } catch (NoSuchMethodException e) {
+ BuilderConfigException ce = new BuilderConfigException("Class does not have a no-arg constructor", e);
+ ce.setIdentifier(implClass.getName());
+ throw ce;
+ }
+ }
+
+ // ----------------------------------
+ // Private methods
+ // ----------------------------------
+
+ /**
+ * Creates an <code>Injector</code> for component properties
+ */
+ private Injector createPropertyInjector(ConfiguredProperty property, Set<Field> fields, Set<Method> methods)
+ throws NoAccessorException {
+ Object value = property.getValue();
+ String propName = property.getProperty().getName();
+ // @FIXME is this how to get property type of object
+ Class type = value.getClass();
+
+ // There is no efficient way to do this
+ Method method = null;
+ Field field = JavaIntrospectionHelper.findClosestMatchingField(propName, type, fields);
+ if (field == null) {
+ method = JavaIntrospectionHelper.findClosestMatchingMethod(propName, new Class[] { type }, methods);
+ if (method == null) {
+ throw new NoAccessorException(propName);
+ }
+ }
+ Injector injector = null;
+ // FIXME support types other than String
+ if (value instanceof DataObject) {
+ if (field != null) {
+ injector = new FieldInjector(field, new SDOObjectFactory((DataObject) value));
+ } else {
+ injector = new MethodInjector(method, new SDOObjectFactory((DataObject) value));
+ }
+ } else if (JavaIntrospectionHelper.isImmutable(type)) {
+ if (field != null) {
+ injector = new FieldInjector(field, new SingletonObjectFactory(value));
+ } else {
+ injector = new MethodInjector(method, new SingletonObjectFactory(value));
+ }
+ } else {
+ if (field != null) {
+ throw new UnknownTypeException(field.getName());
+ } else {
+ throw new UnknownTypeException(method.getName());
+ }
+ }
+ return injector;
+
+ }
+
+ /**
+ * Creates an <code>Injector</code> for service references
+ */
+ private Injector createReferenceInjector(String moduleName, String componentName, AggregateContext parentContext,
+ ConfiguredReference reference, Set<Field> fields, Set<Method> methods) throws NoAccessorException,
+ BuilderConfigException {
+ String refName = reference.getReference().getName();
+ List<ConfiguredService> services = reference.getTargetConfiguredServices();
+ Class type;
+ if (services.size() == 1) {
+ // get the interface
+ type = reference.getReference().getServiceContract().getInterface();
+ } else {
+ // FIXME do we support arrays?
+ type = List.class;
+ }
+ Method method = null;
+ Field field = JavaIntrospectionHelper.findClosestMatchingField(refName, type, fields);
+ if (field == null) {
+ method = JavaIntrospectionHelper.findClosestMatchingMethod(refName, new Class[] { type }, methods);
+ if (method == null) {
+ throw new NoAccessorException(refName);
+ }
+ }
+ Injector injector;
+ try {
+ if (field != null) {
+ injector = new FieldInjector(field, new ReferenceTargetFactory(reference, parentContext));
+ } else {
+ injector = new MethodInjector(method, new ReferenceTargetFactory(reference, parentContext));
+ }
+ } catch (ObjectCreationException e) {
+ BuilderConfigException ce = new BuilderConfigException("Error configuring reference", e);
+ ce.setIdentifier(refName);
+ throw ce;
+ }
+ return injector;
+
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemEntryPointBuilder.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemEntryPointBuilder.java
new file mode 100644
index 0000000000..6520fc0557
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemEntryPointBuilder.java
@@ -0,0 +1,63 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.builder;
+
+import org.apache.tuscany.core.builder.BuilderException;
+import org.apache.tuscany.core.builder.RuntimeConfigurationBuilder;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.injection.FactoryInitException;
+import org.apache.tuscany.core.injection.ReferenceTargetFactory;
+import org.apache.tuscany.core.system.assembly.SystemBinding;
+import org.apache.tuscany.core.system.config.SystemEntryPointRuntimeConfiguration;
+import org.apache.tuscany.model.assembly.AssemblyModelObject;
+import org.apache.tuscany.model.assembly.EntryPoint;
+
+/**
+ * Decorates the logical model with entry point context configuration builders
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemEntryPointBuilder implements RuntimeConfigurationBuilder<AggregateContext> {
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public SystemEntryPointBuilder() {
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public void build(AssemblyModelObject modelObject, AggregateContext context) throws BuilderException {
+ if (!(modelObject instanceof EntryPoint)) {
+ return;
+ }
+ EntryPoint entryPoint = (EntryPoint) modelObject;
+ if (!(entryPoint.getBindings().get(0) instanceof SystemBinding)
+ || entryPoint.getConfiguredReference().getRuntimeConfiguration() != null) {
+ return;
+ }
+ try {
+ SystemEntryPointRuntimeConfiguration config = new SystemEntryPointRuntimeConfiguration(entryPoint.getName(),
+ new ReferenceTargetFactory(entryPoint.getConfiguredReference(), context));
+ entryPoint.getConfiguredReference().setRuntimeConfiguration(config);
+ } catch (FactoryInitException e) {
+ e.addContextName(entryPoint.getName());
+ e.addContextName(context.getName());
+ throw e;
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemExternalServiceBuilder.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemExternalServiceBuilder.java
new file mode 100644
index 0000000000..dc00e6505f
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemExternalServiceBuilder.java
@@ -0,0 +1,77 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.builder;
+
+import org.apache.tuscany.core.builder.BuilderConfigException;
+import org.apache.tuscany.core.builder.BuilderException;
+import org.apache.tuscany.core.builder.RuntimeConfigurationBuilder;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.AutowireContext;
+import org.apache.tuscany.core.injection.ReferenceTargetFactory;
+import org.apache.tuscany.core.system.assembly.SystemBinding;
+import org.apache.tuscany.core.system.config.SystemExternalServiceRuntimeConfiguration;
+import org.apache.tuscany.core.system.injection.AutowireFactory;
+import org.apache.tuscany.model.assembly.AssemblyModelObject;
+import org.apache.tuscany.model.assembly.ExternalService;
+
+/**
+ * Creates runtime configurations for system type external services
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemExternalServiceBuilder implements RuntimeConfigurationBuilder<AggregateContext> {
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public SystemExternalServiceBuilder() {
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public void build(AssemblyModelObject modelObject, AggregateContext context) throws BuilderException {
+ if (!(modelObject instanceof ExternalService)) {
+ return;
+ }
+ ExternalService externalService = (ExternalService) modelObject;
+ if (externalService.getConfiguredService() != null
+ && externalService.getConfiguredService().getRuntimeConfiguration() != null) {
+ return;
+ } else if (externalService.getBindings() == null || externalService.getBindings().size() < 1
+ || !(externalService.getBindings().get(0) instanceof SystemBinding)) {
+ return;
+ }
+ SystemBinding binding = (SystemBinding)externalService.getBindings().get(0);
+ if (binding.getTargetName() != null) {
+ SystemExternalServiceRuntimeConfiguration config = new SystemExternalServiceRuntimeConfiguration(externalService
+ .getName(), new ReferenceTargetFactory(binding.getTargetName(), context));
+ externalService.getConfiguredService().setRuntimeConfiguration(config);
+ } else if (externalService.getConfiguredService().getService().getServiceContract().getInterface() != null) {
+ // autowire
+ Class<?> claz = externalService.getConfiguredService().getService().getServiceContract().getInterface();
+ if (claz == null) {
+ BuilderException e = new BuilderConfigException("Interface type not specified");
+ e.setIdentifier(externalService.getName());
+ e.addContextName(externalService.getName());
+ e.addContextName(context.getName());
+ throw e;
+ }
+ SystemExternalServiceRuntimeConfiguration config = new SystemExternalServiceRuntimeConfiguration(externalService
+ .getName(), new AutowireFactory(claz, (AutowireContext) context));
+ externalService.getConfiguredService().setRuntimeConfiguration(config);
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemComponentRuntimeConfiguration.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemComponentRuntimeConfiguration.java
new file mode 100644
index 0000000000..cf05059b90
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemComponentRuntimeConfiguration.java
@@ -0,0 +1,140 @@
+package org.apache.tuscany.core.system.config;
+
+import java.lang.reflect.Constructor;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.core.builder.ContextCreationException;
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.injection.EventInvoker;
+import org.apache.tuscany.core.injection.Injector;
+import org.apache.tuscany.core.injection.PojoObjectFactory;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.system.context.SystemComponentContext;
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * A RuntimeConfiguration that handles system component implementation types
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemComponentRuntimeConfiguration implements RuntimeConfiguration<InstanceContext> {
+
+ // the component name as configured in the hosting module
+ private String name;
+
+ // the implementation type constructor
+ private Constructor ctr;
+
+ // injectors for properties, references and other metadata values such as @Context
+ private List<Injector> setters;
+
+ // an invoker for a method decorated with @Init
+ private EventInvoker init;
+
+ // whether the component should be eagerly initialized when its scope starts
+ private boolean eagerInit;
+
+ // an invoker for a method decorated with @Destroy
+ private EventInvoker destroy;
+
+ // the scope of the implementation instance
+ private Scope scope;
+
+ // if the component implementation scope is stateless
+ private boolean stateless;
+
+ // if the component implementation is an aggregate context
+ private boolean isAggregate;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ /**
+ * Creates the runtime configuration
+ *
+ * @param name the SCDL name of the component the context refers to
+ * @param ctr the implementation type constructor
+ * @param setters a collection of <code>Injectors</code> used to configure properties, references and other meta
+ * data values on implementation instances
+ * @param eagerInit whether the component should be eagerly initialized
+ * @param init an <code>Invoker</code> pointing to a method on the implementation type decorated with
+ * <code>@Init</code>
+ * @param destroy an <code>Invoker</code> pointing to a method on the implementation type decorated with
+ * <code>@Destroy</code>
+ * @param scope the scope of the component implementation type
+ */
+ public SystemComponentRuntimeConfiguration(String name, Constructor ctr, List<Injector> setters, boolean eagerInit,
+ EventInvoker init, EventInvoker destroy, Scope scope) {
+ assert (name != null) : "Name was null";
+ assert (ctr != null) : "Constructor was null";
+ assert (setters != null) : "Setters were null";
+ this.name = name;
+ this.ctr = ctr;
+ this.isAggregate = AggregateContext.class.isAssignableFrom(ctr.getDeclaringClass());
+ this.setters = setters;
+ this.eagerInit = eagerInit;
+ this.init = init;
+ this.destroy = destroy;
+ this.scope = scope;
+ stateless = (scope == Scope.INSTANCE);
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public String getName() {
+ return name;
+ }
+
+ public Scope getScope() {
+ return scope;
+ }
+
+ public InstanceContext createInstanceContext() throws ContextCreationException {
+ if (isAggregate) {
+ // aggregate context types are themselves an instance context
+ PojoObjectFactory objectFactory = new PojoObjectFactory(ctr, null, setters);
+ AggregateContext ctx = (AggregateContext) objectFactory.getInstance();
+ ctx.setName(name);
+ return ctx;
+ } else {
+ PojoObjectFactory objectFactory = new PojoObjectFactory(ctr, null, setters);
+ return new SystemComponentContext(name, objectFactory, eagerInit, init, destroy, stateless);
+ }
+ }
+
+ // -- Proxy
+
+ public void prepare() {
+ }
+
+ public void addTargetProxyFactory(String serviceName, ProxyFactory factory) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ProxyFactory getTargetProxyFactory(String serviceName) {
+ return null;
+ }
+
+ public Map<String, ProxyFactory> getTargetProxyFactories() {
+ return null;
+ }
+
+ public void addSourceProxyFactory(String referenceName, ProxyFactory factory) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ProxyFactory getSourceProxyFactory(String referenceName) {
+ return null;
+ }
+
+ public Map<String, ProxyFactory> getSourceProxyFactories() {
+ return null;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemEntryPointRuntimeConfiguration.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemEntryPointRuntimeConfiguration.java
new file mode 100644
index 0000000000..f6c25e9b86
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemEntryPointRuntimeConfiguration.java
@@ -0,0 +1,92 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.config;
+
+import java.util.Map;
+
+import org.apache.tuscany.core.builder.ContextCreationException;
+import org.apache.tuscany.core.builder.ObjectFactory;
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.EntryPointContext;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.system.context.SystemEntryPointContext;
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * Creates {@link SystemEntryPointContext} instances based on an entry point configuration in an assembly model
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemEntryPointRuntimeConfiguration implements RuntimeConfiguration<EntryPointContext> {
+
+ // the name of the entry point
+ private String name;
+
+ // the factory for returning a reference to the implementation instance of the component exposed by the entry point
+ private ObjectFactory factory;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public SystemEntryPointRuntimeConfiguration(String name, ObjectFactory factory) {
+ this.name = name;
+ this.factory = factory;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public EntryPointContext createInstanceContext() throws ContextCreationException {
+ return new SystemEntryPointContext(name, factory);
+ }
+
+ public Scope getScope() {
+ return Scope.MODULE;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ // -- Proxy
+ public void prepare() {
+ }
+
+ public void addTargetProxyFactory(String serviceName, ProxyFactory pFactory) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ProxyFactory getTargetProxyFactory(String serviceName) {
+ return null;
+ }
+
+ public Map<String, ProxyFactory> getTargetProxyFactories() {
+ return null;
+ }
+
+ public void addSourceProxyFactory(String referenceName, ProxyFactory pFactory) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ProxyFactory getSourceProxyFactory(String referenceName) {
+ return null;
+ }
+
+ public Map<String, ProxyFactory> getSourceProxyFactories() {
+ return null;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemExternalServiceRuntimeConfiguration.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemExternalServiceRuntimeConfiguration.java
new file mode 100644
index 0000000000..789982bdcf
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemExternalServiceRuntimeConfiguration.java
@@ -0,0 +1,97 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.config;
+
+import java.util.Map;
+
+import org.apache.tuscany.core.builder.ContextCreationException;
+import org.apache.tuscany.core.builder.ObjectFactory;
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.ExternalServiceContext;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.system.context.SystemExternalServiceContext;
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * Creates system type external service contexts
+ *
+ * @see org.apache.tuscany.core.context.ExternalServiceContext
+ * @see org.apache.tuscany.core.system.context.SystemExternalServiceContext
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemExternalServiceRuntimeConfiguration implements RuntimeConfiguration<ExternalServiceContext> {
+
+ // the name of the external service
+ private String name;
+
+ // the factory for returning a reference to the implementation instance of the component represented by the external service
+ private ObjectFactory factory;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public SystemExternalServiceRuntimeConfiguration(String name, ObjectFactory factory) {
+ assert (name != null) : "Name was null";
+ assert (factory != null) : "Object factory was null";
+ this.name = name;
+ this.factory = factory;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public Scope getScope() {
+ return Scope.MODULE;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public ExternalServiceContext createInstanceContext() throws ContextCreationException {
+ return new SystemExternalServiceContext(name, factory);
+ }
+
+ // -- Proxy
+ public void prepare() {
+ }
+
+ public void addTargetProxyFactory(String serviceName, ProxyFactory pFactory) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ProxyFactory getTargetProxyFactory(String serviceName) {
+ return null;
+ }
+
+ public Map<String, ProxyFactory> getTargetProxyFactories() {
+ return null;
+ }
+
+ public void addSourceProxyFactory(String referenceName, ProxyFactory pFactory) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ProxyFactory getSourceProxyFactory(String referenceName) {
+ return null;
+ }
+
+ public Map<String, ProxyFactory> getSourceProxyFactories() {
+ return null;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemObjectRuntimeConfiguration.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemObjectRuntimeConfiguration.java
new file mode 100644
index 0000000000..06acb12deb
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemObjectRuntimeConfiguration.java
@@ -0,0 +1,92 @@
+/**
+ *
+ * Copyright 2005 BEA Systems Inc.
+ * Copyright 2005 International Business Machines Corporation
+ *
+ * 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.system.config;
+
+import java.util.Map;
+
+import org.apache.tuscany.core.builder.ContextCreationException;
+import org.apache.tuscany.core.builder.ObjectFactory;
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.context.Context;
+import org.apache.tuscany.core.injection.SingletonObjectFactory;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.system.context.SystemComponentContext;
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * A RuntimeConfiguration that contains the configuration needed to convert a simple
+ * Java Object into a component. The object is assumed to be fully initialized and
+ * will always be added with MODULE scope.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemObjectRuntimeConfiguration implements RuntimeConfiguration {
+ private final String name;
+ private final ObjectFactory<?> objectFactory;
+
+ /**
+ * Construct a RuntimeConfiguration for the supplied Java Object.
+ *
+ * @param name the name to be assigned to the resulting component
+ * @param instance the Java Object that provides the implementation
+ */
+ public SystemObjectRuntimeConfiguration(String name, Object instance) {
+ this.name = name;
+ objectFactory = new SingletonObjectFactory(instance);
+ }
+
+ public Context createInstanceContext() throws ContextCreationException {
+ return new SystemComponentContext(name, objectFactory, false, null, null, false);
+ }
+
+ public Scope getScope() {
+ return Scope.MODULE;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void prepare() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void addTargetProxyFactory(String serviceName, ProxyFactory factory) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ProxyFactory getTargetProxyFactory(String serviceName) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Map getTargetProxyFactories() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void addSourceProxyFactory(String referenceName, ProxyFactory factory) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ProxyFactory getSourceProxyFactory(String referenceName) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Map getSourceProxyFactories() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemAggregateContextImpl.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemAggregateContextImpl.java
new file mode 100644
index 0000000000..a2efc35ac1
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemAggregateContextImpl.java
@@ -0,0 +1,666 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.context;
+
+import static org.apache.tuscany.core.context.EventContext.HTTP_SESSION;
+import static org.apache.tuscany.core.context.EventContext.REQUEST_END;
+import static org.apache.tuscany.core.context.EventContext.SESSION_NOTIFY;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.tuscany.common.monitor.MonitorFactory;
+import org.apache.tuscany.core.builder.BuilderConfigException;
+import org.apache.tuscany.core.builder.RuntimeConfiguration;
+import org.apache.tuscany.core.config.ConfigurationException;
+import org.apache.tuscany.core.context.AbstractContext;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.AutowireContext;
+import org.apache.tuscany.core.context.AutowireResolutionException;
+import org.apache.tuscany.core.context.ConfigurationContext;
+import org.apache.tuscany.core.context.ContextInitException;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.DuplicateNameException;
+import org.apache.tuscany.core.context.EntryPointContext;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.EventException;
+import org.apache.tuscany.core.context.InstanceContext;
+import org.apache.tuscany.core.context.LifecycleEventListener;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.RuntimeEventListener;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.core.context.ScopeRuntimeException;
+import org.apache.tuscany.core.context.ScopeStrategy;
+import org.apache.tuscany.core.context.SimpleComponentContext;
+import org.apache.tuscany.core.context.SystemAggregateContext;
+import org.apache.tuscany.core.context.TargetException;
+import org.apache.tuscany.core.context.impl.EventContextImpl;
+import org.apache.tuscany.core.invocation.jdk.JDKProxyFactoryFactory;
+import org.apache.tuscany.core.invocation.spi.ProxyFactory;
+import org.apache.tuscany.core.invocation.spi.ProxyFactoryFactory;
+import org.apache.tuscany.core.message.MessageFactory;
+import org.apache.tuscany.core.message.impl.MessageFactoryImpl;
+import org.apache.tuscany.core.runtime.RuntimeContext;
+import org.apache.tuscany.core.system.annotation.Autowire;
+import org.apache.tuscany.core.system.annotation.ParentContext;
+import org.apache.tuscany.core.system.assembly.SystemBinding;
+import org.apache.tuscany.core.system.config.SystemObjectRuntimeConfiguration;
+import org.apache.tuscany.model.assembly.Aggregate;
+import org.apache.tuscany.model.assembly.Component;
+import org.apache.tuscany.model.assembly.EntryPoint;
+import org.apache.tuscany.model.assembly.Extensible;
+import org.apache.tuscany.model.assembly.ExternalService;
+import org.apache.tuscany.model.assembly.Module;
+import org.apache.tuscany.model.assembly.AggregatePart;
+import org.apache.tuscany.model.assembly.Scope;
+import org.apache.tuscany.model.assembly.impl.AssemblyFactoryImpl;
+
+/**
+ * Implements an aggregate context for system components. By default a system context uses the scopes specified by
+ * {@link org.apache.tuscany.core.system.context.SystemScopeStrategy}. In addition, it implements an autowire policy
+ * where entry points configured with a {@link org.apache.tuscany.core.system.assembly.SystemBinding} are matched
+ * according to their exposed interface. A system context may contain child aggregate contexts but an entry point in a
+ * child context will only be outwardly accessible if there is an entry point that exposes it configured in the
+ * top-level system context.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemAggregateContextImpl extends AbstractContext implements SystemAggregateContext {
+
+ public static final int DEFAULT_WAIT = 1000 * 60;
+
+ // ----------------------------------
+ // Fields
+ // ----------------------------------
+
+ // The parent context, if one exists
+ @ParentContext
+ protected AggregateContext parentContext;
+
+ // The parent configuration context, if one exists
+ @Autowire(required = false)
+ protected ConfigurationContext configurationContext;
+
+ // The system monitor factory
+ @Autowire(required = false)
+ protected MonitorFactory monitorFactory;
+
+ // The logical model representing the module assembly
+ // protected ModuleComponent moduleComponent;
+ protected Module module;
+
+ protected List<RuntimeConfiguration<InstanceContext>> configurations = new ArrayList();
+
+ protected ScopeStrategy scopeStrategy;
+
+ // The event context for associating context events to threads
+ protected EventContext eventContext;
+
+ // The scopes for this context
+ protected Map<Scope, ScopeContext> scopeContexts;
+
+ protected Map<Scope, ScopeContext> immutableScopeContexts;
+
+ // A component context name to scope context index
+ protected Map<String, ScopeContext> scopeIndex;
+
+ // Listeners for context events
+ protected List<RuntimeEventListener> listeners = new CopyOnWriteArrayList();
+
+ // Blocking latch to ensure the module is initialized exactly once prior to servicing requests
+ protected CountDownLatch initializeLatch = new CountDownLatch(1);
+
+ // Indicates whether the module context has been initialized
+ protected boolean initialized;
+
+ // a mapping of service type to component name
+ private Map<Class, NameToScope> autowireIndex = new ConcurrentHashMap();
+
+ @Autowire(required = false)
+ private AutowireContext autowireContext;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public SystemAggregateContextImpl() {
+ super();
+ scopeIndex = new ConcurrentHashMap();
+ // FIXME the assembly factory should be injected here
+ module = new AssemblyFactoryImpl().createModule();
+ eventContext = new EventContextImpl();
+ scopeStrategy = new SystemScopeStrategy();
+ }
+
+ public SystemAggregateContextImpl(String name, AggregateContext parent, AutowireContext autowire, ScopeStrategy strategy,
+ EventContext ctx, ConfigurationContext configCtx, MonitorFactory factory) {
+ super(name);
+ this.parentContext = parent;
+ this.autowireContext = autowire;
+ this.scopeStrategy = strategy;
+ this.eventContext = ctx;
+ this.configurationContext = configCtx;
+ this.monitorFactory = factory;
+ scopeIndex = new ConcurrentHashMap();
+ // FIXME the assembly factory should be injected here
+ module = new AssemblyFactoryImpl().createModule();
+ }
+
+ // ----------------------------------
+ // Lifecycle methods
+ // ----------------------------------
+
+ public void start() {
+ synchronized (initializeLatch) {
+ try {
+ if (lifecycleState != UNINITIALIZED && lifecycleState != STOPPED) {
+ throw new IllegalStateException("Context not in UNINITIALIZED state");
+ }
+
+ lifecycleState = INITIALIZING;
+ initializeScopes();
+
+ Map<Scope, List<RuntimeConfiguration<SimpleComponentContext>>> configurationsByScope = new HashMap();
+ if (configurations != null) {
+ for (RuntimeConfiguration config : configurations) {
+ // FIXME scopes are defined at the interface level
+ Scope scope = config.getScope();
+ // ensure duplicate names were not added before the context was started
+ if (scopeIndex.get(config.getName()) != null) {
+ throw new DuplicateNameException(config.getName());
+ }
+ scopeIndex.put(config.getName(), scopeContexts.get(scope));
+ List<RuntimeConfiguration<SimpleComponentContext>> list = configurationsByScope.get(scope);
+ if (list == null) {
+ list = new ArrayList();
+ configurationsByScope.put(scope, list);
+ }
+ list.add(config);
+ }
+ }
+ for (EntryPoint ep : module.getEntryPoints()) {
+ registerAutowire(ep);
+ }
+ for (Component component : module.getComponents()) {
+ registerAutowire(component);
+ }
+ for (ExternalService es : module.getExternalServices()) {
+ registerAutowire(es);
+ }
+ for (Map.Entry entries : configurationsByScope.entrySet()) {
+ // register configurations with scope contexts
+ ScopeContext scope = scopeContexts.get(entries.getKey());
+ scope.registerConfigurations((List<RuntimeConfiguration<InstanceContext>>) entries.getValue());
+ }
+ for (ScopeContext scope : scopeContexts.values()) {
+ // register scope contexts as a listeners for events in the aggregate context
+ registerListener(scope);
+ scope.start();
+ }
+ lifecycleState = RUNNING;
+ } catch (ConfigurationException e) {
+ lifecycleState = ERROR;
+ throw new ContextInitException(e);
+ } catch (CoreRuntimeException e) {
+ lifecycleState = ERROR;
+ e.addContextName(getName());
+ throw e;
+ } finally {
+ initialized = true;
+ // release the latch and allow requests to be processed
+ initializeLatch.countDown();
+ }
+ }
+ }
+
+ public void stop() {
+ if (lifecycleState == STOPPED) {
+ return;
+ }
+ // need to block a start until reset is complete
+ initializeLatch = new CountDownLatch(2);
+ lifecycleState = STOPPING;
+ initialized = false;
+ if (scopeContexts != null) {
+ for (ScopeContext scope : scopeContexts.values()) {
+ try {
+ if (scope.getLifecycleState() == ScopeContext.RUNNING) {
+ scope.stop();
+ }
+ } catch (ScopeRuntimeException e) {
+ // log.error("Error stopping scope container [" + scopeContainers[i].getName() + "]", e);
+ }
+ }
+ }
+ scopeContexts = null;
+ scopeIndex.clear();
+ // allow initialized to be called
+ initializeLatch.countDown();
+ lifecycleState = STOPPED;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public void setModule(Module module) {
+ assert (module != null) : "Module cannot be null";
+ name = module.getName();
+ this.module = module;
+ }
+
+ public void addContextListener(LifecycleEventListener listener) {
+ super.addContextListener(listener);
+ }
+
+ public void setEventContext(EventContext eventContext) {
+ this.eventContext = eventContext;
+ }
+
+ public void setMonitorFactory(MonitorFactory factory) {
+ this.monitorFactory = factory;
+ }
+
+ public AggregateContext getParent() {
+ return parentContext;
+ }
+
+ public void registerModelObjects(List<Extensible> models) throws ConfigurationException {
+ assert (models != null) : "Model object collection was null";
+ for (Extensible model : models) {
+ registerModelObject(model);
+ }
+ }
+
+ public void registerModelObject(Extensible model) throws ConfigurationException {
+ assert (model != null) : "Model object was null";
+ initializeScopes();
+ if (configurationContext != null) {
+ try {
+ configurationContext.configure(model);
+ configurationContext.build(this, model);
+ } catch (ConfigurationException e) {
+ e.addContextName(getName());
+ throw e;
+ } catch (BuilderConfigException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+ RuntimeConfiguration<InstanceContext> configuration = null;
+ if (model instanceof Module) {
+ // merge new module definition with the existing one
+ Module oldModule = module;
+ Module newModule = (Module) model;
+ module = newModule;
+ for (Component component : newModule.getComponents()) {
+ configuration = (RuntimeConfiguration<InstanceContext>) component.getComponentImplementation()
+ .getRuntimeConfiguration();
+ if (configuration == null) {
+ ConfigurationException e = new ConfigurationException("Runtime configuration not set");
+ e.addContextName(component.getName());
+ e.addContextName(getName());
+ throw e;
+ }
+ registerConfiguration(configuration);
+ registerAutowire(component);
+ }
+ for (EntryPoint ep : newModule.getEntryPoints()) {
+ configuration = (RuntimeConfiguration<InstanceContext>) ep.getConfiguredReference().getRuntimeConfiguration();
+ if (configuration == null) {
+ ConfigurationException e = new ConfigurationException("Runtime configuration not set");
+ e.setIdentifier(ep.getName());
+ e.addContextName(getName());
+ throw e;
+ }
+ registerConfiguration(configuration);
+ registerAutowire(ep);
+ }
+ for (ExternalService service : newModule.getExternalServices()) {
+ configuration = (RuntimeConfiguration<InstanceContext>) service.getConfiguredService().getRuntimeConfiguration();
+ if (configuration == null) {
+ ConfigurationException e = new ConfigurationException("Runtime configuration not set");
+ e.setIdentifier(service.getName());
+ e.addContextName(getName());
+ throw e;
+ }
+ registerConfiguration(configuration);
+ registerAutowire(service);
+ }
+ // merge existing module component assets
+ module.getComponents().addAll(oldModule.getComponents());
+ module.getEntryPoints().addAll(oldModule.getEntryPoints());
+ module.getExternalServices().addAll(oldModule.getExternalServices());
+ } else {
+ if (model instanceof Component) {
+ Component component = (Component) model;
+ module.getComponents().add(component);
+ configuration = (RuntimeConfiguration<InstanceContext>) component.getComponentImplementation()
+ .getRuntimeConfiguration();
+ } else if (model instanceof EntryPoint) {
+ EntryPoint ep = (EntryPoint) model;
+ module.getEntryPoints().add(ep);
+ configuration = (RuntimeConfiguration<InstanceContext>) ep.getConfiguredReference().getRuntimeConfiguration();
+ } else if (model instanceof ExternalService) {
+ ExternalService service = (ExternalService) model;
+ module.getExternalServices().add(service);
+ configuration = (RuntimeConfiguration<InstanceContext>) service.getConfiguredService().getRuntimeConfiguration();
+ } else {
+ BuilderConfigException e = new BuilderConfigException("Unknown model type");
+ e.setIdentifier(model.getClass().getName());
+ e.addContextName(getName());
+ throw e;
+ }
+ if (configuration == null) {
+ ConfigurationException e = new ConfigurationException(
+ "Runtime configuration not set. Ensure a runtime configuration builder is registered for the component implementation type");
+ if (model instanceof AggregatePart) {
+ e.setIdentifier(((AggregatePart) model).getName());
+ }
+ e.addContextName(getName());
+ throw e;
+ }
+ registerConfiguration(configuration);
+ registerAutowire(model);
+ }
+ }
+
+ public void registerJavaObject(String componentName, Object instance) throws ConfigurationException {
+ registerConfiguration(new SystemObjectRuntimeConfiguration(componentName, instance));
+ }
+
+ protected void registerConfiguration(RuntimeConfiguration<InstanceContext> configuration) throws ConfigurationException {
+ if (lifecycleState == RUNNING) {
+ if (scopeIndex.get(configuration.getName()) != null) {
+ throw new DuplicateNameException(configuration.getName());
+ }
+ ScopeContext scope = scopeContexts.get(configuration.getScope());
+ if (scope == null) {
+ ConfigurationException e = new ConfigurationException("Component has an unknown scope");
+ e.addContextName(configuration.getName());
+ e.addContextName(getName());
+ throw e;
+ }
+ scope.registerConfiguration(configuration);
+ scopeIndex.put(configuration.getName(), scope);
+ } else {
+ configurations.add(configuration);
+ }
+
+ }
+
+ public void registerListener(RuntimeEventListener listener) {
+ assert (listener != null) : "Listener cannot be null";
+ listeners.add(listener);
+ }
+
+ public void fireEvent(int eventType, Object message) throws EventException {
+ checkInit();
+ if (eventType == SESSION_NOTIFY) {
+ // update context
+ eventContext.setIdentifier(HTTP_SESSION, message);
+ } else if (eventType == REQUEST_END) {
+ // be very careful with pooled threads, ensuring threadlocals are cleaned up
+ eventContext.clearIdentifier(HTTP_SESSION);
+ }
+ for (RuntimeEventListener listener : listeners) {
+ listener.onEvent(eventType, message);
+ }
+ }
+
+ public InstanceContext getContext(String componentName) {
+ checkInit();
+ assert (componentName != null) : "Name was null";
+ ScopeContext scope = scopeIndex.get(componentName);
+ if (scope == null) {
+ return null;
+ }
+ return scope.getContext(componentName);
+
+ }
+
+ /**
+ * @see org.apache.tuscany.core.context.AggregateContext#getAggregate()
+ */
+ public Aggregate getAggregate() {
+ return module;
+ }
+
+ public Object getInstance(QualifiedName qName) throws TargetException {
+ return getInstance(qName, true);
+ }
+
+ public Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ assert (qName != null) : "Name was null ";
+ // use the port name to get the context since entry points ports
+ ScopeContext scope = scopeIndex.get(qName.getPortName());
+ if (scope == null) {
+ return null;
+ }
+ InstanceContext ctx = scope.getContext(qName.getPortName());
+ if (!(ctx instanceof EntryPointContext)) {
+ TargetException e = new TargetException("Target not an entry point");
+ e.setIdentifier(qName.getQualifiedName());
+ e.addContextName(name);
+ throw e;
+ }
+ return ctx.getInstance(null, notify);
+ }
+
+ public Object locateInstance(String qualifiedName) throws TargetException {
+ checkInit();
+ QualifiedName qName = new QualifiedName(qualifiedName);
+ ScopeContext scope = scopeIndex.get(qName.getPartName());
+ if (scope == null) {
+ TargetException e = new TargetException("Component not found");
+ e.setIdentifier(qualifiedName);
+ e.addContextName(getName());
+ throw e;
+ }
+ InstanceContext ctx = scope.getContext(qName.getPartName());
+ try {
+ return ctx.getInstance(qName, true);
+ } catch (TargetException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+
+ // ----------------------------------
+ // InstanceContext methods
+ // ----------------------------------
+
+ public Object getImplementationInstance() throws TargetException {
+ return this;
+ }
+
+ public Object getImplementationInstance(boolean notify) throws TargetException {
+ return this;
+ }
+
+ public Map<Scope, ScopeContext> getScopeContexts() {
+ initializeScopes();
+ return immutableScopeContexts;
+ }
+
+ // ----------------------------------
+ // Protected methods
+ // ----------------------------------
+
+ /**
+ * Blocks until the module context has been initialized
+ */
+ protected void checkInit() {
+ if (!initialized) {
+ try {
+ /* block until the module has initialized */
+ boolean success = initializeLatch.await(DEFAULT_WAIT, TimeUnit.MILLISECONDS);
+ if (!success) {
+ throw new ContextInitException("Timeout waiting for module context to initialize");
+ }
+ } catch (InterruptedException e) { // should not happen
+ }
+ }
+
+ }
+
+ protected void initializeScopes() {
+ if (scopeContexts == null) {
+ scopeContexts = scopeStrategy.createScopes(eventContext);
+ immutableScopeContexts = Collections.unmodifiableMap(scopeContexts);
+ }
+ }
+
+ // ////////////////////////////
+
+ // ----------------------------------
+ // AutowireContext methods
+ // ----------------------------------
+
+ // FIXME These should be removed and configured
+ private static final MessageFactory messageFactory = new MessageFactoryImpl();
+
+ private static final ProxyFactoryFactory proxyFactoryFactory = new JDKProxyFactoryFactory();
+
+ public <T> T resolveInstance(Class<T> instanceInterface) throws AutowireResolutionException {
+ if (RuntimeContext.class.equals(instanceInterface)) {
+ return autowireContext.resolveInstance(instanceInterface);
+ } else if (MonitorFactory.class.equals(instanceInterface)) {
+ return instanceInterface.cast(monitorFactory);
+ } else if (ConfigurationContext.class.equals(instanceInterface)) {
+ return instanceInterface.cast(this);
+ } else if (AggregateContext.class.equals(instanceInterface)) {
+ return instanceInterface.cast(this);
+ } else if (AutowireContext.class.equals(instanceInterface)) {
+ return instanceInterface.cast(this);
+ } else if (MessageFactory.class.equals(instanceInterface)) {
+ return instanceInterface.cast(messageFactory);
+ } else if (ProxyFactoryFactory.class.equals(instanceInterface)) {
+ return instanceInterface.cast(proxyFactoryFactory);
+ }
+
+ NameToScope mapping = autowireIndex.get(instanceInterface);
+ if (mapping != null) {
+ try {
+ return instanceInterface.cast(mapping.getScopeContext().getInstance(mapping.getName()));
+ } catch (TargetException e) {
+ AutowireResolutionException ae = new AutowireResolutionException("Autowire instance not found", e);
+ ae.addContextName(getName());
+ throw ae;
+ }
+ }
+ return null;
+ }
+
+ private void registerAutowire(Extensible model) throws ConfigurationException {
+ if (lifecycleState == INITIALIZING || lifecycleState == INITIALIZED || lifecycleState == RUNNING) {
+ // only autowire entry points with system bindings
+ if (model instanceof EntryPoint) {
+ EntryPoint ep = (EntryPoint) model;
+ if (ep.getBindings() != null) {
+ if (ep.getBindings().get(0) instanceof SystemBinding) {
+ ScopeContext scope = scopeContexts.get(((RuntimeConfiguration) ep.getConfiguredReference()
+ .getRuntimeConfiguration()).getScope());
+ if (scope == null) {
+ ConfigurationException ce = new ConfigurationException("Scope not found for entry point");
+ ce.setIdentifier(ep.getName());
+ ce.addContextName(getName());
+ throw ce;
+ }
+ NameToScope mapping = new NameToScope(new QualifiedName(ep.getName()), scope);
+ autowireIndex.put(ep.getConfiguredService().getService().getServiceContract().getInterface(), mapping);
+ }
+ }
+ }
+ }
+ }
+
+ // ----------------------------------
+ // ConfigurationContext methods
+ // ----------------------------------
+
+ public void configure(Extensible model) throws ConfigurationException {
+ if (configurationContext != null) {
+ configurationContext.configure(model);
+ }
+ }
+
+ public void build(AggregateContext parent, Extensible model) throws BuilderConfigException {
+ if (configurationContext != null) {
+ configurationContext.build(parent, model);
+ }
+ }
+
+ public void wire(ProxyFactory sourceFactory, ProxyFactory targetFactory, Class targetType, boolean downScope,
+ ScopeContext targetScopeContext) throws BuilderConfigException {
+ if (configurationContext != null) {
+ try {
+ configurationContext.wire(sourceFactory, targetFactory, targetType, downScope, targetScopeContext);
+ } catch (BuilderConfigException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+ }
+
+ public void wire(ProxyFactory targetFactory, Class targetType, ScopeContext targetScopeContext) throws BuilderConfigException {
+ if (configurationContext != null) {
+ try {
+ configurationContext.wire(targetFactory, targetType, targetScopeContext);
+ } catch (BuilderConfigException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+ }
+
+ // ----------------------------------
+ // Inner classes
+ // ----------------------------------
+
+ /**
+ * Maps a context name to a scope
+ */
+ private class NameToScope {
+
+ private QualifiedName epName;
+
+ private ScopeContext scope;
+
+ public NameToScope(QualifiedName epName, ScopeContext scope) {
+ this.epName = epName;
+ this.scope = scope;
+ }
+
+ public QualifiedName getName() {
+ return epName;
+ }
+
+ public ScopeContext getScopeContext() {
+ return scope;
+ }
+
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemComponentContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemComponentContext.java
new file mode 100644
index 0000000000..4418f52e19
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemComponentContext.java
@@ -0,0 +1,198 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.context;
+
+import java.util.Iterator;
+
+import org.apache.tuscany.core.builder.ObjectFactory;
+import org.apache.tuscany.core.context.AbstractContext;
+import org.apache.tuscany.core.context.Context;
+import org.apache.tuscany.core.context.ContextInitException;
+import org.apache.tuscany.core.context.LifecycleEventListener;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.SimpleComponentContext;
+import org.apache.tuscany.core.context.TargetException;
+import org.apache.tuscany.core.injection.EventInvoker;
+import org.apache.tuscany.core.injection.Injector;
+import org.apache.tuscany.core.injection.ObjectCallbackException;
+import org.apache.tuscany.core.injection.ObjectCreationException;
+
+/**
+ * Manages system component implementation instances
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemComponentContext extends AbstractContext implements SimpleComponentContext {
+
+ private boolean eagerInit;
+
+ private EventInvoker initInvoker;
+
+ private EventInvoker destroyInvoker;
+
+ private Injector componentName;
+
+ private Injector moduleContext;
+
+ private boolean stateless;
+
+ // the cached target instance
+ private Object cachedTargetInstance;
+
+ // responsible for creating a new implementation instance with injected references and properties
+ private ObjectFactory objectFactory;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public SystemComponentContext(String name, ObjectFactory objectFactory, boolean eagerInit, EventInvoker initInvoker,
+ EventInvoker destroyInvoker, boolean stateless) {
+ super(name);
+ assert (objectFactory != null) : "Object factory was null";
+ if (eagerInit == true && initInvoker == null) {
+ throw new AssertionError("No intialization method found for eager init implementation");
+ }
+ this.objectFactory = objectFactory;
+
+ this.eagerInit = eagerInit;
+ this.initInvoker = initInvoker;
+ this.destroyInvoker = destroyInvoker;
+ this.stateless = stateless;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public void setName(String name) {
+ super.setName(name);
+ }
+
+ protected int type;
+
+ public int getType() {
+ return type;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public synchronized Object getInstance(QualifiedName qName) throws TargetException {
+ return getInstance(qName, true);
+ }
+
+ public synchronized Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ if (cachedTargetInstance != null) {
+ return cachedTargetInstance; // already cached, just return
+ }
+
+ if (getLifecycleState() == ERROR || getLifecycleState() == CONFIG_ERROR) {
+ return null;
+ }
+ synchronized (this) {
+ try {
+ Object instance = objectFactory.getInstance();
+ startInstance(instance);
+ if (notify) {
+ for (Iterator iter = contextListener.iterator(); iter.hasNext();) {
+ LifecycleEventListener listener = (LifecycleEventListener) iter.next();
+ listener.onInstanceCreate(this);
+ }
+ }
+ setLifecycleState(RUNNING);
+ if (stateless) {
+ return instance;
+ } else {
+ // cache the actual instance
+ cachedTargetInstance = instance;
+ return cachedTargetInstance;
+ }
+ } catch (ObjectCreationException e) {
+ setLifecycleState(Context.ERROR);
+ TargetException te = new TargetException("Error creating instance for component", e);
+ te.setIdentifier(getName());
+ throw te;
+ }
+ }
+
+ }
+
+ public Object getImplementationInstance() throws TargetException {
+ return getInstance(null);
+ }
+
+ public Object getImplementationInstance(boolean notify) throws TargetException {
+ return getInstance(null, notify);
+ }
+
+ public boolean isEagerInit() {
+ return eagerInit;
+ }
+
+ public boolean isDestroyable() {
+ return (destroyInvoker != null);
+ }
+
+ // ----------------------------------
+ // Lifecycle methods
+ // ----------------------------------
+
+ public void start() throws ContextInitException {
+ if (getLifecycleState() != UNINITIALIZED && getLifecycleState() != STOPPED) {
+ throw new IllegalStateException("Component must be in UNINITIALIZED state [" + getLifecycleState() + "]");
+ }
+ if (objectFactory == null) {
+ setLifecycleState(ERROR);
+ ContextInitException e = new ContextInitException("Object factory not found ");
+ e.setIdentifier(getName());
+ throw e;
+ }
+ setLifecycleState(INITIALIZED);
+ }
+
+ public void stop() {
+ if (cachedTargetInstance != null) {
+ if (destroyInvoker != null) {
+ try {
+ destroyInvoker.invokeEvent(cachedTargetInstance);
+ } catch (ObjectCallbackException e) {
+ throw new TargetException(e.getCause());
+ }
+ }
+ }
+ setLifecycleState(STOPPED);
+ }
+
+ // ----------------------------------
+ // Private methods
+ // ----------------------------------
+ private void startInstance(Object instance) throws TargetException {
+ try {
+ // handle @Init
+ if (initInvoker != null) {
+ initInvoker.invokeEvent(instance);
+ }
+ } catch (ObjectCallbackException e) {
+ TargetException te = new TargetException("Error initializing instance", e);
+ te.setIdentifier(getName());
+ throw te;
+ }
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemEntryPointContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemEntryPointContext.java
new file mode 100644
index 0000000000..5533424334
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemEntryPointContext.java
@@ -0,0 +1,82 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.context;
+
+import org.apache.tuscany.core.builder.ObjectFactory;
+import org.apache.tuscany.core.context.AbstractContext;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.CoreRuntimeException;
+import org.apache.tuscany.core.context.EntryPointContext;
+import org.apache.tuscany.core.context.TargetException;
+
+/**
+ * Manages an entry point into a system module. System entry points cache a direct (i.e. non-proxied) reference to a
+ * component instance.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemEntryPointContext extends AbstractContext implements EntryPointContext {
+
+ // responsible for resolving the component implementation instance exposed by the entry point
+ private ObjectFactory factory;
+
+ // a reference to the component's implementation instance exposed by the entry point
+ private Object cachedInstance;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public SystemEntryPointContext(String name, ObjectFactory factory) {
+ super(name);
+ assert (factory != null) : "Object factory was null";
+ this.factory = factory;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public Object getInstance(QualifiedName qName) throws TargetException {
+ return getInstance(qName, true);
+ }
+
+ public Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ try {
+ if (cachedInstance == null) {
+ cachedInstance = factory.getInstance();
+ }
+ return cachedInstance;
+ } catch (TargetException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+ }
+
+ public void start() throws CoreRuntimeException {
+ lifecycleState = RUNNING;
+ }
+
+ public void stop() throws CoreRuntimeException {
+ lifecycleState = STOPPED;
+ }
+
+ public Object getImplementationInstance() throws TargetException{
+ return getInstance(null);
+ }
+
+ public Object getImplementationInstance(boolean notify) throws TargetException{
+ return getInstance(null,notify);
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemExternalServiceContext.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemExternalServiceContext.java
new file mode 100644
index 0000000000..9b09cea082
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemExternalServiceContext.java
@@ -0,0 +1,82 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.context;
+
+import org.apache.tuscany.core.builder.ObjectFactory;
+import org.apache.tuscany.core.context.AbstractContext;
+import org.apache.tuscany.core.context.ExternalServiceContext;
+import org.apache.tuscany.core.context.QualifiedName;
+import org.apache.tuscany.core.context.TargetException;
+
+/**
+ * An implementation of an external service for system wiring. As system components are not proxied and the system
+ * binding is by-reference, the implementation caches a reference to its configured target.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemExternalServiceContext extends AbstractContext implements ExternalServiceContext {
+
+ // a factory for retrieving the target of the external service wire
+ private ObjectFactory factory;
+
+ // the cached target
+ private Object cachedInstance;
+
+ // ----------------------------------
+ // Constructors
+ // ----------------------------------
+
+ public SystemExternalServiceContext(String name, ObjectFactory factory) {
+ super(name);
+ assert (factory != null) : "Object factory was null";
+ this.factory = factory;
+ }
+
+ // ----------------------------------
+ // Methods
+ // ----------------------------------
+
+ public Object getInstance(QualifiedName qName) throws TargetException {
+ return getInstance(qName, false);
+ }
+
+ public Object getInstance(QualifiedName qName, boolean notify) throws TargetException {
+ try {
+ if (cachedInstance == null) {
+ cachedInstance = factory.getInstance();
+ }
+ return cachedInstance;
+ } catch (TargetException e) {
+ e.addContextName(getName());
+ throw e;
+ }
+
+ }
+
+ public void start() {
+ lifecycleState = RUNNING;
+ }
+
+ public void stop() {
+ lifecycleState = STOPPED;
+ }
+
+ public Object getImplementationInstance() throws TargetException {
+ return this;
+ }
+
+ public Object getImplementationInstance(boolean notify) throws TargetException {
+ return this;
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemScopeStrategy.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemScopeStrategy.java
new file mode 100644
index 0000000000..0dbd75da19
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemScopeStrategy.java
@@ -0,0 +1,56 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.context;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.ScopeContext;
+import org.apache.tuscany.core.context.scope.AbstractScopeStrategy;
+import org.apache.tuscany.core.context.scope.AggregateScopeContext;
+import org.apache.tuscany.core.context.scope.ModuleScopeContext;
+import org.apache.tuscany.core.context.scope.StatelessScopeContext;
+import org.apache.tuscany.model.assembly.Scope;
+
+/**
+ * Implements a {@link org.apache.tuscany.core.context.ScopeStrategy} for a system aggregate context with the following scopes:
+ * <ul>
+ * <li>{@link org.apache.tuscany.model.assembly.Scope#AGGREGATE</li>
+ * <li>{@link org.apache.tuscany.model.assembly.Scope#MODULE</li>
+ * <li>{@link org.apache.tuscany.model.assembly.Scope#INSTANCE</li>
+ * </ul>
+ *
+ * @version $Rev$ $Date$
+ */
+public class SystemScopeStrategy extends AbstractScopeStrategy {
+
+ public SystemScopeStrategy() {
+ }
+
+ public Map<Scope, ScopeContext> createScopes(EventContext eventContext) {
+ ScopeContext aggregrateScope = new AggregateScopeContext(eventContext);
+ ScopeContext moduleScoper = new ModuleScopeContext(eventContext);
+ ScopeContext statelessScope = new StatelessScopeContext(eventContext);
+ Map<Scope, ScopeContext> scopes = new HashMap();
+ scopes.put(Scope.AGGREGATE, aggregrateScope);
+ scopes.put(Scope.MODULE, moduleScoper);
+ scopes.put(Scope.INSTANCE, statelessScope);
+ return scopes;
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/injection/AutowireFactory.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/injection/AutowireFactory.java
new file mode 100644
index 0000000000..3bde49dbbe
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/injection/AutowireFactory.java
@@ -0,0 +1,50 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.system.injection;
+
+import org.apache.tuscany.core.builder.ObjectFactory;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.AutowireContext;
+import org.apache.tuscany.core.injection.FactoryInitException;
+import org.apache.tuscany.core.injection.ObjectCreationException;
+
+/**
+ * Implementation of ObjectFactory that returns an instance by resolving against an AutowireContext.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AutowireFactory<T> implements ObjectFactory<T> {
+
+ private AutowireContext autoWireContext;
+
+ private Class<T> implementationType;
+
+ /**
+ * Constructor specifying the context to wire against and the type of service required.
+ *
+ * @param implementationType the type of service required
+ * @param autoWireContext the context to wire against
+ */
+ public AutowireFactory(Class<T> implementationType, AutowireContext autoWireContext) {
+ assert (implementationType != null) : "Implementation type was null";
+ assert (autoWireContext != null) : "Autowire context was null";
+ this.implementationType = implementationType;
+ this.autoWireContext = autoWireContext;
+ }
+
+ public T getInstance() throws ObjectCreationException {
+ // todo what about required? should this just return null?
+ return autoWireContext.resolveInstance(implementationType);
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/loader/SystemSCDLModelLoader.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/loader/SystemSCDLModelLoader.java
new file mode 100644
index 0000000000..f49efe3ebc
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/system/loader/SystemSCDLModelLoader.java
@@ -0,0 +1,49 @@
+package org.apache.tuscany.core.system.loader;
+
+import org.apache.tuscany.core.system.assembly.SystemAssemblyFactory;
+import org.apache.tuscany.core.system.assembly.impl.SystemAssemblyFactoryImpl;
+import org.apache.tuscany.core.system.scdl.ScdlFactory;
+import org.apache.tuscany.core.system.scdl.SystemImplementation;
+import org.apache.tuscany.model.assembly.AssemblyModelContext;
+import org.apache.tuscany.model.assembly.AssemblyModelObject;
+import org.apache.tuscany.model.scdl.loader.SCDLModelLoader;
+import org.apache.tuscany.sdo.util.SDOUtil;
+
+/**
+ * Populates the assembly model from an SCDL model
+ */
+public class SystemSCDLModelLoader implements SCDLModelLoader {
+
+ private SystemAssemblyFactory systemFactory;
+
+ static {
+ // Register the system SCDL model
+ SDOUtil.registerStaticTypes(ScdlFactory.class);
+ }
+
+ /**
+ * Constructs a new JavaSCDLModelLoader.
+ */
+ public SystemSCDLModelLoader() {
+ this.systemFactory=new SystemAssemblyFactoryImpl();
+ }
+
+ /**
+ * @see org.apache.tuscany.model.scdl.loader.SCDLModelLoader#load(org.apache.tuscany.model.assembly.AssemblyModelContext, java.lang.Object)
+ */
+ public AssemblyModelObject load(AssemblyModelContext modelContext, Object object) {
+ if (object instanceof SystemImplementation) {
+ SystemImplementation scdlImplementation=(SystemImplementation)object;
+ org.apache.tuscany.core.system.assembly.SystemImplementation implementation=systemFactory.createSystemImplementation();
+ Class implementationClass;
+ try {
+ implementationClass=modelContext.getSystemResourceLoader().loadClass(scdlImplementation.getClass_());
+ } catch (ClassNotFoundException e) {
+ throw new IllegalArgumentException(e);
+ }
+ implementation.setImplementationClass(implementationClass);
+ return implementation;
+ } else
+ return null;
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/webapp/ContextBinder.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/webapp/ContextBinder.java
new file mode 100644
index 0000000000..690d03ac36
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/webapp/ContextBinder.java
@@ -0,0 +1,39 @@
+/**
+ *
+ * Copyright 2005 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.webapp;
+
+import org.osoa.sca.SCA;
+import org.osoa.sca.ModuleContext;
+
+/**
+ * @version $Rev$ $Date$
+ */
+class ContextBinder extends SCA {
+ static final ContextBinder BINDER = new ContextBinder();
+
+ public void setContext(ModuleContext context) {
+ setModuleContext(context);
+ }
+
+ public void start() {
+ throw new AssertionError();
+ }
+
+ public void stop() {
+ throw new AssertionError();
+ }
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/webapp/TuscanyRequestFilter.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/webapp/TuscanyRequestFilter.java
new file mode 100644
index 0000000000..b72c546bf6
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/webapp/TuscanyRequestFilter.java
@@ -0,0 +1,97 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.webapp;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+
+import org.osoa.sca.ModuleContext;
+import org.osoa.sca.CurrentModuleContext;
+
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.context.webapp.LazyHTTPSessionId;
+
+/**
+ * Notifies the {@link org.apache.tuscany.core.context.AggregateContext} of web request start and end events as well as setting up the
+ * current session context. The latter is done using lazy Servlet-based session retrieval. The filter fires a session
+ * start event, passing a <tt>LazyServletSessionId</tt> as the session id. The <tt>LazyServletSessionId</tt> is a
+ * wrapper for the servlet request which may be called by the <tt>ModuleContext</tt> to retrieve the session id
+ * lazily.
+ *
+ * @version $Rev: 379957 $ $Date: 2006-02-22 14:58:24 -0800 (Wed, 22 Feb 2006) $
+ */
+public class TuscanyRequestFilter implements Filter {
+ private AggregateContext moduleContext;
+
+ public TuscanyRequestFilter() {
+ }
+
+ public void init(FilterConfig filterConfig) throws ServletException {
+ ServletContext servletContext = filterConfig.getServletContext();
+ moduleContext = (AggregateContext) servletContext.getAttribute(TuscanyServletListener.MODULE_COMPONENT_NAME);
+ }
+
+ public void destroy() {
+ }
+
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {
+ ModuleContext oldContext = CurrentModuleContext.getContext();
+ try {
+ // Set the current module context
+ ContextBinder.BINDER.setContext((ModuleContext) moduleContext);
+
+ // Handle a request
+ if (request instanceof HttpServletRequest) {
+ if (((HttpServletRequest) request).getSession(false) != null) {
+
+ // A session is already active
+ moduleContext.fireEvent(EventContext.SESSION_NOTIFY, ((HttpServletRequest) request).getSession(true));
+ } else {
+ // Create a lazy wrapper since a session is not yet active
+ moduleContext.fireEvent(EventContext.SESSION_NOTIFY, new LazyHTTPSessionId((HttpServletRequest) request));
+ }
+ } else {
+ moduleContext.fireEvent(EventContext.SESSION_NOTIFY, request);
+ }
+ // Start processing the request
+ moduleContext.fireEvent(EventContext.REQUEST_START, request);
+ // Dispatch to the next filter
+ filterChain.doFilter(request, response);
+ } catch (Exception e) {
+ throw new ServletException(e);
+
+ } finally {
+ try {
+ // End processing the request
+ moduleContext.fireEvent(EventContext.REQUEST_END, request);
+ } catch (Exception e) {
+ throw new ServletException(e);
+ }
+ ContextBinder.BINDER.setContext(oldContext);
+ }
+ }
+
+}
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/webapp/TuscanyServletListener.java b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/webapp/TuscanyServletListener.java
new file mode 100644
index 0000000000..56b4b52495
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/core/src/main/java/org/apache/tuscany/core/webapp/TuscanyServletListener.java
@@ -0,0 +1,168 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.webapp;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+
+import org.osoa.sca.CurrentModuleContext;
+import org.osoa.sca.ModuleContext;
+
+import org.apache.tuscany.common.monitor.MonitorFactory;
+import org.apache.tuscany.common.monitor.impl.NullMonitorFactory;
+import org.apache.tuscany.common.resource.ResourceLoader;
+import org.apache.tuscany.common.resource.impl.ResourceLoaderImpl;
+import org.apache.tuscany.core.builder.RuntimeConfigurationBuilder;
+import org.apache.tuscany.core.builder.impl.DefaultWireBuilder;
+import org.apache.tuscany.core.config.ConfigurationException;
+import org.apache.tuscany.core.config.ModuleComponentConfigurationLoader;
+import org.apache.tuscany.core.config.impl.ModuleComponentConfigurationLoaderImpl;
+import org.apache.tuscany.core.context.AggregateContext;
+import org.apache.tuscany.core.context.EventContext;
+import org.apache.tuscany.core.runtime.RuntimeContext;
+import org.apache.tuscany.core.runtime.RuntimeContextImpl;
+import org.apache.tuscany.core.system.builder.SystemComponentContextBuilder;
+import org.apache.tuscany.core.system.builder.SystemEntryPointBuilder;
+import org.apache.tuscany.core.system.builder.SystemExternalServiceBuilder;
+import org.apache.tuscany.core.system.loader.SystemSCDLModelLoader;
+import org.apache.tuscany.model.assembly.AssemblyFactory;
+import org.apache.tuscany.model.assembly.AssemblyModelContext;
+import org.apache.tuscany.model.assembly.ModuleComponent;
+import org.apache.tuscany.model.assembly.impl.AssemblyFactoryImpl;
+import org.apache.tuscany.model.assembly.impl.AssemblyModelContextImpl;
+import org.apache.tuscany.model.assembly.loader.AssemblyModelLoader;
+import org.apache.tuscany.model.scdl.loader.SCDLModelLoader;
+import org.apache.tuscany.model.scdl.loader.impl.SCDLAssemblyModelLoaderImpl;
+
+/**
+ * ServletContextListener that can be added to a standard web application to boot
+ * a Tuscany runtime inside that application. All implementation classes should
+ * be located in the web application itself.
+ *
+ * @version $Rev: 380792 $ $Date: 2006-02-24 11:25:11 -0800 (Fri, 24 Feb 2006) $
+ */
+public class TuscanyServletListener implements ServletContextListener, HttpSessionListener {
+ public static final String SCA_COMPONENT_NAME = "org.apache.tuscany.core.webapp.ModuleComponentName";
+ public static final String MODULE_COMPONENT_NAME = "org.apache.tuscany.core.webapp.ModuleComponentContext";
+ public static final String TUSCANY_RUNTIME_NAME = RuntimeContext.class.getName();
+
+ private final Object sessionKey = new Object();
+
+ private RuntimeContext runtimeContext;
+ private AggregateContext systemModuleComponentContext;
+ private AggregateContext moduleContext;
+
+ private static final String SYSTEM_MODULE_COMPONENT = "org.apache.tuscany.core.system";
+
+ public void contextInitialized(ServletContextEvent servletContextEvent) {
+ ServletContext servletContext = servletContextEvent.getServletContext();
+ String name = servletContext.getInitParameter(SCA_COMPONENT_NAME);
+ String uri = name; // todo get from context path
+ MonitorFactory monitorFactory = new NullMonitorFactory(); // todo have one that writes to the servlet log
+
+ try {
+ bootRuntime(name, uri, monitorFactory);
+ } catch (ConfigurationException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+
+ servletContext.setAttribute(TUSCANY_RUNTIME_NAME, runtimeContext);
+ servletContext.setAttribute(MODULE_COMPONENT_NAME, moduleContext);
+ }
+
+ public void contextDestroyed(ServletContextEvent servletContextEvent) {
+ moduleContext.fireEvent(EventContext.MODULE_STOP, null);
+ moduleContext.stop();
+ systemModuleComponentContext.fireEvent(EventContext.MODULE_STOP, null);
+ systemModuleComponentContext.stop();
+ runtimeContext.stop();
+ servletContextEvent.getServletContext().removeAttribute(MODULE_COMPONENT_NAME);
+ servletContextEvent.getServletContext().removeAttribute(TUSCANY_RUNTIME_NAME);
+ }
+
+ public void sessionCreated(HttpSessionEvent event) {
+ // do nothing since sessions are lazily created in {@link TuscanyRequestFilter}
+ }
+
+ public void sessionDestroyed(HttpSessionEvent event) {
+ // todo do we actually need to bind the module context to the thread to fire this event?
+ ModuleContext oldContext = CurrentModuleContext.getContext();
+ try {
+ ContextBinder.BINDER.setContext((ModuleContext) moduleContext);
+ moduleContext.fireEvent(EventContext.SESSION_END, event.getSession());
+ } finally{
+ ContextBinder.BINDER.setContext(oldContext);
+ }
+ }
+
+ private void bootRuntime(String name, String uri, MonitorFactory monitorFactory) throws ConfigurationException {
+ // Create a resource loader from the current classloader
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ ResourceLoader resourceLoader = new ResourceLoaderImpl(classLoader);
+
+ // Create an assembly model factory
+ AssemblyFactory modelFactory=new AssemblyFactoryImpl();
+
+ // Create an assembly model loader
+ List<SCDLModelLoader> scdlLoaders=new ArrayList<SCDLModelLoader>();
+ scdlLoaders.add(new SystemSCDLModelLoader());
+ AssemblyModelLoader modelLoader=new SCDLAssemblyModelLoaderImpl(scdlLoaders);
+
+ // Create an assembly model context
+ AssemblyModelContext modelContext = new AssemblyModelContextImpl(modelFactory, modelLoader, resourceLoader);
+
+ // Create system configuration builders
+ List<RuntimeConfigurationBuilder> configBuilders = new ArrayList();
+ configBuilders.add((new SystemComponentContextBuilder()));
+ configBuilders.add(new SystemEntryPointBuilder());
+ configBuilders.add(new SystemExternalServiceBuilder());
+
+ // Create a runtime context and start it
+ runtimeContext = new RuntimeContextImpl(monitorFactory, scdlLoaders, configBuilders,new DefaultWireBuilder());
+ runtimeContext.start();
+
+ // Get the system context
+ AggregateContext systemContext = runtimeContext.getSystemContext();
+
+ // Load the system module component
+ ModuleComponentConfigurationLoader loader = new ModuleComponentConfigurationLoaderImpl(modelContext);
+ ModuleComponent systemModuleComponent = loader.loadSystemModuleComponent(SYSTEM_MODULE_COMPONENT, SYSTEM_MODULE_COMPONENT);
+
+ // Register it with the system context
+ systemContext.registerModelObject(systemModuleComponent);
+
+ // Get the aggregate context representing the system module component
+ systemModuleComponentContext = (AggregateContext) systemContext.getContext(SYSTEM_MODULE_COMPONENT);
+ systemModuleComponentContext.registerModelObject(systemModuleComponent.getComponentImplementation());
+ systemModuleComponentContext.fireEvent(EventContext.MODULE_START, null);
+
+ // Load the SCDL configuration of the application module
+ ModuleComponent moduleComponent = loader.loadModuleComponent(name, uri);
+
+ // Register it under the root application context
+ runtimeContext.getRootContext().registerModelObject(moduleComponent);
+ moduleContext=(AggregateContext)runtimeContext.getContext(moduleComponent.getName());
+ moduleContext.registerModelObject(moduleComponent.getComponentImplementation());
+
+ moduleContext.fireEvent(EventContext.MODULE_START, null);
+ }
+}