From bdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a Mon Sep 17 00:00:00 2001 From: dims Date: Tue, 17 Jun 2008 00:23:01 +0000 Subject: Move Tuscany from Incubator to top level. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68 --- branches/java-post-M1/sca/core/pom.xml | 107 ++ .../core/async/builder/AsyncPolicyBuilder.java | 86 ++ .../core/async/invocation/AsyncInterceptor.java | 108 ++ .../core/async/work/DefaultWorkManager.java | 68 ++ .../core/builder/BuilderConfigException.java | 42 + .../tuscany/core/builder/BuilderException.java | 41 + .../tuscany/core/builder/BuilderInitException.java | 39 + .../core/builder/ContextCreationException.java | 41 + .../tuscany/core/builder/ContextFactory.java | 123 ++ .../core/builder/ContextFactoryBuilder.java | 50 + .../builder/ContextFactoryBuilderRegistry.java | 31 + .../tuscany/core/builder/ContextResolver.java | 29 + .../core/builder/HierarchicalWireBuilder.java | 29 + .../tuscany/core/builder/NoAccessorException.java | 39 + .../apache/tuscany/core/builder/ObjectFactory.java | 35 + .../apache/tuscany/core/builder/PolicyBuilder.java | 28 + .../apache/tuscany/core/builder/PolicyOrderer.java | 26 + .../tuscany/core/builder/SourcePolicyBuilder.java | 31 + .../tuscany/core/builder/SourcePolicyOrderer.java | 32 + .../tuscany/core/builder/TargetPolicyBuilder.java | 29 + .../tuscany/core/builder/TargetPolicyOrderer.java | 28 + .../tuscany/core/builder/UnknownTypeException.java | 42 + .../apache/tuscany/core/builder/WireBuilder.java | 71 ++ .../impl/ArrayMultiplicityObjectFactory.java | 49 + .../core/builder/impl/AssemblyVisitorImpl.java | 63 + .../impl/ContextFactoryBuilderRegistryImpl.java | 39 + .../core/builder/impl/DefaultWireBuilder.java | 111 ++ .../core/builder/impl/HierarchicalBuilder.java | 57 + .../impl/ListMultiplicityObjectFactory.java | 45 + .../core/builder/impl/ProxyObjectFactory.java | 42 + .../system/DefaultPolicyBuilderRegistry.java | 102 ++ .../core/builder/system/PolicyBuilderRegistry.java | 92 ++ .../tuscany/core/client/BootstrapHelper.java | 138 +++ .../apache/tuscany/core/client/TuscanyRuntime.java | 182 +++ .../core/config/ComponentTypeIntrospector.java | 57 + .../core/config/ConfigurationException.java | 44 + .../core/config/ConfigurationLoadException.java | 59 + .../tuscany/core/config/ImplementationCache.java | 46 + .../core/config/InvalidMetaDataException.java | 35 + .../core/config/InvalidRootElementException.java | 45 + .../core/config/InvalidSetterException.java | 39 + .../core/config/JavaIntrospectionHelper.java | 446 +++++++ .../tuscany/core/config/MetaDataException.java | 37 + .../core/config/MissingInterfaceException.java | 39 + .../core/config/MissingResourceException.java | 35 + .../config/ModuleComponentConfigurationLoader.java | 75 ++ .../tuscany/core/config/SidefileLoadException.java | 50 + ...AbstractModuleComponentConfigurationLoader.java | 171 +++ .../impl/Java5ComponentTypeIntrospector.java | 139 +++ ...StAXModuleComponentConfigurationLoaderImpl.java | 91 ++ .../config/processor/ComponentNameProcessor.java | 51 + .../core/config/processor/ContextProcessor.java | 50 + .../core/config/processor/DefaultProcessor.java | 112 ++ .../core/config/processor/DestroyProcessor.java | 47 + .../processor/ImplementationProcessorSupport.java | 107 ++ .../core/config/processor/InitProcessor.java | 43 + .../core/config/processor/ProcessorHelper.java | 59 + .../core/config/processor/ProcessorUtils.java | 65 + .../core/config/processor/PropertyProcessor.java | 104 ++ .../processor/PropertyReferenceValidator.java | 80 ++ .../core/config/processor/ReferenceProcessor.java | 119 ++ .../core/config/processor/ScopeProcessor.java | 74 ++ .../core/config/processor/ServiceProcessor.java | 129 ++ .../apache/tuscany/core/context/AtomicContext.java | 55 + .../tuscany/core/context/AutowireContext.java | 47 + .../core/context/AutowireResolutionException.java | 40 + .../tuscany/core/context/CompositeContext.java | 91 ++ .../tuscany/core/context/ConfigurationContext.java | 30 + .../org/apache/tuscany/core/context/Context.java | 46 + .../tuscany/core/context/ContextInitException.java | 43 + .../core/context/ContextRuntimeException.java | 39 + .../tuscany/core/context/CoreRuntimeException.java | 43 + .../core/context/DuplicateNameException.java | 39 + .../tuscany/core/context/EntryPointContext.java | 69 ++ .../apache/tuscany/core/context/EventContext.java | 46 + .../tuscany/core/context/EventException.java | 43 + .../apache/tuscany/core/context/EventFilter.java | 32 + .../tuscany/core/context/EventPublisher.java | 44 + .../core/context/ExternalServiceContext.java | 30 + .../tuscany/core/context/InvalidNameException.java | 43 + .../org/apache/tuscany/core/context/Lifecycle.java | 79 ++ .../context/MissingContextFactoryException.java | 42 + .../context/MissingImplementationException.java | 42 + .../core/context/MissingScopeException.java | 42 + .../core/context/ProxyConfigurationException.java | 42 + .../apache/tuscany/core/context/QualifiedName.java | 84 ++ .../tuscany/core/context/RuntimeEventListener.java | 32 + .../tuscany/core/context/ScopeAwareContext.java | 31 + .../apache/tuscany/core/context/ScopeContext.java | 74 ++ .../tuscany/core/context/ScopeIdentifier.java | 33 + .../core/context/ScopeInitializationException.java | 42 + .../core/context/ScopeRuntimeException.java | 43 + .../apache/tuscany/core/context/ScopeStrategy.java | 43 + .../core/context/ServiceNotFoundException.java | 42 + .../core/context/SystemCompositeContext.java | 37 + .../tuscany/core/context/TargetException.java | 42 + .../tuscany/core/context/event/AbstractEvent.java | 33 + .../core/context/event/AbstractRequestEvent.java | 43 + .../apache/tuscany/core/context/event/Event.java | 28 + .../core/context/event/HttpSessionBound.java | 33 + .../tuscany/core/context/event/HttpSessionEnd.java | 32 + .../core/context/event/HttpSessionEvent.java | 47 + .../core/context/event/InstanceCreated.java | 27 + .../tuscany/core/context/event/ModuleEvent.java | 23 + .../tuscany/core/context/event/ModuleStart.java | 26 + .../tuscany/core/context/event/ModuleStop.java | 29 + .../tuscany/core/context/event/RequestEnd.java | 33 + .../tuscany/core/context/event/RequestEvent.java | 26 + .../tuscany/core/context/event/RequestStart.java | 32 + .../tuscany/core/context/event/SessionBound.java | 23 + .../tuscany/core/context/event/SessionEnd.java | 23 + .../tuscany/core/context/event/SessionEvent.java | 34 + .../tuscany/core/context/event/SessionStart.java | 26 + .../tuscany/core/context/filter/TrueFilter.java | 32 + .../context/impl/AbstractCompositeContext.java | 852 +++++++++++++ .../tuscany/core/context/impl/AbstractContext.java | 45 + .../core/context/impl/AbstractLifecycle.java | 129 ++ .../core/context/impl/CompositeContextImpl.java | 117 ++ .../core/context/impl/EntryPointContextImpl.java | 90 ++ .../core/context/impl/EventContextImpl.java | 81 ++ .../context/impl/ExternalServiceContextImpl.java | 75 ++ .../core/context/scope/AbstractScopeContext.java | 74 ++ .../core/context/scope/AbstractScopeStrategy.java | 67 + .../core/context/scope/CompositeScopeContext.java | 156 +++ .../core/context/scope/DefaultScopeStrategy.java | 52 + .../core/context/scope/ModuleScopeContext.java | 194 +++ .../core/context/scope/RequestScopeContext.java | 228 ++++ .../core/context/scope/SessionScopeContext.java | 258 ++++ .../core/context/scope/StatelessScopeContext.java | 132 ++ .../core/extension/ComponentTargetInvoker.java | 122 ++ .../extension/ContextFactoryBuilderSupport.java | 174 +++ .../core/extension/EntryPointBuilderSupport.java | 111 ++ .../core/extension/EntryPointContextFactory.java | 111 ++ .../extension/ExternalServiceBuilderSupport.java | 112 ++ .../extension/ExternalServiceContextFactory.java | 121 ++ .../core/extension/ExternalServiceInvoker.java | 23 + .../extension/ExternalServiceTargetInvoker.java | 122 ++ .../tuscany/core/extension/WireBuilderSupport.java | 102 ++ .../extension/config/ImplementationProcessor.java | 65 + .../config/InjectorExtensibilityElement.java | 32 + .../extension/config/JavaExtensibilityElement.java | 25 + .../ComponentNameExtensibilityElement.java | 52 + .../extensibility/ContextExtensibilityElement.java | 52 + .../DestroyInvokerExtensibilityElement.java | 29 + .../InitInvokerExtensibilityElement.java | 37 + .../extensibility/InvokerExtensibilityElement.java | 42 + .../core/injection/ContextObjectFactory.java | 41 + .../tuscany/core/injection/EventInvoker.java | 33 + .../core/injection/FactoryInitException.java | 43 + .../tuscany/core/injection/FieldInjector.java | 53 + .../core/injection/InjectionRuntimeException.java | 45 + .../apache/tuscany/core/injection/Injector.java | 33 + .../injection/InterCompositeReferenceFactory.java | 75 ++ .../tuscany/core/injection/JNDIObjectFactory.java | 46 + .../tuscany/core/injection/MethodEventInvoker.java | 47 + .../tuscany/core/injection/MethodInjector.java | 48 + .../core/injection/NonProxiedTargetFactory.java | 54 + .../tuscany/core/injection/NullEventInvoker.java | 30 + .../core/injection/ObjectCallbackException.java | 42 + .../core/injection/ObjectCreationException.java | 43 + .../tuscany/core/injection/PojoObjectFactory.java | 76 ++ .../core/injection/SingletonObjectFactory.java | 37 + .../loader/InvalidPropertyFactoryException.java | 46 + .../apache/tuscany/core/loader/LoaderContext.java | 47 + .../tuscany/core/loader/StAXElementLoader.java | 40 + .../tuscany/core/loader/StAXLoaderRegistry.java | 91 ++ .../tuscany/core/loader/StAXPropertyFactory.java | 42 + .../org/apache/tuscany/core/loader/StAXUtil.java | 160 +++ .../core/loader/WSDLDefinitionRegistry.java | 95 ++ .../core/loader/assembly/AbstractLoader.java | 61 + .../core/loader/assembly/AssemblyConstants.java | 47 + .../core/loader/assembly/ComponentLoader.java | 189 +++ .../core/loader/assembly/ComponentTypeLoader.java | 65 + .../core/loader/assembly/CompositeLoader.java | 62 + .../core/loader/assembly/EntryPointLoader.java | 90 ++ .../loader/assembly/ExternalServiceLoader.java | 75 ++ .../core/loader/assembly/ImportWSDLLoader.java | 95 ++ .../core/loader/assembly/InterfaceJavaLoader.java | 45 + .../core/loader/assembly/InterfaceWSDLLoader.java | 110 ++ .../core/loader/assembly/ModuleFragmentLoader.java | 42 + .../tuscany/core/loader/assembly/ModuleLoader.java | 50 + .../core/loader/assembly/PropertyLoader.java | 79 ++ .../core/loader/assembly/ReferenceLoader.java | 64 + .../core/loader/assembly/ServiceLoader.java | 61 + .../tuscany/core/loader/assembly/WireLoader.java | 84 ++ .../assembly/recursive/AssemblyConstants.java | 46 + .../loader/assembly/recursive/ComponentLoader.java | 181 +++ .../assembly/recursive/ComponentTypeLoader.java | 66 + .../loader/assembly/recursive/CompositeLoader.java | 51 + .../recursive/CompositeReferenceLoader.java | 77 ++ .../assembly/recursive/CompositeServiceLoader.java | 92 ++ .../assembly/recursive/ImportWSDLLoader.java | 96 ++ .../assembly/recursive/InterfaceJavaLoader.java | 46 + .../assembly/recursive/InterfaceWSDLLoader.java | 111 ++ .../loader/assembly/recursive/PropertyLoader.java | 81 ++ .../loader/assembly/recursive/ReferenceLoader.java | 66 + .../loader/assembly/recursive/ServiceLoader.java | 62 + .../core/loader/assembly/recursive/WireLoader.java | 85 ++ .../core/loader/impl/JNDIPropertyFactory.java | 62 + .../core/loader/impl/StAXLoaderRegistryImpl.java | 105 ++ .../loader/impl/StringParserPropertyFactory.java | 110 ++ .../loader/impl/WSDLDefinitionRegistryImpl.java | 202 ++++ .../core/loader/system/SystemBindingLoader.java | 47 + .../loader/system/SystemImplementationLoader.java | 68 ++ .../org/apache/tuscany/core/message/Message.java | 58 + .../tuscany/core/message/MessageFactory.java | 29 + .../core/message/impl/MessageFactoryImpl.java | 44 + .../tuscany/core/message/impl/MessageImpl.java | 86 ++ .../tuscany/core/runtime/RuntimeContext.java | 62 + .../tuscany/core/runtime/RuntimeContextImpl.java | 221 ++++ .../tuscany/core/runtime/RuntimeMonitor.java | 32 + .../tuscany/core/runtime/RuntimeScopeStrategy.java | 46 + .../tuscany/core/sdo/DataFactoryObjectFactory.java | 61 + .../tuscany/core/sdo/TypeHelperObjectFactory.java | 61 + .../tuscany/core/sdo/XMLHelperObjectFactory.java | 61 + .../tuscany/core/sdo/XSDHelperObjectFactory.java | 62 + .../apache/tuscany/core/sdo/helper/SDOHelper.java | 40 + .../sdo/helper/SDOHelperExtensibilityElement.java | 80 ++ .../core/sdo/helper/SDOHelperProcessor.java | 78 ++ .../tuscany/core/system/annotation/Autowire.java | 31 + .../tuscany/core/system/annotation/Monitor.java | 32 + .../core/system/annotation/ParentContext.java | 32 + .../system/assembly/SystemAssemblyFactory.java | 66 + .../core/system/assembly/SystemBinding.java | 37 + .../core/system/assembly/SystemImplementation.java | 38 + .../tuscany/core/system/assembly/SystemModule.java | 34 + .../assembly/impl/SystemAssemblyFactoryImpl.java | 84 ++ .../system/assembly/impl/SystemBindingImpl.java | 41 + .../assembly/impl/SystemImplementationImpl.java | 45 + .../system/assembly/impl/SystemModuleImpl.java | 174 +++ .../builder/SystemContextFactoryBuilder.java | 343 ++++++ .../system/builder/SystemEntryPointBuilder.java | 67 + .../builder/SystemExternalServiceBuilder.java | 67 + .../core/system/config/SystemContextFactory.java | 208 ++++ .../config/SystemEntryPointContextFactory.java | 99 ++ .../system/config/SystemExtensibilityElement.java | 23 + .../SystemExternalServiceContextFactory.java | 110 ++ .../config/SystemInjectorExtensibilityElement.java | 34 + .../system/config/SystemObjectContextFactory.java | 98 ++ .../AutowireExtensibilityElement.java | 53 + .../extensibility/MonitorExtensibilityElement.java | 58 + .../ParentContextExtensibilityElement.java | 54 + .../system/config/processor/AutowireProcessor.java | 90 ++ .../system/config/processor/MonitorProcessor.java | 69 ++ .../config/processor/ParentContextProcessor.java | 72 ++ .../core/system/context/SystemAtomicContext.java | 159 +++ .../system/context/SystemCompositeContextImpl.java | 91 ++ .../system/context/SystemEntryPointContext.java | 82 ++ .../context/SystemExternalServiceContext.java | 67 + .../core/system/context/SystemScopeStrategy.java | 56 + .../system/injection/AutowireObjectFactory.java | 72 ++ .../apache/tuscany/core/webapp/ContextBinder.java | 39 + .../tuscany/core/webapp/LazyHTTPSessionId.java | 56 + .../apache/tuscany/core/webapp/ServletHost.java | 58 + .../tuscany/core/webapp/TuscanyRequestFilter.java | 96 ++ .../core/webapp/TuscanyServletListener.java | 129 ++ .../org/apache/tuscany/core/wire/Interceptor.java | 42 + .../tuscany/core/wire/InvocationConfiguration.java | 181 +++ .../core/wire/InvocationRuntimeException.java | 44 + .../apache/tuscany/core/wire/MessageChannel.java | 33 + .../apache/tuscany/core/wire/MessageHandler.java | 34 + .../apache/tuscany/core/wire/MethodHashMap.java | 55 + .../tuscany/core/wire/ProxyCreationException.java | 43 + .../core/wire/SourceInvocationConfiguration.java | 131 ++ .../tuscany/core/wire/SourceWireFactory.java | 34 + .../core/wire/TargetInvocationConfiguration.java | 49 + .../apache/tuscany/core/wire/TargetInvoker.java | 47 + .../tuscany/core/wire/TargetWireFactory.java | 33 + .../tuscany/core/wire/WireConfiguration.java | 92 ++ .../apache/tuscany/core/wire/WireException.java | 43 + .../org/apache/tuscany/core/wire/WireFactory.java | 76 ++ .../tuscany/core/wire/WireFactoryFactory.java | 47 + .../core/wire/WireFactoryInitException.java | 43 + .../tuscany/core/wire/WireSourceConfiguration.java | 68 ++ .../tuscany/core/wire/WireTargetConfiguration.java | 48 + .../tuscany/core/wire/impl/InvokerInterceptor.java | 46 + .../tuscany/core/wire/impl/MessageChannelImpl.java | 68 ++ .../tuscany/core/wire/impl/MessageDispatcher.java | 46 + .../tuscany/core/wire/impl/NullWireFactory.java | 71 ++ .../tuscany/core/wire/impl/OneWayInterceptor.java | 48 + .../core/wire/impl/RequestResponseInterceptor.java | 73 ++ .../core/wire/jdk/JDKInvocationHandler.java | 137 +++ .../core/wire/jdk/JDKSourceWireFactory.java | 92 ++ .../core/wire/jdk/JDKTargetWireFactory.java | 95 ++ .../core/wire/jdk/JDKWireFactoryFactory.java | 66 + .../wire/service/DefaultWireFactoryService.java | 157 +++ .../core/wire/service/WireFactoryService.java | 51 + .../core/src/main/resources/META-INF/LICENSE.txt | 1277 ++++++++++++++++++++ .../sca/core/src/main/resources/META-INF/NOTICE | 18 + .../core/src/main/resources/META-INF/README.txt | 35 + ....tuscany.core.runtime.proxy.ServiceProxyFactory | 1 + .../core/src/main/resources/model/anyobject.xsd | 35 + .../src/main/resources/model/tuscany-system.xsd | 53 + .../apache/tuscany/core/MonitorMessages.properties | 23 + .../sca/core/src/main/resources/system.module | 146 +++ .../AsyncInvocationConfigurationTestCase.java | 197 +++ .../tuscany/core/async/wire/mock/MockHandler.java | 38 + .../core/async/wire/mock/MockStaticInvoker.java | 86 ++ .../core/async/wire/mock/MockSyncInterceptor.java | 45 + .../tuscany/core/async/wire/mock/SimpleTarget.java | 28 + .../core/async/wire/mock/SimpleTargetImpl.java | 54 + .../async/work/DefaultWorkManagerTestCase.java | 98 ++ .../async/work/GeronimoWorkManagerTestCase.java | 138 +++ .../builder/impl/DefaultWireBuilderTestCase.java | 465 +++++++ .../impl/NegativeDefaultWireBuilderTestCase.java | 89 ++ .../java/org/apache/tuscany/core/config/Bean1.java | 45 + .../java/org/apache/tuscany/core/config/Bean2.java | 46 + .../config/JavaIntrospectionHelperTestCase.java | 163 +++ .../org/apache/tuscany/core/config/SuperBean.java | 48 + .../impl/CoreAnnotationsProcessingTestCase.java | 173 +++ .../core/config/impl/ScopeTestComponent.java | 24 + .../tuscany/core/config/impl/ScopedParent.java | 26 + .../apache/tuscany/core/config/impl/SuperFoo.java | 23 + .../tuscany/core/config/impl/SuperFooImpl.java | 26 + .../tuscany/core/config/impl/SuperSuperFoo.java | 23 + .../core/config/impl/SuperSuperFooImpl.java | 20 + .../tuscany/core/config/impl/TestComponent.java | 30 + .../core/config/impl/TestComponentImpl.java | 66 + .../core/config/impl/TestLocalComponent.java | 29 + .../core/config/impl/TestLocalComponentImpl.java | 32 + .../impl/TestMultipleInterfacesComponentImpl.java | 29 + .../core/config/impl/TestNonServiceInterface.java | 20 + .../core/config/impl/TestNonServiceInterface2.java | 23 + .../config/impl/TestNonServiceInterfacesImpl.java | 23 + .../config/impl/TestNonServiceSpecifiedImpl.java | 28 + .../context/AbstractCompositeHierarchyTests.java | 109 ++ .../context/CompositeContextRegisterTestCase.java | 132 ++ .../core/context/CompositeHierarchyTestCase.java | 99 ++ .../core/context/QualifiedNameTestCase.java | 52 + .../scope/DefaultScopeStrategyTestCase.java | 51 + .../extension/ContextFactorySupportTestCase.java | 80 ++ .../EntryPointBuilderSupportTestCase.java | 78 ++ .../ExternalServiceBuilderSupportTestCase.java | 80 ++ .../core/extension/WireBuilderSupportTestCase.java | 261 ++++ .../IntraCompositeWireIntegrationTestCase.java | 107 ++ .../core/loader/JNDIPropertyFactoryTestCase.java | 210 ++++ .../tuscany/core/loader/MockReaderSupport.java | 210 ++++ .../core/loader/StAXLoaderRegistryTestCase.java | 145 +++ .../StringParserPropertyFactoryTestCase.java | 111 ++ .../loader/assembly/ComponentLoaderTestCase.java | 151 +++ .../assembly/ComponentTypeLoaderTestCase.java | 49 + .../loader/assembly/EntryPointLoaderTestCase.java | 63 + .../assembly/ExternalServiceLoaderTestCase.java | 64 + ...InterfaceWSDLLoaderInterfaceStylesTestCase.java | 101 ++ .../assembly/InterfaceWSDLLoaderTestCase.java | 88 ++ .../core/loader/assembly/LoaderTestSupport.java | 82 ++ .../tuscany/core/loader/assembly/MockService.java | 23 + .../assembly/WSDLDefinitionRegistryTestCase.java | 76 ++ .../core/loader/assembly/WireLoaderTestCase.java | 60 + .../tuscany/core/mock/MockConfigContext.java | 53 + .../org/apache/tuscany/core/mock/MockFactory.java | 413 +++++++ .../core/mock/component/AutowireSourceImpl.java | 64 + .../mock/component/GenericSystemComponent.java | 22 + .../mock/component/ModuleScopeSystemComponent.java | 28 + .../component/ModuleScopeSystemComponentImpl.java | 25 + .../apache/tuscany/core/mock/component/Source.java | 34 + .../tuscany/core/mock/component/SourceImpl.java | 67 + .../apache/tuscany/core/mock/component/Target.java | 27 + .../tuscany/core/mock/component/TargetImpl.java | 33 + .../tuscany/core/runtime/RuntimeBootTestCase.java | 99 ++ .../core/runtime/RuntimeContextImplTestCase.java | 286 +++++ .../core/runtime/SystemBootstrapTestCase.java | 127 ++ .../system/builder/MonitorInjectionTestCase.java | 106 ++ .../core/system/builder/SystemComponentImpl.java | 167 +++ .../SystemContextFactoryBuilderTestCase.java | 173 +++ .../builder/impl/AssemblyVisitorTestCase.java | 136 +++ .../core/system/context/AutowireTestCase.java | 310 +++++ .../system/context/CompositeNestingTestCase.java | 98 ++ .../system/context/IntraCompositeWireTestCase.java | 125 ++ .../SystemCompositeComponentContextTestCase.java | 108 ++ .../SystemCompositeContextRegisterTestCase.java | 37 + .../context/SystemCompositeHierarchyTestCase.java | 46 + .../context/SystemObjectRegistrationTestCase.java | 84 ++ .../tuscany/core/system/context/TestBuilder.java | 55 + .../wire/InvocationConfigurationErrorTestCase.java | 155 +++ .../core/wire/InvocationConfigurationTestCase.java | 153 +++ .../tuscany/core/wire/InvocationErrorTestCase.java | 122 ++ .../wire/jdk/JDKInvocationHandlerTestCase.java | 126 ++ .../wire/jdk/JDKWireFactoryFactoryTestCase.java | 83 ++ .../apache/tuscany/core/wire/mock/MockHandler.java | 38 + .../tuscany/core/wire/mock/MockScopeContext.java | 131 ++ .../tuscany/core/wire/mock/MockStaticInvoker.java | 86 ++ .../core/wire/mock/MockSyncInterceptor.java | 45 + .../tuscany/core/wire/mock/SimpleSource.java | 25 + .../tuscany/core/wire/mock/SimpleSourceImpl.java | 36 + .../tuscany/core/wire/mock/SimpleTarget.java | 28 + .../tuscany/core/wire/mock/SimpleTargetImpl.java | 39 + .../core/config/ModuleComponentLoaderTest1.module | 24 + .../tuscany/core/loader/assembly/example.wsdl | 23 + .../tuscany/core/loader/assembly/example.xsd | 23 + .../core/loader/assembly/interfacestyles.wsdl | 239 ++++ .../sca/core/src/test/resources/system.fragment | 21 + 392 files changed, 31028 insertions(+) create mode 100644 branches/java-post-M1/sca/core/pom.xml create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/async/builder/AsyncPolicyBuilder.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/async/invocation/AsyncInterceptor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/async/work/DefaultWorkManager.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderConfigException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderInitException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextCreationException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextFactoryBuilder.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextFactoryBuilderRegistry.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextResolver.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/HierarchicalWireBuilder.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/NoAccessorException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ObjectFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/PolicyBuilder.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/PolicyOrderer.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/SourcePolicyBuilder.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/SourcePolicyOrderer.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/TargetPolicyBuilder.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/TargetPolicyOrderer.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/UnknownTypeException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/WireBuilder.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ArrayMultiplicityObjectFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/AssemblyVisitorImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ContextFactoryBuilderRegistryImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/DefaultWireBuilder.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/HierarchicalBuilder.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ListMultiplicityObjectFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ProxyObjectFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/system/DefaultPolicyBuilderRegistry.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/system/PolicyBuilderRegistry.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/client/BootstrapHelper.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/client/TuscanyRuntime.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ComponentTypeIntrospector.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ConfigurationException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ConfigurationLoadException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ImplementationCache.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/InvalidMetaDataException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/InvalidRootElementException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/InvalidSetterException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/JavaIntrospectionHelper.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/MetaDataException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/MissingInterfaceException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/MissingResourceException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ModuleComponentConfigurationLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/SidefileLoadException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/impl/AbstractModuleComponentConfigurationLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/impl/Java5ComponentTypeIntrospector.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/impl/StAXModuleComponentConfigurationLoaderImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ComponentNameProcessor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ContextProcessor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/DefaultProcessor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/DestroyProcessor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ImplementationProcessorSupport.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/InitProcessor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ProcessorHelper.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ProcessorUtils.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/PropertyProcessor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/PropertyReferenceValidator.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ReferenceProcessor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ScopeProcessor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ServiceProcessor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/AtomicContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireResolutionException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/CompositeContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ConfigurationContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/Context.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ContextInitException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ContextRuntimeException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/CoreRuntimeException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/DuplicateNameException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EntryPointContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EventContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EventException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EventFilter.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EventPublisher.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ExternalServiceContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/InvalidNameException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/Lifecycle.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/MissingContextFactoryException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/MissingImplementationException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/MissingScopeException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ProxyConfigurationException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/QualifiedName.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/RuntimeEventListener.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeAwareContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeIdentifier.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeInitializationException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeRuntimeException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeStrategy.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ServiceNotFoundException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/SystemCompositeContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/TargetException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/AbstractEvent.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/AbstractRequestEvent.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/Event.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/HttpSessionBound.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/HttpSessionEnd.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/HttpSessionEvent.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/InstanceCreated.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/ModuleEvent.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/ModuleStart.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/ModuleStop.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/RequestEnd.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/RequestEvent.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/RequestStart.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/SessionBound.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/SessionEnd.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/SessionEvent.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/SessionStart.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/filter/TrueFilter.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractCompositeContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractLifecycle.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/CompositeContextImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EntryPointContextImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EventContextImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/ExternalServiceContextImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeStrategy.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/CompositeScopeContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/DefaultScopeStrategy.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/SessionScopeContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ComponentTargetInvoker.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ContextFactoryBuilderSupport.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/EntryPointBuilderSupport.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/EntryPointContextFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ExternalServiceBuilderSupport.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ExternalServiceContextFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ExternalServiceInvoker.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ExternalServiceTargetInvoker.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/WireBuilderSupport.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/ImplementationProcessor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/InjectorExtensibilityElement.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/JavaExtensibilityElement.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/ComponentNameExtensibilityElement.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/ContextExtensibilityElement.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/DestroyInvokerExtensibilityElement.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/InitInvokerExtensibilityElement.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/InvokerExtensibilityElement.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/ContextObjectFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/EventInvoker.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/FactoryInitException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/FieldInjector.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/InjectionRuntimeException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/Injector.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/InterCompositeReferenceFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/JNDIObjectFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/MethodEventInvoker.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/MethodInjector.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/NonProxiedTargetFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/NullEventInvoker.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/ObjectCallbackException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/ObjectCreationException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/PojoObjectFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/SingletonObjectFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/InvalidPropertyFactoryException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/LoaderContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXElementLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXLoaderRegistry.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXPropertyFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXUtil.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/WSDLDefinitionRegistry.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/AbstractLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/AssemblyConstants.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ComponentLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ComponentTypeLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/CompositeLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/EntryPointLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ExternalServiceLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ImportWSDLLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/InterfaceJavaLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/InterfaceWSDLLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ModuleFragmentLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ModuleLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/PropertyLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ReferenceLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ServiceLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/WireLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/AssemblyConstants.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ComponentLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ComponentTypeLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/CompositeLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/CompositeReferenceLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/CompositeServiceLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ImportWSDLLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/InterfaceJavaLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/InterfaceWSDLLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/PropertyLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ReferenceLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ServiceLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/WireLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/JNDIPropertyFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/StAXLoaderRegistryImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/StringParserPropertyFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/WSDLDefinitionRegistryImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/system/SystemBindingLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/system/SystemImplementationLoader.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/message/Message.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/message/MessageFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/message/impl/MessageFactoryImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/message/impl/MessageImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeContextImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeMonitor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeScopeStrategy.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/DataFactoryObjectFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/TypeHelperObjectFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/XMLHelperObjectFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/XSDHelperObjectFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/helper/SDOHelper.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/helper/SDOHelperExtensibilityElement.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/helper/SDOHelperProcessor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/Autowire.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/Monitor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/ParentContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemAssemblyFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemBinding.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemImplementation.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemModule.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemAssemblyFactoryImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemBindingImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemImplementationImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemModuleImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemContextFactoryBuilder.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemEntryPointBuilder.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemExternalServiceBuilder.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemContextFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemEntryPointContextFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemExtensibilityElement.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemExternalServiceContextFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemInjectorExtensibilityElement.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemObjectContextFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/extensibility/AutowireExtensibilityElement.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/extensibility/MonitorExtensibilityElement.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/extensibility/ParentContextExtensibilityElement.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/processor/AutowireProcessor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/processor/MonitorProcessor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/processor/ParentContextProcessor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemAtomicContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemCompositeContextImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemEntryPointContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemExternalServiceContext.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemScopeStrategy.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/injection/AutowireObjectFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/ContextBinder.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/LazyHTTPSessionId.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/ServletHost.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/TuscanyRequestFilter.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/TuscanyServletListener.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/Interceptor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/InvocationConfiguration.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/InvocationRuntimeException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/MessageChannel.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/MessageHandler.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/MethodHashMap.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/ProxyCreationException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/SourceInvocationConfiguration.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/SourceWireFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/TargetInvocationConfiguration.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/TargetInvoker.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/TargetWireFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireConfiguration.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireFactoryFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireFactoryInitException.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireSourceConfiguration.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireTargetConfiguration.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/InvokerInterceptor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/MessageChannelImpl.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/MessageDispatcher.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/NullWireFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/OneWayInterceptor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/RequestResponseInterceptor.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandler.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKSourceWireFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKTargetWireFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKWireFactoryFactory.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/service/DefaultWireFactoryService.java create mode 100644 branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/service/WireFactoryService.java create mode 100644 branches/java-post-M1/sca/core/src/main/resources/META-INF/LICENSE.txt create mode 100644 branches/java-post-M1/sca/core/src/main/resources/META-INF/NOTICE create mode 100644 branches/java-post-M1/sca/core/src/main/resources/META-INF/README.txt create mode 100644 branches/java-post-M1/sca/core/src/main/resources/META-INF/services/org.apache.tuscany.core.runtime.proxy.ServiceProxyFactory create mode 100644 branches/java-post-M1/sca/core/src/main/resources/model/anyobject.xsd create mode 100644 branches/java-post-M1/sca/core/src/main/resources/model/tuscany-system.xsd create mode 100644 branches/java-post-M1/sca/core/src/main/resources/org/apache/tuscany/core/MonitorMessages.properties create mode 100644 branches/java-post-M1/sca/core/src/main/resources/system.module create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/invocation/AsyncInvocationConfigurationTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/MockHandler.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/MockStaticInvoker.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/MockSyncInterceptor.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/SimpleTarget.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/SimpleTargetImpl.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/work/DefaultWorkManagerTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/work/GeronimoWorkManagerTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/builder/impl/DefaultWireBuilderTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/builder/impl/NegativeDefaultWireBuilderTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/Bean1.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/Bean2.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/JavaIntrospectionHelperTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/SuperBean.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/CoreAnnotationsProcessingTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/ScopeTestComponent.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/ScopedParent.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/SuperFoo.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/SuperFooImpl.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/SuperSuperFoo.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/SuperSuperFooImpl.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestComponent.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestComponentImpl.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestLocalComponent.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestLocalComponentImpl.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestMultipleInterfacesComponentImpl.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestNonServiceInterface.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestNonServiceInterface2.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestNonServiceInterfacesImpl.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestNonServiceSpecifiedImpl.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/AbstractCompositeHierarchyTests.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/CompositeContextRegisterTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/CompositeHierarchyTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/QualifiedNameTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/scope/DefaultScopeStrategyTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/extension/ContextFactorySupportTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/extension/EntryPointBuilderSupportTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/extension/ExternalServiceBuilderSupportTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/extension/WireBuilderSupportTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/integration/IntraCompositeWireIntegrationTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/JNDIPropertyFactoryTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/MockReaderSupport.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/StAXLoaderRegistryTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/StringParserPropertyFactoryTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/ComponentLoaderTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/ComponentTypeLoaderTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/EntryPointLoaderTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/ExternalServiceLoaderTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/InterfaceWSDLLoaderInterfaceStylesTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/InterfaceWSDLLoaderTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/LoaderTestSupport.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/MockService.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/WSDLDefinitionRegistryTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/WireLoaderTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/MockConfigContext.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/MockFactory.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/AutowireSourceImpl.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/GenericSystemComponent.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/ModuleScopeSystemComponent.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/ModuleScopeSystemComponentImpl.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/Source.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/SourceImpl.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/Target.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/TargetImpl.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/runtime/RuntimeBootTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/runtime/RuntimeContextImplTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/runtime/SystemBootstrapTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/builder/MonitorInjectionTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/builder/SystemComponentImpl.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/builder/SystemContextFactoryBuilderTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/builder/impl/AssemblyVisitorTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/AutowireTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/CompositeNestingTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/IntraCompositeWireTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/SystemCompositeComponentContextTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/SystemCompositeContextRegisterTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/SystemCompositeHierarchyTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/SystemObjectRegistrationTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/TestBuilder.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationErrorTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/InvocationErrorTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandlerTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKWireFactoryFactoryTestCase.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/MockHandler.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/MockScopeContext.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/MockStaticInvoker.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/MockSyncInterceptor.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/SimpleSource.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/SimpleSourceImpl.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/SimpleTarget.java create mode 100644 branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/SimpleTargetImpl.java create mode 100644 branches/java-post-M1/sca/core/src/test/resources/org/apache/tuscany/core/config/ModuleComponentLoaderTest1.module create mode 100644 branches/java-post-M1/sca/core/src/test/resources/org/apache/tuscany/core/loader/assembly/example.wsdl create mode 100644 branches/java-post-M1/sca/core/src/test/resources/org/apache/tuscany/core/loader/assembly/example.xsd create mode 100644 branches/java-post-M1/sca/core/src/test/resources/org/apache/tuscany/core/loader/assembly/interfacestyles.wsdl create mode 100644 branches/java-post-M1/sca/core/src/test/resources/system.fragment (limited to 'branches/java-post-M1/sca/core') diff --git a/branches/java-post-M1/sca/core/pom.xml b/branches/java-post-M1/sca/core/pom.xml new file mode 100644 index 0000000000..b5e934d45e --- /dev/null +++ b/branches/java-post-M1/sca/core/pom.xml @@ -0,0 +1,107 @@ + + + + + org.apache.tuscany + tuscany-sca + incubating-M1 + + 4.0.0 + tuscany-core + Tuscany Core + Core Tuscany runtime. + incubating-M1 + + + + org.apache.tuscany + tuscany-model + ${pom.version} + compile + + + + stax + stax-api + 1.0 + compile + + + + woodstox + wstx-asl + 2.9.3 + runtime + + + + tomcat + servlet-api + 5.0.18 + provided + + + + org.apache.geronimo.specs + geronimo-j2ee-connector_1.5_spec + 1.0 + compile + + + + org.apache.geronimo + geronimo-connector + 1.0 + compile + + + org.apache.geronimo + geronimo-transaction + 1.0 + compile + + + + org.apache.geronimo.specs + geronimo-jta_1.0.1B_spec + 1.0 + runtime + + + + concurrent + concurrent + 1.3.4 + runtime + + + + commons-logging + commons-logging + 1.0.4 + runtime + + + + junit + junit + 3.8.1 + test + + + + diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/async/builder/AsyncPolicyBuilder.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/async/builder/AsyncPolicyBuilder.java new file mode 100644 index 0000000000..6acebdaa8e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/async/builder/AsyncPolicyBuilder.java @@ -0,0 +1,86 @@ +/** + * + * 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.async.builder; + +import java.util.List; + +import javax.resource.spi.work.WorkManager; + +import org.apache.tuscany.core.async.invocation.AsyncInterceptor; +import org.apache.tuscany.core.builder.BuilderException; +import org.apache.tuscany.core.builder.SourcePolicyBuilder; +import org.apache.tuscany.core.builder.TargetPolicyBuilder; +import org.apache.tuscany.core.builder.system.PolicyBuilderRegistry; +import org.apache.tuscany.core.message.MessageFactory; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.core.wire.TargetInvocationConfiguration; +import org.apache.tuscany.core.wire.WireSourceConfiguration; +import org.apache.tuscany.core.wire.WireTargetConfiguration; +import org.apache.tuscany.model.assembly.ConfiguredReference; +import org.apache.tuscany.model.assembly.ConfiguredService; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.OneWay; + +/** + * Builds context factories for component implementations that map to {@link org.apache.tuscany.container.java.assembly.JavaImplementation}. + * The logical model is then decorated with the runtime configuration. + * + * @version $Rev: 368822 $ $Date: 2006-01-13 10:54:38 -0800 (Fri, 13 Jan 2006) $ + * @see org.apache.tuscany.core.builder.ContextFactory + */ +@org.osoa.sca.annotations.Scope("MODULE") +public class AsyncPolicyBuilder implements SourcePolicyBuilder, TargetPolicyBuilder { + + private PolicyBuilderRegistry builderRegistry; + private WorkManager workManager; + private MessageFactory messageFactory; + + public AsyncPolicyBuilder() { + } + + @Init(eager = true) + public void init() { + builderRegistry.registerSourceBuilder(this); + builderRegistry.registerTargetBuilder(this); + } + + @Autowire + public void setBuilderRegistry(PolicyBuilderRegistry builderRegistry) { + this.builderRegistry = builderRegistry; + } + + @Autowire + public void setWorkManager(WorkManager workManager) { + this.workManager = workManager; + } + + @Autowire + public void setMessageFactory(MessageFactory messageFactory) { + this.messageFactory = messageFactory; + } + + public void build(ConfiguredReference arg0, List arg1) throws BuilderException { + } + + public void build(ConfiguredService service, WireTargetConfiguration wireTargetConfiguration) throws BuilderException { + for (TargetInvocationConfiguration configuration : wireTargetConfiguration.getInvocationConfigurations().values()) { + if (configuration.getMethod().getAnnotation(OneWay.class)!=null) { + configuration.addInterceptor(new AsyncInterceptor(workManager, messageFactory)); + } + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/async/invocation/AsyncInterceptor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/async/invocation/AsyncInterceptor.java new file mode 100644 index 0000000000..08a718bd73 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/async/invocation/AsyncInterceptor.java @@ -0,0 +1,108 @@ +/** + * + * 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.async.invocation; + +import javax.resource.spi.work.Work; +import javax.resource.spi.work.WorkException; +import javax.resource.spi.work.WorkManager; + +import org.apache.tuscany.core.message.Message; +import org.apache.tuscany.core.message.MessageFactory; +import org.apache.tuscany.core.wire.Interceptor; +import org.osoa.sca.CurrentModuleContext; +import org.osoa.sca.ModuleContext; +import org.osoa.sca.SCA; +import org.osoa.sca.ServiceRuntimeException; + +/** + * A wire interceptor that uses a WorkManager to schedule asynchronous execution of invocations in Work instances. + */ +public class AsyncInterceptor implements Interceptor { + + private static final ContextBinder BINDER = new ContextBinder(); + + private WorkManager workManager; + private MessageFactory messageFactory; + private Interceptor next; + + /** + * Constructs a new instance + * @param workManager + */ + public AsyncInterceptor(WorkManager workManager, MessageFactory messageFactory) { + this.workManager=workManager; + this.messageFactory=messageFactory; + } + + public Message invoke(final Message message) { + + final ModuleContext currentModuleContext=CurrentModuleContext.getContext(); + + // Schedule the invocation of the next interceptor in a new Work instance + try { + workManager.scheduleWork(new Work() { + + public void run() { + ModuleContext oldModuleContext=CurrentModuleContext.getContext(); + try { + BINDER.setContext(currentModuleContext); + + // Invoke the next interceptor + next.invoke(message); + + } catch (Exception e) { + //FIXME How do we report exceptions? + e.printStackTrace(); + + } finally { + + BINDER.setContext(oldModuleContext); + } + } + + public void release() { + } + + }); + } catch (WorkException e) { + //FIXME Which exception should we throw here? + throw new ServiceRuntimeException(e); + } + + // No return on a OneWay invocation. + return messageFactory.createMessage(); + } + + public void setNext(Interceptor next) { + this.next=next; + } + + private static class ContextBinder extends SCA { + public void setContext(ModuleContext context) { + setModuleContext(context); + } + + public void start() { + throw new AssertionError(); + } + + public void stop() { + throw new AssertionError(); + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/async/work/DefaultWorkManager.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/async/work/DefaultWorkManager.java new file mode 100644 index 0000000000..866e101b0e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/async/work/DefaultWorkManager.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.async.work; + +import javax.resource.spi.work.WorkManager; + +import org.apache.geronimo.connector.work.GeronimoWorkManager; +import org.apache.geronimo.transaction.context.TransactionContextManager; +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * A Work Manager service component implementation which just reuses the Geronimo WorkManager. + * + * @version $Rev$ $Date$ + */ +@Service(WorkManager.class) +@Scope("MODULE") +public class DefaultWorkManager extends GeronimoWorkManager implements WorkManager { + + private final static int DEFAULT_POOL_SIZE = 10; + + @Property + public int scheduledMaximumPoolSize; + + /** + * Constructs a new instance. + */ + public DefaultWorkManager() { + super(DEFAULT_POOL_SIZE, new TransactionContextManager()); + } + + @Init(eager=true) + public void init() throws Exception { + doStart(); + } + + @Destroy + public void destroy() throws Exception { + doStop(); + } + + public void setScheduledMaximumPoolSize(int maxSize) { + super.setScheduledMaximumPoolSize(maxSize); + } + + public int getScheduledMaximumPoolSize() { + return super.getScheduledMaximumPoolSize(); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderConfigException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderConfigException.java new file mode 100644 index 0000000000..c2402d9141 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderConfigException.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; + +/** + * Represents an error processing an assembly model + * + * @version $Rev$ $Date$ + */ +public class BuilderConfigException extends BuilderException { + + public BuilderConfigException() { + super(); + } + + public BuilderConfigException(String message) { + super(message); + } + + public BuilderConfigException(String message, Throwable cause) { + super(message, cause); + } + + public BuilderConfigException(Throwable cause) { + super(cause); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderException.java new file mode 100644 index 0000000000..246f188988 --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderInitException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/BuilderInitException.java new file mode 100644 index 0000000000..cd57eaf7ab --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextCreationException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextCreationException.java new file mode 100644 index 0000000000..24b526371d --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextFactory.java new file mode 100644 index 0000000000..ccef8024e8 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextFactory.java @@ -0,0 +1,123 @@ +/** + * + * 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.CompositeContext; +import org.apache.tuscany.core.context.Context; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.model.assembly.Scope; + +import java.util.List; +import java.util.Map; + +/** + * Implementations create {@link org.apache.tuscany.core.context.Context}s based on an assembly configuration. + *

+ * Context factories are "built" in two phases. {@link ContextFactoryBuilder}s analyze an assembly, producing + * ContextFactorys for {@link org.apache.tuscany.model.assembly.Component}s, {@link + * org.apache.tuscany.model.assembly.EntryPoint}s, and {@link org.apache.tuscany.model.assembly.ExternalService}s. During this + * phase, {@link org.apache.tuscany.core.wire.WireFactory}s for source- and target-side wires are produced for the + * ContextFactorys. Ê + *

+ * The second build phase connects the source- and target-side WireFactories, thereby completing wire configuration. + *

+ * At runtime, ContextFactorys are called to create new Contexts when a new implementation instance is + * required for a component, entry point, or external service. The Context is then responsible for instantiating and + * managing the actual implementation instance. When a Context creates a new instance, the previously configured + * WireFactorys are used to create wires to and from the instance. A wire is a collection of stateless invocation + * chains that are managed by the Context's ContextFactory. + * + * @version $Rev: 385747 $ $Date: 2006-03-13 22:12:53 -0800 (Mon, 13 Mar 2006) $ + */ +public interface ContextFactory { + + /** + * Creates a Context based on configuration supplied by a logical model assembly + * + * @return a new instance context + * @throws ContextCreationException if an error occurs creating the context + */ + public T createContext() throws ContextCreationException; + + /** + * Returns the scope identifier associated with the type of contexts produced by the current factory + */ + public Scope getScope(); + + /** + * Returns the name of the Context produced by the current factory + */ + public String getName(); + + /** + * Adds a property to the context + */ + public void addProperty(String propertyName, Object value); + + /** + * Adds a target-side wire factory for the given service name. Target-side wire factories contain the invocation chains + * associated with the destination service of a wire and are responsible for generating proxies + */ + public void addTargetWireFactory(String serviceName, TargetWireFactory factory); + + /** + * Returns the target-side wire factory associated with the given service name + */ + public TargetWireFactory getTargetWireFactory(String serviceName); + + /** + * Returns a collection of target-side wire factories keyed by service name + */ + public Map getTargetWireFactories(); + + /** + * Adds a source-side wire factory for the given reference. Source-side wire factories contain the invocation chains for a + * reference in the implementation associated with the instance context created by this configuration. Source-side wire + * factories also produce proxies that are injected on a reference in a component implementation. + * + * @param referenceName + * @param factory + */ + public void addSourceWireFactory(String referenceName, SourceWireFactory factory); + + /** + * Adds a set of source-side wire factories for the given reference. Source-side wire factories contain the invocation chains + * for a reference in the implementation associated with the instance context created by this configuration. Source-side wire + * factories also produce proxies that are injected on a reference in a component implementation. + * + * @param referenceName + * @param referenceInterface + * @param factory + * @param multiplicity + */ + public void addSourceWireFactories(String referenceName, Class referenceInterface, List factory, boolean multiplicity); + + /** + * Returns a collection of source-side wire factories for references. There may 1..n wire factories per reference. + */ + public List getSourceWireFactories(); + + /** + * Called to signal to the configuration that its parent context has been activated and that it shoud perform any required + * initialization steps + * + * @param parent the parent context + */ + public void prepare(CompositeContext parent); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextFactoryBuilder.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextFactoryBuilder.java new file mode 100644 index 0000000000..786298809e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextFactoryBuilder.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.builder; + +import org.apache.tuscany.model.assembly.AssemblyObject; + +/** + * The extension point for component types in the runtime. Implementations perform the first phase of converting an assembly model + * into a series of runtime artifacts. Specifically, ContextFactoryBuilders are responsible for analyzing the + * assembly model and producing {@link ContextFactory}s that are used to generate executable artifacts such as an {@link + * org.apache.tuscany.core.context.Context}. In the case of components, the ContextFactory will typically contain + * configuration for instantiating implementation instances with injected properties and references. + *

+ * As the assembly model is analyzed, ContextFactoryBuilders are guaranteed to be called first and are expected to + * decorate the assembly model with ContextFactorys. + *

+ * The second phase uses {@link WireBuilder}s to connect the source and target wire chains held in these + * ContextFactorys to form a completed wire. WireBuilders may use a similar delegation strategy and + * perform various optimizations. + * + * @version $Rev$ $Date$ + * @see ContextFactory + * @see WireBuilder + */ +public interface ContextFactoryBuilder { + + /** + * Creates or updates a context factory based on configuration contained in the given model object. The model object is + * decorated with the factory. + * + * @param object the logical configuration model node + * @throws BuilderException + */ + public void build(AssemblyObject object) throws BuilderException; + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextFactoryBuilderRegistry.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextFactoryBuilderRegistry.java new file mode 100644 index 0000000000..a002627c2e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextFactoryBuilderRegistry.java @@ -0,0 +1,31 @@ +/** + * + * Copyright 2006 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.builder; + +/** + * System wide registry for ContextFactoryBuilder implementations. + * + * @version $Rev$ $Date$ + */ +public interface ContextFactoryBuilderRegistry { + /** + * Register a builder. Called by extensions to register their builders. + * + * @param builder the builder to register + */ + void register(ContextFactoryBuilder builder); +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextResolver.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextResolver.java new file mode 100644 index 0000000000..5c99d6dd43 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ContextResolver.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; + +import org.apache.tuscany.core.context.CompositeContext; + +/** + * Implementations are responsible for resolving the current composite context + * + * @version $Rev$ $Date$ + */ +public interface ContextResolver { + + /** + * Returns the current composite context + */ + CompositeContext getCurrentContext(); +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/HierarchicalWireBuilder.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/HierarchicalWireBuilder.java new file mode 100644 index 0000000000..ace34a1ad5 --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/NoAccessorException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/NoAccessorException.java new file mode 100644 index 0000000000..34b6294638 --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ObjectFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ObjectFactory.java new file mode 100644 index 0000000000..ab2cfd9bac --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/ObjectFactory.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.builder; + +import org.apache.tuscany.core.injection.ObjectCreationException; + +/** + * Implementations create new instances of a particular type + * + * @version $Rev$ $Date$ + */ +public interface ObjectFactory { + + /** + * Return a instance of the type that this factory creates. + * + * @return a instance from this factory + */ + T getInstance() throws ObjectCreationException; + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/PolicyBuilder.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/PolicyBuilder.java new file mode 100644 index 0000000000..489541a213 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/PolicyBuilder.java @@ -0,0 +1,28 @@ +/** + * + * 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 marker for policy extensions in the runtime. Implementations evaluate wire-related policy metadata on a {@link + * org.apache.tuscany.model.assembly.ConfiguredReference} or {@link org.apache.tuscany.model.assembly.ConfiguredService} and + * contribute {@link org.apache.tuscany.core.wire.Interceptor}s or {@link org.apache.tuscany.core.wire.MessageHandler}s + * implementing a policy to {@link org.apache.tuscany.core.wire.InvocationConfiguration}s that are part of a {@link + * org.apache.tuscany.core.wire.WireConfiguration}. The contributed Interceptors or Handlers will be + * called as part of an invocation over a wire. + * + * @version $$Rev$$ $$Date$$ + */ +public interface PolicyBuilder { + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/PolicyOrderer.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/PolicyOrderer.java new file mode 100644 index 0000000000..1038b6e878 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/PolicyOrderer.java @@ -0,0 +1,26 @@ +/** + * + * 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 marker for implementations that order source- or target-side policy {@link org.apache.tuscany.core.wire.Interceptor}s or + * {@link org.apache.tuscany.core.wire.MessageHandler}s in a {@link org.apache.tuscany.core.wire.WireConfiguration}. + * + * @see SourcePolicyOrderer + * @see TargetPolicyOrderer + * @version $$Rev$$ $$Date$$ + */ +public interface PolicyOrderer { + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/SourcePolicyBuilder.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/SourcePolicyBuilder.java new file mode 100644 index 0000000000..76a376e3d5 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/SourcePolicyBuilder.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.builder; + +import org.apache.tuscany.core.wire.WireSourceConfiguration; +import org.apache.tuscany.model.assembly.ConfiguredReference; + +import java.util.List; + +/** + * Implementations contribute {@link org.apache.tuscany.core.wire.Interceptor}s or {@link + * org.apache.tuscany.core.wire.MessageHandler}s that handle source-side policy on a wire. + * + * @version $$Rev$$ $$Date$$ + */ +public interface SourcePolicyBuilder extends PolicyBuilder { + + public void build(ConfiguredReference reference, List configurations) throws BuilderException; + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/SourcePolicyOrderer.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/SourcePolicyOrderer.java new file mode 100644 index 0000000000..6bc3bcda6e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/SourcePolicyOrderer.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.builder; + +import org.apache.tuscany.core.wire.WireSourceConfiguration; + +/** + * Implementations order source-side policy {@link org.apache.tuscany.core.wire.Interceptor}s or + * {@link org.apache.tuscany.core.wire.MessageHandler}s in a {@link org.apache.tuscany.core.wire.WireConfiguration}. + * + * @version $$Rev$$ $$Date$$ + */ +public interface SourcePolicyOrderer extends PolicyOrderer{ + + public void order(WireSourceConfiguration configuration); + + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/TargetPolicyBuilder.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/TargetPolicyBuilder.java new file mode 100644 index 0000000000..10c34751e2 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/TargetPolicyBuilder.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; + +import org.apache.tuscany.model.assembly.ConfiguredService; +import org.apache.tuscany.core.wire.WireTargetConfiguration; + +/** + * Implementations contribute {@link org.apache.tuscany.core.wire.Interceptor}s or {@link + * org.apache.tuscany.core.wire.MessageHandler}s that handle target-side policy on a wire. + * + * @version $$Rev$$ $$Date$$ + */ +public interface TargetPolicyBuilder extends PolicyBuilder{ + + public void build(ConfiguredService service, WireTargetConfiguration configuration) throws BuilderException; + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/TargetPolicyOrderer.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/TargetPolicyOrderer.java new file mode 100644 index 0000000000..4b596bfdc1 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/TargetPolicyOrderer.java @@ -0,0 +1,28 @@ +/** + * + * 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.wire.WireTargetConfiguration; + +/** + * Implementation order target-side policy {@link org.apache.tuscany.core.wire.Interceptor}s or + * {@link org.apache.tuscany.core.wire.MessageHandler}s in a {@link org.apache.tuscany.core.wire.WireConfiguration}. + + * @version $$Rev$$ $$Date$$ + */ +public interface TargetPolicyOrderer { + + public void order(WireTargetConfiguration configuration); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/UnknownTypeException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/UnknownTypeException.java new file mode 100644 index 0000000000..24c1fa24ff --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/UnknownTypeException.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; + +/** + * 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/WireBuilder.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/WireBuilder.java new file mode 100644 index 0000000000..54f2ff4b4e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/WireBuilder.java @@ -0,0 +1,71 @@ +/** + * + * 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.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.TargetWireFactory; + +/** + * Implementations perform the second phase of converting a logical model representing an assembly into a series of + * runtime or executable artifacts. Specifically, they are responsible for finalizing target-side proxy factories and + * bridging {@link org.apache.tuscany.core.wire.InvocationConfiguration}s held by source- and target-side proxy + * factories. WireBuilders generally operate by target implementation type. In other words, for a wire + * from a Java source to a JavaScript target, the Javascript WireBuilder will complete the wire. This is + * necessary as a WireBuilder must set a {@link org.apache.tuscany.core.wire.TargetInvoker} that is + * responsible for dispatching to an implementation on the source side of the wire. + *

+ * Runtimes are generally configured with a {@link org.apache.tuscany.core.builder.impl.DefaultWireBuilder} as a + * top-most wire builder, which delegates to other builders wired to it as part of a system configuration. + *

+ * Wire builders may optimize the wire chains based on certain characteristics of th wire, such as source and + * target scopes. + * + * @see org.apache.tuscany.core.builder.ContextFactoryBuilder + * @see org.apache.tuscany.core.builder.impl.DefaultWireBuilder + * @version $Rev$ $Date$ + */ +public interface WireBuilder { + + /** + * Connects wire 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 wire chain + * @param targetFactory the proxy factory used in constructing the target side of the wire 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 buildSource process + */ + public void connect(SourceWireFactory sourceFactory, TargetWireFactory targetFactory, Class targetType, boolean downScope, + ScopeContext targetScopeContext) throws BuilderConfigException; + + /** + * Finishes processing the target side wire chain. For example, a + * {@link org.apache.tuscany.core.wire.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 buildSource process + */ + public void completeTargetChain(TargetWireFactory targetFactory, Class targetType, ScopeContext targetScopeContext) + throws BuilderConfigException; + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ArrayMultiplicityObjectFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ArrayMultiplicityObjectFactory.java new file mode 100644 index 0000000000..8f0cbbf91b --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ArrayMultiplicityObjectFactory.java @@ -0,0 +1,49 @@ +/** + * + * 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 java.lang.reflect.Array; +import java.util.List; + +/** + * Resolves targets configured in a multiplicity by delegating to object factories and returning an + * Array containing object instances + * + * @version $Rev$ $Date$ + */ +public class ArrayMultiplicityObjectFactory implements ObjectFactory { + + private ObjectFactory[] factories; + + private Class interfaceType; + + public ArrayMultiplicityObjectFactory(Class interfaceType, List factories) { + assert (interfaceType != null) : "Interface type was null"; + assert (factories != null) : "Object factories were null"; + this.interfaceType = interfaceType; + this.factories = factories.toArray(new ObjectFactory[factories.size()]); + } + + public Object getInstance() throws ObjectCreationException { + Object array = Array.newInstance(interfaceType, factories.length); + for (int i = 0; i < factories.length; i++) { + Array.set(array, i, factories[i].getInstance()); + } + return array; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/AssemblyVisitorImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/AssemblyVisitorImpl.java new file mode 100644 index 0000000000..178d3d4de6 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/AssemblyVisitorImpl.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.builder.impl; + +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.AssemblyVisitor; +import org.apache.tuscany.model.assembly.ContextFactoryHolder; + +import java.util.List; + +/** + * Decorates an assembly object graph with runtime configurations using a set of builders + * + * @version $Rev: 392146 $ $Date: 2006-04-06 18:11:28 -0700 (Thu, 06 Apr 2006) $ + */ +public class AssemblyVisitorImpl implements AssemblyVisitor { + + private List builders; + + /** + * Constructs a visitor + * + * @param builders the collection of builders for creating context factories + */ + public AssemblyVisitorImpl(List builders) { + this.builders = builders; + } + + /** + * Initiate walking the object graph + */ + public boolean start(AssemblyObject modelObject) { + return modelObject.accept(this); + } + + /** + * Callback when walking the graph + */ + public boolean visit(AssemblyObject modelObject) { + if (modelObject instanceof ContextFactoryHolder){ + if (((ContextFactoryHolder)modelObject).getContextFactory() != null){ + return true; // HACK FIX for TUSCANY 249 + } + } + for (ContextFactoryBuilder builder : builders) { + builder.build(modelObject); + } + return true; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ContextFactoryBuilderRegistryImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ContextFactoryBuilderRegistryImpl.java new file mode 100644 index 0000000000..d500b2e503 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ContextFactoryBuilderRegistryImpl.java @@ -0,0 +1,39 @@ +/** + * + * Copyright 2006 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.builder.impl; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.core.builder.ContextFactoryBuilderRegistry; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; + +/** + * @version $Rev$ $Date$ + */ +public class ContextFactoryBuilderRegistryImpl implements ContextFactoryBuilderRegistry { + + private final List builders = new ArrayList(); + + public void register(ContextFactoryBuilder builder) { + builders.add(builder); + } + + public List getBuilders() { + return builders; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/DefaultWireBuilder.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/DefaultWireBuilder.java new file mode 100644 index 0000000000..5243c2a8cd --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/DefaultWireBuilder.java @@ -0,0 +1,111 @@ +/** + * + * 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.BuilderConfigException; +import org.apache.tuscany.core.builder.HierarchicalWireBuilder; +import org.apache.tuscany.core.builder.WireBuilder; +import org.apache.tuscany.core.context.ScopeContext; +import org.apache.tuscany.core.wire.TargetInvocationConfiguration; +import org.apache.tuscany.core.wire.SourceInvocationConfiguration; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.impl.InvokerInterceptor; +import org.apache.tuscany.core.wire.impl.MessageChannelImpl; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * The top-most WireBuilder 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 builders = new ArrayList(); + + public DefaultWireBuilder() { + } + + /** + * Adds a wire builder to delegate to + */ + public void addWireBuilder(WireBuilder builder) { + builders.add(builder); + } + + public void connect(SourceWireFactory sourceFactory, TargetWireFactory targetFactory, Class targetType, boolean downScope, + ScopeContext targetScopeContext) { + // get the proxy chain for the target + if (targetFactory != null) { + // if null, the target side has no interceptors or handlers + Map targetInvocationConfigs = targetFactory.getConfiguration().getInvocationConfigurations(); + for (SourceInvocationConfiguration sourceInvocationConfig : sourceFactory.getConfiguration() + .getInvocationConfigurations().values()) { + // match wire chains + TargetInvocationConfiguration targetInvocationConfig = targetInvocationConfigs.get(sourceInvocationConfig.getMethod()); + if (targetInvocationConfig == null){ + BuilderConfigException e= new BuilderConfigException("Incompatible source and target interface types for reference"); + //FIXME xcv + e.setIdentifier(sourceFactory.getConfiguration().getReferenceName()); + throw e; + } + // 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.getHeadInterceptor() == null) { + BuilderConfigException e = new BuilderConfigException("No target handler or interceptor for operation"); + e.setIdentifier(targetInvocationConfig.getMethod().getName()); + throw e; + } + //xcv if (!(sourceInvocationConfig.getLastTargetInterceptor() instanceof InvokerInterceptor && targetInvocationConfig + if (!(sourceInvocationConfig.getTailInterceptor() instanceof InvokerInterceptor && targetInvocationConfig + .getHeadInterceptor() instanceof InvokerInterceptor)) { + // check that we do not have the case where the only interceptors are invokers since we just need one + sourceInvocationConfig.setTargetInterceptor(targetInvocationConfig.getHeadInterceptor()); + } + } + } + } + // delegate to other wire builders + for (WireBuilder builder : builders) { + builder.connect(sourceFactory, targetFactory, targetType, downScope, targetScopeContext); + } + // signal that wire buildSource process is complete + for (SourceInvocationConfiguration sourceInvocationConfig : sourceFactory.getConfiguration().getInvocationConfigurations() + .values()) { + sourceInvocationConfig.build(); + // TODO optimize if no proxy needed using NullWireFactory + } + } + + public void completeTargetChain(TargetWireFactory targetFactory, Class targetType, ScopeContext targetScopeContext) + throws BuilderConfigException { + // delegate to other wire builders + for (WireBuilder builder : builders) { + builder.completeTargetChain(targetFactory, targetType, targetScopeContext); + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/HierarchicalBuilder.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/HierarchicalBuilder.java new file mode 100644 index 0000000000..ffab32bd37 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/HierarchicalBuilder.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.builder.impl; + +import org.apache.tuscany.core.builder.BuilderException; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.model.assembly.AssemblyObject; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * A builder that contains nested builders. Used for synchronizing parts of the buildSource process, such as references. + * + * @version $Rev$ $Date$ + */ +public class HierarchicalBuilder implements ContextFactoryBuilder { + private List builders = new CopyOnWriteArrayList(); + + private List readOnlyBuilders = Collections.unmodifiableList(builders); + + public HierarchicalBuilder() { + } + + public void addBuilder(ContextFactoryBuilder builder) { + builders.add(builder); + } + + public void removeBuilder(ContextFactoryBuilder builder){ + builders.remove(builder); + } + + public List getBuilders(){ + return readOnlyBuilders; + } + + public void build(AssemblyObject object) throws BuilderException { + for (ContextFactoryBuilder builder : builders) { + builder.build(object); + } + + } + + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ListMultiplicityObjectFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ListMultiplicityObjectFactory.java new file mode 100644 index 0000000000..5d37eb8e89 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ListMultiplicityObjectFactory.java @@ -0,0 +1,45 @@ +/** + * + * 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 java.util.ArrayList; +import java.util.List; + +/** + * Resolves targets configured in a multiplicity by delegating to object factories and returning an + * List containing object instances + * + * @version $Rev$ $Date$ + */ +public class ListMultiplicityObjectFactory implements ObjectFactory { + + private ObjectFactory[] factories; + + public ListMultiplicityObjectFactory(List factories) { + assert (factories != null) : "Object factories were null"; + this.factories = factories.toArray(new ObjectFactory[factories.size()]); + } + + public List getInstance() throws ObjectCreationException { + List list = new ArrayList(); + for (ObjectFactory factory : factories) { + list.add(factory.getInstance()); + } + return list; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ProxyObjectFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/impl/ProxyObjectFactory.java new file mode 100644 index 0000000000..1dc6627306 --- /dev/null +++ b/branches/java-post-M1/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.wire.ProxyCreationException; +import org.apache.tuscany.core.wire.WireFactory; + +/** + * Uses a proxy factory to return an object instance + * + * @version $Rev$ $Date$ + */ +public class ProxyObjectFactory implements ObjectFactory { + + private WireFactory factory; + + public ProxyObjectFactory(WireFactory factory) { + this.factory = factory; + } + + public Object getInstance() throws ObjectCreationException { + try { + return factory.createProxy(); + } catch (ProxyCreationException e) { + throw new ObjectCreationException(e); + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/system/DefaultPolicyBuilderRegistry.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/system/DefaultPolicyBuilderRegistry.java new file mode 100644 index 0000000000..4c53a2c830 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/system/DefaultPolicyBuilderRegistry.java @@ -0,0 +1,102 @@ +/** + * + * 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.system; + +import org.apache.tuscany.core.builder.BuilderException; +import org.apache.tuscany.core.builder.SourcePolicyBuilder; +import org.apache.tuscany.core.builder.SourcePolicyOrderer; +import org.apache.tuscany.core.builder.TargetPolicyBuilder; +import org.apache.tuscany.core.builder.TargetPolicyOrderer; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.core.wire.WireSourceConfiguration; +import org.apache.tuscany.core.wire.WireTargetConfiguration; +import org.apache.tuscany.model.assembly.ConfiguredReference; +import org.apache.tuscany.model.assembly.ConfiguredService; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + * A system service that serves as the default implementation of a policy builder registry + * + * @version $$Rev$$ $$Date$$ + */ + +@Scope("MODULE") +@Service(interfaces = {PolicyBuilderRegistry.class}) +public class DefaultPolicyBuilderRegistry implements PolicyBuilderRegistry { + + private final List sourceBuilders = new ArrayList(); + private final List targetBuilders = new ArrayList(); + + private TargetPolicyOrderer targetOrderer; + + private SourcePolicyOrderer sourceOrderer; + + @Autowire + public void setTargetOrderer(TargetPolicyOrderer orderer) { + this.targetOrderer = orderer; + } + + @Autowire + public void setSourceOrderer(SourcePolicyOrderer orderer) { + this.sourceOrderer = orderer; + } + + public void registerTargetBuilder(TargetPolicyBuilder builder) { + targetBuilders.add(builder); + } + + public void unregisterTargetBuilder(TargetPolicyBuilder builder) { + targetBuilders.remove(builder); + } + + public void registerSourceBuilder(SourcePolicyBuilder builder) { + sourceBuilders.add(builder); + } + + public void unregisterSourceBuilder(SourcePolicyBuilder builder) { + sourceBuilders.remove(builder); + } + + public List getTargetBuilders() { + return targetBuilders; + } + + public List getSourceBuilders() { + return sourceBuilders; + } + + public void buildSource(ConfiguredReference reference, List configurations) throws BuilderException { + for (SourcePolicyBuilder builder : sourceBuilders) { + builder.build(reference, configurations); + } + if (sourceOrderer != null) { + for (WireSourceConfiguration configuration : configurations) { + sourceOrderer.order(configuration); + } + } + } + + public void buildTarget(ConfiguredService service, WireTargetConfiguration configuration) throws BuilderException { + for (TargetPolicyBuilder builder : targetBuilders) { + builder.build(service, configuration); + } + if (targetOrderer != null) { + targetOrderer.order(configuration); + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/system/PolicyBuilderRegistry.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/system/PolicyBuilderRegistry.java new file mode 100644 index 0000000000..fb9b0b25db --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/builder/system/PolicyBuilderRegistry.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.builder.system; + +import org.apache.tuscany.core.builder.BuilderException; +import org.apache.tuscany.core.builder.SourcePolicyBuilder; +import org.apache.tuscany.core.builder.TargetPolicyBuilder; +import org.apache.tuscany.core.wire.WireSourceConfiguration; +import org.apache.tuscany.core.wire.WireTargetConfiguration; +import org.apache.tuscany.model.assembly.ConfiguredReference; +import org.apache.tuscany.model.assembly.ConfiguredService; + +import java.util.List; + +/** + * A System registry for {@link org.apache.tuscany.core.builder.PolicyBuilder}s. PolicyBuilders will be invoked when + * a {@link org.apache.tuscany.core.wire.WireFactory} is constructed by the {@link org.apache.tuscany.core.wire.WireFactory} + * service. + *

+ * PolicyBuilders operate on either a source- or target-side wire and typically are registered by runtime extensions + * through {@link #registerTargetBuilder} or {@link #registerSourceBuilder} + * + * @version $Rev$ $Date$ + */ +public interface PolicyBuilderRegistry { + + /** + * Registers a target-side policy builder. Called by extensions to register their builders. + * + * @param builder the builder to register + */ + public void registerTargetBuilder(TargetPolicyBuilder builder); + + /** + * De-registers a target-side builder. Called by extensions to register their builders. + * + * @param builder the builder to register + */ + public void unregisterTargetBuilder(TargetPolicyBuilder builder); + + /** + * Registers a source-side policy builder. Called by extensions to register their builders. + * + * @param builder the builder to register + */ + public void registerSourceBuilder(SourcePolicyBuilder builder); + + /** + * De-registers a source-side builder. Called by extensions to register their builders. + * + * @param builder the builder to register + */ + public void unregisterSourceBuilder(SourcePolicyBuilder builder); + + /** + * Returns the list of registered target-side builders + */ + public List getTargetBuilders(); + + /** + * Returns the list of registered source-side builders + */ + public List getSourceBuilders(); + + /** + * Evaluates source-side policy metadata for configured reference and updates the curresponding collection of wire configurations + * + * @throws BuilderException + */ + public void buildSource(ConfiguredReference reference, List configurations) throws BuilderException; + + /** + * Evaluates target-side policy metadata for configured reference and updates the curresponding collection of wire configurations + * + * @throws BuilderException + */ + public void buildTarget(ConfiguredService service, WireTargetConfiguration configuration) throws BuilderException; +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/client/BootstrapHelper.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/client/BootstrapHelper.java new file mode 100644 index 0000000000..556b0991f7 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/client/BootstrapHelper.java @@ -0,0 +1,138 @@ +/** + * + * Copyright 2006 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.client; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.stream.XMLInputFactory; + +import org.apache.tuscany.common.monitor.MonitorFactory; +import org.apache.tuscany.common.resource.ResourceLoader; +import org.apache.tuscany.common.resource.impl.ResourceLoaderImpl; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.core.builder.ContextFactoryBuilderRegistry; +import org.apache.tuscany.core.builder.impl.ContextFactoryBuilderRegistryImpl; +import org.apache.tuscany.core.config.ConfigurationException; +import org.apache.tuscany.core.config.ModuleComponentConfigurationLoader; +import org.apache.tuscany.core.config.impl.StAXModuleComponentConfigurationLoaderImpl; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.SystemCompositeContext; +import org.apache.tuscany.core.context.event.ModuleStart; +import org.apache.tuscany.core.loader.StAXLoaderRegistry; +import org.apache.tuscany.core.loader.StAXUtil; +import org.apache.tuscany.core.system.assembly.impl.SystemAssemblyFactoryImpl; +import org.apache.tuscany.core.system.builder.SystemContextFactoryBuilder; +import org.apache.tuscany.core.system.builder.SystemEntryPointBuilder; +import org.apache.tuscany.core.system.builder.SystemExternalServiceBuilder; +import org.apache.tuscany.model.assembly.AssemblyFactory; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.model.assembly.ModuleComponent; +import org.apache.tuscany.model.assembly.impl.AssemblyContextImpl; +import org.apache.tuscany.model.assembly.loader.AssemblyModelLoader; +import org.apache.tuscany.model.scdl.loader.impl.SCDLAssemblyModelLoaderImpl; + +/** + * @version $Rev$ $Date$ + */ +public final class BootstrapHelper { + private BootstrapHelper() { + } + + /** + * Returns a default AssemblyModelContext. + * + * @param classLoader the classloader to use for application artifacts + * @return a default AssemblyModelContext + */ + public static AssemblyContext getModelContext(ClassLoader classLoader) { + // Create an assembly model factory + AssemblyFactory modelFactory = new SystemAssemblyFactoryImpl(); + + // Create a default assembly model loader + AssemblyModelLoader modelLoader = new SCDLAssemblyModelLoaderImpl(); + + // Create a resource loader from the supplied classloader + ResourceLoader resourceLoader = new ResourceLoaderImpl(classLoader); + + // Create an assembly model context + return new AssemblyContextImpl(modelFactory, modelLoader, resourceLoader); + } + + /** + * Returns a default list of configuration builders. + * + * @param monitorFactory + * @return a default list of configuration builders + */ + public static List getBuilders(MonitorFactory monitorFactory) { + List configBuilders = new ArrayList(); + configBuilders.add((new SystemContextFactoryBuilder(monitorFactory))); + configBuilders.add(new SystemEntryPointBuilder()); + configBuilders.add(new SystemExternalServiceBuilder()); + return configBuilders; + } + + /** + * Returns a ContextFactoryBuilderRegistry with default builders registered for system contexts. + * + * @param monitorFactory a monitorFactory that will be used to obtain monitors for system components + * @return a default ContextFactoryBuilderRegistry + */ + public static ContextFactoryBuilderRegistry bootstrapContextFactoryBuilders(MonitorFactory monitorFactory) { + ContextFactoryBuilderRegistryImpl registry = new ContextFactoryBuilderRegistryImpl(); + registry.register(new SystemContextFactoryBuilder(monitorFactory)); + registry.register(new SystemEntryPointBuilder()); + registry.register(new SystemExternalServiceBuilder()); + return registry; + } + + public static final String SYSTEM_LOADER_COMPONENT = "tuscany.loader"; + + /** + * Returns the default module configuration loader. + * + * @param systemContext the runtime's system context + * @param modelContext the model context the loader will use + * @return the default module configuration loader + */ + public static ModuleComponentConfigurationLoader getConfigurationLoader(SystemCompositeContext systemContext, AssemblyContext modelContext) { + return new StAXModuleComponentConfigurationLoaderImpl(modelContext, XMLInputFactory.newInstance(), systemContext.resolveInstance(StAXLoaderRegistry.class)); + } + + /** + * Bootstrap the StAX-based loader. + * + * @param parentContext the parent system context + * @param modelContext + * @return the system context for the loader + * @throws ConfigurationException + */ + public static CompositeContext bootstrapStaxLoader(SystemCompositeContext parentContext, AssemblyContext modelContext) throws ConfigurationException { + ModuleComponent loaderComponent = StAXUtil.bootstrapLoader(SYSTEM_LOADER_COMPONENT, modelContext); + CompositeContext loaderContext = registerModule(parentContext, loaderComponent); + loaderContext.publish(new ModuleStart(loaderComponent)); + return loaderContext; + } + + public static CompositeContext registerModule(CompositeContext parent, ModuleComponent component) throws ConfigurationException { + // register the component + parent.registerModelObject(component); + + // Get the composite context representing the component + return (CompositeContext) parent.getContext(component.getName()); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/client/TuscanyRuntime.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/client/TuscanyRuntime.java new file mode 100644 index 0000000000..fe78cd712a --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/client/TuscanyRuntime.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.client; + +import org.osoa.sca.ModuleContext; +import org.osoa.sca.SCA; +import org.osoa.sca.ServiceRuntimeException; + +import org.apache.tuscany.common.monitor.LogLevel; +import org.apache.tuscany.common.monitor.MonitorFactory; +import org.apache.tuscany.common.monitor.impl.NullMonitorFactory; +import org.apache.tuscany.core.builder.ContextFactoryBuilderRegistry; +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.context.CompositeContext; +import org.apache.tuscany.core.context.CoreRuntimeException; +import org.apache.tuscany.core.context.SystemCompositeContext; +import org.apache.tuscany.core.context.event.HttpSessionBound; +import org.apache.tuscany.core.context.event.HttpSessionEnd; +import org.apache.tuscany.core.context.event.ModuleStart; +import org.apache.tuscany.core.context.event.ModuleStop; +import org.apache.tuscany.core.context.event.RequestEnd; +import org.apache.tuscany.core.context.event.RequestStart; +import org.apache.tuscany.core.runtime.RuntimeContext; +import org.apache.tuscany.core.runtime.RuntimeContextImpl; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.model.assembly.ModuleComponent; + +/** + * 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 runtime; + private final CompositeContext moduleContext; + + private static final 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 { + assert(monitorFactory != null): "monitor factory was null"; + this.monitor = monitorFactory.getMonitor(Monitor.class); + + // Create an assembly model context + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + AssemblyContext modelContext = BootstrapHelper.getModelContext(classLoader); + + // Create a runtime context and start it + ContextFactoryBuilderRegistry builderRegistry = BootstrapHelper.bootstrapContextFactoryBuilders(monitorFactory); + runtime = new RuntimeContextImpl(monitorFactory, builderRegistry, new DefaultWireBuilder()); + runtime.start(); + + // Load and start the system configuration + SystemCompositeContext systemContext = runtime.getSystemContext(); + BootstrapHelper.bootstrapStaxLoader(systemContext, modelContext); + ModuleComponentConfigurationLoader loader = BootstrapHelper.getConfigurationLoader(systemContext, modelContext); + ModuleComponent systemModuleComponent = loader.loadSystemModuleComponent(SYSTEM_MODULE_COMPONENT, SYSTEM_MODULE_COMPONENT); + CompositeContext context = BootstrapHelper.registerModule(systemContext, systemModuleComponent); + context.publish(new ModuleStart(this)); + + // Load the SCDL configuration of the application module + CompositeContext rootContext = runtime.getRootContext(); + ModuleComponent moduleComponent = loader.loadModuleComponent(name, uri); + moduleContext = BootstrapHelper.registerModule(rootContext, moduleComponent); + if (moduleContext.getURI() == null){ + moduleContext.setURI(uri); + } + //TODO remove hack + moduleContext.setAssemblyContext(modelContext); + } + + /** + * Start the runtime and associate the module context with the calling thread. + */ + @Override + public void start() { + setModuleContext((ModuleContext) moduleContext); + try { + //moduleContext.start(); + moduleContext.publish(new ModuleStart(this)); + moduleContext.publish(new RequestStart(this, new Object())); + moduleContext.publish(new HttpSessionBound(this, sessionKey)); + monitor.moduleStarted(moduleContext.getName()); + } catch (CoreRuntimeException e) { + setModuleContext(null); + monitor.moduleStartFailed(moduleContext.getName(), 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.publish(new RequestEnd(this, new Object())); + moduleContext.publish(new HttpSessionEnd(this, sessionKey)); + moduleContext.publish(new ModuleStop(this)); + moduleContext.stop(); + monitor.moduleStopped(moduleContext.getName()); + } + + /** + * Shut down the Tuscany runtime. + */ + public void shutdown() { + runtime.getSystemContext().publish(new ModuleStop(this)); + runtime.stop(); + } + + /** + * Monitor interface for a TuscanyRuntime. + */ + public static interface Monitor { + /** + * Event emitted after an application module has been started. + * + * @param name the name of the application module + */ + @LogLevel("INFO") + void moduleStarted(String name); + + /** + * Event emitted when an attempt to start an application module failed. + * + * @param name the name of the application module + * @param e the exception that caused the failure + */ + @LogLevel("SEVERE") + void moduleStartFailed(String name, CoreRuntimeException e); + + /** + * Event emitted after an application module has been stopped. + * + * @param name the name of the application module + */ + @LogLevel("INFO") + void moduleStopped(String name); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ComponentTypeIntrospector.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ComponentTypeIntrospector.java new file mode 100644 index 0000000000..9f9c125a5e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ComponentTypeIntrospector.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.config; + +import org.apache.tuscany.model.assembly.ComponentType; +import org.apache.tuscany.core.extension.config.ImplementationProcessor; + +/** + * 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 ConfigurationLoadException if the Class does not define a valid component type + */ + ComponentType introspect(Class implClass) throws ConfigurationLoadException; + + /** + * Completes the given componentType definition by introspecting a Java Class. + * + * @param implClass the class to inspect + * @return a componentType definition + * @throws ConfigurationLoadException if the Class does not define a valid component type + */ + ComponentType introspect(Class implClass, ComponentType compType) throws ConfigurationLoadException; + + /** + * Registers an annotation processor + */ + void registerProcessor(ImplementationProcessor processor); + + /** + * De-registers an annotation processor + */ + void unregisterProcessor(ImplementationProcessor processor); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ConfigurationException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ConfigurationException.java new file mode 100644 index 0000000000..de0e4a3733 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ConfigurationException.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.config; + +import org.apache.tuscany.common.TuscanyException; + + +/** + * Base class for exceptions that pertain to configuration. + * + * @version $Rev$ $Date$ + */ +public abstract class ConfigurationException extends TuscanyException { + private static final long serialVersionUID = 7441469809266868036L; + + 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ConfigurationLoadException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ConfigurationLoadException.java new file mode 100644 index 0000000000..2a9e325b0b --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ConfigurationLoadException.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.config; + +/** + * Exception indicating that there was a problem loading a configuration resource. + * + * @version $Rev$ $Date$ + */ +public class ConfigurationLoadException extends ConfigurationException { + private static final long serialVersionUID = -2310798146091959144L; + + private String resourceURI; + + public ConfigurationLoadException() { + } + + public ConfigurationLoadException(String message) { + super(message); + } + + public ConfigurationLoadException(String message, Throwable cause) { + super(message, cause); + } + + public ConfigurationLoadException(Throwable cause) { + super(cause); + } + + /** + * Returns the location of the resource that was being loaded. + * @return the location of the resource that was being loaded + */ + public String getResourceURI() { + return resourceURI; + } + + /** + * Sets the location of the resource that was being loaded. + * @param resourceURI the location of the resource that was being loaded + */ + public void setResourceURI(String resourceURI) { + this.resourceURI = resourceURI; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ImplementationCache.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ImplementationCache.java new file mode 100644 index 0000000000..cc5f2999fe --- /dev/null +++ b/branches/java-post-M1/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 org.apache.tuscany.model.assembly.Implementation; + +import javax.xml.namespace.QName; + +/** + * 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 + */ + Implementation 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, Implementation implementation); +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/InvalidMetaDataException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/InvalidMetaDataException.java new file mode 100644 index 0000000000..71b2329044 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/InvalidMetaDataException.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.config; + +/** + * Denotes an validation error processing component metadata + * @version $$Rev$$ $$Date$$ + */ +public class InvalidMetaDataException extends MetaDataException { + public InvalidMetaDataException() { + } + + public InvalidMetaDataException(String message) { + super(message); + } + + public InvalidMetaDataException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidMetaDataException(Throwable cause) { + super(cause); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/InvalidRootElementException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/InvalidRootElementException.java new file mode 100644 index 0000000000..a355d884a5 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/InvalidRootElementException.java @@ -0,0 +1,45 @@ +/** + * + * 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; + +/** + * Configuration exception that indicates the actual root element in an XML file was not the one expected. + * + * @version $Rev$ $Date$ + */ +public class InvalidRootElementException extends ConfigurationLoadException { + private static final long serialVersionUID = 2376629433948140418L; + + private final QName expected; + private final QName actual; + + public InvalidRootElementException(QName expected, QName actual) { + super("Invalid root element, expected [" + expected + "], was [" + actual + ']'); + this.expected = expected; + this.actual = actual; + } + + public QName getExpected() { + return expected; + } + + public QName getActual() { + return actual; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/InvalidSetterException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/InvalidSetterException.java new file mode 100644 index 0000000000..ed4e53645f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/InvalidSetterException.java @@ -0,0 +1,39 @@ +/** + * + * Copyright 2006 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.config; + +/** + * @version $Rev$ $Date$ + */ +public class InvalidSetterException extends ConfigurationLoadException { + private static final long serialVersionUID = -3298236203808038211L; + + public InvalidSetterException() { + } + + public InvalidSetterException(String message) { + super(message); + } + + public InvalidSetterException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidSetterException(Throwable cause) { + super(cause); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/JavaIntrospectionHelper.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/JavaIntrospectionHelper.java new file mode 100644 index 0000000000..9d74633519 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/JavaIntrospectionHelper.java @@ -0,0 +1,446 @@ +/** + * + * 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.lang.reflect.AccessibleObject; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.Modifier; +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]; + + /** + * Hide the constructor + */ + private JavaIntrospectionHelper() { + } + + /** + * Returns a collection of public, private, protected, or default fields declared by a class or one of its + * supertypes + */ + public static Set getAllFields(Class pClass) { + return getAllFields(pClass, new HashSet()); + } + + /** + * Recursively evaluates the type hierachy to return all fields on a given type + */ + private static Set getAllFields(Class pClass, Set fields) { + if (pClass == null || pClass.isArray() || Object.class.equals(pClass)) { + return fields; + } + fields = getAllFields(pClass.getSuperclass(), fields); + Field[] declaredFields = pClass.getDeclaredFields(); + for (Field field : declaredFields) { + field.setAccessible(true); // ignore Java accessibility + fields.add(field); + } + return fields; + } + + /** + * Returns a collection of public, and protected fields declared by a class or one of its + * supertypes + */ + public static Set getAllPublicAndProtectedFields(Class clazz) { + return getAllPublicAndProtectedFields(clazz, new HashSet()); + } + + /** + * Recursively evaluates the type hierachy to return all fields that are public or protected + */ + private static Set getAllPublicAndProtectedFields(Class clazz, Set fields) { + if (clazz == null || clazz.isArray() || Object.class.equals(clazz)) { + return fields; + } + fields = getAllPublicAndProtectedFields(clazz.getSuperclass(), fields); + Field[] declaredFields = clazz.getDeclaredFields(); +// fields = new HashSet(); +// Field[] declaredFields = clazz.getFields(); + for (Field field : declaredFields) { + int modifiers = field.getModifiers(); + if ((Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)) && !Modifier.isStatic(modifiers)){ + field.setAccessible(true); // ignore Java accessibility + fields.add(field); + } + } + return fields; + } + + /** + * Returns a collection of public, 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).

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 getAllUniqueMethods(Class clazz) { + return getAllUniqueMethods(clazz, new HashSet()); + } + + /** + * Recursively evaluates the type hierarchy to return all unique methods + */ + private static Set getAllUniqueMethods(Class pClass, Set methods) { + if (pClass == null || pClass.isArray() || Object.class.equals(pClass)) { + return methods; + } + // we first evaluate methods of the subclass and then move to the parent + Method[] declaredMethods = pClass.getDeclaredMethods(); + for (Method declaredMethod : declaredMethods) { + if (methods.size() == 0) { + methods.add(declaredMethod); + } 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(declaredMethod, method)) { + matched = true; + break; + } + } + if (!matched) { + // TODO ignore Java accessibility + declaredMethod.setAccessible(true); + temp.add(declaredMethod); + + } + methods.addAll(temp); + temp.clear(); + } + } + // evaluate class hierarchy - this is done last to track inherited methods + methods = getAllUniqueMethods(pClass.getSuperclass(), methods); + return methods; + } + + /** + * Finds the closest matching field with the given name, that is, a field of the exact specified type or, + * alternately, of a supertype. + * + * @param name the name of the field + * @param type the field type + * @param fields the collection of fields to search + * @return the matching field or null if not found + */ + public static Field findClosestMatchingField(String name, Class type, Set fields) { + Field candidate = null; + for (Field field : fields) { + if (field.getName().equals(name)) { + if (field.getType().equals(type)) { + return field; // exact match + } else if (field.getType().isAssignableFrom(type) + || (field.getType().isPrimitive() && primitiveAssignable(field.getType(), type))) { + // We could have the situation where a field parameter is a primitive and the demarshalled value is + // an object counterpart (e.g. Integer and int) + // @spec issue + // either an interface or super class, so keep a reference until + // we know there are no closer types + candidate = field; + } + } + } + if (candidate != null) { + return candidate; + } else { + return null; + } + } + + /** + * Finds the closest matching method with the given name, that is, a method taking the exact parameter + * types or, alternately, parameter supertypes. + * + * @param name the name of the method + * @param types the method parameter types + * @param methods the collection of methods to search + * @return the matching method or null if not found + */ + public static Method findClosestMatchingMethod(String name, Class[] types, Set methods) { + if (types == null) { + types = EMPTY_CLASS_ARRY; + } + Method candidate = null; + for (Method method : methods) { + if (method.getName().equals(name) && method.getParameterTypes().length == types.length) { + Class[] params = method.getParameterTypes(); + boolean disqualify = false; + boolean exactMatch = true; + for (int i = 0; i < params.length; i++) { + if (!params[i].equals(types[i]) && !params[i].isAssignableFrom(types[i])) { + // no match + disqualify = true; + exactMatch = false; + break; + } else if (!params[i].equals(types[i]) && params[i].isAssignableFrom(types[i])) { + // not exact match + exactMatch = false; + } + } + if (disqualify) { + continue; + } else if (exactMatch) { + return method; + } else { + candidate = method; + } + } + } + if (candidate != null) { + return candidate; + } else { + return null; + } + } + + /** + * Searches a collection of fields for one that matches by name and has a multiplicity type. i.e. a List + * or Array of interfaces + * + * @return a matching field or null + */ + public static Field findMultiplicityFieldByName(String name, Set fields) { + for (Field candidate : fields) { + if (candidate.getName().equals(name) + && (List.class.isAssignableFrom(candidate.getType()) || (candidate.getType().isArray() + && candidate.getType().getComponentType() != null && candidate.getType().getComponentType() + .isInterface()))) { + return candidate; + } + } + return null; + } + + /** + * Searches a collection of method for one that matches by name and has single parameter of a multiplicity + * type. i.e. a List or Array of interfaces + * + * @return a matching method or null + */ + public static Method findMultiplicityMethodByName(String name, Set methods) { + for (Method candidate : methods) { + if (candidate.getName().equals(name) + && candidate.getParameterTypes().length == 1 + && (List.class.isAssignableFrom(candidate.getParameterTypes()[0]) || (candidate.getParameterTypes()[0] + .isArray() + && candidate.getParameterTypes()[0].getComponentType() != null && candidate.getParameterTypes()[0] + .getComponentType().isInterface()))) { + return candidate; + } + } + return null; + } + + /** + * Returns a field or method defined in the given class or its superclasses matching a literal name and + * parameter types

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 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 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 + */ + 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 foo is returned as getFoo + */ + 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, setFoo(var) is returned as property foo + */ + public static String toPropertyName(String name) { + return Character.toLowerCase(name.charAt(3)) + name.substring(4); + } + + /** + * Takes a property name and converts it to a setter method name according to JavaBean conventions. For + * example, the property foo is returned as setFoo(var) + */ + public static String toSetter(String name) { + return "set" + name.toUpperCase().substring(0, 1) + name.substring(1); + } + + /** + * Compares a two types, assuming one is a primitive, to determine if the other is its object counterpart + */ + private static boolean primitiveAssignable(Class memberType, Class param) { + if (memberType == Integer.class) { + return (param == Integer.TYPE); + } else if (memberType == Double.class) { + return (param == Double.TYPE); + } else if (memberType == Float.class) { + return (param == Float.TYPE); + } else if (memberType == Short.class) { + return (param == Short.TYPE); + } else if (memberType == Character.class) { + return (param == Character.TYPE); + } else if (memberType == Boolean.class) { + return (param == Boolean.TYPE); + } else if (memberType == Byte.class) { + return (param == Byte.TYPE); + } else if (param == Integer.class) { + return (memberType == Integer.TYPE); + } else if (param == Double.class) { + return (memberType == Double.TYPE); + } else if (param == Float.class) { + return (memberType == Float.TYPE); + } else if (param == Short.class) { + return (memberType == Short.TYPE); + } else if (param == Character.class) { + return (memberType == Character.TYPE); + } else if (param == Boolean.class) { + return (memberType == Boolean.TYPE); + } else if (param == Byte.class) { + return (memberType == Byte.TYPE); + } else { + return false; + } + } + + /** + * Returns the generic types represented in the given type. Usage as follows: + *

+ * // to return the generic type of a field: JavaIntrospectionHelper.getGenerics(field.getGenericType()); + *

+ * // to return the generic types for the first parameter of a method: JavaIntrospectionHelper.getGenerics(m.getGenericParameterTypes()[0];); + *

+ * + * + * @return the generic types in order of declaration or an empty array if the type is not genericized + */ + public static List getGenerics(Type genericType) { + List classes = new ArrayList(); + if (genericType instanceof ParameterizedType) { + ParameterizedType ptype = (ParameterizedType) genericType; + // get the type arguments + Type[] targs = ptype.getActualTypeArguments(); + for (Type targ : targs) { + classes.add(targ); + } + } + return classes; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/MetaDataException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/MetaDataException.java new file mode 100644 index 0000000000..30840a6e15 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/MetaDataException.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; + +/** + * Denotes an error processing component metadata + * + * @version $$Rev$$ $$Date$$ + */ +public class MetaDataException extends ConfigurationLoadException{ + + public MetaDataException() { + } + + public MetaDataException(String message) { + super(message); + } + + public MetaDataException(String message, Throwable cause) { + super(message, cause); + } + + public MetaDataException(Throwable cause) { + super(cause); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/MissingInterfaceException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/MissingInterfaceException.java new file mode 100644 index 0000000000..6164b6a011 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/MissingInterfaceException.java @@ -0,0 +1,39 @@ +/** + * + * Copyright 2006 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.config; + +/** + * Exception indicating that the interface referenced in an assembly file could not be found. + * + * @version $Rev$ $Date$ + */ +public class MissingInterfaceException extends ConfigurationLoadException { + public MissingInterfaceException() { + } + + public MissingInterfaceException(String message) { + super(message); + } + + public MissingInterfaceException(String message, Throwable cause) { + super(message, cause); + } + + public MissingInterfaceException(Throwable cause) { + super(cause); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/MissingResourceException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/MissingResourceException.java new file mode 100644 index 0000000000..8260dbc8ae --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/MissingResourceException.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.config; + +/** + * Exception that indicates an expected resource could not be found. + * + * @version $Rev$ $Date$ + */ +public class MissingResourceException extends ConfigurationLoadException { + /** + * 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); + setResourceURI(resource); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ModuleComponentConfigurationLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ModuleComponentConfigurationLoader.java new file mode 100644 index 0000000000..15857441b1 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/ModuleComponentConfigurationLoader.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.config; + +import org.apache.tuscany.model.assembly.ModuleComponent; + +import java.net.URL; +import java.util.Collection; + +/** + * 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 ConfigurationLoadException 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 ConfigurationLoadException 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 ConfigurationLoadException if there was a problem loading the module component. + */ + ModuleComponent loadModuleComponent(String name, String uri, URL 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 ConfigurationLoadException if there was a problem loading the module component. + */ + ModuleComponent loadModuleComponent(String name, String uri, URL url, Collection urls) throws ConfigurationLoadException; + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/SidefileLoadException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/SidefileLoadException.java new file mode 100644 index 0000000000..b432d4ea68 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/SidefileLoadException.java @@ -0,0 +1,50 @@ +/** + * + * Copyright 2006 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.config; + +/** + * Exception indicating that there was a problem loading a sidefile. + * + * @version $Rev$ $Date$ + */ +public class SidefileLoadException extends ConfigurationLoadException { + private static final long serialVersionUID = -3530306758412789392L; + private String sidefileURI; + + public SidefileLoadException() { + } + + public SidefileLoadException(String message) { + super(message); + } + + public SidefileLoadException(String message, Throwable cause) { + super(message, cause); + } + + public SidefileLoadException(Throwable cause) { + super(cause); + } + + public String getSidefileURI() { + return sidefileURI; + } + + public void setSidefileURI(String sidefileURI) { + this.sidefileURI = sidefileURI; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/impl/AbstractModuleComponentConfigurationLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/impl/AbstractModuleComponentConfigurationLoader.java new file mode 100644 index 0000000000..2725a00068 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/impl/AbstractModuleComponentConfigurationLoader.java @@ -0,0 +1,171 @@ +/** + * + * 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.config.impl; + +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.core.config.ComponentTypeIntrospector; +import org.apache.tuscany.core.config.processor.ProcessorUtils; +import org.apache.tuscany.core.system.context.SystemCompositeContextImpl; +import org.apache.tuscany.core.context.impl.CompositeContextImpl; +import org.apache.tuscany.model.assembly.AssemblyFactory; +import org.apache.tuscany.model.assembly.AssemblyContext; +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.ComponentType; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * @version $Rev$ $Date$ + */ +public abstract class AbstractModuleComponentConfigurationLoader 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"; + + protected final AssemblyContext modelContext; + protected final ResourceLoader resourceLoader; + protected final AssemblyFactory assemblyFactory; + + // JFM HACK + private ComponentTypeIntrospector introspector; + + private ComponentType systemType; + + private ComponentType compositeType; + + protected ComponentTypeIntrospector getIntrospector(){ + if (introspector == null){ + introspector = ProcessorUtils.createCoreIntrospector(assemblyFactory); + } + return introspector; + } + + protected ComponentType getSystemCompositeComponentType() throws ConfigurationLoadException { + if (systemType == null){ + systemType = getIntrospector().introspect(SystemCompositeContextImpl.class); + } + return systemType; + } + + protected ComponentType getCompositeComponentType() throws ConfigurationLoadException { + if (compositeType == null){ + compositeType = getIntrospector().introspect(CompositeContextImpl.class); + } + return compositeType; + } + /// JFM HACK + + protected AbstractModuleComponentConfigurationLoader(AssemblyContext modelContext) { + this.modelContext = modelContext; + resourceLoader = modelContext.getApplicationResourceLoader(); + assemblyFactory = modelContext.getAssemblyFactory(); + } + + public ModuleComponent loadSystemModuleComponent(String name, String uri) throws ConfigurationLoadException { + ModuleComponent mc = loadModuleComponent(SYSTEM_MODULE_FILE_NAME, SYSTEM_FRAGMENT_FILE_NAME, name, uri); + //JFM HACK - this is completely gross since it overwrites existing component type + mc.getImplementation().setImplementationClass(SystemCompositeContextImpl.class); + mc.getImplementation().setComponentType(getSystemCompositeComponentType()); + //END HACK + return mc; + } + + public ModuleComponent loadModuleComponent(String name, String uri) throws ConfigurationLoadException { + ModuleComponent mc; + try { + mc = loadModuleComponent(SCA_MODULE_FILE_NAME, SCA_FRAGMENT_FILE_NAME, name, uri); + } catch (ConfigurationLoadException e) { + //JSD HACK, need a better way to specify the composite to load in the future + // for now use the URI as the composite name + mc = loadModuleComponent(uri+".composite", SCA_FRAGMENT_FILE_NAME, name, uri); + } + //JFM HACK + mc.getImplementation().setImplementationClass(CompositeContextImpl.class); + mc.getImplementation().setComponentType(getCompositeComponentType()); + //END HACK + return mc; + } + + protected ModuleComponent loadModuleComponent(String moduleFileName, String fragmentFileName, String name, String uri) throws ConfigurationLoadException { + + // Load the sca.module file + URL moduleUrl; + moduleUrl = resourceLoader.getResource(moduleFileName); + + + if (moduleUrl == null) { + throw new ConfigurationLoadException(moduleFileName); + } + + // Load the sca.fragment files + Iterator i; + try { + i = resourceLoader.getResources(fragmentFileName); + } catch (IOException e) { + throw new ConfigurationLoadException(fragmentFileName, e); + } + List moduleFragmentUris=new ArrayList(); + while (i.hasNext()) { + URL url=i.next(); + moduleFragmentUris.add(url); + } + + return loadModuleComponent(name, uri, moduleUrl, moduleFragmentUris); + } + + public ModuleComponent loadModuleComponent(String name, String uri, URL url) throws ConfigurationLoadException { + return loadModuleComponent( name, uri, url, null); + } + + public ModuleComponent loadModuleComponent(String name, String uri, URL moduleUri, Collection moduleFragmentUris) throws ConfigurationLoadException { + + // Load the module file + Module module=loadModule(moduleUri); + // Load the sca.fragment files + if (moduleFragmentUris!=null) { + for (URL moduleFragmentUri : moduleFragmentUris) { + ModuleFragment moduleFragment=loadModuleFragment(moduleFragmentUri); + module.getModuleFragments().add(moduleFragment); + } + } + + // Create the module component + ModuleComponent moduleComponent=assemblyFactory.createModuleComponent(); + moduleComponent.setName(name); + moduleComponent.setURI(uri); + moduleComponent.setImplementation(module); + moduleComponent.initialize(modelContext); + + return moduleComponent; + } + + public abstract Module loadModule(URL url) throws ConfigurationLoadException; + + public abstract ModuleFragment loadModuleFragment(URL url) throws ConfigurationLoadException; +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/impl/Java5ComponentTypeIntrospector.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/impl/Java5ComponentTypeIntrospector.java new file mode 100644 index 0000000000..fdbb6e0942 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/impl/Java5ComponentTypeIntrospector.java @@ -0,0 +1,139 @@ +/** + * + * 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.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.core.config.ComponentTypeIntrospector; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.config.JavaIntrospectionHelper; +import org.apache.tuscany.core.config.processor.ProcessorUtils; +import org.apache.tuscany.core.extension.config.ImplementationProcessor; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.core.system.assembly.SystemAssemblyFactory; +import org.apache.tuscany.model.assembly.AssemblyFactory; +import org.apache.tuscany.model.assembly.ComponentType; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.ComponentName; + +/** + * Introspects Java annotation-based metata data + * + * @version $Rev$ $Date$ + */ +@org.osoa.sca.annotations.Service(ComponentTypeIntrospector.class) +public class Java5ComponentTypeIntrospector implements ComponentTypeIntrospector { + + private AssemblyFactory factory; + + private List processors = new ArrayList(); + + public Java5ComponentTypeIntrospector() { + } + + public Java5ComponentTypeIntrospector(AssemblyFactory factory) { + this.factory = factory; + } + + @Autowire + public void setFactory(SystemAssemblyFactory factory) { + this.factory = factory; + //FIXME JFM HACK + List processors = ProcessorUtils.createCoreProcessors(factory); + for (ImplementationProcessor processor : processors) { + this.registerProcessor(processor); + } + // END hack + } + + @ComponentName + protected String name; + + @Init(eager = true) + public void init(){ + } + + public void registerProcessor(ImplementationProcessor processor) { + processors.add(processor); + } + + public void unregisterProcessor(ImplementationProcessor processor) { + processors.remove(processor); + } + + /** + * Visits the given implementation type and calls back to {@link org.apache.tuscany.core.extension.config.ImplementationProcessor}s + * registered with this introspector to build up a {@link ComponentType} + * + * @return ComponentType representing the implementation type metadata + * @throws ConfigurationLoadException if there is an error introspecting the implementation type + */ + public ComponentType introspect(Class implClass) throws ConfigurationLoadException { + ComponentType compType = factory.createComponentType(); + return introspect(implClass, compType); + } + + public ComponentType introspect(Class implClass, ComponentType compType) throws ConfigurationLoadException { + for (ImplementationProcessor processor : processors) { + processor.visitClass(implClass, compType); + } + Constructor[] constructors = implClass.getConstructors(); + for (Constructor constructor : constructors) { + for (ImplementationProcessor processor : processors) { + processor.visitConstructor(constructor, compType); + } + } + Method[] methods = implClass.getMethods(); + for (Method method : methods) { + for (ImplementationProcessor processor : processors) { + processor.visitMethod(method, compType); + } + } + Set fields = JavaIntrospectionHelper.getAllPublicAndProtectedFields(implClass); + for (Field field : fields) { + for (ImplementationProcessor processor : processors) { + processor.visitField(field, compType); + } + } + Class superClass = implClass.getSuperclass(); + if (superClass != null) { + visitSuperClass(superClass, compType); + } + for (ImplementationProcessor processor : processors) { + processor.visitEnd(implClass, compType); + } + return compType; + } + + private void visitSuperClass(Class superClass, ComponentType compType) throws ConfigurationLoadException { + if (!Object.class.equals(superClass)) { + for (ImplementationProcessor processor : processors) { + processor.visitSuperClass(superClass, compType); + } + superClass = superClass.getSuperclass(); + if (superClass != null) { + visitSuperClass(superClass, compType); + } + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/impl/StAXModuleComponentConfigurationLoaderImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/impl/StAXModuleComponentConfigurationLoaderImpl.java new file mode 100644 index 0000000000..3bd6e6361d --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/impl/StAXModuleComponentConfigurationLoaderImpl.java @@ -0,0 +1,91 @@ +/** + * + * 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 org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.StAXLoaderRegistry; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.model.assembly.Module; +import org.apache.tuscany.model.assembly.ModuleFragment; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import java.io.IOException; +import java.net.URL; + +/** + * @version $Rev$ $Date$ + */ +public class StAXModuleComponentConfigurationLoaderImpl extends AbstractModuleComponentConfigurationLoader { + private final XMLInputFactory xmlFactory; + private final StAXLoaderRegistry registry; + + public StAXModuleComponentConfigurationLoaderImpl(AssemblyContext modelContext, XMLInputFactory xmlFactory, StAXLoaderRegistry registry) { + super(modelContext); + this.xmlFactory = xmlFactory; + this.registry = registry; + } + + public Module loadModule(URL url) throws ConfigurationLoadException { + registry.setContext(modelContext); + try { + XMLStreamReader reader = xmlFactory.createXMLStreamReader(url.openStream()); + getDocumentRoot(reader); + return (Module) registry.load(reader, new LoaderContext(resourceLoader)); + } catch (XMLStreamException e) { + ConfigurationLoadException ce = new ConfigurationLoadException(e); + ce.setResourceURI(url.toString()); + throw ce; + } catch (IOException e) { + ConfigurationLoadException ce = new ConfigurationLoadException(e); + ce.setResourceURI(url.toString()); + throw ce; + } finally { + registry.setContext(null); + } + } + + public ModuleFragment loadModuleFragment(URL url) throws ConfigurationLoadException { + registry.setContext(modelContext); + try { + XMLStreamReader reader = xmlFactory.createXMLStreamReader(url.openStream()); + getDocumentRoot(reader); + return (ModuleFragment) registry.load(reader, new LoaderContext(resourceLoader)); + } catch (XMLStreamException e) { + ConfigurationLoadException ce = new ConfigurationLoadException(e); + ce.setResourceURI(url.toString()); + throw ce; + } catch (IOException e) { + ConfigurationLoadException ce = new ConfigurationLoadException(e); + ce.setResourceURI(url.toString()); + throw ce; + } finally { + registry.setContext(null); + } + } + + private static void getDocumentRoot(XMLStreamReader reader) throws XMLStreamException { + while (true) { + if (reader.next() == XMLStreamConstants.START_ELEMENT) { + return; + } + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ComponentNameProcessor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ComponentNameProcessor.java new file mode 100644 index 0000000000..0314bcc9bf --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ComponentNameProcessor.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.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.apache.tuscany.core.extension.config.extensibility.ComponentNameExtensibilityElement; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.model.assembly.AssemblyFactory; +import org.apache.tuscany.model.assembly.ComponentType; +import org.osoa.sca.annotations.ComponentName; + +/** + * Processes the {@link ComponentName} annotation + * + * @version $$Rev$$ $$Date$$ + */ +public class ComponentNameProcessor extends ImplementationProcessorSupport { + + public ComponentNameProcessor(AssemblyFactory factory) { + super(factory); + } + + public void visitMethod(Method method, ComponentType type) throws ConfigurationLoadException { + ComponentName name = method.getAnnotation(ComponentName.class); + if (name == null) { + return; + } + type.getExtensibilityElements().add(new ComponentNameExtensibilityElement(method)); + } + + public void visitField(Field field, ComponentType type) throws ConfigurationLoadException { + ComponentName name = field.getAnnotation(ComponentName.class); + if (name == null) { + return; + } + type.getExtensibilityElements().add(new ComponentNameExtensibilityElement(field)); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ContextProcessor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ContextProcessor.java new file mode 100644 index 0000000000..ff5c3736b7 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ContextProcessor.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.config.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.extension.config.extensibility.ContextExtensibilityElement; +import org.apache.tuscany.model.assembly.ComponentType; +import org.osoa.sca.annotations.Context; + +/** + * Processes the {@link org.osoa.sca.annotations.Context} annotation + * + * @version $$Rev$$ $$Date$$ + */ +public class ContextProcessor extends ImplementationProcessorSupport { + + public ContextProcessor() { + } + + public void visitMethod(Method method, ComponentType type) throws ConfigurationLoadException { + Context context = method.getAnnotation(Context.class); + if (context == null) { + return; + } + type.getExtensibilityElements().add(new ContextExtensibilityElement(method)); + } + + public void visitField(Field field, ComponentType type) throws ConfigurationLoadException { + Context context = field.getAnnotation(Context.class); + if (context == null) { + return; + } + type.getExtensibilityElements().add(new ContextExtensibilityElement(field)); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/DefaultProcessor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/DefaultProcessor.java new file mode 100644 index 0000000000..8445526dc8 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/DefaultProcessor.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.config.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Set; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +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.Property; +import org.apache.tuscany.model.assembly.Reference; + +/** + * Adds public methods and public/protected fields as properties that are not declared explicitly with an + * {@link org.osoa.sca.annotations.Property} or {@link org.osoa.sca.annotations.Reference} annotation + * + * @version $$Rev$$ $$Date$$ + */ +public class DefaultProcessor extends ImplementationProcessorSupport { + + public DefaultProcessor(AssemblyFactory factory) { + super(factory); + } + + public DefaultProcessor() { + } + + public void visitEnd(Class clazz, ComponentType type) throws ConfigurationLoadException { + // add any public/protected fields and public setter methods as properties + Set fields = JavaIntrospectionHelper.getAllPublicAndProtectedFields(clazz); + List properties = type.getProperties(); + List references = type.getReferences(); + boolean contains; + Method[] methods = clazz.getMethods(); + String name; + for (Method method : methods) { + if (Object.class.equals(method.getDeclaringClass()) || method.getParameterTypes().length != 1 + || method.isAnnotationPresent(org.osoa.sca.annotations.Property.class) + || method.isAnnotationPresent(org.osoa.sca.annotations.Reference.class)) { + continue; + } + contains = containsProperty(properties, method.getName()); + if (contains) { + continue; + } + name = method.getName(); + if (name.length() > 3 && name.startsWith("set")) { + // follow JavaBeans conventions + name = JavaIntrospectionHelper.toPropertyName(name); + } + contains = containsReference(references, name); + if (!contains) { + addProperty(name, method.getParameterTypes()[0], type); + } + } + for (Field field : fields) { + if (field.isAnnotationPresent(org.osoa.sca.annotations.Property.class) + || field.isAnnotationPresent(org.osoa.sca.annotations.Reference.class)) { + continue; + } + contains = containsProperty(properties, field.getName()); + if (contains) { + continue; + } + contains = containsReference(references, field.getName()); + if (!contains) { + addProperty(field.getName(), field.getType(), type); + } + } + } + + private boolean containsProperty(List properties, String name) { + for (Property prop : properties) { + if (prop.getName().equals(name)) { + return true; + } + } + return false; + } + + private boolean containsReference(List references, String name) { + for (Reference ref : references) { + if (ref.getName().equals(name)) { + return true; + } + } + return false; + } + + private void addProperty(String name, Class propType, ComponentType type) { + Property property = factory.createProperty(); + property.setName(name); + property.setRequired(false); + property.setType(propType); + type.getProperties().add(property); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/DestroyProcessor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/DestroyProcessor.java new file mode 100644 index 0000000000..a16845bbf8 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/DestroyProcessor.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.processor; + +import java.lang.reflect.Method; + +import org.apache.tuscany.core.extension.config.extensibility.DestroyInvokerExtensibilityElement; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.model.assembly.AssemblyFactory; +import org.apache.tuscany.model.assembly.ComponentType; +import org.osoa.sca.annotations.Destroy; + +/** + * Processes a {@link Destroy} + * + * @version $$Rev$$ $$Date$$ + */ +public class DestroyProcessor extends ImplementationProcessorSupport { + + public DestroyProcessor() { + } + + public void visitMethod(Method method, ComponentType type) throws ConfigurationLoadException { + Destroy destroy = method.getAnnotation(Destroy.class); + if (destroy == null) { + return; + } + if (method.getParameterTypes().length != 0) { + throw new ConfigurationLoadException("Destroy methods cannot take parameters"); + } + type.getExtensibilityElements().add(new DestroyInvokerExtensibilityElement(method)); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ImplementationProcessorSupport.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ImplementationProcessorSupport.java new file mode 100644 index 0000000000..175de28a92 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ImplementationProcessorSupport.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.config.processor; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.apache.tuscany.core.config.ComponentTypeIntrospector; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.extension.config.ImplementationProcessor; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.model.assembly.AssemblyFactory; +import org.apache.tuscany.model.assembly.ComponentType; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Scope; + +/** + * A base implementation of an ImplementationProcessor + * + * @version $$Rev$$ $$Date$$ + */ +@Scope("MODULE") +public abstract class ImplementationProcessorSupport implements ImplementationProcessor { + + protected ComponentTypeIntrospector introspector; + protected AssemblyFactory factory; + + protected ImplementationProcessorSupport(AssemblyFactory factory) { + this.factory = factory; + } + + protected ImplementationProcessorSupport() { + } + + @Init(eager = true) + public void init() throws Exception { + introspector.registerProcessor(this); + } + + @Autowire + public void setIntrospector(ComponentTypeIntrospector introspector) { + this.introspector = introspector; + } + + @Autowire + public void setFactory(AssemblyFactory factory) { + this.factory = factory; + + } + + public void visitClass(Class clazz, ComponentType type) throws ConfigurationLoadException { + + } + + public void visitSuperClass(Class clazz, ComponentType type) throws ConfigurationLoadException { + + } + + public void visitMethod(Method method, ComponentType type) throws ConfigurationLoadException { + + } + + public void visitConstructor(Constructor constructor, ComponentType type) throws ConfigurationLoadException { + + } + + public void visitField(Field field, ComponentType type) throws ConfigurationLoadException { + + } + + public void visitInterface(Class clazz, Annotation[] annotations, ComponentType type) throws ConfigurationLoadException { + + } + + public void visitInterfaceMethod(Method method, Annotation[] annotations, ComponentType type) throws ConfigurationLoadException { + + } + + public void visitEnd(Class clazz, ComponentType type) throws ConfigurationLoadException { + + } + +// /** +// * Creates a {@link JavaExtensibilityElement} subclasses may update while processing annotations +// */ +// protected JavaExtensibilityElement getExtensibilityElement(ComponentType type) { +// JavaExtensibilityElement element = (JavaExtensibilityElement) type.getExtensibilityElements().get(JAVA_ELEMENT); +// if (element == null) { +// element = new JavaExtensibilityElementImpl(); +// type.getExtensibilityElements().put(JAVA_ELEMENT, element); +// } +// return element; +// } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/InitProcessor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/InitProcessor.java new file mode 100644 index 0000000000..9f4a53a651 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/InitProcessor.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.processor; + +import java.lang.reflect.Method; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.extension.config.extensibility.InitInvokerExtensibilityElement; +import org.apache.tuscany.model.assembly.ComponentType; +import org.osoa.sca.annotations.Init; + +/** + * Processes the {@link org.osoa.sca.annotations.Init} annotation + * + * @version $$Rev$$ $$Date$$ + */ +public class InitProcessor extends ImplementationProcessorSupport { + + public InitProcessor() { + } + + public void visitMethod(Method method, ComponentType type) throws ConfigurationLoadException { + Init init = method.getAnnotation(Init.class); + if (init == null) { + return; + } + if (method.getParameterTypes().length != 0) { + throw new ConfigurationLoadException("Initialize methods cannot take parameters"); + } + type.getExtensibilityElements().add(new InitInvokerExtensibilityElement(method, init.eager())); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ProcessorHelper.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ProcessorHelper.java new file mode 100644 index 0000000000..d4c6c4a40e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ProcessorHelper.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.config.processor; + +import java.util.List; + +import org.apache.tuscany.model.assembly.Scope; +import org.apache.tuscany.model.assembly.Service; + +/** + * Provides utility functions for {@link org.apache.tuscany.core.extension.config.ImplementationProcessor}s + * + * @version $$Rev$$ $$Date$$ + */ +public class ProcessorHelper { + + private ProcessorHelper() { + } + + /** + * Returns the first Service from a collection matching the interface type + */ + public static Service getService(Class interfaceType, List services) { + for (Service service : services) { + Class serviceInterface = service.getServiceContract().getInterface(); + if (serviceInterface.equals(interfaceType)) { + return service; + } + } + return null; + } + + /** + * Returns the scope enum specified by the annotation + */ + public static Scope getScope(org.osoa.sca.annotations.Scope annotation) { + if ("MODULE".equalsIgnoreCase(annotation.value())) { + return Scope.MODULE; + } else if ("SESSION".equalsIgnoreCase(annotation.value())) { + return Scope.SESSION; + } else if ("REQUEST".equalsIgnoreCase(annotation.value())) { + return Scope.REQUEST; + } else { + return Scope.INSTANCE; + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ProcessorUtils.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ProcessorUtils.java new file mode 100644 index 0000000000..b0400c183f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ProcessorUtils.java @@ -0,0 +1,65 @@ +/** + * + * 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.processor; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.core.extension.config.ImplementationProcessor; +import org.apache.tuscany.core.system.config.processor.AutowireProcessor; +import org.apache.tuscany.core.system.config.processor.MonitorProcessor; +import org.apache.tuscany.core.system.config.processor.ParentContextProcessor; +import org.apache.tuscany.core.config.ComponentTypeIntrospector; +import org.apache.tuscany.core.config.impl.Java5ComponentTypeIntrospector; +import org.apache.tuscany.core.sdo.helper.SDOHelperProcessor; +import org.apache.tuscany.model.assembly.AssemblyFactory; + +/** + * Temporary class to create bootstrap {@link ImplementationProcessor}s + * + * @version $$Rev$$ $$Date$$ + */ +public class ProcessorUtils { + + private ProcessorUtils() { + } + + public static List createCoreProcessors(AssemblyFactory factory) { + List processors = new ArrayList(); + processors.add(new PropertyProcessor(factory)); + processors.add(new ReferenceProcessor(factory)); + processors.add(new ScopeProcessor()); + processors.add(new ServiceProcessor(factory)); + processors.add(new InitProcessor()); + processors.add(new DestroyProcessor()); + processors.add(new ContextProcessor()); + processors.add(new ComponentNameProcessor(factory)); + processors.add(new DefaultProcessor(factory)); + processors.add(new AutowireProcessor()); + processors.add(new MonitorProcessor()); + processors.add(new ParentContextProcessor()); + processors.add(new SDOHelperProcessor()); + return processors; + } + + public static ComponentTypeIntrospector createCoreIntrospector(AssemblyFactory factory){ + ComponentTypeIntrospector introspector = new Java5ComponentTypeIntrospector(factory); + List processors = createCoreProcessors(factory); + for (ImplementationProcessor processor : processors) { + introspector.registerProcessor(processor); + } + return introspector; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/PropertyProcessor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/PropertyProcessor.java new file mode 100644 index 0000000000..9191b75793 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/PropertyProcessor.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.config.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.config.InvalidSetterException; +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.Property; +import org.osoa.sca.annotations.Scope; + +/** + * Processes the {@link org.osoa.sca.annotations.Property} annotation + * + * @version $$Rev$$ $$Date$$ + */ +@Scope("MODULE") +public class PropertyProcessor extends ImplementationProcessorSupport { + + public PropertyProcessor(AssemblyFactory factory) { + super(factory); + } + + public PropertyProcessor() { + } + + @Override + public void visitMethod(Method method, ComponentType type) throws ConfigurationLoadException { + if (method.getDeclaringClass().equals(Object.class)) { + return; + } + org.osoa.sca.annotations.Property annotation = method.getAnnotation(org.osoa.sca.annotations.Property.class); + if (annotation != null) { + if (!Modifier.isPublic(method.getModifiers())) { + InvalidSetterException e = new InvalidSetterException("Property setter method is not public"); + e.setIdentifier(method.toString()); + throw e; + } + Class[] params = method.getParameterTypes(); + if (params.length != 1) { + InvalidSetterException e = new InvalidSetterException("Property setter method must have one parameter"); + e.setIdentifier(method.toString()); + throw e; + } + String name = annotation.name(); + if (name.length() == 0) { + name = method.getName(); + if (name.length() > 3 && name.startsWith("set")) { + // follow JavaBeans conventions + name = JavaIntrospectionHelper.toPropertyName(name); + } + } + addProperty(name, method.getParameterTypes()[0], annotation.required(), type); + } + + + } + + @Override + public void visitField(Field field, ComponentType type) throws ConfigurationLoadException { + if (field.getDeclaringClass().equals(Object.class)) { + return; + } + int modifiers = field.getModifiers(); + org.osoa.sca.annotations.Property annotation = field.getAnnotation(org.osoa.sca.annotations.Property.class); + if (annotation != null) { + if (!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers)) { + InvalidSetterException e = new InvalidSetterException("Property field is not public or protected"); + e.setIdentifier(field.getName()); + throw e; + } + String name = annotation.name(); + if (name.length() == 0) { + name = field.getName(); + } + addProperty(name, field.getType(), annotation.required(), type); + } + } + + private void addProperty(String name, Class propType, boolean required, ComponentType type) { + Property property = factory.createProperty(); + property.setName(name); + property.setRequired(required); + property.setType(propType); + type.getProperties().add(property); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/PropertyReferenceValidator.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/PropertyReferenceValidator.java new file mode 100644 index 0000000000..bc8ef02777 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/PropertyReferenceValidator.java @@ -0,0 +1,80 @@ +/** + * + * 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.processor; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.lang.reflect.Field; +import java.util.Set; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.config.MetaDataException; +import org.apache.tuscany.core.config.JavaIntrospectionHelper; +import org.apache.tuscany.model.assembly.AssemblyFactory; +import org.apache.tuscany.model.assembly.ComponentType; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; + +/** + * Validates the use of {@link org.osoa.sca.annotations.Property} and {@link + * org.osoa.sca.annotations.Reference} annotations beyond native Java syntactic capabilities + * + * @version $$Rev$$ $$Date$$ + */ +public class PropertyReferenceValidator extends ImplementationProcessorSupport { + + public PropertyReferenceValidator(AssemblyFactory factory) { + super(factory); + } + + public void visitEnd(Class clazz, ComponentType type) throws ConfigurationLoadException { + // validate methods do not contain both @Reference and @Property annotations + Method[] methods = clazz.getMethods(); + boolean found; + for (Method method : methods) { + found = false; + Annotation[] anotations = method.getAnnotations(); + for (Annotation annotation : anotations) { + if (Property.class.equals(annotation.annotationType()) + || Reference.class.equals(annotation.annotationType())) { + if (found) { + MetaDataException e = new MetaDataException("Method cannot specify both property and reference"); + e.setIdentifier(method.getName()); + throw e; + } + found = true; + } + } + } + // validate fields do not contain both @Reference and @Property annotations + Set fields = JavaIntrospectionHelper.getAllPublicAndProtectedFields(clazz); + for (Field field : fields) { + found = false; + Annotation[] anotations = field.getAnnotations(); + for (Annotation annotation : anotations) { + if (Property.class.equals(annotation.annotationType()) + || Reference.class.equals(annotation.annotationType())) { + if (found) { + MetaDataException e = new MetaDataException("Field cannot specify both property and reference"); + e.setIdentifier(field.getName()); + throw e; + } + found = true; + } + } + } + + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ReferenceProcessor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ReferenceProcessor.java new file mode 100644 index 0000000000..007410b500 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ReferenceProcessor.java @@ -0,0 +1,119 @@ +/** + * + * 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.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Collection; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.config.InvalidSetterException; +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.Reference; +import org.apache.tuscany.model.assembly.ServiceContract; +import org.osoa.sca.annotations.Scope; + +/** + * Processes the {@link org.osoa.sca.annotations.Reference} annotation + * + * @version $$Rev$$ $$Date$$ + */ +@Scope("MODULE") +public class ReferenceProcessor extends ImplementationProcessorSupport { + + public ReferenceProcessor() { + } + + public ReferenceProcessor(AssemblyFactory factory) { + super(factory); + } + + @Override + public void visitMethod(Method method, ComponentType type) throws ConfigurationLoadException { + if(method.getDeclaringClass().equals(Object.class)){ + return; + } + int modifiers = method.getModifiers(); + org.osoa.sca.annotations.Reference annotation = method.getAnnotation(org.osoa.sca.annotations.Reference.class); + if (annotation != null) { + if (!Modifier.isPublic(modifiers)) { + InvalidSetterException e = new InvalidSetterException("Reference setter method is not public"); + e.setIdentifier(method.getName()); + throw e; + } + if (!Void.TYPE.equals(method.getReturnType())) { + InvalidSetterException e = new InvalidSetterException("Refence setter method must return void"); + e.setIdentifier(method.toString()); + throw e; + } + Class[] params = method.getParameterTypes(); + if (params.length != 1) { + InvalidSetterException e = new InvalidSetterException("Reference setter method must have one parameter"); + e.setIdentifier(method.toString()); + throw e; + } + String name = annotation.name(); + if (name.length() == 0) { + name = method.getName(); + if (name.length() > 3 && name.startsWith("set")) { + // follow JavaBeans conventions + name = JavaIntrospectionHelper.toPropertyName(name); + } + } + addReference(name, params[0], annotation.required(), type); + } + } + + @Override + public void visitField(Field field, ComponentType type) throws ConfigurationLoadException { + if(field.getDeclaringClass().equals(Object.class)){ + return; + } + int modifiers = field.getModifiers(); + org.osoa.sca.annotations.Reference annotation = field.getAnnotation(org.osoa.sca.annotations.Reference.class); + if (annotation != null) { + if (!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers)) { + InvalidSetterException e = new InvalidSetterException("Reference field is not public or protected"); + e.setIdentifier(field.getName()); + throw e; + } + String name = annotation.name(); + if (name.length() == 0) { + name = field.getName(); + } + addReference(name, field.getType(), annotation.required(), type); + } + } + + private void addReference(String name, Class paramType, boolean required, ComponentType type) { + Reference reference = factory.createReference(); + reference.setName(name); + ServiceContract contract = factory.createJavaServiceContract(); + contract.setInterface(paramType); + reference.setServiceContract(contract); + boolean many = paramType.isArray() || Collection.class.isAssignableFrom(paramType); + Multiplicity multiplicity; + if (required) + multiplicity = many ? Multiplicity.ONE_N : Multiplicity.ONE_ONE; + else + multiplicity = many ? Multiplicity.ZERO_N : Multiplicity.ZERO_ONE; + reference.setMultiplicity(multiplicity); + type.getReferences().add(reference); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ScopeProcessor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ScopeProcessor.java new file mode 100644 index 0000000000..e81430115a --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ScopeProcessor.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.processor; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.model.assembly.ComponentType; +import org.apache.tuscany.model.assembly.Scope; +import org.apache.tuscany.model.assembly.Service; + +/** + * Processes the {@link org.osoa.sca.annotations.Scope} annotation + * + * @version $$Rev$$ $$Date$$ + */ +public class ScopeProcessor extends ImplementationProcessorSupport { + + public ScopeProcessor() { + } + + @Override + public void visitEnd(Class clazz, ComponentType type) throws ConfigurationLoadException { + Scope scope = null; + org.osoa.sca.annotations.Scope annotation = clazz.getAnnotation(org.osoa.sca.annotations.Scope.class); + if (annotation != null) { + scope = ProcessorHelper.getScope(annotation); + } else { + Class superClass = clazz.getSuperclass(); + if (superClass != null) { + scope = recurseScope(superClass); + } + } + if (scope == null) { + scope = Scope.INSTANCE; + } + //FIXME hack for now - set scope to implementation scope + //This will be clean up with spec change + for (Service service : type.getServices()) { + Scope serviceScope = service.getServiceContract().getScope(); + if (serviceScope == Scope.INSTANCE || serviceScope == null) { + service.getServiceContract().setScope(scope); + } + } + + } + + /** + * Walks the class hierarchy until a scope annotation is found + */ + private Scope recurseScope(Class superClass) { + if (Object.class.equals(superClass)) { + return null; + } + org.osoa.sca.annotations.Scope scope = superClass.getAnnotation(org.osoa.sca.annotations.Scope.class); + if (scope == null) { + superClass = superClass.getSuperclass(); + if (superClass != null) { + return recurseScope(superClass); + } + } + return ProcessorHelper.getScope(scope); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ServiceProcessor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ServiceProcessor.java new file mode 100644 index 0000000000..2c7ba823f2 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/config/processor/ServiceProcessor.java @@ -0,0 +1,129 @@ +/** + * + * 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.processor; + +import java.util.List; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.config.InvalidMetaDataException; +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.Scope; +import org.apache.tuscany.model.assembly.Service; +import org.apache.tuscany.model.types.java.JavaServiceContract; +import org.osoa.sca.annotations.Callback; + +/** + * Processes the {@link org.osoa.sca.annotations.Service} annotation + * + * @version $$Rev$$ $$Date$$ + */ +public class ServiceProcessor extends ImplementationProcessorSupport { + + public ServiceProcessor() { + } + + public ServiceProcessor(AssemblyFactory factory) { + super(factory); + } + + @Override + public void visitClass(Class clazz, ComponentType type) throws ConfigurationLoadException { + if (!clazz.isInterface()) { + processImplementation(clazz,type); + } else { + processInterface(clazz, type); + } + } + + private void processImplementation(Class clazz, ComponentType type) throws ConfigurationLoadException { + // visiting the base implementation class + List services = type.getServices(); + Class[] interfaces = clazz.getInterfaces(); + org.osoa.sca.annotations.Service serviceAnnotation = clazz.getAnnotation(org.osoa.sca.annotations.Service.class); + if (interfaces.length == 0) { + // no interfaces so the class is the service + addService(services, clazz); + } else if (serviceAnnotation == null && interfaces.length == 1) { + // the impl has one interface, assign it to be the service + addService(services, interfaces[0]); + } else { + // visiting the implementation class + if (serviceAnnotation == null) { + return; + } + Class[] serviceInterfaces = serviceAnnotation.interfaces(); + Class value = serviceAnnotation.value(); + if (serviceInterfaces.length > 0) { + if (!Void.class.equals(value)) { + InvalidMetaDataException e = new InvalidMetaDataException("Both interfaces and value specified in @Service on "); + e.setIdentifier(clazz.getName()); + throw e; + } + for (Class intf : interfaces) { + addService(services, intf); + } + } else if (!Void.class.equals(value)) { + addService(services, value); + } + } + } + + + @Override + public void visitEnd(Class clazz, ComponentType type) throws ConfigurationLoadException { + List services = type.getServices(); + if (services.size() == 0) { + // no services processed so the class is the service + addService(services, clazz); + } + } + + private void processInterface(Class clazz, ComponentType type) { + List services = type.getServices(); + // the interface is a remotable service, add it + org.osoa.sca.annotations.Remotable remotableAnnotation = clazz.getAnnotation(org.osoa.sca.annotations.Remotable.class); + if (remotableAnnotation != null) { + // check to see if service added previously b/c it was specified on @Service + if (ProcessorHelper.getService(clazz, services) == null) { + addService(services, clazz); + } + } + } + + + private void addService(List services, Class serviceClass) { + //FIXME how do we support specifying remotable? + JavaServiceContract javaInterface = factory.createJavaServiceContract(); + javaInterface.setInterface(serviceClass); + org.osoa.sca.annotations.Scope scopeAnnotation = serviceClass.getAnnotation(org.osoa.sca.annotations.Scope.class); + Scope scope; + if (scopeAnnotation == null) { + scope = Scope.INSTANCE; + } else { + scope = ProcessorHelper.getScope(scopeAnnotation); + } + javaInterface.setScope(scope); + 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); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/AtomicContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/AtomicContext.java new file mode 100644 index 0000000000..7d4b990ab5 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/AtomicContext.java @@ -0,0 +1,55 @@ +/** + * + * 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 an atomic (i.e. leaf-type) artifact. + * + * @version $Rev$ $Date$ + */ +public interface AtomicContext extends Context { + + /** + * Returns whether the context should be eagerly initialized + */ + public boolean isEagerInit(); + + /** + * Notifies the context of an initialization event + * @throws TargetException + */ + public void init() throws TargetException; + + /** + * Notifies the context of a destroy event + * @throws TargetException + */ + public void destroy() throws TargetException; + + /** + * Returns whether the context should be called back when its scope ends + */ + public boolean isDestroyable(); + + /** + * Returns the target instance associated with the context. A target instance is the actual + * object a request is dispatched to sans proxy wire chain. + * @throws TargetException + */ + public Object getTargetInstance() throws TargetException; + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireContext.java new file mode 100644 index 0000000000..7fa459e76d --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireContext.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.context; + +/** + * A specialization of a CompositeContext 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 CompositeContext { + + /** + * Invoked by child contexts to return an an autowire target. Resolved targets may be entry points or + * components in the parent or its ancestors, or entry points in a sibling context + * + * @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 resolveInstance(Class instanceInterface) throws AutowireResolutionException; + + /** + * Invoked by a parent context to return an autowire target in a child. Resolved targets must be entry points. + * For example, given a parent P and two siblings, A and B, A would request an autowire by invoking + * {@link #resolveInstance(Class)} on P, which in turn could invoke the present method on B in order to resolve + * a target. + * + * @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 resolveExternalInstance(Class instanceInterface) throws AutowireResolutionException; + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireResolutionException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/AutowireResolutionException.java new file mode 100644 index 0000000000..4da4206a94 --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/CompositeContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/CompositeContext.java new file mode 100644 index 0000000000..abd23feb38 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/CompositeContext.java @@ -0,0 +1,91 @@ +/** + * + * 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; +import org.apache.tuscany.model.assembly.Composite; +import org.apache.tuscany.model.assembly.Part; +import org.apache.tuscany.model.assembly.Extensible; +import org.apache.tuscany.model.assembly.AssemblyContext; + +import java.util.List; + +/** + * A context which contains child component contexts. + * + * @version $Rev$ $Date$ + */ +public interface CompositeContext extends Context { + + public String getURI(); + + public void setURI(String uri); + + /** + * TODO remove this method + * @deprecated + */ + public void setAssemblyContext(AssemblyContext context); + + /** + * Returns the parent context, or null if the context does not have one + */ + public CompositeContext getParent(); + + /** + * Sets the parent context + */ + public void setParent(CompositeContext parent); + + /** + * Adds runtime artifacts represented by the set of model objects to the composite context by merging them with + * existing artifacts. Implementing classes may support only a subset of {@link Part} types. + * + * @see org.apache.tuscany.model.assembly.Component + * @see org.apache.tuscany.model.assembly.ModuleComponent + * @see org.apache.tuscany.model.assembly.AtomicComponent + * @see org.apache.tuscany.model.assembly.EntryPoint + * @see org.apache.tuscany.model.assembly.ExternalService + */ + public void registerModelObjects(List models) throws ConfigurationException; + + /** + * Adds a runtime artifact represented by the model object to the composite context by merging it with existing + * artifacts. Implementing classes may support only a subset of {@link Part} types. + * + * @see org.apache.tuscany.model.assembly.Component + * @see org.apache.tuscany.model.assembly.ModuleComponent + * @see org.apache.tuscany.model.assembly.AtomicComponent + * @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 Context getContext(String name); + + /** + * Returns the composite managed by this composite context + */ + @Deprecated + public Composite getComposite(); + + public void removeContext(String name); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ConfigurationContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ConfigurationContext.java new file mode 100644 index 0000000000..558de7609f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ConfigurationContext.java @@ -0,0 +1,30 @@ +/** + * + * 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.ContextFactoryBuilder; +import org.apache.tuscany.core.builder.WireBuilder; + +/** + * Offers configuration services in the runtime. A ConfigurationContext is able to configure a model and then buildSource the + * runtime representation corresponding to that model in the live system. + *

+ * Configuration contexts will typically be hierarchical, delegating to their parent after performing an + * operation. The parent ConfigurationContext will typically be injected into an implementation of this interface during + * registration. + * + * @version $Rev$ $Date$ + */ +public interface ConfigurationContext extends ContextFactoryBuilder, WireBuilder { +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/Context.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/Context.java new file mode 100644 index 0000000000..df313d8000 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/Context.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.context; + +/** + * An entity that provides an execution context for a runtime artifact or artifacts. A Context may + * be a composite, managing child contexts or it may be an atomic, i.e. leaf, context. + * + * @version $Rev$ $Date$ + */ +public interface Context extends EventPublisher, Lifecycle { + /** + * Returns the instance associated with the requested name, which may be in a atomic or composite form. Atomic (i.e. + * leaf) contexts will return an instance associated with the service name part of the compound name, which may be + * null. + *

+ * Composite 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 composite 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 CompositeContext + * @see org.apache.tuscany.model.assembly.EntryPoint + */ + public Object getInstance(QualifiedName qName) throws TargetException; + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ContextInitException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ContextInitException.java new file mode 100644 index 0000000000..e024a98b0e --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ContextRuntimeException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ContextRuntimeException.java new file mode 100644 index 0000000000..0d35f145dc --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/CoreRuntimeException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/CoreRuntimeException.java new file mode 100644 index 0000000000..63e6f18e99 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/CoreRuntimeException.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 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/DuplicateNameException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/DuplicateNameException.java new file mode 100644 index 0000000000..81a334d3c8 --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EntryPointContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EntryPointContext.java new file mode 100644 index 0000000000..63feabc43c --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EntryPointContext.java @@ -0,0 +1,69 @@ +/** + * + * 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.wire.SourceWireFactory; + +/** + * The runtime artifact representing an entry point, EntryPointContext manages wire handler + * instances that expose service operations offered by a component in the parent composite. The wire handler + * instance is responsible for dispatching the request down an wire chain to the target instance. The wire + * chain may contain {@link org.apache.tuscany.core.wire.Interceptor}s and + * {@link org.apache.tuscany.core.wire.MessageHandler}s that implement policies or perform mediations on the + * wire. + *

+ * 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 EntryPointContext + * to perform the wire as in: + * + *

+ *              CompositeContext compositeContext = ...
+ *              EntryPointContext ctx = (EntryPointContext) compositeContext.getContext("source");
+ *              Assert.assertNotNull(ctx);
+ *              InvocationHandler handler = (InvocationHandler) ctx.getHandler();
+ *              Object response = handler.invoke(null, operation, new Object[] { param });
+ * 
+ * + * The Proxy instance passed to InvocationHandler may be null as the client is invoking + * directly on the handler. + *

+ * Alternatively, the following will return a proxy implementing the service interface exposed by the entry point: + * + *

+ *              CompositeContext compositeContext = ...
+ *              EntryPointContext ctx = (EntryPointContext) compositeContext.getContext("source");
+ *              Assert.assertNotNull(ctx);
+ *              HelloWorld proxy = (Helloworld) ctx.getInstance(null); // service name not necessary
+ * 
+ * + * The proxy returned will be backed by the entry point wire chain. + * + * @version $Rev$ $Date$ + */ +public interface EntryPointContext extends Context { + + /** + * Returns the handler responsible for flowing a request through the entry point + * @throws TargetException + */ + public Object getHandler() throws TargetException; + + /** + * Returns the service interface configured for the entry poitn + */ + public Class getServiceInterface(); +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EventContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EventContext.java new file mode 100644 index 0000000000..36b0f98928 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EventContext.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.context; + +/** + * Implementations are responsible for tracking scope keys associated with the current request. + * + * @version $Rev$ $Date$ + */ +public interface EventContext { + + /** + * Returns the unique key for the given identifier associated with the current request + */ + public Object getIdentifier(Object type); + + /** + * Sets the unique key for the given identifier associated with the current request + */ + public void setIdentifier(Object type, Object identifier); + + /** + * Clears the unique key for the given identifier associated with the current request + */ + public void clearIdentifier(Object type); + + /** + * Clears all identifiers associated with the current request + */ + public void clearIdentifiers(); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EventException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EventException.java new file mode 100644 index 0000000000..aaf26aee69 --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EventFilter.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EventFilter.java new file mode 100644 index 0000000000..ee1334bef2 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EventFilter.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 org.apache.tuscany.core.context.event.Event; + +import java.util.EventObject; + +/** + * Evaluates whether a {@link RuntimeEventListener} is applicable to a given runtime event + * + * @version $$Rev$$ $$Date$$ + */ +public interface EventFilter { + + /** + * Performs the actual evaluation on an event + */ + public boolean match(Event event); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EventPublisher.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EventPublisher.java new file mode 100644 index 0000000000..c7ccf88e25 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/EventPublisher.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.context; + +import org.apache.tuscany.core.context.event.Event; + +/** + * Publishes events in the runtime + * + * @version $$Rev$$ $$Date$$ + */ +public interface EventPublisher { + + public void publish(Event object); + + /** + * Registers a listener to receive notifications for the context + */ + public void addListener(RuntimeEventListener listener); + + /** + * Registers a listener to receive notifications for the context + */ + public void addListener(EventFilter filter, RuntimeEventListener listener); + + + /** + * Removes a previously registered listener + */ + public void removeListener(RuntimeEventListener listener); + + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ExternalServiceContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ExternalServiceContext.java new file mode 100644 index 0000000000..f7b4a6c572 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ExternalServiceContext.java @@ -0,0 +1,30 @@ +/** + * + * 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 Context { + + /** + * Returns the handler responsible for flowing a request through the external service + * @throws TargetException + */ + public Object getHandler() throws TargetException; + +} + diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/InvalidNameException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/InvalidNameException.java new file mode 100644 index 0000000000..65c709e569 --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/Lifecycle.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/Lifecycle.java new file mode 100644 index 0000000000..6572841cf0 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/Lifecycle.java @@ -0,0 +1,79 @@ +/** + * + * Copyright 2006 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; + +/** + * @version $Rev$ $Date$ + */ +public interface Lifecycle { + /* A configuration error state */ + int CONFIG_ERROR = -1; + /* Has not been initialized */ + int UNINITIALIZED = 0; + /* In the process of being configured and initialized */ + int INITIALIZING = 1; + /* Instantiated and configured */ + int INITIALIZED = 2; + /* Started */ + int STARTED = 4; + /* Configured and initialized */ + int RUNNING = 4; + /* In the process of being shutdown */ + int STOPPING = 5; + /* Has been shutdown and removed from the module */ + int STOPPED = 6; + /* In an error state */ + int ERROR = 7; + + /** + * Returns the lifecycle state + * + * @see #UNINITIALIZED + * @see #INITIALIZING + * @see #INITIALIZED + * @see #RUNNING + * @see #STOPPING + * @see #STOPPED + */ + int getLifecycleState(); + + /** + * Starts the Lifecycle. + * + * @throws CoreRuntimeException + */ + void start() throws CoreRuntimeException; + + /** + * Stops the Lifecycle. + * + * @throws CoreRuntimeException + */ + void stop() throws CoreRuntimeException; + + /** + * Returns the name of the Lifecycle. + * @return the name of the Lifecycle + */ + String getName(); + + /** + * Sets the name of the Lifecycle. + * @param name the name of the Lifecycle + */ + void setName(String name); +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/MissingContextFactoryException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/MissingContextFactoryException.java new file mode 100644 index 0000000000..fd4d613e34 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/MissingContextFactoryException.java @@ -0,0 +1,42 @@ +/** + * + * Copyright 2006 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.context; + +import org.apache.tuscany.core.config.ConfigurationException; + +/** + * + * @version $Rev$ $Date$ + */ +public class MissingContextFactoryException extends ConfigurationException { + private static final long serialVersionUID = 5140433835245354247L; + + public MissingContextFactoryException() { + } + + public MissingContextFactoryException(String message) { + super(message); + } + + public MissingContextFactoryException(String message, Throwable cause) { + super(message, cause); + } + + public MissingContextFactoryException(Throwable cause) { + super(cause); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/MissingImplementationException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/MissingImplementationException.java new file mode 100644 index 0000000000..787e9cae20 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/MissingImplementationException.java @@ -0,0 +1,42 @@ +/** + * + * Copyright 2006 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.context; + +import org.apache.tuscany.core.config.ConfigurationException; + +/** + * + * @version $Rev$ $Date$ + */ +public class MissingImplementationException extends ConfigurationException { + private static final long serialVersionUID = 7274481740916067128L; + + public MissingImplementationException() { + } + + public MissingImplementationException(String message) { + super(message); + } + + public MissingImplementationException(String message, Throwable cause) { + super(message, cause); + } + + public MissingImplementationException(Throwable cause) { + super(cause); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/MissingScopeException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/MissingScopeException.java new file mode 100644 index 0000000000..53108e6e6b --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/MissingScopeException.java @@ -0,0 +1,42 @@ +/** + * + * Copyright 2006 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.context; + +import org.apache.tuscany.core.config.ConfigurationException; + +/** + * + * @version $Rev$ $Date$ + */ +public class MissingScopeException extends ConfigurationException { + private static final long serialVersionUID = -6999184494724096056L; + + public MissingScopeException() { + } + + public MissingScopeException(String message) { + super(message); + } + + public MissingScopeException(String message, Throwable cause) { + super(message, cause); + } + + public MissingScopeException(Throwable cause) { + super(cause); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ProxyConfigurationException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ProxyConfigurationException.java new file mode 100644 index 0000000000..2d15118c1c --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ProxyConfigurationException.java @@ -0,0 +1,42 @@ +/** + * + * Copyright 2006 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.context; + +import org.apache.tuscany.core.config.ConfigurationException; + +/** + * + * @version $Rev$ $Date$ + */ +public class ProxyConfigurationException extends ConfigurationException { + private static final long serialVersionUID = -5860342620108741058L; + + public ProxyConfigurationException() { + } + + public ProxyConfigurationException(String message) { + super(message); + } + + public ProxyConfigurationException(String message, Throwable cause) { + super(message, cause); + } + + public ProxyConfigurationException(Throwable cause) { + super(cause); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/QualifiedName.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/QualifiedName.java new file mode 100644 index 0000000000..a9a0baeff9 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/QualifiedName.java @@ -0,0 +1,84 @@ +/** + * + * 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 in the form of part/port where part is the parent context and port represents a + * child, which is either a service in the case of an atomic context or a contained context in the case of a composite. + * + * @throws InvalidNameException if the name is in an invalid format + */ + public QualifiedName(String qualifiedName) throws InvalidNameException { + if (qualifiedName == null){ + return; + } + 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 + */ + public String getQualifiedName() { + return qName; + } + + public String toString() { + return qName; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/RuntimeEventListener.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/RuntimeEventListener.java new file mode 100644 index 0000000000..89cc51f3fc --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/RuntimeEventListener.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 org.apache.tuscany.core.context.event.Event; + +import java.util.EventListener; +import java.util.EventObject; + +/** + * Listeners observe events fired in the SCA runtime. + * + * @version $Rev$ $Date$ + */ +public interface RuntimeEventListener extends EventListener { + + public void onEvent(Event event); +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeAwareContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeAwareContext.java new file mode 100644 index 0000000000..d57d59cb58 --- /dev/null +++ b/branches/java-post-M1/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 org.apache.tuscany.model.assembly.Scope; + +import java.util.Map; + +/** + * Denotes a composite context that supports scopes + * + * @version $Rev$ $Date$ + */ +public interface ScopeAwareContext extends CompositeContext { + + /** + * Returns an immutable collection of scopes keyed by type for the composite context + */ + public Map getScopeContexts(); +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java new file mode 100644 index 0000000000..c582bde2b4 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.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.context; + +import org.apache.tuscany.core.builder.ContextFactory; + +import java.util.List; + +/** + * Manages the lifecycle and visibility of Contexts. + * + * @see org.apache.tuscany.core.context.Context + * + * @version $Rev$ $Date$ + */ +public interface ScopeContext extends Lifecycle, RuntimeEventListener { + + public Object getInstance(QualifiedName qName) throws TargetException; + + /** + * Returns whether implementation instances may be held for the duration of an wire + */ + public boolean isCacheable(); + + /** + * Registers the context factory used to construct instance contexts for the scope + */ + public void registerFactories(List> configurations); + + /** + * Adds a context factory to the scope + */ + public void registerFactory(ContextFactory 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 Context 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 Context 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeIdentifier.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeIdentifier.java new file mode 100644 index 0000000000..d25477f71c --- /dev/null +++ b/branches/java-post-M1/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.core.context.EventContext + */ +public interface ScopeIdentifier { + + /** + * Returns the scope id for the request. + */ + public Object getIdentifier(); +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeInitializationException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeInitializationException.java new file mode 100644 index 0000000000..6ef5bfe9dd --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeRuntimeException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeRuntimeException.java new file mode 100644 index 0000000000..5022f7589d --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeStrategy.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeStrategy.java new file mode 100644 index 0000000000..c01df8ff9e --- /dev/null +++ b/branches/java-post-M1/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 org.apache.tuscany.model.assembly.Scope; + +import java.util.Map; + +/** + * 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 getScopeContexts(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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ServiceNotFoundException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/ServiceNotFoundException.java new file mode 100644 index 0000000000..ee8c9f91b8 --- /dev/null +++ b/branches/java-post-M1/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.ServiceRuntimeException; + +/** + * Denotes the specific case where a service was not found at runtime + * + * @version $Rev$ $Date$ + */ +public class ServiceNotFoundException extends ServiceRuntimeException { + + 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/SystemCompositeContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/SystemCompositeContext.java new file mode 100644 index 0000000000..7e3b4b8045 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/SystemCompositeContext.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.context; + +import org.apache.tuscany.core.config.ConfigurationException; + +/** + * Marker type for system composite contexts + * + * @version $Rev$ $Date$ + */ +public interface SystemCompositeContext 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 service + * @param instance the Object that will become the component's implementation + * @throws ConfigurationException + */ + void registerJavaObject(String name, Class service, Object instance) throws ConfigurationException; +} + diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/TargetException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/TargetException.java new file mode 100644 index 0000000000..dd39d06aa1 --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/AbstractEvent.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/AbstractEvent.java new file mode 100644 index 0000000000..cef0c25a63 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/AbstractEvent.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.event; + +/** + * A basic implementation of a runtime event + * + * @version $$Rev$$ $$Date$$ + */ +public abstract class AbstractEvent implements Event{ + + protected transient Object source; + + public AbstractEvent(Object source) { + assert (source !=null): "Source id was null"; + this.source = source; + } + + public Object getSource() { + return source; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/AbstractRequestEvent.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/AbstractRequestEvent.java new file mode 100644 index 0000000000..c038f141b5 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/AbstractRequestEvent.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.event; + +/** + * Base implementation of a request event + * + * @version $$Rev$$ $$Date$$ + */ +public abstract class AbstractRequestEvent extends AbstractEvent implements RequestEvent { + + private Object id; + + /** + * Creates a new event + * @param source the source of the event + * @param id the id of the request associated with the event + */ + public AbstractRequestEvent(Object source, Object id) { + super(source); + assert (id !=null): "Request id was null"; + this.id = id; + } + + public Object getId(){ + return id; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/Event.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/Event.java new file mode 100644 index 0000000000..5b370b8c73 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/Event.java @@ -0,0 +1,28 @@ +/** + * + * 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.event; + +/** + * Represents an event that is propagated in the runtime + * + * @version $$Rev$$ $$Date$$ + */ +public interface Event { + + /** + * Returns the source of the event + */ + public Object getSource(); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/HttpSessionBound.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/HttpSessionBound.java new file mode 100644 index 0000000000..8af7042ad3 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/HttpSessionBound.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.event; + + +/** + * An event propagated when an HTTP session is bound to the current request + * + * @version $$Rev$$ $$Date$$ + */ +public class HttpSessionBound extends HttpSessionEvent implements SessionBound { + + /** + * Creates a new event + * @param source the source of the event + * @param id the id of the HTTP session associated with the event or possibly a lazy wrapper + */ + public HttpSessionBound(Object source, Object id) { + super(source,id); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/HttpSessionEnd.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/HttpSessionEnd.java new file mode 100644 index 0000000000..3b2aff1353 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/HttpSessionEnd.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.event; + +/** + * Propagated when an HTTP-based session is expired + * + * @version $$Rev$$ $$Date$$ + */ +public class HttpSessionEnd extends HttpSessionEvent implements SessionEnd { + + /** + * Creates a new event + * @param source the source of the event + * @param id the id of the HTTP session being ended + */ + public HttpSessionEnd(Object source, Object id) { + super(source,id); + } + + } diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/HttpSessionEvent.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/HttpSessionEvent.java new file mode 100644 index 0000000000..ecfbefa808 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/HttpSessionEvent.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.context.event; + +/** + * A base implementation of HTTP-based session events in the runtime + * + * @version $$Rev$$ $$Date$$ + */ +public abstract class HttpSessionEvent implements SessionEvent { + + // FIXME this needs to be made private and not directly referenced in the runtime + public static final Object HTTP_IDENTIFIER = new Object(); + + private Object id; + protected transient Object source; + + public HttpSessionEvent(Object source, Object id) { + assert (source !=null): "Source id was null"; + assert (id !=null): "Session id was null"; + this.source = source; + this.id = id; + } + + public Object getSource() { + return source; + } + + public Object getId(){ + return id; + } + + public Object getSessionTypeIdentifier(){ + return HTTP_IDENTIFIER; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/InstanceCreated.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/InstanceCreated.java new file mode 100644 index 0000000000..d157b4b1e1 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/InstanceCreated.java @@ -0,0 +1,27 @@ +/** + * + * 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.event; + +/** + * An event propagated upon the creation of an instance belonging to a {@link org.apache.tuscany.core.context.Context} + * + * @version $$Rev$$ $$Date$$ + */ +public class InstanceCreated extends AbstractEvent { + + public InstanceCreated(Object source) { + super(source); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/ModuleEvent.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/ModuleEvent.java new file mode 100644 index 0000000000..48de538048 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/ModuleEvent.java @@ -0,0 +1,23 @@ +/** + * + * 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.event; + +/** + * Implemented by runtime events associated with a module, e.g. lifecycle events + * + * @version $$Rev$$ $$Date$$ + */ +public interface ModuleEvent extends Event{ + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/ModuleStart.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/ModuleStart.java new file mode 100644 index 0000000000..d953ddd65f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/ModuleStart.java @@ -0,0 +1,26 @@ +/** + * + * 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.event; + +/** + * Propagated when a module starts + * + * @version $$Rev$$ $$Date$$ + */ +public class ModuleStart extends AbstractEvent implements ModuleEvent { + + public ModuleStart(Object source) { + super(source); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/ModuleStop.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/ModuleStop.java new file mode 100644 index 0000000000..fb3c31bdff --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/ModuleStop.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.context.event; + +/** + * Propagated when a module stops + * + * @version $$Rev$$ $$Date$$ + */ +public class ModuleStop extends AbstractEvent implements ModuleEvent{ + + public ModuleStop(Object source) { + super(source); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/RequestEnd.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/RequestEnd.java new file mode 100644 index 0000000000..1cbe024be3 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/RequestEnd.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.event; + +/** + * Propagated when a request completes or is ended + * + * @version $$Rev$$ $$Date$$ + */ +public class RequestEnd extends AbstractRequestEvent{ + + /** + * Creates a new event + * @param source the source of the event + * @param id the id of the completed/ended request + */ + public RequestEnd(Object source, Object id) { + super(source,id); + } + + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/RequestEvent.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/RequestEvent.java new file mode 100644 index 0000000000..0b7e1b8005 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/RequestEvent.java @@ -0,0 +1,26 @@ +/** + * + * 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.event; + +/** + * Implemented by runtime events associated request + * @version $$Rev$$ $$Date$$ + */ +public interface RequestEvent { + + /** + * Returns the id of the request the event is associated with + */ + public Object getId(); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/RequestStart.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/RequestStart.java new file mode 100644 index 0000000000..8c07a3d607 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/RequestStart.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.event; + +/** + * Propagated when a request is started in the runtime + * + * @version $$Rev$$ $$Date$$ + */ +public class RequestStart extends AbstractRequestEvent { + + /** + * Creates a new event + * @param source the source of the event + * @param id the id of the request being started + */ + public RequestStart(Object source, Object id) { + super(source,id); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/SessionBound.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/SessionBound.java new file mode 100644 index 0000000000..5d977911be --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/SessionBound.java @@ -0,0 +1,23 @@ +/** + * + * 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.event; + +/** + * Propagated when a generic session is associated with the current request. + * + * @version $$Rev$$ $$Date$$ + */ +public interface SessionBound extends SessionEvent { + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/SessionEnd.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/SessionEnd.java new file mode 100644 index 0000000000..809d63bd0f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/SessionEnd.java @@ -0,0 +1,23 @@ +/** + * + * 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.event; + +/** + * Propagated when a session ended or expired + * + * @version $$Rev$$ $$Date$$ + */ +public interface SessionEnd extends SessionEvent{ + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/SessionEvent.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/SessionEvent.java new file mode 100644 index 0000000000..7eaff1de24 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/SessionEvent.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.context.event; + +/** + * Implemented by runtime events associated with a session. There may be multiple session types in the runtime such as + * HTTP-based or conversational. + * + * @version $$Rev$$ $$Date$$ + */ +public interface SessionEvent extends Event { + + /** + * Returns the unique key identifying the session type the event is associated with, e.g. an HTTP-based or conversational + * session + */ + public Object getSessionTypeIdentifier(); + + /** + * Returns the session id associated with the event + */ + public Object getId(); +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/SessionStart.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/SessionStart.java new file mode 100644 index 0000000000..cfe490e2ff --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/event/SessionStart.java @@ -0,0 +1,26 @@ +/** + * + * 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.event; + +/** + * Propagated when a session starts + * + * @version $$Rev$$ $$Date$$ + */ +public interface SessionStart extends SessionEvent{ + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/filter/TrueFilter.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/filter/TrueFilter.java new file mode 100644 index 0000000000..35601646f2 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/filter/TrueFilter.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.filter; + +import org.apache.tuscany.core.context.EventFilter; +import org.apache.tuscany.core.context.event.Event; + +/** + * An event filter that always returns a true condition + * + * @version $$Rev$$ $$Date$$ + */ +public class TrueFilter implements EventFilter { + + public boolean match(Event event) { + return true; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractCompositeContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractCompositeContext.java new file mode 100644 index 0000000000..c9e563302c --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractCompositeContext.java @@ -0,0 +1,852 @@ +/** + * + * 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.ArrayList; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.apache.tuscany.common.TuscanyRuntimeException; +import org.apache.tuscany.core.builder.BuilderConfigException; +import org.apache.tuscany.core.builder.ContextFactory; +import org.apache.tuscany.core.config.ConfigurationException; +import org.apache.tuscany.core.context.AutowireContext; +import org.apache.tuscany.core.context.AutowireResolutionException; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.ConfigurationContext; +import org.apache.tuscany.core.context.Context; +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.Lifecycle; +import org.apache.tuscany.core.context.MissingContextFactoryException; +import org.apache.tuscany.core.context.MissingImplementationException; +import org.apache.tuscany.core.context.MissingScopeException; +import org.apache.tuscany.core.context.ProxyConfigurationException; +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.core.context.ScopeAwareContext; +import org.apache.tuscany.core.context.ScopeContext; +import org.apache.tuscany.core.context.ScopeStrategy; +import org.apache.tuscany.core.context.TargetException; +import org.apache.tuscany.core.context.event.Event; +import org.apache.tuscany.core.context.event.RequestEnd; +import org.apache.tuscany.core.context.event.SessionBound; +import org.apache.tuscany.core.context.event.SessionEvent; +import org.apache.tuscany.core.context.scope.DefaultScopeStrategy; +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.wire.InvocationConfiguration; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.core.wire.WireConfiguration; +import org.apache.tuscany.core.wire.WireFactory; +import org.apache.tuscany.core.wire.WireFactoryInitException; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Binding; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.Composite; +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.Implementation; +import org.apache.tuscany.model.assembly.Module; +import org.apache.tuscany.model.assembly.ModuleComponent; +import org.apache.tuscany.model.assembly.Scope; +import org.apache.tuscany.model.assembly.Service; +import org.apache.tuscany.model.assembly.impl.AssemblyFactoryImpl; + +/** + * The base implementation of a composite context + * + * @version $Rev$ $Date$ + */ +@SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized", "RawUseOfParameterizedType", "NonPrivateFieldAccessedInSynchronizedContext"}) +public abstract class AbstractCompositeContext extends AbstractContext implements AutowireContext, ScopeAwareContext, ConfigurationContext { + + public static final int DEFAULT_WAIT = 1000 * 60; + + protected AssemblyContext assemblyContext; + + protected CompositeContext parentContext; + + // The parent configuration context, if one exists + @Autowire + protected ConfigurationContext configurationContext; + + // The logical model representing the module assembly + // protected ModuleComponent moduleComponent; + protected Module module; + + protected Map> configurations = new HashMap>(); + + // Factory for scope contexts + protected ScopeStrategy scopeStrategy; + + // The event context for associating context events to threads + protected EventContext eventContext; + + // The scopes for this context + protected Map scopeContexts; + + protected Map immutableScopeContexts; + + // A component context name to scope context index + protected Map scopeIndex; + + // Blocking latch to ensure the module is initialized exactly once prior to servicing requests + protected CountDownLatch initializeLatch = new CountDownLatch(1); + + protected final Object lock = new Object(); + + // Indicates whether the module context has been initialized + protected boolean initialized; + + // a mapping of service type to component name + private final Map autowireInternal = new ConcurrentHashMap(); + private final Map autowireExternal = new ConcurrentHashMap(); + + private AutowireContext autowireContext; + + public AbstractCompositeContext() { + scopeIndex = new ConcurrentHashMap(); + // FIXME the factory should be injected + module = new AssemblyFactoryImpl().createModule(); + scopeStrategy = new DefaultScopeStrategy(); + } + + public AbstractCompositeContext(String name, CompositeContext parent, ScopeStrategy strategy, EventContext ctx, ConfigurationContext configCtx) { + super(name); + if (strategy == null) { + strategy = new DefaultScopeStrategy(); + } + this.scopeStrategy = strategy; + this.eventContext = ctx; + this.configurationContext = configCtx; + scopeIndex = new ConcurrentHashMap(); + parentContext = parent; + // FIXME the factory should be injected + module = new AssemblyFactoryImpl().createModule(); + } + + public void setAssemblyContext(AssemblyContext assemblyContext) { + this.assemblyContext = assemblyContext; + } + + private String uri; + + public String getURI() { + return uri; + } + + public void setURI(String uri) { + this.uri = uri; + } + + + public void start() { + synchronized (lock) { + try { + if (lifecycleState == STOPPED) { + throw new IllegalStateException("Context cannot be restarted - create a new one"); + } else if (lifecycleState != UNINITIALIZED) { + throw new IllegalStateException("Context not in UNINITIALIZED state"); + } + + lifecycleState = INITIALIZING; + initializeScopes(); + + Map>> configurationsByScope = new EnumMap>>(Scope.class); + if (configurations != null) { + for (ContextFactory contextFactory : configurations.values()) { + // FIXME scopes are defined at the interface level + Scope sourceScope = contextFactory.getScope(); + wireSource(contextFactory); + buildTarget(contextFactory); + scopeIndex.put(contextFactory.getName(), scopeContexts.get(sourceScope)); + List> list = configurationsByScope.get(sourceScope); + if (list == null) { + list = new ArrayList>(); + configurationsByScope.put(sourceScope, list); + } + list.add(contextFactory); + } + } + for (EntryPoint ep : module.getEntryPoints()) { + registerAutowire(ep); + } + for (Component component : module.getComponents()) { + if (component instanceof ModuleComponent) { + registerAutowire((ModuleComponent) component); + } else { + 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.registerFactories(entries.getValue()); + } + initializeWireFactories(); + for (ScopeContext scope : scopeContexts.values()) { + // register scope contexts as a listeners for events in the composite context + addListener(scope); + scope.start(); + } + lifecycleState = RUNNING; + } catch (WireFactoryInitException e) { + lifecycleState = ERROR; + ContextInitException cie = new ContextInitException(e); + cie.addContextName(getName()); + throw cie; + } 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(1); //xcv + lifecycleState = STOPPING; + initialized = false; + if (scopeContexts != null) { + for (ScopeContext scopeContext : scopeContexts.values()) { + if (scopeContext.getLifecycleState() == Lifecycle.RUNNING) { + scopeContext.stop(); + } + } + } + scopeContexts = null; + scopeIndex.clear(); + // allow initialized to be called + initializeLatch.countDown(); + lifecycleState = STOPPED; + + } + + public void setModule(Module module) { + assert (module != null) : "Module cannot be null"; + name = module.getName(); + this.module = module; + } + + public void setEventContext(EventContext eventContext) { + this.eventContext = eventContext; + } + + public void setConfigurationContext(ConfigurationContext context) { + this.configurationContext = context; + } + + public CompositeContext getParent() { + return parentContext; + } + + @ParentContext + public void setParent(CompositeContext parent) { + parentContext = parent; + } + + public void registerModelObjects(List 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.build(model); + } catch (BuilderConfigException e) { + e.addContextName(getName()); + throw e; + } + } + ContextFactory configuration; + 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()) { + Implementation componentImplementation = component.getImplementation(); + if (componentImplementation == null) { + ConfigurationException e = new MissingImplementationException("Component implementation not set"); + e.addContextName(component.getName()); + e.addContextName(getName()); + throw e; + } + configuration = (ContextFactory) component.getContextFactory(); + if (configuration == null) { + ConfigurationException e = new MissingContextFactoryException("Context factory not set"); + e.addContextName(component.getName()); + e.addContextName(getName()); + throw e; + } + registerConfiguration(configuration); + if (component instanceof ModuleComponent) { + registerAutowire((ModuleComponent) component); + } else { + registerAutowire(component); + } + } + for (EntryPoint ep : newModule.getEntryPoints()) { + configuration = (ContextFactory) ep.getContextFactory(); + if (configuration == null) { + ConfigurationException e = new MissingContextFactoryException("Context factory not set"); + e.setIdentifier(ep.getName()); + e.addContextName(getName()); + throw e; + } + registerConfiguration(configuration); + registerAutowire(ep); + } + for (ExternalService service : newModule.getExternalServices()) { + configuration = (ContextFactory) service.getContextFactory(); + if (configuration == null) { + ConfigurationException e = new MissingContextFactoryException("Context factory not set"); + e.setIdentifier(service.getName()); + e.addContextName(getName()); + throw e; + } + registerConfiguration(configuration); + registerAutowire(service); + } + if (lifecycleState == RUNNING) { + for (Component component : newModule.getComponents()) { + ContextFactory contextFactory = (ContextFactory) component.getContextFactory(); + wireSource(contextFactory); + buildTarget(contextFactory); + contextFactory.prepare(this); + try { + if (contextFactory.getSourceWireFactories() != null) { + for (SourceWireFactory sourceWireFactory : contextFactory.getSourceWireFactories()) + { + sourceWireFactory.initialize(); + } + } + if (contextFactory.getTargetWireFactories() != null) { + for (TargetWireFactory targetWireFactory : contextFactory.getTargetWireFactories() + .values()) { + targetWireFactory.initialize(); + } + } + } catch (WireFactoryInitException e) { + ProxyConfigurationException ce = new ProxyConfigurationException(e); + ce.addContextName(getName()); + throw ce; + } + + } + for (EntryPoint ep : newModule.getEntryPoints()) { + ContextFactory contextFactory = (ContextFactory) ep.getContextFactory(); + wireSource(contextFactory); + buildTarget(contextFactory); + contextFactory.prepare(this); + try { + if (contextFactory.getSourceWireFactories() != null) { + for (SourceWireFactory sourceWireFactory : contextFactory.getSourceWireFactories()) + { + sourceWireFactory.initialize(); + } + } + if (contextFactory.getTargetWireFactories() != null) { + for (TargetWireFactory targetWireFactory : contextFactory.getTargetWireFactories() + .values()) { + targetWireFactory.initialize(); + } + } + } catch (WireFactoryInitException e) { + ProxyConfigurationException ce = new ProxyConfigurationException(e); + ce.addContextName(getName()); + throw ce; + } + + } + for (ExternalService es : newModule.getExternalServices()) { + ContextFactory contextFactory = (ContextFactory) es.getContextFactory(); + wireSource(contextFactory); + buildTarget(contextFactory); + contextFactory.prepare(this); + try { + if (contextFactory.getSourceWireFactories() != null) { + for (SourceWireFactory sourceWireFactory : contextFactory.getSourceWireFactories()) + { + sourceWireFactory.initialize(); + } + } + if (contextFactory.getTargetWireFactories() != null) { + for (WireFactory targetWireFactory : contextFactory.getTargetWireFactories() + .values()) { + targetWireFactory.initialize(); + } + } + } catch (WireFactoryInitException e) { + ProxyConfigurationException ce = new ProxyConfigurationException(e); + ce.addContextName(getName()); + throw ce; + } + + } + + } + // 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 = (ContextFactory) component.getContextFactory(); + if (configuration == null) { + ConfigurationException e = new MissingContextFactoryException("Context factory not set"); + e.setIdentifier(component.getName()); + e.addContextName(getName()); + throw e; + } + registerConfiguration(configuration); + if (component instanceof ModuleComponent) { + registerAutowire((ModuleComponent) component); + } else { + registerAutowire(component); + } + } else if (model instanceof EntryPoint) { + EntryPoint ep = (EntryPoint) model; + module.getEntryPoints().add(ep); + configuration = (ContextFactory) ep.getContextFactory(); + if (configuration == null) { + ConfigurationException e = new MissingContextFactoryException("Context factory not set"); + e.setIdentifier(ep.getName()); + e.addContextName(getName()); + throw e; + } + registerConfiguration(configuration); + registerAutowire(ep); + } else if (model instanceof ExternalService) { + ExternalService service = (ExternalService) model; + module.getExternalServices().add(service); + configuration = (ContextFactory) service.getContextFactory(); + if (configuration == null) { + ConfigurationException e = new MissingContextFactoryException("Context factory not set"); + e.setIdentifier(service.getName()); + e.addContextName(getName()); + throw e; + } + registerConfiguration(configuration); + registerAutowire(service); + } else { + BuilderConfigException e = new BuilderConfigException("Unknown model type"); + e.setIdentifier(model.getClass().getName()); + e.addContextName(getName()); + throw e; + } + } + } + + protected void registerConfiguration(ContextFactory factory) throws ConfigurationException { + factory.prepare(this); + if (lifecycleState == RUNNING) { + if (scopeIndex.get(factory.getName()) != null) { + throw new DuplicateNameException(factory.getName()); + } + try { + ScopeContext scope = scopeContexts.get(factory.getScope()); + if (scope == null) { + ConfigurationException e = new MissingScopeException("Component has an unknown scope"); + e.addContextName(factory.getName()); + e.addContextName(getName()); + throw e; + } + scope.registerFactory(factory); + scopeIndex.put(factory.getName(), scope); + } catch (TuscanyRuntimeException e) { + e.addContextName(getName()); + throw e; + } + configurations.put(factory.getName(), factory); // xcv + } else { + if (configurations.get(factory.getName()) != null) { + throw new DuplicateNameException(factory.getName()); + } + configurations.put(factory.getName(), factory); + } + + } + + public void fireEvent(int eventType, Object message) throws EventException { + throw new UnsupportedOperationException(); + } + + public void publish(Event event) { + checkInit(); + if (event instanceof SessionBound) { + SessionEvent sessionEvent = ((SessionBound) event); + // update context + eventContext.setIdentifier(sessionEvent.getSessionTypeIdentifier(), sessionEvent.getId()); + } else if (event instanceof RequestEnd) { + // be very careful with pooled threads, ensuring threadlocals are cleaned up + eventContext.clearIdentifiers(); + } + super.publish(event); + } + + public Context 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 { + 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; + } + Context 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); + } + + public Map getScopeContexts() { + initializeScopes(); + return immutableScopeContexts; + } + + /** + * Blocks until the module context has been initialized + */ + protected void checkInit() { + if (lifecycleState == STOPPED) { + throw new IllegalStateException("Context cannot be restarted - create a new one"); + } + 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.getScopeContexts(eventContext); + immutableScopeContexts = Collections.unmodifiableMap(scopeContexts); + } + } + + /** + * Iterates through references and delegates to the configuration context to wire them to their targets + */ + protected void wireSource(ContextFactory source) { + Scope sourceScope = source.getScope(); + if (source.getSourceWireFactories() != null) { + for (SourceWireFactory sourceFactory : source.getSourceWireFactories()) { + WireConfiguration wireConfiguration = sourceFactory.getConfiguration(); + QualifiedName targetName = wireConfiguration.getTargetName(); + ContextFactory 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 + TargetWireFactory targetFactory = target.getTargetWireFactory(targetName.getPortName()); + if (targetFactory == null) { + ContextInitException e = new ContextInitException("No proxy factory found for service"); + e.setIdentifier(wireConfiguration.getTargetName().getPortName()); + e.addContextName(target.getName()); + e.addContextName(source.getName()); + e.addContextName(name); + throw e; + } + try { + boolean downScope = scopeStrategy.downScopeReference(sourceScope, target.getScope()); + configurationContext.connect(sourceFactory, targetFactory, target.getClass(), downScope, scopeContexts + .get(target.getScope())); + } catch (BuilderConfigException e) { + e.addContextName(target.getName()); + e.addContextName(source.getName()); + e.addContextName(name); + throw e; + } + + } + } + // wire invokers when the proxy only contains the target chain + if (source.getTargetWireFactories() != null) { + for (TargetWireFactory targetFactory : source.getTargetWireFactories().values()) { + try { + configurationContext.completeTargetChain(targetFactory, source.getClass(), scopeContexts.get(sourceScope)); + } catch (BuilderConfigException e) { + e.addContextName(source.getName()); + e.addContextName(name); + throw e; + } + } + } + } + + /** + * Signals to target side of reference configurations to initialize + */ + protected void buildTarget(ContextFactory target) { + Map targetProxyFactories = target.getTargetWireFactories(); + if (targetProxyFactories != null) { + for (TargetWireFactory targetFactory : targetProxyFactories.values()) { + for (InvocationConfiguration iConfig : targetFactory + .getConfiguration().getInvocationConfigurations().values()) { + iConfig.build(); + } + } + } + } + + protected void initializeWireFactories() throws WireFactoryInitException { + for (ContextFactory config : configurations.values()) { + List sourceProxyFactories = config.getSourceWireFactories(); + if (sourceProxyFactories != null) { + for (WireFactory sourceWireFactory : sourceProxyFactories) { + sourceWireFactory.initialize(); + } + } + if (sourceProxyFactories != null) { + Map targetWireFactories = config.getTargetWireFactories(); + for (TargetWireFactory targetWireFactory : targetWireFactories.values()) { + targetWireFactory.initialize(); + } + } + } + } + + public Composite getComposite() { + return module; + } + + @Autowire + public void setAutowireContext(AutowireContext context) { + autowireContext = context; + } + + public T resolveInstance(Class instanceInterface) throws AutowireResolutionException { + if (ConfigurationContext.class.equals(instanceInterface)) { + return instanceInterface.cast(this); + } else if (AutowireContext.class.equals(instanceInterface)) { + return instanceInterface.cast(this); + } else if (AssemblyContext.class.equals(instanceInterface)) { + return instanceInterface.cast(assemblyContext); + } + + NameToScope nts = autowireInternal.get(instanceInterface); + if (nts != null) { + try { + return instanceInterface.cast(nts.getScopeContext().getInstance(nts.getName())); + } catch (TargetException e) { + AutowireResolutionException ae = new AutowireResolutionException("Autowire instance not found", e); + ae.addContextName(getName()); + throw ae; + } + } else if (autowireContext != null) { + try { + // resolve to parent + return autowireContext.resolveInstance(instanceInterface); + } catch (AutowireResolutionException e) { + e.addContextName(getName()); + throw e; + } + } else { + return null; + } + } + + public T resolveExternalInstance(Class instanceInterface) throws AutowireResolutionException { + NameToScope nts = autowireExternal.get(instanceInterface); + if (nts != null) { + try { + return instanceInterface.cast(nts.getScopeContext().getInstance(nts.getName())); + } catch (TargetException e) { + AutowireResolutionException ae = new AutowireResolutionException("Autowire instance not found", e); + ae.addContextName(getName()); + throw ae; + } + } else { + return null; + } + } + + private void registerAutowire(ExternalService service) { + } + + private void registerAutowire(ModuleComponent component) { + for (EntryPoint ep : component.getImplementation().getEntryPoints()) { + for (Binding binding : ep.getBindings()) { + if (binding instanceof SystemBinding) { + Class interfaze = ep.getConfiguredService().getPort().getServiceContract().getInterface(); + ScopeContext scope = scopeContexts.get(Scope.AGGREGATE); + String qname = component.getName() + QualifiedName.NAME_SEPARATOR + ep.getName(); + registerAutowireInternal(interfaze, qname, scope); + } + } + } + } + + private void registerAutowire(Component component) { + for (Service service : component.getImplementation().getComponentType().getServices()) { + Class interfaze = service.getServiceContract().getInterface(); + ScopeContext scopeCtx = scopeContexts.get(service.getServiceContract().getScope()); + registerAutowireInternal(interfaze, component.getName(), scopeCtx); + } + } + + protected void registerAutowireInternal(Class interfaze, String name, ScopeContext scopeContext) { + assert interfaze != null; + if (autowireInternal.containsKey(interfaze)) { + return; + } + QualifiedName qname = new QualifiedName(name); + NameToScope nts = new NameToScope(qname, scopeContext); + autowireInternal.put(interfaze, nts); + } + + private void registerAutowire(EntryPoint ep) { + for (Binding binding : ep.getBindings()) { + if (binding instanceof SystemBinding) { + Class interfaze = ep.getConfiguredService().getPort().getServiceContract().getInterface(); + ScopeContext scope = scopeContexts.get(((ContextFactory) ep.getContextFactory()).getScope()); + registerAutowireExternal(interfaze, ep.getName(), scope); + } + } + } + + protected void registerAutowireExternal(Class interfaze, String name, ScopeContext scopeContext) { + assert interfaze != null; + if (autowireExternal.containsKey(interfaze)) { + return; + } + QualifiedName qname = new QualifiedName(name); + NameToScope nts = new NameToScope(qname, scopeContext); + autowireExternal.put(interfaze, nts); + } + + protected static class NameToScope { + + private final QualifiedName qName; + + private final ScopeContext scope; + + public NameToScope(QualifiedName name, ScopeContext scope) { + this.qName = name; + this.scope = scope; + } + + public QualifiedName getName() { + return qName; + } + + public ScopeContext getScopeContext() { + return scope; + } + } + + + public void build(AssemblyObject model) throws BuilderConfigException { + if (configurationContext != null) { + try { + configurationContext.build(model); + } catch (BuilderConfigException e) { + e.addContextName(getName()); + throw e; + } + } + } + + public void connect(SourceWireFactory sourceFactory, TargetWireFactory targetFactory, Class targetType, boolean downScope, + ScopeContext targetScopeContext) throws BuilderConfigException { + if (configurationContext != null) { + try { + configurationContext.connect(sourceFactory, targetFactory, targetType, downScope, targetScopeContext); + } catch (BuilderConfigException e) { + e.addContextName(getName()); + throw e; + } + } + } + + public void completeTargetChain(TargetWireFactory targetFactory, Class targetType, ScopeContext targetScopeContext) + throws BuilderConfigException { + if (configurationContext != null) { + try { + configurationContext.completeTargetChain(targetFactory, targetType, targetScopeContext); + } catch (BuilderConfigException e) { + e.addContextName(getName()); + throw e; + } + } + } + + + public void removeContext(String name){ + configurations.remove(name); + ScopeContext ctx = scopeIndex.remove(name); + if (ctx != null){ + ctx.removeContext(name); + } + + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractContext.java new file mode 100644 index 0000000000..680267d53e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractContext.java @@ -0,0 +1,45 @@ +/** + * + * 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.context.Context; +import org.apache.tuscany.core.context.RuntimeEventListener; +import org.apache.tuscany.core.context.EventFilter; +import org.apache.tuscany.core.context.event.Event; +import org.apache.tuscany.core.context.filter.TrueFilter; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Functionality common to all Context implementations + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractContext extends AbstractLifecycle implements Context { + + public AbstractContext() { + } + + public AbstractContext(String name) { + super(name); + } + + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractLifecycle.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractLifecycle.java new file mode 100644 index 0000000000..ddeebe361f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/AbstractLifecycle.java @@ -0,0 +1,129 @@ +/** + * + * Copyright 2006 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.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.tuscany.core.context.RuntimeEventListener; +import org.apache.tuscany.core.context.EventFilter; +import org.apache.tuscany.core.context.Lifecycle; +import org.apache.tuscany.core.context.filter.TrueFilter; +import org.apache.tuscany.core.context.event.Event; + +/** + * @version $Rev$ $Date$ + */ +public class AbstractLifecycle { + private static final EventFilter TRUE_FILTER = new TrueFilter(); + protected String name; + protected int lifecycleState = Lifecycle.UNINITIALIZED; + // Listeners for context events + private Map> listeners; + + public AbstractLifecycle(String name) { + this.name = name; + } + + public AbstractLifecycle() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getLifecycleState() { + return lifecycleState; + } + + public void addListener(RuntimeEventListener listener) { + addListener(TRUE_FILTER, listener); + } + + public void removeListener(RuntimeEventListener listener) { + assert (listener != null) : "Listener cannot be null"; + synchronized(getListeners()){ + for (List currentList :getListeners().values() ) { + for(RuntimeEventListener current : currentList){ + if (current == listener){ + currentList.remove(current); + return; + } + } + } + } + } + + public void addListener(EventFilter filter, RuntimeEventListener listener){ + assert (listener != null) : "Listener cannot be null"; + synchronized (getListeners()){ + List list = getListeners().get(filter); + if (list == null){ + list = new CopyOnWriteArrayList(); + listeners.put(filter,list); + } + list.add(listener); + } + } + + public void publish(Event event){ + assert(event != null): "Event object was null"; + for(Map.Entry> entry :getListeners().entrySet()){ + if(entry.getKey().match(event)){ + for(RuntimeEventListener listener : entry.getValue()){ + listener.onEvent(event); + } + } + } + } + + protected Map> getListeners(){ + if (listeners == null) { + listeners = new ConcurrentHashMap>(); + } + return listeners; + } + + public String toString() { + switch (lifecycleState) { + case (Lifecycle.CONFIG_ERROR): + return "Context [" + name + "] in state [CONFIG_ERROR]"; + case (Lifecycle.ERROR): + return "Context [" + name + "] in state [ERROR]"; + case (Lifecycle.INITIALIZING): + return "Context [" + name + "] in state [INITIALIZING]"; + case (Lifecycle.INITIALIZED): + return "Context [" + name + "] in state [INITIALIZED]"; + case (Lifecycle.RUNNING): + return "Context [" + name + "] in state [RUNNING]"; + case (Lifecycle.STOPPING): + return "Context [" + name + "] in state [STOPPING]"; + case (Lifecycle.STOPPED): + return "Context [" + name + "] in state [STOPPED]"; + case (Lifecycle.UNINITIALIZED): + return "Context [" + name + "] in state [UNINITIALIZED]"; + default: + return "Context [" + name + "] in state [UNKNOWN]"; + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/CompositeContextImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/CompositeContextImpl.java new file mode 100644 index 0000000000..4a1e115b42 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/CompositeContextImpl.java @@ -0,0 +1,117 @@ +/** + * + * 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.osoa.sca.ModuleContext; +import org.osoa.sca.RequestContext; +import org.osoa.sca.ServiceReference; +import org.osoa.sca.ServiceUnavailableException; + +import org.apache.tuscany.core.context.AutowireContext; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.ConfigurationContext; +import org.apache.tuscany.core.context.Context; +import org.apache.tuscany.core.context.EventContext; +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.system.annotation.Autowire; + +/** + * The standard implementation of an composite context. Autowiring is performed by delegating to the parent context. + * + * @version $Rev$ $Date$ + */ +public class CompositeContextImpl extends AbstractCompositeContext implements ModuleContext, org.osoa.sca.CompositeContext { + + @Autowire + public void setScopeStrategy(ScopeStrategy scopeStrategy) { + if (scopeStrategy != null) { + this.scopeStrategy = scopeStrategy; + } + } + + public CompositeContextImpl() { + super(); + eventContext = new EventContextImpl(); + } + + public CompositeContextImpl(String name, CompositeContext parent, ScopeStrategy strategy, EventContext ctx, + ConfigurationContext configCtx) { + super(name, parent, strategy, ctx, configCtx); + } + + public CompositeContextImpl(String name, CompositeContext parent, AutowireContext autowireContext, ScopeStrategy strategy, + EventContext ctx, ConfigurationContext configCtx) { + super(name, parent, strategy, ctx, configCtx); + setAutowireContext(autowireContext); + } + + // ---------------------------------- + // ModuleContext methods + // ---------------------------------- + + 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); + } + Context ctx = scope.getContext(qName.getPartName()); + try { + Object o = ctx.getInstance(qName); + if (o == null) { + throw new ServiceNotFoundException(qualifiedName); + } + return o; + } catch (TargetException e) { + e.addContextName(getName()); + throw new ServiceNotFoundException(e); + } + } + + public T locateService(Class serviceInterface, String serviceName) { + return (T)locateService(serviceName); + } + + 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(); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EntryPointContextImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EntryPointContextImpl.java new file mode 100644 index 0000000000..d1ad7a5548 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EntryPointContextImpl.java @@ -0,0 +1,90 @@ +/** + * + * 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.context.QualifiedName; +import org.apache.tuscany.core.context.TargetException; +import org.apache.tuscany.core.context.EntryPointContext; +import org.apache.tuscany.core.context.ContextInitException; +import org.apache.tuscany.core.context.CoreRuntimeException; +import org.apache.tuscany.core.wire.jdk.JDKInvocationHandler; +import org.apache.tuscany.core.wire.ProxyCreationException; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.message.MessageFactory; + +import java.lang.reflect.InvocationHandler; + +/** + * The default implementation of an entry point context + * + * @version $Rev$ $Date$ + */ +public class EntryPointContextImpl extends AbstractContext implements EntryPointContext { + + private SourceWireFactory sourceWireFactory; + + + private InvocationHandler invocationHandler; + + // a proxy implementing the service exposed by the entry point backed by the invocation handler + private Object proxy; + + /** + * Creates a new entry point + * + * @param name the entry point name + * @param sourceWireFactory the proxy factory containing the invocation chains for 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, SourceWireFactory sourceWireFactory, MessageFactory messageFactory) + throws ContextInitException { + super(name); + assert (sourceWireFactory != null) : "Proxy factory was null"; + assert (messageFactory != null) : "Message factory was null"; + this.sourceWireFactory = sourceWireFactory; + invocationHandler = new JDKInvocationHandler(messageFactory, sourceWireFactory.getConfiguration() + .getInvocationConfigurations()); + } + + public Object getInstance(QualifiedName qName) throws TargetException { + if (proxy == null) { + try { + proxy = sourceWireFactory.createProxy(); + } catch (ProxyCreationException e) { + TargetException te = new TargetException(e); + te.addContextName(getName()); + throw te; + } + } + return proxy; + } + + public void start() throws ContextInitException { + lifecycleState = RUNNING; + } + + public void stop() throws CoreRuntimeException { + lifecycleState = STOPPED; + } + + public Object getHandler() throws TargetException { + return invocationHandler; + } + + public Class getServiceInterface() { + return sourceWireFactory.getBusinessInterface(); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EventContextImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EventContextImpl.java new file mode 100644 index 0000000000..6888e66f20 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/EventContextImpl.java @@ -0,0 +1,81 @@ +/** + * + * 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.context.EventContext; +import org.apache.tuscany.core.context.ScopeIdentifier; + +import java.util.HashMap; +import java.util.Map; + +/** + * An implementation of an {@link org.apache.tuscany.core.context.EventContext} that handles event-to-thread associations using an + * InheritableThreadLocal + * + * @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 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 void clearIdentifiers() { + eventContext.remove(); + } + + public EventContextImpl() { + super(); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/ExternalServiceContextImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/ExternalServiceContextImpl.java new file mode 100644 index 0000000000..0ab44fa8fc --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/impl/ExternalServiceContextImpl.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.impl; + +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.core.context.TargetException; +import org.apache.tuscany.core.context.CoreRuntimeException; +import org.apache.tuscany.core.context.ExternalServiceContext; +import org.apache.tuscany.core.wire.ProxyCreationException; +import org.apache.tuscany.core.wire.TargetWireFactory; + +/** + * The default implementation of an external service context + * + * @version $Rev$ $Date$ + */ +public class ExternalServiceContextImpl extends AbstractContext implements ExternalServiceContext { + + private TargetWireFactory targetWireFactory; + + private ObjectFactory targetInstanceFactory; + + /** + * Creates an external service context + * + * @param name the name of the external service + * @param targetWireFactory 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, TargetWireFactory targetWireFactory, ObjectFactory targetInstanceFactory) { + super(name); + assert (targetInstanceFactory != null) : "Target instance factory was null"; + this.targetWireFactory = targetWireFactory; + this.targetInstanceFactory = targetInstanceFactory; + } + + public void start() throws CoreRuntimeException { + lifecycleState = RUNNING; + } + + public void stop() throws CoreRuntimeException { + lifecycleState = STOPPED; + } + + + public Object getInstance(QualifiedName qName) throws TargetException { + try { + return targetWireFactory.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 getHandler() throws TargetException { + return targetInstanceFactory.getInstance(); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java new file mode 100644 index 0000000000..7eed472101 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.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.context.scope; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.tuscany.core.builder.ContextFactory; +import org.apache.tuscany.core.context.Context; +import org.apache.tuscany.core.context.EventContext; +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.core.context.ScopeContext; +import org.apache.tuscany.core.context.TargetException; +import org.apache.tuscany.core.context.impl.AbstractLifecycle; + +/** + * Implements functionality common to scope contexts. + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractScopeContext extends AbstractLifecycle implements ScopeContext { + + // The collection of runtime configurations for the scope + protected Map> contextFactories = new ConcurrentHashMap>(); + + // The event context the scope container is associated with + protected EventContext eventContext; + + public AbstractScopeContext(EventContext eventContext) { + assert (eventContext != null) : "Event context was null"; + this.eventContext = eventContext; + } + + public void registerFactories(List> configurations) { + for (ContextFactory configuration : configurations) { + contextFactories.put(configuration.getName(), configuration); + } + } + + public Object getInstance(QualifiedName qName) throws TargetException { + Context context = getContext(qName.getPartName()); + if (context == null) { + TargetException e = new TargetException("Target not found"); + e.setIdentifier(qName.getQualifiedName()); + throw e; + } + return context.getInstance(qName); + } + + protected void checkInit() { + if (getLifecycleState() != RUNNING) { + throw new IllegalStateException("Scope not running [" + getLifecycleState() + "]"); + } + } + + protected EventContext getEventContext() { + return eventContext; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeStrategy.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeStrategy.java new file mode 100644 index 0000000000..f89d09196d --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/CompositeScopeContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/CompositeScopeContext.java new file mode 100644 index 0000000000..7468ff9dd6 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/CompositeScopeContext.java @@ -0,0 +1,156 @@ +/** + * + * 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.ContextFactory; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.Context; +import org.apache.tuscany.core.context.EventContext; +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; +import org.apache.tuscany.core.context.event.Event; +import org.apache.tuscany.core.context.event.ModuleStart; +import org.apache.tuscany.core.context.event.ModuleStop; +import org.apache.tuscany.core.context.impl.AbstractLifecycle; + +/** + * Manages the lifecycle of composite component contexts, i.e. contexts which contain child contexts + * + * @see org.apache.tuscany.core.context.CompositeContext + * @version $Rev$ $Date$ + */ +public class CompositeScopeContext extends AbstractLifecycle implements ScopeContext { + + private List> configs = new ArrayList>(); + + // Composite component contexts in this scope keyed by name + private Map contexts = new ConcurrentHashMap(); + + // indicates if a module start event has been previously propagated so child contexts added after can be notified + private boolean moduleScopeStarted; + + public CompositeScopeContext(EventContext eventContext) { + assert (eventContext != null) : "Event context was null"; + setName("Composite Scope"); + } + + public void start() throws ScopeInitializationException { + for (ContextFactory configuration : configs) { + Context context = configuration.createContext(); + if (!(context instanceof CompositeContext)) { + ScopeInitializationException e = new ScopeInitializationException("Context not an composite type"); + e.addContextName(context.getName()); + throw e; + } + CompositeContext compositeCtx = (CompositeContext) context; + compositeCtx.start(); + contexts.put(compositeCtx.getName(), compositeCtx); + } + lifecycleState = RUNNING; + } + + public void stop() throws ScopeRuntimeException { + for (CompositeContext context : contexts.values()) { + context.stop(); + } + } + + public void registerFactories(List> configurations) { + this.configs = configurations; + } + + public void registerFactory(ContextFactory configuration) { + assert (configuration != null) : "Configuration was null"; + configs.add(configuration); + if (getLifecycleState() == RUNNING) { + Context context = configuration.createContext(); + if (!(context instanceof CompositeContext)) { + ScopeInitializationException e = new ScopeInitializationException("Context not an composite type"); + e.setIdentifier(context.getName()); + throw e; + } + CompositeContext compositeCtx = (CompositeContext) context; + compositeCtx.start(); + if (moduleScopeStarted) { + compositeCtx.publish(new ModuleStart(this)); + } + contexts.put(compositeCtx.getName(), compositeCtx); + } + } + + public boolean isCacheable() { + return false; + } + + public Object getInstance(QualifiedName qName) throws TargetException { + Context 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 Context getContext(String ctxName) { + checkInit(); + return contexts.get(ctxName); + } + + public Context getContextByKey(String ctxName, Object key) { + return getContext(ctxName); + } + + public void removeContext(String ctxName) throws ScopeRuntimeException { + Context context = contexts.remove(ctxName); + if (context != null) { + context.stop(); + } + } + + public void removeContextByKey(String ctxName, Object key) throws ScopeRuntimeException { + throw new UnsupportedOperationException(); + } + + public void onEvent(Event event){ + if (event instanceof ModuleStart) { + // track module starting so that composite contexts registered after the event are notified properly + moduleScopeStarted = true; + } else if (event instanceof ModuleStop) { + moduleScopeStarted = false; + publish(event); + } + // propagate events to child contexts + for (CompositeContext context : contexts.values()) { + context.publish(event); + } + } + + private void checkInit() { + if (getLifecycleState()!= RUNNING) { + throw new IllegalStateException("Scope not running [" + getLifecycleState() + "]"); + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/DefaultScopeStrategy.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/DefaultScopeStrategy.java new file mode 100644 index 0000000000..1f386fd35f --- /dev/null +++ b/branches/java-post-M1/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 org.apache.tuscany.core.context.EventContext; +import org.apache.tuscany.core.context.ScopeContext; +import org.apache.tuscany.model.assembly.Scope; + +import java.util.HashMap; +import java.util.Map; + +/** + * 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 getScopeContexts(EventContext eventContext) { + ScopeContext moduleScope = new ModuleScopeContext(eventContext); + ScopeContext sessionScope = new SessionScopeContext(eventContext); + ScopeContext requestScope = new RequestScopeContext(eventContext); + ScopeContext statelessScope = new StatelessScopeContext(eventContext); + ScopeContext aggregrateScope = new CompositeScopeContext(eventContext); + Map 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java new file mode 100644 index 0000000000..dbb342bb5a --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java @@ -0,0 +1,194 @@ +/** + * + * 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.builder.ContextFactory; +import org.apache.tuscany.core.context.AtomicContext; +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.TargetException; +import org.apache.tuscany.core.context.Lifecycle; +import org.apache.tuscany.core.context.event.InstanceCreated; +import org.apache.tuscany.core.context.event.Event; +import org.apache.tuscany.core.context.event.ModuleStart; +import org.apache.tuscany.core.context.event.ModuleStop; + +import java.util.Map; +import java.util.List; +import java.util.ArrayList; +import java.util.ListIterator; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Manages contexts whose implementations are module scoped. This scope contexts eagerly starts contexts when + * a {@link ModuleStart} event is received. If a contained context has an implementation marked to eagerly initialized, + * the an instance will be created at that time as well. Contained contexts are shutdown when a {@link ModuleStop} + * event is received in reverse order to which their implementation instances were created. + * + * @version $Rev$ $Date$ + */ +public class ModuleScopeContext extends AbstractScopeContext { + + // Component contexts in this scope keyed by name + private Map contexts; + + // the queue of contexts to destroy, in the order that their instances were created + private List destroyQueue; + + public ModuleScopeContext(EventContext eventContext) { + super(eventContext); + setName("Module Scope"); + } + + public void onEvent(Event event) { + if (event instanceof ModuleStart) { + lifecycleState = RUNNING; + initComponentContexts(); + } else if (event instanceof ModuleStop) { + shutdownContexts(); + } else if (event instanceof InstanceCreated) { + checkInit(); + if (event.getSource() instanceof Context) { + Context context = (Context) event.getSource(); + // Queue the context to have its implementation instance released if destroyable + destroyQueue.add(context); + } + } + } + + 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 + "]"); + } + contexts = null; + destroyQueue = null; + lifecycleState = STOPPED; + } + + public boolean isCacheable() { + return true; + } + + public void registerFactory(ContextFactory configuration) { + contextFactories.put(configuration.getName(), configuration); + if (lifecycleState == RUNNING) { + contexts.put(configuration.getName(), configuration.createContext()); + } + } + + public Context getContext(String ctxName) { + checkInit(); + initComponentContexts(); + return contexts.get(ctxName); + } + + public Context getContextByKey(String ctxName, Object key) { + checkInit(); + initComponentContexts(); + return contexts.get(ctxName); + } + + public void removeContext(String ctxName) { + checkInit(); + if (contexts == null){ + return; + } + Context context = contexts.remove(ctxName); + if (context != null) { + destroyQueue.remove(context); + } + } + + public void removeContextByKey(String ctxName, Object key){ + removeContext(ctxName); + } + + /** + * Notifies contexts of a shutdown in reverse order to which they were started + */ + private synchronized void shutdownContexts() { + if (destroyQueue == null || destroyQueue.size() == 0) { + return; + } + // shutdown destroyable instances in reverse instantiation order + ListIterator iter = destroyQueue.listIterator(destroyQueue.size()); + while(iter.hasPrevious()){ + Lifecycle context = iter.previous(); + if (context.getLifecycleState() == RUNNING) { + try { + if (context instanceof AtomicContext){ + ((AtomicContext)context).destroy(); + } + } catch (TargetException e) { + // TODO send a monitoring event + } + } + } + if (contexts == null){ + return; + } + for(Lifecycle context: contexts.values()) { + try { + if (context.getLifecycleState() == RUNNING) { + context.stop(); + } + } catch (CoreRuntimeException e){ + // TODO send monitoring event + } + } + contexts = null; + destroyQueue = null; + } + + /** + * Creates and starts components contexts in the module scope. Implementations marked to eagerly initialize will + * also be notified to do so. + * + * @throws CoreRuntimeException + */ + private synchronized void initComponentContexts() throws CoreRuntimeException { + if (contexts == null) { + contexts = new ConcurrentHashMap(); + destroyQueue = new ArrayList(); + for (ContextFactory config : contextFactories.values()) { + Context context = config.createContext(); + context.start(); + contexts.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 (Context context : contexts.values()) { + if (context instanceof AtomicContext) { + AtomicContext atomic = (AtomicContext) context; + if (atomic.isEagerInit()) { + // perform silent creation and manual shutdown registration + atomic.init(); + destroyQueue.add(context); + } + } + context.addListener(this); + } + } + } +} \ No newline at end of file diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java new file mode 100644 index 0000000000..67ce176af5 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java @@ -0,0 +1,228 @@ +/** + * + * 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.builder.ContextFactory; +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.AtomicContext; +import org.apache.tuscany.core.context.TargetException; +import org.apache.tuscany.core.context.Lifecycle; +import org.apache.tuscany.core.context.event.InstanceCreated; +import org.apache.tuscany.core.context.event.Event; +import org.apache.tuscany.core.context.event.RequestEnd; +import org.apache.tuscany.core.context.event.RequestStart; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.ListIterator; +import java.util.concurrent.ConcurrentHashMap; + +/** + * An implementation of a request-scoped component container. This scope contexts eagerly starts contexts when + * a {@link org.apache.tuscany.core.context.event.RequestStart} event is received. If a contained context has an implementation marked to eagerly initialized, + * the an instance will be created at that time as well. Contained contexts are shutdown when a {@link org.apache.tuscany.core.context.event.RequestEnd} + * event is received in reverse order to which their implementation instances were created. + * + * @version $Rev$ $Date$ + */ +public class RequestScopeContext extends AbstractScopeContext { + + // 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> contexts; + + // stores ordered lists of contexts to shutdown for each thread. + private Map> destroyQueues; + + public RequestScopeContext(EventContext eventContext) { + super(eventContext); + setName("Request Scope"); + } + + public void onEvent(Event event){ + if (event instanceof RequestStart){ + getContexts(); // eager load + }else if (event instanceof RequestEnd){ + checkInit(); + getEventContext().clearIdentifiers(); // clean up current context for pooled threads + shutdownContexts(); + cleanupRequestContexts(); + }else if (event instanceof InstanceCreated){ + checkInit(); + assert(event.getSource() instanceof Context): "Context must be passed on created event"; + Context context = (Context)event.getSource(); + List collection = destroyQueues.get(Thread.currentThread()); + collection.add(context); + } + } + + public synchronized void start() { + if (lifecycleState != UNINITIALIZED) { + throw new IllegalStateException("Scope must be in UNINITIALIZED state [" + lifecycleState + "]"); + } + contexts = new ConcurrentHashMap>(); + destroyQueues = new ConcurrentHashMap>(); + lifecycleState = RUNNING; + } + + public synchronized void stop() { + if (lifecycleState != RUNNING) { + throw new IllegalStateException("Scope in wrong state [" + lifecycleState + "]"); + } + contexts = null; + destroyQueues = null; + lifecycleState = STOPPED; + } + + public boolean isCacheable() { + return true; + } + + public void registerFactory(ContextFactory configuration) { + contextFactories.put(configuration.getName(), configuration); + } + + public Context getContext(String ctxName) { + checkInit(); + Map contexts = getContexts(); + Context ctx = contexts.get(ctxName); + if (ctx == null){ + // check to see if the configuration was added after the request was started + ContextFactory configuration = contextFactories.get(ctxName); + if (configuration != null) { + ctx = configuration.createContext(); + //ctx.addListener(this); + ctx.start(); + contexts.put(ctx.getName(), ctx); + } + } + return ctx; + } + + public Context getContextByKey(String ctxName, Object key) { + checkInit(); + if (key == null) { + return null; + } + Map components = contexts.get(key); + if (components == null) { + return null; + } + return components.get(ctxName); + } + + public void removeContext(String ctxName) { + removeContextByKey(ctxName, Thread.currentThread()); + } + + public void removeContextByKey(String ctxName, Object key) { + checkInit(); + if (key == null || ctxName == null) { + return; + } + Map components = contexts.get(key); + if (components == null) { + return; + } + components.remove(ctxName); + } + + + + private void cleanupRequestContexts() { + // TODO uninitialize all request-scoped components + contexts.remove(Thread.currentThread()); + destroyQueues.remove(Thread.currentThread()); + } + + /** + * Initializes ServiceComponentContexts for the current request. + *

+ * 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 + *

+ * TODO Eager initialization is not performed for request-scoped components + */ + + private Map getContexts() throws CoreRuntimeException { + Map requestContexts = this.contexts.get(Thread.currentThread()); + if (requestContexts == null) { + requestContexts = new ConcurrentHashMap(); + List shutdownQueue = new ArrayList(); + for (ContextFactory config : contextFactories.values()) { + Context context = config.createContext(); + context.start(); + requestContexts.put(context.getName(), context); + } + // 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 (Context context : requestContexts.values()) { + if (context instanceof AtomicContext) { + AtomicContext atomic = (AtomicContext) context; + if (atomic.isEagerInit()) { + atomic.init(); // Notify the instance + synchronized(shutdownQueue){ + shutdownQueue.add(context); + } + } + } + context.addListener(this); + } + contexts.put(Thread.currentThread(), requestContexts); + destroyQueues.put(Thread.currentThread(), shutdownQueue); + } + return requestContexts; + } + + private void shutdownContexts() { + List destroyQueue = destroyQueues.remove(Thread.currentThread()); + if (destroyQueue == null || destroyQueue.size() == 0) { + return; + } + synchronized(destroyQueue){ + // shutdown destroyable instances in reverse instantiation order + ListIterator iter = destroyQueue.listIterator(destroyQueue.size()); + while(iter.hasPrevious()){ + Lifecycle context = iter.previous(); + if (context.getLifecycleState() == RUNNING) { + try { + if (context instanceof AtomicContext){ + ((AtomicContext)context).destroy(); + } + } catch (TargetException e) { + // TODO send a monitoring event + } + } + } + } + // shutdown contexts + Map currentContexts = contexts.remove(Thread.currentThread()); + if (currentContexts == null){ + return; + } + for (Lifecycle context: currentContexts.values()){ + if (context.getLifecycleState() == RUNNING) { + context.stop(); + } + } + + } + +} \ No newline at end of file diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/SessionScopeContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/SessionScopeContext.java new file mode 100644 index 0000000000..c5785d25f7 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/SessionScopeContext.java @@ -0,0 +1,258 @@ +/** + * + * 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.builder.ContextFactory; +import org.apache.tuscany.core.context.AtomicContext; +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.ScopeRuntimeException; +import org.apache.tuscany.core.context.TargetException; +import org.apache.tuscany.core.context.Lifecycle; +import org.apache.tuscany.core.context.event.Event; +import org.apache.tuscany.core.context.event.HttpSessionEvent; +import org.apache.tuscany.core.context.event.InstanceCreated; +import org.apache.tuscany.core.context.event.SessionEnd; +import org.apache.tuscany.core.context.event.SessionStart; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * An implementation of an session-scoped component container. This scope contexts eagerly starts contexts when a + * {@link org.apache.tuscany.core.context.event.SessionStart} event is received. If a contained context has an implementation + * marked to eagerly initialized, the an instance will be created at that time as well. Contained contexts are shutdown when a + * {@link org.apache.tuscany.core.context.event.SessionEnd} event is received in reverse order to which their implementation + * instances were created. + * TODO this implementation needs to be made generic so that it supports a range of session types, i.e. not tied to HTTP + * session scope + * + * @version $Rev$ $Date$ + */ +public class SessionScopeContext extends AbstractScopeContext { + + // The collection of service component contexts keyed by session + private Map> contexts; + + // Stores ordered lists of contexts to shutdown keyed by session + private Map> destroyQueues; + + public SessionScopeContext(EventContext eventContext) { + super(eventContext); + setName("Session Scope"); + } + + public synchronized void start() { + if (lifecycleState != UNINITIALIZED) { + throw new IllegalStateException("Scope container must be in UNINITIALIZED state"); + } + contexts = new ConcurrentHashMap>(); + destroyQueues = new ConcurrentHashMap>(); + lifecycleState = RUNNING; + } + + public synchronized void stop() { + if (lifecycleState != RUNNING) { + throw new IllegalStateException("Scope container in wrong state"); + } + contexts = null; + contexts = null; + destroyQueues = null; + lifecycleState = STOPPED; + } + + public void onEvent(Event event) { + if (event instanceof SessionStart) { + checkInit(); + Object key = ((SessionEnd) event).getId(); + getSessionContexts(key); + }else if (event instanceof SessionEnd) { + checkInit(); + Object key = ((SessionEnd) event).getId(); + shutdownContexts(key); + destroyComponentContext(key); + } else if (event instanceof InstanceCreated) { + checkInit(); + Object sessionKey = getEventContext().getIdentifier(HttpSessionEvent.HTTP_IDENTIFIER); + List shutdownQueue = destroyQueues.get(sessionKey); + Context context = (Context) event.getSource(); + assert(shutdownQueue != null): "Shutdown queue not found for key"; + shutdownQueue.add(context); + } + } + + public boolean isCacheable() { + return true; + } + + public void registerFactory(ContextFactory configuration) { + contextFactories.put(configuration.getName(), configuration); + } + + public Context getContext(String ctxName) { + assert(ctxName != null): "No context name specified"; + checkInit(); + Map ctxs = getSessionContexts(); + Context context = ctxs.get(ctxName); + if (context == null) { + // the configuration was added after the session had started, so create a context now and start it + ContextFactory configuration = contextFactories.get(ctxName); + if (configuration != null) { + context = configuration.createContext(); + context.start(); + if (context instanceof AtomicContext) { + ((AtomicContext) context).init(); + } + + ctxs.put(context.getName(), context); + List shutdownQueue = destroyQueues.get(getEventContext().getIdentifier(HttpSessionEvent.HTTP_IDENTIFIER)); + synchronized (shutdownQueue) { + shutdownQueue.add(context); + } + context.addListener(this); + } + } + return context; + } + + public Context getContextByKey(String ctxName, Object key) { + checkInit(); + assert(ctxName != null): "No context name specified"; + assert(key != null): "No key specified"; + Map ctxs = contexts.get(key); + if (ctxs == null) { + return null; + } + return (Context) ctxs.get(ctxName); + } + + public void removeContext(String ctxName) { + checkInit(); + Object key = getEventContext().getIdentifier(HttpSessionEvent.HTTP_IDENTIFIER); + removeContextByKey(ctxName, key); + } + + public void removeContextByKey(String ctxName, Object key) { + checkInit(); + assert(ctxName != null): "No context name specified"; + assert(key != null): "No key specified"; + Map components = contexts.get(key); + if (components == null) { + return; + } + components.remove(ctxName); + Map definitions = contexts.get(key); + Context ctx = definitions.get(ctxName); + if (ctx != null) { + destroyQueues.get(key).remove(ctx); + } + definitions.remove(ctxName); + } + + /** + * Returns and, if necessary, creates a context for the current sesion + */ + private Map getSessionContexts() throws CoreRuntimeException { + Object key = getEventContext().getIdentifier(HttpSessionEvent.HTTP_IDENTIFIER); + return getSessionContexts(key); + } + + /** + * Returns and, if necessary, creates a context for the given session key + */ + private Map getSessionContexts(Object key) throws CoreRuntimeException { + 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 sessionContext = new ConcurrentHashMap(contextFactories.size()); + for (ContextFactory config : contextFactories.values()) { + Context context = config.createContext(); + context.start(); + sessionContext.put(context.getName(), context); + } + + List shutdownQueue = new ArrayList(); + contexts.put(key, sessionContext); + destroyQueues.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 (Context context : sessionContext.values()) { + if (context instanceof AtomicContext) { + AtomicContext atomic = (AtomicContext) context; + if (atomic.isEagerInit()) { + atomic.init(); // Notify the instance + synchronized (shutdownQueue) { + shutdownQueue.add(context); + } + } + } + context.addListener(this); + } + return sessionContext; + } + + /** + * Removes the components associated with an expiring context + */ + private void destroyComponentContext(Object key) { + contexts.remove(key); + destroyQueues.remove(key); + } + + + private synchronized void shutdownContexts(Object key) { + List destroyQueue = destroyQueues.remove(key); + if (destroyQueue == null || destroyQueue.size() == 0) { + return; + } + // shutdown destroyable instances in reverse instantiation order + ListIterator iter = destroyQueue.listIterator(destroyQueue.size()); + synchronized (destroyQueue) { + while (iter.hasPrevious()) { + Lifecycle context = iter.previous(); + if (context.getLifecycleState() == RUNNING) { + try { + if (context instanceof AtomicContext) { + ((AtomicContext) context).destroy(); + } + } catch (TargetException e) { + // TODO send a monitoring event + } + } + } + } + // shutdown contexts + Map currentContexts = contexts.remove(Thread.currentThread()); + if (currentContexts == null) { + return; + } + for (Lifecycle context : currentContexts.values()) { + if (context.getLifecycleState() == RUNNING) { + context.stop(); + } + } + } + +} \ No newline at end of file diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java new file mode 100644 index 0000000000..46bf58b548 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java @@ -0,0 +1,132 @@ +/** + * + * 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.builder.ContextFactory; +import org.apache.tuscany.core.context.EventContext; +import org.apache.tuscany.core.context.Context; +import org.apache.tuscany.core.context.CoreRuntimeException; +import org.apache.tuscany.core.context.Lifecycle; +import org.apache.tuscany.core.context.event.Event; +import org.apache.tuscany.core.context.event.ModuleStop; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * A container that manages stateless components. + * + * @version $Rev$ $Date$ + */ +public class StatelessScopeContext extends AbstractScopeContext { + + // Component contexts keyed by name + private Map contexts; + + public StatelessScopeContext(EventContext eventContext) { + super(eventContext); + setName("Stateless Scope"); + } + + public synchronized void start() { + if (lifecycleState != UNINITIALIZED) { + throw new IllegalStateException("Scope must be in UNINITIALIZED state [" + lifecycleState + "]"); + } + lifecycleState = RUNNING; + } + + public synchronized void stop() { + if (lifecycleState != RUNNING) { + throw new IllegalStateException("Scope in wrong state [" + lifecycleState + "]"); + } + contexts = null; + lifecycleState = STOPPED; + } + + public void registerFactory(ContextFactory configuration) { + contextFactories.put(configuration.getName(), configuration); + if (contexts != null) { + contexts.put(configuration.getName(), configuration.createContext()); + } + } + + public void onEvent(Event event){ + if (event instanceof ModuleStop) { + shutdownContexts(); + } + } + + public boolean isCacheable() { + return true; + } + + public Context getContext(String ctxName) { + prepare(); + return contexts.get(ctxName); + } + + public Context getContextByKey(String ctxName, Object key) { + return getContext(ctxName); + } + + public void removeContext(String ctxName) { + if (contexts == null){ + return; + } + contexts.remove(ctxName); + } + + public void removeContextByKey(String ctxName, Object key) { + removeContext(ctxName); + } + + private void prepare() throws CoreRuntimeException { + if (lifecycleState != RUNNING) { + throw new IllegalStateException("Scope not in INITIALIZED state [" + lifecycleState + "]"); + } + if (contexts == null) { + contexts = new ConcurrentHashMap (); + for (ContextFactory config : contextFactories.values()) { + for (int i = 0; i < contextFactories.size(); i++) { + Context context = config.createContext(); + context.start(); + contexts.put(context.getName(), context); + } + + } + } + } + + private void shutdownContexts(){ + if (contexts == null){ + return; + } + for(Lifecycle context: contexts.values()) { + try { + if (context.getLifecycleState() == RUNNING) { + context.stop(); + } + } catch (CoreRuntimeException e){ + // TODO send monitoring event + } + + } + contexts = null; + } + + +} \ No newline at end of file diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ComponentTargetInvoker.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ComponentTargetInvoker.java new file mode 100644 index 0000000000..57fcffc2b2 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ComponentTargetInvoker.java @@ -0,0 +1,122 @@ +/** + * + * 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.extension; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.tuscany.core.context.AtomicContext; +import org.apache.tuscany.core.context.Context; +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.core.context.ScopeContext; +import org.apache.tuscany.core.context.TargetException; +import org.apache.tuscany.core.message.Message; +import org.apache.tuscany.core.wire.Interceptor; +import org.apache.tuscany.core.wire.TargetInvoker; + +/** + * Responsible for invoking an external service + * TODO: virtualy identical to ExternalServiceTargetInvoker + * @version $Rev$ $Date$ + */ +public class ComponentTargetInvoker implements TargetInvoker { + + private QualifiedName serviceName; + + private String esName; + + private Method method; + + private ScopeContext container; + + private AtomicContext context; + + /** + * Constructs a new ExternalWebServiceTargetInvoker. + * + * @param container + */ + public ComponentTargetInvoker(QualifiedName serviceName, Method method, ScopeContext container) { + assert serviceName != null : "No service name specified"; + assert method != null : "No method specified"; + assert container != null : "No scope container specified"; + this.serviceName = serviceName; + this.esName = serviceName.getPartName(); + this.method = method; + this.container = container; + } + + public Object invokeTarget(Object payload) throws InvocationTargetException { + if (context == null) { + Context iContext = container.getContext(esName); + if (!(iContext instanceof AtomicContext)) { + TargetException te = new TargetException("Unexpected target context type"); + te.setIdentifier(iContext.getClass().getName()); + te.addContextName(iContext.getName()); + throw te; + } + context = (AtomicContext) iContext; + } + + ExternalServiceInvoker invoker = (ExternalServiceInvoker) context.getTargetInstance(); + if (payload != null) { + return doInvoke(invoker, (Object[]) payload); + } else { + return doInvoke(invoker, null); + } + } + + protected Object doInvoke(ExternalServiceInvoker invoker, Object[] args) { + return invoker.invoke(method.getName(), args); + } + + public boolean isCacheable() { + return false; + } + + public Message invoke(Message msg) { + try { + Object resp = invokeTarget(msg.getBody()); + msg.setBody(resp); + } catch (InvocationTargetException e) { + msg.setBody(e.getCause()); + } catch (Throwable e) { + msg.setBody(e); + } + return msg; + } + + public void setNext(Interceptor next) { + throw new UnsupportedOperationException(); + } + + public Object clone() throws CloneNotSupportedException { + try { + ComponentTargetInvoker invoker = (ComponentTargetInvoker) super.clone(); + invoker.container = container; + invoker.context = this.context; + invoker.esName = this.esName; + invoker.method = this.method; + invoker.serviceName = this.serviceName; + return invoker; + } catch (CloneNotSupportedException e) { + // will not happen + return null; + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ContextFactoryBuilderSupport.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ContextFactoryBuilderSupport.java new file mode 100644 index 0000000000..81770d49b8 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ContextFactoryBuilderSupport.java @@ -0,0 +1,174 @@ +/** + * + * 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.extension; + +import org.apache.tuscany.core.builder.BuilderConfigException; +import org.apache.tuscany.core.builder.BuilderException; +import org.apache.tuscany.core.builder.ContextFactory; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.core.builder.ContextFactoryBuilderRegistry; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.core.wire.service.WireFactoryService; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Component; +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.Implementation; +import org.apache.tuscany.model.assembly.Multiplicity; +import org.apache.tuscany.model.assembly.Scope; +import org.apache.tuscany.model.assembly.Service; +import org.osoa.sca.annotations.Init; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.List; + +/** + * A runtime extension point for component types. Subclasses must be genericized according to the model implementation type they + * handle, i.e. a subclass of {@link Implementation}, and implement {@link #createContextFactory}. + * + * @version $Rev: 368822 $ $Date: 2006-01-13 10:54:38 -0800 (Fri, 13 Jan 2006) $ + * @see org.apache.tuscany.core.builder.ContextFactory + */ +@org.osoa.sca.annotations.Scope("MODULE") +public abstract class ContextFactoryBuilderSupport implements ContextFactoryBuilder { + + protected ContextFactoryBuilderRegistry builderRegistry; + + protected WireFactoryService wireFactoryService; + + protected Class implementationClass; + + /** + * Default constructor + */ + public ContextFactoryBuilderSupport() { + // reflect the generic type of the subclass + Type type = this.getClass().getGenericSuperclass(); + if (type instanceof ParameterizedType) { + implementationClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[0]; + } else { + throw new AssertionError("Subclasses of " + ContextFactoryBuilderSupport.class.getName() + " must be genericized"); + } + } + + /** + * Constructs a new instance + * + * @param wireFactoryService the system service responsible for creating wire factories + */ + public ContextFactoryBuilderSupport(WireFactoryService wireFactoryService) { + this(); + this.wireFactoryService = wireFactoryService; + } + + @Init(eager = true) + public void init() { + builderRegistry.register(this); + } + + @Autowire + public void setBuilderRegistry(ContextFactoryBuilderRegistry builderRegistry) { + this.builderRegistry = builderRegistry; + } + + /** + * Sets the system service used to construct wire factories + */ + @Autowire + public void setWireFactoryService(WireFactoryService wireFactoryService) { + this.wireFactoryService = wireFactoryService; + } + + public void build(AssemblyObject modelObject) throws BuilderException { + if (!(modelObject instanceof Component)) { + return; + } + Component nonGenricComponent = (Component) modelObject; + if (!implementationClass.isAssignableFrom(nonGenricComponent.getImplementation().getClass())) { + return; + } + Component component = (Component) modelObject; + List services = component.getImplementation().getComponentType().getServices(); + Scope previous = null; + Scope scope = Scope.INSTANCE; + for (Service service : services) { + // calculate and validate the scope of the component; ensure that all service scopes are the same unless stateless + Scope current = service.getServiceContract().getScope(); + if (previous != null && current != null && current != previous + && (current != Scope.INSTANCE && previous != Scope.INSTANCE)) { + BuilderException e = new BuilderConfigException("Incompatible scopes specified for services on component"); + e.setIdentifier(component.getName()); + throw e; + } + if (scope != null && current != Scope.INSTANCE) { + scope = current; + } + } + ContextFactory contextFactory; + try { + contextFactory = createContextFactory(component.getName(), component.getImplementation(), scope); + // create target-side wire invocation chains for each service offered by the implementation + for (ConfiguredService configuredService : component.getConfiguredServices()) { + Service service = configuredService.getPort(); + TargetWireFactory wireFactory = wireFactoryService.createTargetFactory(configuredService); + contextFactory.addTargetWireFactory(service.getName(), wireFactory); + } + // handle properties + List configuredProperties = component.getConfiguredProperties(); + if (configuredProperties != null) { + for (ConfiguredProperty property : configuredProperties) { + contextFactory.addProperty(property.getName(), property.getValue()); + } + } + // handle references and source side reference chains + List configuredReferences = component.getConfiguredReferences(); + if (configuredReferences != null) { + for (ConfiguredReference reference : configuredReferences) { + if (reference.getPort().getMultiplicity() == Multiplicity.ZERO_N || reference.getPort().getMultiplicity() == Multiplicity.ZERO_ONE){ + if (reference.getTargetConfiguredServices().size() < 1 && reference.getTargets().size() <1 ){ + continue; // not required, not configured fix TUSCANY-299 + } + } + List wireFactories = wireFactoryService.createSourceFactory(reference); + String refName = reference.getPort().getName(); + Class refClass = reference.getPort().getServiceContract().getInterface(); + boolean multiplicity = reference.getPort().getMultiplicity() == Multiplicity.ONE_N + || reference.getPort().getMultiplicity() == Multiplicity.ZERO_N; + contextFactory.addSourceWireFactories(refName, refClass, wireFactories, multiplicity); + } + } + component.setContextFactory(contextFactory); + } catch (BuilderException e) { + e.addContextName(component.getName()); + throw e; + } + } + + /** + * Subclasses must implement, returning a context factory appropriate to the component implementation + * + * @param componentName the name of the component + * @param implementation the component implementation + * @param scope the component implementation scope + */ + protected abstract ContextFactory createContextFactory(String componentName, T implementation, Scope scope); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/EntryPointBuilderSupport.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/EntryPointBuilderSupport.java new file mode 100644 index 0000000000..58d7a626a6 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/EntryPointBuilderSupport.java @@ -0,0 +1,111 @@ +/** + * + * 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.extension; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +import org.apache.tuscany.core.builder.BuilderException; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.core.builder.ContextFactoryBuilderRegistry; +import org.apache.tuscany.core.message.MessageFactory; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.service.WireFactoryService; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Binding; +import org.apache.tuscany.model.assembly.ConfiguredService; +import org.apache.tuscany.model.assembly.EntryPoint; +import org.apache.tuscany.model.assembly.Service; +import org.osoa.sca.annotations.Init; + +/** + * A base class for a {@link ContextFactoryBuilder} that creates {@link org.apache.tuscany.core.context.EntryPointContext}s + * + * @version $$Rev$$ $$Date$$ + */ +public abstract class EntryPointBuilderSupport implements ContextFactoryBuilder { + + protected ContextFactoryBuilderRegistry builderRegistry; + protected WireFactoryService wireService; + protected MessageFactory messageFactory; + protected Class bindingClass; + + public EntryPointBuilderSupport() { + // reflect the generic type of the subclass + Type type = this.getClass().getGenericSuperclass(); + if (type instanceof ParameterizedType) { + bindingClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[0]; + } else { + throw new AssertionError("Subclasses of " + ContextFactoryBuilderSupport.class.getName() + " must be genericized"); + } + } + + @Init(eager = true) + public void init() throws Exception { + builderRegistry.register(this); + } + + @Autowire + public void setBuilderRegistry(ContextFactoryBuilderRegistry registry) { + builderRegistry = registry; + } + + @Autowire + public void setWireService(WireFactoryService wireService) { + this.wireService = wireService; + } + + /** + * Sets the factory used to construct wire messages + * + * @param msgFactory + */ + @Autowire + public void setMessageFactory(MessageFactory msgFactory) { + this.messageFactory = msgFactory; + } + + public void build(AssemblyObject object) throws BuilderException { + if (!(object instanceof EntryPoint)) { + return; + } + EntryPoint entryPoint = (EntryPoint) object; + if (entryPoint.getBindings().size() < 1) { + return; + } + if (!bindingClass.isAssignableFrom(entryPoint.getBindings().get(0).getClass())) { + return; + } + + EntryPointContextFactory contextFactory = createEntryPointContextFactory(entryPoint, messageFactory); + ConfiguredService configuredService = entryPoint.getConfiguredService(); + Service service = configuredService.getPort(); + SourceWireFactory wireFactory = wireService.createSourceFactory(entryPoint.getConfiguredReference()).get(0); + contextFactory.addSourceWireFactory(service.getName(), wireFactory); + entryPoint.setContextFactory(contextFactory); + } + + /** + * Callback to create the specific ContextFactory type associated with the extending + * implementation + * + * @param entryPoint the entry point being processed + * @param msgFactory the message factory to be used by EntryPointContext when flowing + * invocations + */ + protected abstract EntryPointContextFactory createEntryPointContextFactory(EntryPoint entryPoint, MessageFactory msgFactory); + + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/EntryPointContextFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/EntryPointContextFactory.java new file mode 100644 index 0000000000..bb4d1207d4 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/EntryPointContextFactory.java @@ -0,0 +1,111 @@ +/** + * + * 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.extension; + +import org.apache.tuscany.core.builder.ContextCreationException; +import org.apache.tuscany.core.builder.ContextFactory; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.EntryPointContext; +import org.apache.tuscany.core.context.impl.EntryPointContextImpl; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.core.message.MessageFactory; +import org.apache.tuscany.model.assembly.Scope; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * Default factory for contexts that represent entry points. + * + * @version $Rev$ $Date$ + */ +public abstract class EntryPointContextFactory implements ContextFactory { + + private String name; + + private SourceWireFactory sourceWireFactory; + + private MessageFactory msgFactory; + + private List sourceProxyFactories; + + public EntryPointContextFactory(String name, MessageFactory msgFactory) { + assert (name != null) : "Entry point name was null"; + assert (msgFactory != null) : "Message factory was null"; + this.name = name; + this.msgFactory = msgFactory; + } + + public EntryPointContext createContext() throws ContextCreationException { + return new EntryPointContextImpl(name, sourceWireFactory, msgFactory); + } + + public Scope getScope() { + return Scope.MODULE; + } + + public String getName() { + return name; + } + + public void prepare() { + } + + public void addTargetWireFactory(String serviceName, TargetWireFactory factory) { + // no wires to an entry point from within a composite + } + + public TargetWireFactory getTargetWireFactory(String serviceName) { + // no wires to an entry point from within a composite + return null; + } + + public Map getTargetWireFactories() { + // no wires to an entry point from within a composite + return Collections.emptyMap(); + } + + public void addSourceWireFactory(String refName, SourceWireFactory factory) { + assert (refName != null) : "No reference name specified"; + assert (factory != null) : "Proxy factory was null"; + this.sourceWireFactory = factory; + } + + public List getSourceWireFactories() { + if (sourceProxyFactories == null) { + sourceProxyFactories = new ArrayList(1); + sourceProxyFactories.add(sourceWireFactory); + } + return sourceProxyFactories; + } + + public void addProperty(String propertyName, Object value) { + throw new UnsupportedOperationException(); + } + + public void addSourceWireFactories(String referenceName, Class referenceInterface, List factories, boolean multiplicity) { + if (factories.size() >1){ + throw new UnsupportedOperationException("Multiple wires for an entry point not allowed"); + }else if(factories.size() <1){ + throw new AssertionError("Empty wire factory list"); + } + this.sourceWireFactory = factories.get(0); + } + + public void prepare(CompositeContext parent) { + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ExternalServiceBuilderSupport.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ExternalServiceBuilderSupport.java new file mode 100644 index 0000000000..7c030324f1 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ExternalServiceBuilderSupport.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.extension; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +import org.apache.tuscany.core.builder.BuilderException; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.core.builder.ContextFactoryBuilderRegistry; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.core.wire.service.WireFactoryService; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Binding; +import org.apache.tuscany.model.assembly.ConfiguredService; +import org.apache.tuscany.model.assembly.ExternalService; +import org.apache.tuscany.model.assembly.Service; +import org.osoa.sca.annotations.Init; + +/** + * A base class for a {@link ContextFactoryBuilder} that creates {@link org.apache.tuscany.core.context.ExternalServiceContext}s + * + * @version $$Rev$$ $$Date$$ + */ +public abstract class ExternalServiceBuilderSupport implements ContextFactoryBuilder { + + private ContextFactoryBuilderRegistry builderRegistry; + private WireFactoryService wireService; + protected Class bindingClass; + + public ExternalServiceBuilderSupport() { + // reflect the generic type of the subclass + Type type = this.getClass().getGenericSuperclass(); + if (type instanceof ParameterizedType) { + bindingClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[0]; + } else { + throw new AssertionError("Subclasses of " + ContextFactoryBuilderSupport.class.getName() + " must be genericized"); + } + } + + public ExternalServiceBuilderSupport(WireFactoryService wireService) { + this(); + this.wireService = wireService; + } + + @Init(eager = true) + public void init() throws Exception { + builderRegistry.register(this); + } + + @Autowire + public void setBuilderRegistry(ContextFactoryBuilderRegistry registry) { + builderRegistry = registry; + } + + @Autowire + public void setWireService(WireFactoryService wireService) { + this.wireService = wireService; + } + + public void build(AssemblyObject object) throws BuilderException { + if (!(object instanceof ExternalService)) { + return; + } + ExternalService externalService = (ExternalService) object; + if (externalService.getBindings().size() < 1) { + // || !(handlesBindingType(externalService.getBindings().get(0)))) { + return; + } + if (!bindingClass.isAssignableFrom(externalService.getBindings().get(0).getClass())) { + return; + } + + ExternalServiceContextFactory contextFactory + = createExternalServiceContextFactory(externalService); + + ConfiguredService configuredService = externalService.getConfiguredService(); + Service service = configuredService.getPort(); + TargetWireFactory wireFactory = wireService.createTargetFactory(configuredService); + contextFactory.addTargetWireFactory(service.getName(), wireFactory); + externalService.setContextFactory(contextFactory); + } + + /** + * Returns true if an extending implementation can process the given binding element + */ + //protected abstract boolean handlesBindingType(Binding binding); + + /** + * Callback to create the specific ContextFactory type associated with the extending + * implementation + * + * @param externalService the external service being processed + */ + protected abstract ExternalServiceContextFactory createExternalServiceContextFactory(ExternalService externalService); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ExternalServiceContextFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ExternalServiceContextFactory.java new file mode 100644 index 0000000000..396da3d39e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ExternalServiceContextFactory.java @@ -0,0 +1,121 @@ +/** + * + * 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.extension; + +import org.apache.tuscany.core.builder.ContextCreationException; +import org.apache.tuscany.core.builder.ContextFactory; +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.ExternalServiceContext; +import org.apache.tuscany.core.context.impl.ExternalServiceContextImpl; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.model.assembly.Scope; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * A template implementation that creates instances of {@link org.apache.tuscany.core.context.ExternalServiceContext} + * configured with the appropriate wire 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 org.apache.tuscany.core.builder.WireBuilder + * + * + * + * } + * responsible for setting the proper {@link org.apache.tuscany.core.wire.TargetInvoker} on the wire chains + * can be notified. + * + * @version $Rev$ $Date$ + */ +public abstract class ExternalServiceContextFactory implements ContextFactory { + + private String name; + + private TargetWireFactory targetWireFactory; + + private ObjectFactory objectFactory; + + private String targetServiceName; + + private Map targetProxyFactories; + + public ExternalServiceContextFactory(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 createContext() throws ContextCreationException { + return new ExternalServiceContextImpl(name, targetWireFactory, objectFactory); + } + + public Scope getScope() { + return Scope.MODULE; + } + + public String getName() { + return name; + } + + public void prepare() { + } + + public void addTargetWireFactory(String serviceName, TargetWireFactory 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.targetWireFactory = factory; + } + + public TargetWireFactory getTargetWireFactory(String serviceName) { + if (this.targetServiceName.equals(serviceName)) { + return targetWireFactory; + } else { + return null; + } + } + + public Map getTargetWireFactories() { + if (targetProxyFactories == null) { + targetProxyFactories = new HashMap (1); + targetProxyFactories.put(targetServiceName, targetWireFactory); + } + return targetProxyFactories; + } + + public void addSourceWireFactory(String referenceName, SourceWireFactory factory) { + throw new UnsupportedOperationException(); + } + + public void addSourceWireFactories(String referenceName, Class referenceInterface, List factory, boolean multiplicity) { + + } + + public List getSourceWireFactories() { + return Collections.emptyList(); + } + + public void addProperty(String propertyName, Object value) { + throw new UnsupportedOperationException(); + } + + public void prepare(CompositeContext parent) { + //parentContext = parent; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ExternalServiceInvoker.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ExternalServiceInvoker.java new file mode 100644 index 0000000000..0424bf5de6 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ExternalServiceInvoker.java @@ -0,0 +1,23 @@ +/** + * + * 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.extension; + +public interface ExternalServiceInvoker { + + public Object invoke(String methodName, Object[] args); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ExternalServiceTargetInvoker.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ExternalServiceTargetInvoker.java new file mode 100644 index 0000000000..0d664e0207 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/ExternalServiceTargetInvoker.java @@ -0,0 +1,122 @@ +/** + * + * 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.extension; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.tuscany.core.context.Context; +import org.apache.tuscany.core.context.ExternalServiceContext; +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.core.context.ScopeContext; +import org.apache.tuscany.core.context.TargetException; +import org.apache.tuscany.core.message.Message; +import org.apache.tuscany.core.wire.Interceptor; +import org.apache.tuscany.core.wire.TargetInvoker; + +/** + * Responsible for invoking an external service + * + * @version $Rev$ $Date$ + */ +public class ExternalServiceTargetInvoker implements TargetInvoker { + + private QualifiedName serviceName; + + private String esName; + + private Method method; + + private ScopeContext container; + + private ExternalServiceContext context; + + /** + * Constructs a new ExternalWebServiceTargetInvoker. + * + * @param container + */ + public ExternalServiceTargetInvoker(QualifiedName serviceName, Method method, ScopeContext container) { + assert serviceName != null : "No service name specified"; + assert method != null : "No method specified"; + assert container != null : "No scope container specified"; + this.serviceName = serviceName; + this.esName = serviceName.getPartName(); + this.method = method; + this.container = container; + } + + public Object invokeTarget(Object payload) throws InvocationTargetException { + if (context == null) { + Context iContext = container.getContext(esName); + if (!(iContext instanceof ExternalServiceContext)) { + TargetException te = new TargetException("Unexpected target context type"); + te.setIdentifier(iContext.getClass().getName()); + te.addContextName(iContext.getName()); + throw te; + } + context = (ExternalServiceContext) iContext; + } + + ExternalServiceInvoker invoker = (ExternalServiceInvoker) context.getHandler(); + if (payload != null) { + return doInvoke(invoker, (Object[]) payload); + } else { + return doInvoke(invoker, null); + } + } + + protected Object doInvoke(ExternalServiceInvoker invoker, Object[] args) { + return invoker.invoke(method.getName(), args); + } + + public boolean isCacheable() { + return false; + } + + public Message invoke(Message msg) { + try { + Object resp = invokeTarget(msg.getBody()); + msg.setBody(resp); + } catch (InvocationTargetException e) { + msg.setBody(e.getCause()); + } catch (Throwable e) { + msg.setBody(e); + } + return msg; + } + + public void setNext(Interceptor next) { + throw new UnsupportedOperationException(); + } + + public Object clone() throws CloneNotSupportedException { + try { + ExternalServiceTargetInvoker invoker = (ExternalServiceTargetInvoker) super.clone(); + invoker.container = container; + invoker.context = this.context; + invoker.esName = this.esName; + invoker.method = this.method; + invoker.serviceName = this.serviceName; + return invoker; + } catch (CloneNotSupportedException e) { + // will not happen + return null; + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/WireBuilderSupport.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/WireBuilderSupport.java new file mode 100644 index 0000000000..5b2d9de0e3 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/WireBuilderSupport.java @@ -0,0 +1,102 @@ +/** + * + * 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.extension; + +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +import org.apache.tuscany.core.builder.BuilderConfigException; +import org.apache.tuscany.core.builder.ContextFactory; +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.runtime.RuntimeContext; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.core.wire.SourceInvocationConfiguration; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.TargetInvocationConfiguration; +import org.apache.tuscany.core.wire.TargetInvoker; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.osoa.sca.annotations.Init; + +/** + * A base class for {@link WireBuilder} implementations + * + * @version $$Rev$$ $$Date$$ + */ +public abstract class WireBuilderSupport> implements WireBuilder { + + protected RuntimeContext runtimeContext; + protected Class targetClass; + + @Autowire + public void setRuntimeContext(RuntimeContext context) { + runtimeContext = context; + } + + public WireBuilderSupport() { + // reflect the generic type of the subclass + Type type = this.getClass().getGenericSuperclass(); + if (type instanceof ParameterizedType) { + targetClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[0]; + } else { + throw new AssertionError("Subclasses of " + ContextFactoryBuilderSupport.class.getName() + " must be genericized"); + } + } + + @Init(eager = true) + public void init() throws Exception { + runtimeContext.addBuilder(this); + } + + public void connect(SourceWireFactory sourceFactory, TargetWireFactory targetFactory, Class targetType, boolean downScope, + ScopeContext targetScopeContext) throws BuilderConfigException { + if (!targetClass.isAssignableFrom(targetType)) { + return; + } + + for (SourceInvocationConfiguration sourceInvocationConfig : sourceFactory.getConfiguration().getInvocationConfigurations() + .values()) { + TargetInvoker invoker = createInvoker(sourceFactory.getConfiguration() + .getTargetName(), sourceInvocationConfig.getMethod(), targetScopeContext, downScope); + sourceInvocationConfig.setTargetInvoker(invoker); + } + } + + public void completeTargetChain(TargetWireFactory targetFactory, Class targetType, ScopeContext targetScopeContext) + throws BuilderConfigException { + + if (!targetClass.isAssignableFrom(targetType)) { + return; + } + for (TargetInvocationConfiguration targetInvocationConfig : targetFactory.getConfiguration().getInvocationConfigurations() + .values()) { + Method method = targetInvocationConfig.getMethod(); + TargetInvoker invoker = createInvoker(targetFactory.getConfiguration().getTargetName(), method, targetScopeContext, false); + targetInvocationConfig.setTargetInvoker(invoker); + } + } + + /** + * Callback to create the specific TargetInvoker type for dispatching to the target type + * + * @param targetName the fully qualified name of the wire target + * @param operation the operation the invoker will be associated with + * @param context the scope context that manages the target context + * @param downScope whether the wire source scope is "longer" than the target + */ + protected abstract TargetInvoker createInvoker(QualifiedName targetName, Method operation, ScopeContext context, boolean downScope); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/ImplementationProcessor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/ImplementationProcessor.java new file mode 100644 index 0000000000..b464a7f00f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/ImplementationProcessor.java @@ -0,0 +1,65 @@ +/** + * + * 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.extension.config; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.apache.tuscany.model.assembly.ComponentType; +import org.apache.tuscany.core.config.ConfigurationLoadException; + +/** + * Implementations process a Java class and contribute to a {@link org.apache.tuscany.model.assembly.ComponentType} + * or provide some validation function. Implementations may contribute to defined ComponentType + * metadata, a general ComponentType extensibility element, or a more specific Java extensibility + * element, which is associated with {@link org.apache.tuscany.core.extension.config.JavaExtensibilityElement} and + * stored in the ComponentType's extensibility collection. Processors will typically use {@link + * JavaExtensibilityHelper#getExtensibilityElement(org.apache.tuscany.model.assembly.Extensible)}, which + * provides methods for retrieving the Java extensibility element. + *

+ * In the runtime, a {@link org.apache.tuscany.core.config.ComponentTypeIntrospector} system service introspects component implementation + * types when an assembly is loaded, calling out to registered processors in the order defined by {@link + * ComponentTypeIntrospector#introspect(Class)}. Generally, processors are also system services which + * register themeselves with a ComponentTypeIntrospector. For convenience, a processor + * implementation can extend <@link org.apache.tuscany.core.config.processor.ImplementationProcessorSupport}, + * which provides mechanisms for doing this. + *

+ * There are a series of bootsrap, or primordial, processors configured in the runtime, and they serve as + * examples of how an ImplementationProcessor can be implemented. + * + * @see org.apache.tuscany.core.config.processor.PropertyProcessor + * @see org.apache.tuscany.core.config.processor.ReferenceProcessor + * @see org.apache.tuscany.core.config.processor.InitProcessor + * @see org.apache.tuscany.core.config.processor.DestroyProcessor + * @see org.apache.tuscany.core.config.processor.ComponentNameProcessor + * + * @version $$Rev$$ $$Date$$ + * @see org.apache.tuscany.core.config.processor.ImplementationProcessorSupport + */ +public interface ImplementationProcessor { + + public void visitClass(Class clazz, ComponentType type) throws ConfigurationLoadException; + + public void visitSuperClass(Class clazz, ComponentType type) throws ConfigurationLoadException; + + public void visitMethod(Method method, ComponentType type) throws ConfigurationLoadException; + + public void visitConstructor(Constructor constructor, ComponentType type) throws ConfigurationLoadException; + + public void visitField(Field field, ComponentType type) throws ConfigurationLoadException; + + public void visitEnd(Class clazz, ComponentType type) throws ConfigurationLoadException; + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/InjectorExtensibilityElement.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/InjectorExtensibilityElement.java new file mode 100644 index 0000000000..50818d1ac0 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/InjectorExtensibilityElement.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.extension.config; + +import org.apache.tuscany.core.builder.ContextResolver; +import org.apache.tuscany.core.injection.Injector; + +/** + * An extensiblity element which provides {@link Injector}s based on component type metadata + * + * @version $$Rev$$ $$Date$$ + */ +public interface InjectorExtensibilityElement extends JavaExtensibilityElement { + + /** + * Creates an injector + * @param resolver that returns the current composite context + */ + public Injector getInjector(ContextResolver resolver); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/JavaExtensibilityElement.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/JavaExtensibilityElement.java new file mode 100644 index 0000000000..fba57d8254 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/JavaExtensibilityElement.java @@ -0,0 +1,25 @@ +/** + * + * 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.extension.config; + +/** + * Serves as a marker for a metadata extensibility point. For example, {@link ImplementationProcessor}s may + * create extensibility elements which are responsible for implementing injection functionality prescribed by + * a Java source annotation. + * + * @version $$Rev$$ $$Date$$ + */ +public interface JavaExtensibilityElement { + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/ComponentNameExtensibilityElement.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/ComponentNameExtensibilityElement.java new file mode 100644 index 0000000000..e04ca34da6 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/ComponentNameExtensibilityElement.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.extension.config.extensibility; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.apache.tuscany.core.injection.Injector; +import org.apache.tuscany.core.injection.MethodInjector; +import org.apache.tuscany.core.injection.SingletonObjectFactory; +import org.apache.tuscany.core.injection.FieldInjector; +import org.apache.tuscany.core.extension.config.JavaExtensibilityElement; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class ComponentNameExtensibilityElement implements JavaExtensibilityElement { + + private Method method; + private Field field; + + public ComponentNameExtensibilityElement(Method m) { + method = m; + } + + public ComponentNameExtensibilityElement(Field f) { + field = f; + } + + public Injector getEventInvoker(String name) { + if (method != null) { + return new MethodInjector(method, new SingletonObjectFactory(name)); + }else{ + return new FieldInjector(field, new SingletonObjectFactory(name)); + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/ContextExtensibilityElement.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/ContextExtensibilityElement.java new file mode 100644 index 0000000000..9099132e36 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/ContextExtensibilityElement.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.extension.config.extensibility; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.apache.tuscany.core.extension.config.JavaExtensibilityElement; +import org.apache.tuscany.core.injection.Injector; +import org.apache.tuscany.core.injection.MethodInjector; +import org.apache.tuscany.core.injection.FieldInjector; +import org.apache.tuscany.core.injection.ContextObjectFactory; +import org.apache.tuscany.core.builder.ContextResolver; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class ContextExtensibilityElement implements JavaExtensibilityElement { + + private Method method; + private Field field; + + public ContextExtensibilityElement(Method m) { + method = m; + } + + public ContextExtensibilityElement(Field f) { + field = f; + } + + public Injector getInjector(ContextResolver resolver) { + if (method != null) { + return new MethodInjector(method, new ContextObjectFactory(resolver)); + } else { + return new FieldInjector(field, new ContextObjectFactory(resolver)); + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/DestroyInvokerExtensibilityElement.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/DestroyInvokerExtensibilityElement.java new file mode 100644 index 0000000000..9952f507b2 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/DestroyInvokerExtensibilityElement.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.extension.config.extensibility; + +import java.lang.reflect.Method; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class DestroyInvokerExtensibilityElement extends InvokerExtensibilityElement{ + + public DestroyInvokerExtensibilityElement(Method m) { + super(m); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/InitInvokerExtensibilityElement.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/InitInvokerExtensibilityElement.java new file mode 100644 index 0000000000..4c542b4b5d --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/InitInvokerExtensibilityElement.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.extension.config.extensibility; + +import java.lang.reflect.Method; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class InitInvokerExtensibilityElement extends InvokerExtensibilityElement{ + + private boolean eager; + + public InitInvokerExtensibilityElement(Method m, boolean eager) { + super(m); + this.eager = eager; + } + + public boolean isEager() { + return eager; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/InvokerExtensibilityElement.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/InvokerExtensibilityElement.java new file mode 100644 index 0000000000..a87acd16cc --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/extension/config/extensibility/InvokerExtensibilityElement.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.extension.config.extensibility; + +import java.lang.reflect.Method; + +import org.apache.tuscany.core.extension.config.JavaExtensibilityElement; +import org.apache.tuscany.core.injection.MethodEventInvoker; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class InvokerExtensibilityElement implements JavaExtensibilityElement { + + private Method method; + private MethodEventInvoker invoker; + + public InvokerExtensibilityElement(Method m) { + method = m; + } + + public MethodEventInvoker getEventInvoker() { + if (invoker == null) { + invoker = new MethodEventInvoker(method); + } + return invoker; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/ContextObjectFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/ContextObjectFactory.java new file mode 100644 index 0000000000..6facd25e59 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/ContextObjectFactory.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.injection; + +import org.apache.tuscany.core.builder.ContextResolver; +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.context.CompositeContext; + +/** + * An implementation of ObjectFactory that resolves the current parent context + * + * @version $Rev: 380903 $ $Date: 2006-02-25 00:53:26 -0800 (Sat, 25 Feb 2006) $ + */ +public class ContextObjectFactory implements ObjectFactory { + + private final ContextResolver resolver; + + public ContextObjectFactory(ContextResolver resolver) { + assert (resolver != null) : "Resolver cannot be null"; + this.resolver = resolver; + } + + public CompositeContext getInstance() { + return resolver.getCurrentContext(); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/EventInvoker.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/EventInvoker.java new file mode 100644 index 0000000000..6f5de43b96 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/EventInvoker.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.injection; + +/** + * Performs an wire on an instance + * + * @version $Rev$ $Date$ + * @see MethodEventInvoker + */ +public interface EventInvoker { + + /** + * Performs the wire on a given instance + * + * @throws ObjectCallbackException + */ + void invokeEvent(T instance) throws ObjectCallbackException; +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/FactoryInitException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/FactoryInitException.java new file mode 100644 index 0000000000..589ae796ac --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/FactoryInitException.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.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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/FieldInjector.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/FieldInjector.java new file mode 100644 index 0000000000..7be73462d3 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/FieldInjector.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.injection; + +import org.apache.tuscany.core.builder.ObjectFactory; + +import java.lang.reflect.Field; + +/** + * Injects a value created by an {@link ObjectFactory} on a given field + * + * @version $Rev$ $Date$ + */ +public class FieldInjector implements Injector { + + private final Field field; + + private final ObjectFactory objectFactory; + + /** + * Create an injector and have it use the given ObjectFactory + * to inject a value on the instance using the reflected Field + */ + public FieldInjector(Field field, ObjectFactory objectFactory) { + this.field = field; + this.objectFactory = objectFactory; + } + + /** + * Inject a new value on the given isntance + */ + public void inject(T instance) throws ObjectCreationException { + try { + field.set(instance, objectFactory.getInstance()); + } catch (IllegalAccessException e) { + throw new AssertionError("Field is not accessible [" + field + "]"); + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/InjectionRuntimeException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/InjectionRuntimeException.java new file mode 100644 index 0000000000..2c26f3c4b1 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/InjectionRuntimeException.java @@ -0,0 +1,45 @@ +/** + * + * 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.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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/Injector.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/Injector.java new file mode 100644 index 0000000000..306dab3e98 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/Injector.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.injection; + +/** + * Implementations inject a pre-configured value on an instance + * + * @version $Rev$ $Date$ + * @see MethodInjector + * @see FieldInjector + */ +public interface Injector { + + /** + * Inject a value on the given instance + */ + void inject(T instance) throws ObjectCreationException; + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/InterCompositeReferenceFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/InterCompositeReferenceFactory.java new file mode 100644 index 0000000000..55d8a88790 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/InterCompositeReferenceFactory.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.injection; + +import org.apache.tuscany.core.builder.ContextResolver; +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.Context; +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.core.context.TargetException; + +/** + * Returns a direct reference to a target service exposed in another composite, i.e. the factory avoids creating proxies + * and returns the actual target instance + * + * @version $Rev: 384135 $ $Date: 2006-03-07 22:53:58 -0800 (Tue, 07 Mar 2006) $ + */ +public class InterCompositeReferenceFactory implements ObjectFactory { + + private ContextResolver resolver; + + private QualifiedName targetQualifiedName; + + /** + * Reference source is an external service, target is in another module + * + * @param targetName the name of the target service + */ + public InterCompositeReferenceFactory(String targetName) { + targetQualifiedName = new QualifiedName(targetName); + } + + public void setContextResolver(ContextResolver resolver){ + this.resolver = resolver; + } + + public T getInstance() throws ObjectCreationException { + // only return entry points since this is an inter-module wire + Object o = resolver.getCurrentContext().getInstance(targetQualifiedName); + if (o != null) { + return (T) o; + } else { + // walk up the hierarchy of composite contexts + CompositeContext ctx = resolver.getCurrentContext(); + do { + if (ctx == null) { + break; // reached top of context hierarchy + } + Context compContext = ctx.getContext(targetQualifiedName.getPartName()); + if (compContext != null) { + o = compContext.getInstance(targetQualifiedName); + if (o != null) { + return (T) o; + } + } + ctx = ctx.getParent(); + } while (ctx != null); + TargetException e = new TargetException("Target reference not found"); + e.setIdentifier(targetQualifiedName.getQualifiedName()); + throw e; + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/JNDIObjectFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/JNDIObjectFactory.java new file mode 100644 index 0000000000..bed7db887a --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/JNDIObjectFactory.java @@ -0,0 +1,46 @@ +/** + * + * Copyright 2006 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.injection; + +import javax.naming.Context; +import javax.naming.NamingException; + +import org.apache.tuscany.core.builder.ObjectFactory; + +/** + * An implementation of ObjectFactory that creates instances + * by looking them up in a JNDI context. + * + * @version $Rev$ $Date$ + */ +public class JNDIObjectFactory implements ObjectFactory { + private final Context context; + private final String name; + + public JNDIObjectFactory(Context context, String name) { + this.context = context; + this.name = name; + } + + public T getInstance() throws ObjectCreationException { + try { + return (T) context.lookup(name); + } catch (NamingException e) { + throw new ObjectCreationException(e); + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/MethodEventInvoker.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/MethodEventInvoker.java new file mode 100644 index 0000000000..69c7670c03 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/MethodEventInvoker.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.injection; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Performs an wire on a method of a given instance + * + * @version $Rev$ $Date$ + */ +public class MethodEventInvoker implements EventInvoker { + private final Method method; + + /** + * Intantiates an invoker for the given method + */ + public MethodEventInvoker(Method method) { + this.method = method; + } + + 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/MethodInjector.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/MethodInjector.java new file mode 100644 index 0000000000..6095061872 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/MethodInjector.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.injection; + +import org.apache.tuscany.core.builder.ObjectFactory; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Injects a value created by an {@link ObjectFactory} using a given method + * @version $Rev$ $Date$ + */ +public class MethodInjector implements Injector { + 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, objectFactory.getInstance()); + } catch (IllegalAccessException e) { + throw new AssertionError("Method is not accessible [" + method + "]"); + } catch (InvocationTargetException e) { + ObjectCreationException oce= new ObjectCreationException("Exception thrown by setter", e); + oce.setIdentifier(method.getName()); + throw oce; + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/NonProxiedTargetFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/NonProxiedTargetFactory.java new file mode 100644 index 0000000000..7f7a307433 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/NonProxiedTargetFactory.java @@ -0,0 +1,54 @@ +/** + * + * 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.ContextResolver; +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.model.assembly.ConfiguredService; + +/** + * Returns a direct reference to a target within the same composite, i.e. the factory avoids creating proxies and + * returns the actual target instance + * + * @version $Rev$ $Date$ + */ +public class NonProxiedTargetFactory implements ObjectFactory { + + private ContextResolver resolver; + + // the name of the target component/service for this reference + private QualifiedName targetName; + private QualifiedName qualifiedServiceName; + + /** + * Constructs a reference object factory from a configured reference on a type + * + * @throws FactoryInitException + */ + public NonProxiedTargetFactory(ConfiguredService targetService, ContextResolver resolver) throws FactoryInitException { + assert (targetService != null) : "Target service was null"; + assert (resolver != null) : "Context resolver was null"; + + this.resolver = resolver; + targetName = new QualifiedName(targetService.getPart().getName()); + qualifiedServiceName = new QualifiedName("./"+targetName.getPortName()); + } + + public T getInstance() throws ObjectCreationException { + return (T) resolver.getCurrentContext().getContext(targetName.getPartName()).getInstance(qualifiedServiceName); //locateInstance(targetName); //locateInstance(targetName); + } + + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/NullEventInvoker.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/NullEventInvoker.java new file mode 100644 index 0000000000..e8f109f2d8 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/NullEventInvoker.java @@ -0,0 +1,30 @@ +/** + * + * 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; + +/** + * A no-op invoker + * + * @version $Rev$ $Date$ + */ +public final class NullEventInvoker implements EventInvoker { + public static final EventInvoker NULL_INVOKER = new NullEventInvoker(); + + public void invokeEvent(T instance) { + // does nothing + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/ObjectCallbackException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/ObjectCallbackException.java new file mode 100644 index 0000000000..44edee43eb --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/ObjectCallbackException.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.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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/ObjectCreationException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/ObjectCreationException.java new file mode 100644 index 0000000000..875eda3680 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/ObjectCreationException.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.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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/PojoObjectFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/PojoObjectFactory.java new file mode 100644 index 0000000000..fac8248b0c --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/PojoObjectFactory.java @@ -0,0 +1,76 @@ +/** + * + * 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 java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Collections; +import java.util.List; + +/** + * 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 implements ObjectFactory { + + private static final ObjectFactory[] NO_INIT_PARAM = {}; + + private static final List NO_SETTER_PARAM = Collections.emptyList(); + + private final Constructor ctr; + + private final ObjectFactory[] initParamsArray; + + private final List setters; + + public PojoObjectFactory(Constructor ctr, List initParams, List 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; + } + + 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/SingletonObjectFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/SingletonObjectFactory.java new file mode 100644 index 0000000000..8a7e0bf782 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/injection/SingletonObjectFactory.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.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 implements ObjectFactory { + private final T instance; + + public SingletonObjectFactory(T instance) { + this.instance = instance; + } + + public T getInstance() { + return instance; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/InvalidPropertyFactoryException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/InvalidPropertyFactoryException.java new file mode 100644 index 0000000000..9ccbbb3a7a --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/InvalidPropertyFactoryException.java @@ -0,0 +1,46 @@ +/** + * + * Copyright 2006 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 org.apache.tuscany.core.config.ConfigurationLoadException; + +/** + * Exception raised if there is a problem configuring a PropertyFactory. + * + * @version $Rev$ $Date$ + */ +public class InvalidPropertyFactoryException extends ConfigurationLoadException { + private static final long serialVersionUID = 5017976138519117474L; + + /** + * Constructor indicating the cause why the property factory could not be created. + * + * @param className the name of the class that is intended to be the PropertyFactory + * @param cause the Throwable that prevented the PropertyFactory from being created + */ + public InvalidPropertyFactoryException(String className, Throwable cause) { + super(className, cause); + } + + /** + * Returns the name of the property factory implementation class. + * @return the name of the property factory implementation class + */ + public String getClassName() { + return getMessage(); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/LoaderContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/LoaderContext.java new file mode 100644 index 0000000000..cef7353bbf --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/LoaderContext.java @@ -0,0 +1,47 @@ +/** + * + * Copyright 2006 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.loader; + +import org.apache.tuscany.common.resource.ResourceLoader; + +/** + * Context holder that can be used during the load process to store information + * that is not part of the logical model. This should be regarded as transient + * and references to this context should not be stored inside the model. + * + * @version $Rev$ $Date$ + */ +public class LoaderContext { + private final ResourceLoader resourceLoader; + + /** + * Constructor specifying the loader for application resources. + * + * @param resourceLoader the loader for application resources + */ + public LoaderContext(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + + /** + * Returns a resource loader that can be used to load application resources. + * @return a resource loader that can be used to load application resources + */ + public ResourceLoader getResourceLoader() { + return resourceLoader; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXElementLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXElementLoader.java new file mode 100644 index 0000000000..e1a9f55ca4 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXElementLoader.java @@ -0,0 +1,40 @@ +/** + * + * 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 javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.model.assembly.AssemblyObject; + +/** + * A loader that creates a model object from a StAX input stream. + * + * @version $Rev$ $Date$ + */ +public interface StAXElementLoader { + /** + * Build the model object for an element in an XML stream. + * When this method returns the stream will be positioned on the corresponding END_ELEMENT. + * + * @param reader the XML stream reader positioned on the applicable START_ELEMENT + * @param loaderContext the context for the load operation + * @return the model object for that element + */ + T load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException; +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXLoaderRegistry.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXLoaderRegistry.java new file mode 100644 index 0000000000..a38d388815 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXLoaderRegistry.java @@ -0,0 +1,91 @@ +/** + * + * 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 javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.model.assembly.AssemblyObject; + +/** + * Registry for XML loaders that can parse a StAX input stream and return model objects. + *

+ * Loaders will typically be contributed to the system by any extension that needs to + * handle extension specific information contained in some XML configuration file. + * The loader can be contributed as a system component with an autowire reference + * to this registry which is used during initialization to actually register. + *

+ * This registry can also be used to parse an input stream, dispatching to the + * appropriate loader for each element accepted. Loaders can call back to the + * registry to load sub-elements that they are not able to handle directly. + * + * @version $Rev$ $Date$ + */ +public interface StAXLoaderRegistry { + /** + * Register a loader. This operation will typically be called by a loader + * during its initialization. + * + * @param element the element that should be delegated to the contibuted loader + * @param loader a loader that is being contributed to the system + */ + void registerLoader(QName element, StAXElementLoader loader); + + /** + * Unregister a loader. This will typically be called by a loader as it is being destroyed. + * + * @param element the element that was being delegated to the contibuted loader + * @param loader a loader that should no longer be used + */ + void unregisterLoader(QName element, StAXElementLoader loader); + + /** + * Parse the supplied XML stream dispatching to the appropriate registered loader + * for each element encountered in the stream. + *

+ * This method must be called with the XML cursor positioned on a START_ELEMENT event. + * When this method returns, the stream will be positioned on the corresponding + * END_ELEMENT event. + * + * @param reader the XML stream to parse + * @param loaderContext + * @return the model object obtained by parsing the current element on the stream + * @throws XMLStreamException if there was a problem reading the stream + */ + AssemblyObject load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException; + + /** + * Hack to allow loaders to initialize model objects on the fly. + * Remove when initialization has been moved from the model implementation to the loader. + * + * @return the model context for this load operation + */ + @Deprecated + AssemblyContext getContext(); + + /** + * Hack to allow loaders to initialize model objects on the fly. + * Remove when initialization has been moved from the model implementation to the loader. + * + * @param context the model context for this load operation + */ + @Deprecated + void setContext(AssemblyContext context); +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXPropertyFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXPropertyFactory.java new file mode 100644 index 0000000000..a05597b51b --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXPropertyFactory.java @@ -0,0 +1,42 @@ +/** + * + * Copyright 2006 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 org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.model.assembly.Property; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +/** + * A factory that will create an ObjectFactory for a property by parsing a StAX XMLStreamReader. + * + * @version $Rev$ $Date$ + */ +public interface StAXPropertyFactory { + /** + * Return an ObjectFactory for instances of a property defined in an XML stream. + * + * @param reader the reader to use to access the XML stream + * @param property the Property definition that the resulting ObjectFactory must be able to assign to + * @return an ObjectFactory that can produce instances that can be assigned to the supplied Property + * @throws XMLStreamException if there is a problem reading the stream + * @throws ConfigurationLoadException if there is a problem creating the ObjectFactory + */ + ObjectFactory createObjectFactory(XMLStreamReader reader, Property property) throws XMLStreamException, ConfigurationLoadException; +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXUtil.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXUtil.java new file mode 100644 index 0000000000..f9ac2b0559 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXUtil.java @@ -0,0 +1,160 @@ +/** + * + * 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.HashMap; +import java.util.List; +import java.util.Map; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.core.config.ComponentTypeIntrospector; +import org.apache.tuscany.core.config.ConfigurationException; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.config.impl.Java5ComponentTypeIntrospector; +import org.apache.tuscany.core.config.processor.ProcessorUtils; +import org.apache.tuscany.core.loader.assembly.ComponentLoader; +import org.apache.tuscany.core.loader.assembly.EntryPointLoader; +import org.apache.tuscany.core.loader.assembly.InterfaceJavaLoader; +import org.apache.tuscany.core.loader.assembly.ModuleFragmentLoader; +import org.apache.tuscany.core.loader.assembly.ModuleLoader; +import org.apache.tuscany.core.loader.impl.StAXLoaderRegistryImpl; +import org.apache.tuscany.core.loader.impl.StringParserPropertyFactory; +import org.apache.tuscany.core.loader.system.SystemBindingLoader; +import org.apache.tuscany.core.loader.system.SystemImplementationLoader; +import org.apache.tuscany.core.system.assembly.SystemAssemblyFactory; +import org.apache.tuscany.core.system.assembly.SystemImplementation; +import org.apache.tuscany.core.system.assembly.impl.SystemAssemblyFactoryImpl; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.EntryPoint; +import org.apache.tuscany.model.assembly.Module; +import org.apache.tuscany.model.assembly.ModuleComponent; +import org.apache.tuscany.model.assembly.Multiplicity; +import org.apache.tuscany.model.assembly.OverrideOption; +import org.apache.tuscany.model.assembly.Scope; + +/** + * @version $Rev$ $Date$ + */ +public final class StAXUtil { + private static final Map MULTIPLICITY = new HashMap(4); + private static final Map OVERRIDE_OPTIONS = new HashMap(3); + + static { + MULTIPLICITY.put("0..1", Multiplicity.ZERO_ONE); + MULTIPLICITY.put("1..1", Multiplicity.ONE_ONE); + MULTIPLICITY.put("0..n", Multiplicity.ZERO_N); + MULTIPLICITY.put("1..n", Multiplicity.ONE_N); + + OVERRIDE_OPTIONS.put("no", OverrideOption.NO); + OVERRIDE_OPTIONS.put("may", OverrideOption.MAY); + OVERRIDE_OPTIONS.put("must", OverrideOption.MUST); + } + + private StAXUtil() { + } + + public static void skipToEndElement(XMLStreamReader reader) throws XMLStreamException { + int depth = 0; + while (true) { + int event = reader.next(); + if (event == XMLStreamConstants.START_ELEMENT) { + depth++; + } else if (event == XMLStreamConstants.END_ELEMENT) { + if (depth == 0) { + return; + } + depth--; + } + } + } + + public static Multiplicity multiplicity(String multiplicity, Multiplicity def) { + return multiplicity == null ? def : MULTIPLICITY.get(multiplicity); + } + + public static OverrideOption overrideOption(String overrideOption, OverrideOption def) { + return overrideOption == null ? def : OVERRIDE_OPTIONS.get(overrideOption); + } + + public static ModuleComponent bootstrapLoader(String name, AssemblyContext context) throws ConfigurationLoadException { + SystemAssemblyFactory factory = new SystemAssemblyFactoryImpl(); + ComponentTypeIntrospector introspector = ProcessorUtils.createCoreIntrospector(factory); + Module module = factory.createModule(); + module.setName("org.apache.tuscany.core.system.loader"); + + List components = module.getComponents(); + + // bootstrap the minimal set of loaders needed to read the system module files + // all others should be defined in the system.module file + components.add(bootstrapLoader(factory, introspector, ModuleLoader.class)); + components.add(bootstrapLoader(factory, introspector, ModuleFragmentLoader.class)); + Component propFactory = factory.createSystemComponent("org.apache.tuscany.core.system.loader.DefaultPropertyFactory", StAXPropertyFactory.class, StringParserPropertyFactory.class, Scope.MODULE); + introspector.introspect(StAXPropertyFactory.class); + components.add(propFactory); + components.add(bootstrapLoader(factory, introspector, ComponentLoader.class)); + components.add(bootstrapLoader(factory, introspector, EntryPointLoader.class)); + components.add(bootstrapLoader(factory, introspector, InterfaceJavaLoader.class)); + components.add(bootstrapLoader(factory, introspector, SystemImplementationLoader.class)); + components.add(bootstrapLoader(factory, introspector, SystemBindingLoader.class)); + // do not add additional loaders above - they should be in the system.module file + + // bootstrap the registries needed by the bootstrap loaders above + bootstrapService(factory, introspector, module, StAXLoaderRegistry.class, StAXLoaderRegistryImpl.class); + bootstrapService(factory, introspector, module, SystemAssemblyFactory.class, SystemAssemblyFactoryImpl.class); + bootstrapService(factory, introspector, module, ComponentTypeIntrospector.class, Java5ComponentTypeIntrospector.class); + + ModuleComponent mc = factory.createModuleComponent(); + mc.setName(name); + mc.setImplementation(module); + mc.initialize(context); + return mc; + } + + private static Component bootstrapLoader(SystemAssemblyFactory factory, ComponentTypeIntrospector introspector, Class loaderClass) { + SystemImplementation implementation = factory.createSystemImplementation(); + implementation.setImplementationClass(loaderClass); + try { + implementation.setComponentType(introspector.introspect(loaderClass)); + } catch (ConfigurationException e) { + throw (AssertionError) new AssertionError("Invalid bootstrap loader").initCause(e); + } + Component component = factory.createSimpleComponent(); + component.setName(loaderClass.getName()); + component.setImplementation(implementation); + return component; + } + + private static void bootstrapService(SystemAssemblyFactory factory, ComponentTypeIntrospector introspector, Module module, Class service, Class impl) { + String epName = service.getName(); + String compName = impl.getName(); + + Component component = factory.createSystemComponent(compName, service, impl, Scope.MODULE); + try { + component.getImplementation().setComponentType(introspector.introspect(impl)); + } catch (ConfigurationException e) { + throw (AssertionError) new AssertionError("Invalid bootstrap loader").initCause(e); + } + + EntryPoint entryPoint = factory.createSystemEntryPoint(epName, service, compName); + + module.getComponents().add(component); + module.getEntryPoints().add(entryPoint); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/WSDLDefinitionRegistry.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/WSDLDefinitionRegistry.java new file mode 100644 index 0000000000..f88e0f0b35 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/WSDLDefinitionRegistry.java @@ -0,0 +1,95 @@ +/** + * + * Copyright 2006 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.net.URL; +import java.util.List; +import java.io.IOException; +import javax.wsdl.Definition; +import javax.wsdl.PortType; +import javax.wsdl.Service; +import javax.wsdl.WSDLException; +import javax.wsdl.extensions.ExtensionRegistry; +import javax.xml.namespace.QName; + +import org.apache.tuscany.common.resource.ResourceLoader; + +/** + * @version $Rev$ $Date$ + */ +public interface WSDLDefinitionRegistry { + /** + * Loads and registers a WSDL Definition. + * + * @param namespace the expected namespace, or null if any namespace should be allowed + * @param location the location to load the definition from + * @param resourceLoader the application resource loader + * @return the loaded Definition + * @throws IOException if there was a problem reading the document + * @throws WSDLException if there was a problem parsing the definition + */ + Definition loadDefinition(String namespace, URL location, ResourceLoader resourceLoader) throws IOException, WSDLException; + + /** + * Load and register a WSDL definition as specified in a WSDL2.0 wsdlLocation attribute. + * + * @param wsdlLocation the value of the wsdlLocation attribute + * @param resourceLoader application resource loader used to support relative locations + * @return the loaded Definition + * @throws IOException if there was a problem reading the document + * @throws WSDLException if there was a problem parsing the definition + */ + Definition loadDefinition(String wsdlLocation, ResourceLoader resourceLoader) throws IOException, WSDLException; + + /** + * Returns the PortType with the supplied qualified name, or null if no such port has been defined. + * + * @param name the qualified name of the WSDL portType + * @param resourceLoader the application resource loader + * @return the PortType for the supplied name, or null if none has been defined + */ + PortType getPortType(QName name, ResourceLoader resourceLoader); + + /** + * Returns the Service with the supplied qualified name, or null if no such service has been defined. + * + * @param name the qualified name of the WSDL service + * @param resourceLoader the application resource loader + * @return the Service for the supplied name, or null if none has been defined + */ + Service getService(QName name, ResourceLoader resourceLoader); + + + /** + * Returns a list of definitions that have been loaded for the given namespace, or null if + * no WSDL documents have been loaded for the given namespace + * + * @param namespace the namespace to lookup + * @param resourceLoader the application resource loader + * @return The list of definitions that have been loaded for the given namespace, or null + */ + List getDefinitionsForNamespace(String namespace, ResourceLoader resourceLoader); + + + /** + * Returns the ExtensionRegistry that is used when parsing WSDL documents during the + * loadDefinition call. + * + * @return the ExtensionRegistry that is used when parsing WSDL documents. + */ + ExtensionRegistry getExtensionRegistry(); +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/AbstractLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/AbstractLoader.java new file mode 100644 index 0000000000..fce343df4b --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/AbstractLoader.java @@ -0,0 +1,61 @@ +/** + * + * 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.assembly; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.core.loader.StAXElementLoader; +import org.apache.tuscany.core.loader.StAXLoaderRegistry; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.core.system.assembly.SystemAssemblyFactory; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Init; + +/** + * @version $Rev$ $Date$ + */ +public abstract class AbstractLoader implements StAXElementLoader { + protected SystemAssemblyFactory factory; + protected StAXLoaderRegistry registry; + + @Autowire + public void setFactory(SystemAssemblyFactory factory) { + this.factory = factory; + } + + @Autowire + public void setRegistry(StAXLoaderRegistry registry) { + this.registry = registry; + } + + @Init(eager = true) + public void start() { + registry.registerLoader(getXMLType(), this); + } + + @Destroy + public void stop() { + registry.unregisterLoader(getXMLType(), this); + } + + /** + * Returns the QName of the element that this implementation handles. + * @return the QName of the element that this implementation handles + */ + protected abstract QName getXMLType(); +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/AssemblyConstants.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/AssemblyConstants.java new file mode 100644 index 0000000000..73ef4119f8 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/AssemblyConstants.java @@ -0,0 +1,47 @@ +/** + * + * 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.assembly; + +import javax.xml.namespace.QName; + +/** + * @version $Rev$ $Date$ + */ +public final class AssemblyConstants { + public static final String SCA_NAMESPACE = "http://www.osoa.org/xmlns/sca/0.9"; + + public static final QName COMPONENT = new QName(SCA_NAMESPACE, "component"); + public static final QName COMPONENT_TYPE = new QName(SCA_NAMESPACE, "componentType"); + public static final QName ENTRY_POINT = new QName(SCA_NAMESPACE, "entryPoint"); + public static final QName EXTERNAL_SERVICE = new QName(SCA_NAMESPACE, "externalService"); + public static final QName IMPORT_WSDL = new QName(SCA_NAMESPACE, "import.wsdl"); + public static final QName INTERFACE_JAVA = new QName(SCA_NAMESPACE, "interface.java"); + public static final QName INTERFACE_WSDL = new QName(SCA_NAMESPACE, "interface.wsdl"); + public static final QName MODULE = new QName(SCA_NAMESPACE, "module"); + public static final QName MODULE_FRAGMENT = new QName(SCA_NAMESPACE, "moduleFragment"); + public static final QName PROPERTY = new QName(SCA_NAMESPACE, "property"); + public static final QName PROPERTIES = new QName(SCA_NAMESPACE, "properties"); + public static final QName REFERENCE = new QName(SCA_NAMESPACE, "reference"); + public static final QName REFERENCES = new QName(SCA_NAMESPACE, "references"); + public static final QName SERVICE = new QName(SCA_NAMESPACE, "service"); + public static final QName WIRE = new QName(SCA_NAMESPACE, "wire"); + public static final QName WIRE_SOURCE = new QName(SCA_NAMESPACE, "source.uri"); + public static final QName WIRE_TARGET = new QName(SCA_NAMESPACE, "target.uri"); + + private AssemblyConstants() { + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ComponentLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ComponentLoader.java new file mode 100644 index 0000000000..0fa3e7ddeb --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ComponentLoader.java @@ -0,0 +1,189 @@ +/** + * + * 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.assembly; + +import java.util.List; +import javax.xml.namespace.QName; +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.common.resource.ResourceLoader; +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.InvalidPropertyFactoryException; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.loader.StAXPropertyFactory; +import org.apache.tuscany.core.loader.StAXUtil; +import static org.apache.tuscany.core.loader.assembly.AssemblyConstants.*; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.ComponentType; +import org.apache.tuscany.model.assembly.ConfiguredProperty; +import org.apache.tuscany.model.assembly.ConfiguredReference; +import org.apache.tuscany.model.assembly.Implementation; +import org.apache.tuscany.model.assembly.OverrideOption; +import org.apache.tuscany.model.assembly.Property; +import org.osoa.sca.annotations.Scope; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class ComponentLoader extends AbstractLoader { + private StAXPropertyFactory defaultPropertyFactory; + + @Autowire + public void setDefaultPropertyFactory(StAXPropertyFactory defaultPropertyFactory) { + this.defaultPropertyFactory = defaultPropertyFactory; + } + + public QName getXMLType() { + return COMPONENT; + } + + public Component load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert COMPONENT.equals(reader.getName()); + + Component component = factory.createSimpleComponent(); + component.setName(reader.getAttributeValue(null, "name")); + + while (true) { + switch (reader.next()) { + case START_ELEMENT: + QName name = reader.getName(); + if (PROPERTIES.equals(name)) { + loadProperties(reader, loaderContext.getResourceLoader(), component); + } else if (REFERENCES.equals(name)) { + loadReferences(reader, component); + } else { + AssemblyObject o = registry.load(reader, loaderContext); + if (o instanceof Implementation) { + Implementation impl = (Implementation) o; + impl.initialize(registry.getContext()); + component.setImplementation(impl); + } + } + reader.next(); + break; + case END_ELEMENT: + List props = component.getImplementation().getComponentType().getProperties(); + for (Property property : props) { + if (property.isRequired()) { + if (component.getConfiguredProperty(property.getName()) == null) { + ConfigurationLoadException e = new ConfigurationLoadException("Required property not configured"); + e.setIdentifier(property.getName()); + throw e; + } + } + } + return component; + } + } + } + + protected void loadProperties(XMLStreamReader reader, ResourceLoader resourceLoader, Component component) throws XMLStreamException, ConfigurationLoadException { + ComponentType componentType = component.getImplementation().getComponentType(); + List configuredProperties = component.getConfiguredProperties(); + + while (true) { + switch (reader.next()) { + case START_ELEMENT: + String name = reader.getLocalName(); + Property property = componentType.getProperty(name); + if (property == null) { + throw new ConfigurationLoadException(name); + } + OverrideOption override = StAXUtil.overrideOption(reader.getAttributeValue(null, "override"), OverrideOption.NO); + +// get a factory for the property + StAXPropertyFactory propertyFactory; + String factoryName = reader.getAttributeValue(null, "factory"); + if (factoryName == null) { + propertyFactory = defaultPropertyFactory; + } else { + propertyFactory = getPropertyFactory(factoryName, resourceLoader); + } + + // create the property value + // FIXME to support complex types we probably should store the factory in the ConfiguredProperty + // FIXME instead of the value as the value may be mutable and should not be shared between instances + ObjectFactory objectFactory = propertyFactory.createObjectFactory(reader, property); + Object value = objectFactory.getInstance(); + + // create the configured property definition + ConfiguredProperty configuredProperty = factory.createConfiguredProperty(); + configuredProperty.setName(name); + configuredProperty.setValue(value); + configuredProperty.setOverrideOption(override); + configuredProperties.add(configuredProperty); + break; + case END_ELEMENT: + return; + } + } + } + + protected StAXPropertyFactory getPropertyFactory(String factoryName, ResourceLoader resourceLoader) throws InvalidPropertyFactoryException { + Class impl; + try { + // try to load factory from application classloader + impl = resourceLoader.loadClass(factoryName); + } catch (ClassNotFoundException e) { + try { + // try to load factory from container classloader + impl = Class.forName(factoryName); + } catch (ClassNotFoundException e1) { + throw new InvalidPropertyFactoryException(factoryName, e); + } + } + try { + return (StAXPropertyFactory) impl.newInstance(); + } catch (InstantiationException e) { + throw new InvalidPropertyFactoryException(factoryName, e); + } catch (IllegalAccessException e) { + throw new InvalidPropertyFactoryException(factoryName, e); + } catch (ClassCastException e) { + throw new InvalidPropertyFactoryException(factoryName, e); + } + } + + protected void loadReferences(XMLStreamReader reader, Component component) throws XMLStreamException { + List configuredReferences = component.getConfiguredReferences(); + while (true) { + switch (reader.next()) { + case START_ELEMENT: + String name = reader.getLocalName(); + String uri = reader.getElementText(); + + ConfiguredReference configuredReference = component.getConfiguredReference(name); + if (configuredReference == null) { + configuredReference = factory.createConfiguredReference(); + configuredReference.setName(name); + configuredReferences.add(configuredReference); + } + + configuredReference.getTargets().add(uri); + break; + case END_ELEMENT: + return; + } + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ComponentTypeLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ComponentTypeLoader.java new file mode 100644 index 0000000000..fdb8893830 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ComponentTypeLoader.java @@ -0,0 +1,65 @@ +/** + * + * 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.assembly; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import static org.apache.tuscany.core.loader.assembly.AssemblyConstants.COMPONENT_TYPE; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.ComponentType; +import org.apache.tuscany.model.assembly.Property; +import org.apache.tuscany.model.assembly.Reference; +import org.apache.tuscany.model.assembly.Service; +import org.osoa.sca.annotations.Scope; + +import javax.xml.namespace.QName; +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class ComponentTypeLoader extends AbstractLoader { + public QName getXMLType() { + return COMPONENT_TYPE; + } + + public ComponentType load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert COMPONENT_TYPE.equals(reader.getName()); + ComponentType componentType = factory.createComponentType(); + + while (true) { + switch (reader.next()) { + case START_ELEMENT: + AssemblyObject o = registry.load(reader, loaderContext); + if (o instanceof Service) { + componentType.getServices().add((Service) o); + } else if (o instanceof Reference) { + componentType.getReferences().add((Reference) o); + } else if (o instanceof Property) { + componentType.getProperties().add((Property) o); + } + break; + case END_ELEMENT: + return componentType; + } + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/CompositeLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/CompositeLoader.java new file mode 100644 index 0000000000..9b22a24784 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/CompositeLoader.java @@ -0,0 +1,62 @@ +/** + * + * 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.assembly; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.Composite; +import org.apache.tuscany.model.assembly.EntryPoint; +import org.apache.tuscany.model.assembly.ExternalService; +import org.apache.tuscany.model.assembly.ImportWSDL; +import org.apache.tuscany.model.assembly.Wire; + +/** + * @version $Rev$ $Date$ + */ +public abstract class CompositeLoader extends AbstractLoader { + public void loadComposite(XMLStreamReader reader, Composite composite, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + composite.setName(reader.getAttributeValue(null, "name")); + while (true) { + switch (reader.next()) { + case START_ELEMENT: + AssemblyObject o = registry.load(reader, loaderContext); + if (o instanceof EntryPoint) { + composite.getEntryPoints().add((EntryPoint) o); + } else if (o instanceof ExternalService) { + composite.getExternalServices().add((ExternalService) o); + } else if (o instanceof Component) { + composite.getComponents().add((Component) o); + } else if (o instanceof Wire) { + composite.getWires().add((Wire) o); + } else if (o instanceof ImportWSDL) { + composite.getWSDLImports().add((ImportWSDL) o); + } + reader.next(); + break; + case END_ELEMENT: + return; + } + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/EntryPointLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/EntryPointLoader.java new file mode 100644 index 0000000000..14b60964d5 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/EntryPointLoader.java @@ -0,0 +1,90 @@ +/** + * + * 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.assembly; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.StAXUtil; +import org.apache.tuscany.core.loader.LoaderContext; +import static org.apache.tuscany.core.loader.assembly.AssemblyConstants.ENTRY_POINT; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Binding; +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.Multiplicity; +import org.apache.tuscany.model.assembly.Reference; +import org.apache.tuscany.model.assembly.Service; +import org.apache.tuscany.model.assembly.ServiceContract; +import org.osoa.sca.annotations.Scope; + +import javax.xml.namespace.QName; +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class EntryPointLoader extends AbstractLoader { + public QName getXMLType() { + return ENTRY_POINT; + } + + public EntryPoint load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert ENTRY_POINT.equals(reader.getName()); + EntryPoint entryPoint = factory.createEntryPoint(); + String name = reader.getAttributeValue(null, "name"); + entryPoint.setName(name); + + Service service = factory.createService(); + service.setName(name); + ConfiguredService configuredService = factory.createConfiguredService(); + configuredService.setPort(service); + entryPoint.setConfiguredService(configuredService); + + Reference reference = factory.createReference(); + reference.setMultiplicity(StAXUtil.multiplicity(reader.getAttributeValue(null, "multiplicity"), Multiplicity.ONE_ONE)); + ConfiguredReference configuredReference = factory.createConfiguredReference(); + configuredReference.setPort(reference); + entryPoint.setConfiguredReference(configuredReference); + + while (true) { + switch (reader.next()) { + case START_ELEMENT: + QName qname = reader.getName(); + if (AssemblyConstants.REFERENCE.equals(qname)) { + String uri = reader.getElementText(); + configuredReference.getTargets().add(uri); + } else { + AssemblyObject o = registry.load(reader, loaderContext); + if (o instanceof Binding) { + entryPoint.getBindings().add((Binding) o); + } else if (o instanceof ServiceContract) { + service.setServiceContract((ServiceContract) o); + reference.setServiceContract((ServiceContract) o); + } + } + reader.next(); + break; + case END_ELEMENT: + return entryPoint; + } + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ExternalServiceLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ExternalServiceLoader.java new file mode 100644 index 0000000000..4910c016d8 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ExternalServiceLoader.java @@ -0,0 +1,75 @@ +/** + * + * 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.assembly; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.StAXUtil; +import org.apache.tuscany.core.loader.LoaderContext; +import static org.apache.tuscany.core.loader.assembly.AssemblyConstants.EXTERNAL_SERVICE; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Binding; +import org.apache.tuscany.model.assembly.ConfiguredService; +import org.apache.tuscany.model.assembly.ExternalService; +import org.apache.tuscany.model.assembly.OverrideOption; +import org.apache.tuscany.model.assembly.Service; +import org.apache.tuscany.model.assembly.ServiceContract; +import org.osoa.sca.annotations.Scope; + +import javax.xml.namespace.QName; +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class ExternalServiceLoader extends AbstractLoader { + public QName getXMLType() { + return EXTERNAL_SERVICE; + } + + public ExternalService load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert EXTERNAL_SERVICE.equals(reader.getName()); + String name = reader.getAttributeValue(null, "name"); + ExternalService externalService = factory.createExternalService(); + externalService.setName(name); + externalService.setOverrideOption(StAXUtil.overrideOption(reader.getAttributeValue(null, "overridable"), OverrideOption.NO)); + + while (true) { + switch (reader.next()) { + case START_ELEMENT: + AssemblyObject o = registry.load(reader, loaderContext); + if (o instanceof ServiceContract) { + Service service = factory.createService(); + service.setName(name); + service.setServiceContract((ServiceContract) o); + ConfiguredService configuredService = factory.createConfiguredService(); + configuredService.setPort(service); + externalService.setConfiguredService(configuredService); + } else if (o instanceof Binding) { + externalService.getBindings().add((Binding) o); + } + reader.next(); + break; + case END_ELEMENT: + return externalService; + } + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ImportWSDLLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ImportWSDLLoader.java new file mode 100644 index 0000000000..6981f05372 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ImportWSDLLoader.java @@ -0,0 +1,95 @@ +/** + * + * Copyright 2006 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.assembly; + +import static org.apache.tuscany.core.loader.assembly.AssemblyConstants.IMPORT_WSDL; + +import java.io.IOException; +import java.net.URL; + +import javax.wsdl.Definition; +import javax.wsdl.WSDLException; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.common.resource.ResourceLoader; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.config.MissingResourceException; +import org.apache.tuscany.core.config.SidefileLoadException; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.loader.StAXUtil; +import org.apache.tuscany.core.loader.WSDLDefinitionRegistry; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.model.assembly.ImportWSDL; +import org.osoa.sca.annotations.Scope; + +/** + * Loader that handles <import.wsdl> elements. + * + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class ImportWSDLLoader extends AbstractLoader { + private WSDLDefinitionRegistry wsdlRegistry; + + @Autowire + public void setWsdlRegistry(WSDLDefinitionRegistry wsdlRegistry) { + this.wsdlRegistry = wsdlRegistry; + } + + public QName getXMLType() { + return IMPORT_WSDL; + } + + public ImportWSDL load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert AssemblyConstants.IMPORT_WSDL.equals(reader.getName()); + String namespace = reader.getAttributeValue(null, "namespace"); + String location = reader.getAttributeValue(null, "location"); + if (location == null) + location = reader.getAttributeValue(null, "wsdlLocation"); + ImportWSDL importWSDL = factory.createImportWSDL(location, namespace); + + Definition definition = loadDefinition(namespace, location, loaderContext.getResourceLoader()); +// importWSDL.setDefinition(definition); + + StAXUtil.skipToEndElement(reader); + return importWSDL; + } + + protected Definition loadDefinition(String namespace, String location, ResourceLoader resourceLoader) throws MissingResourceException, SidefileLoadException { + Definition definition; + URL wsdlURL = resourceLoader.getResource(location); + if (wsdlURL == null) { + throw new MissingResourceException(location); + } + + try { + definition = wsdlRegistry.loadDefinition(namespace, wsdlURL, resourceLoader); + } catch (IOException e) { + SidefileLoadException sfe = new SidefileLoadException(e.getMessage()); + sfe.setResourceURI(location); + throw sfe; + } catch (WSDLException e) { + SidefileLoadException sfe = new SidefileLoadException(e.getMessage()); + sfe.setResourceURI(location); + throw sfe; + } + + return definition; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/InterfaceJavaLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/InterfaceJavaLoader.java new file mode 100644 index 0000000000..602cf2cc0a --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/InterfaceJavaLoader.java @@ -0,0 +1,45 @@ +/** + * + * Copyright 2006 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.assembly; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.model.assembly.Scope; +import org.apache.tuscany.model.types.java.JavaServiceContract; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +/** + * @version $Rev$ $Date$ + */ +@org.osoa.sca.annotations.Scope("MODULE") +public class InterfaceJavaLoader extends AbstractLoader { + public QName getXMLType() { + return AssemblyConstants.INTERFACE_JAVA; + } + + public JavaServiceContract load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert AssemblyConstants.INTERFACE_JAVA.equals(reader.getName()); + JavaServiceContract serviceContract = factory.createJavaServiceContract(); + serviceContract.setScope(Scope.INSTANCE); + serviceContract.setInterfaceName(reader.getAttributeValue(null, "interface")); + serviceContract.setCallbackInterfaceName(reader.getAttributeValue(null, "callbackInterface")); + return serviceContract; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/InterfaceWSDLLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/InterfaceWSDLLoader.java new file mode 100644 index 0000000000..9617cf805f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/InterfaceWSDLLoader.java @@ -0,0 +1,110 @@ +/** + * + * Copyright 2006 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.assembly; + +import java.io.IOException; + +import org.apache.tuscany.common.resource.ResourceLoader; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.config.MissingInterfaceException; +import org.apache.tuscany.core.loader.WSDLDefinitionRegistry; +import org.apache.tuscany.core.loader.StAXUtil; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.model.assembly.Scope; +import org.apache.tuscany.model.types.wsdl.WSDLServiceContract; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.wsdl.PortType; +import javax.wsdl.WSDLException; + +/** + * @version $Rev$ $Date$ + */ +@org.osoa.sca.annotations.Scope("MODULE") +public class InterfaceWSDLLoader extends AbstractLoader { + private static final String WSDLI = "http://www.w3.org/2006/01/wsdl-instance"; + private static final String WSDLI_LOCATION = "wsdlLocation"; + + private WSDLDefinitionRegistry wsdlRegistry; + + @Autowire + public void setWsdlRegistry(WSDLDefinitionRegistry wsdlRegistry) { + this.wsdlRegistry = wsdlRegistry; + } + + public QName getXMLType() { + return AssemblyConstants.INTERFACE_WSDL; + } + + public WSDLServiceContract load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert AssemblyConstants.INTERFACE_WSDL.equals(reader.getName()); + WSDLServiceContract serviceContract = factory.createWSDLServiceContract(); + serviceContract.setScope(Scope.INSTANCE); + + ResourceLoader resourceLoader = loaderContext.getResourceLoader(); + + String location = reader.getAttributeValue(WSDLI, WSDLI_LOCATION); + if (location != null) { + try { + wsdlRegistry.loadDefinition(location, resourceLoader); + } catch (IOException e) { + throw new MissingInterfaceException(e); + } catch (WSDLException e) { + throw new MissingInterfaceException(e); + } + } + + String portTypeURI = reader.getAttributeValue(null, "interface"); + if (portTypeURI != null) { + serviceContract.setPortType(getPortType(portTypeURI, resourceLoader)); + } + + portTypeURI = reader.getAttributeValue(null, "callbackInterface"); + if (portTypeURI != null) { + serviceContract.setCallbackPortType(getPortType(portTypeURI, resourceLoader)); + } + StAXUtil.skipToEndElement(reader); + return serviceContract; + } + + protected PortType getPortType(String uri, ResourceLoader resourceLoader) throws MissingInterfaceException { + + // We currently support two syntaxes for specifying a WSDL portType: + // namespace#portTypeName, this is what we supported in the initial contribution, we will + // deprecate this after M1 + // namespace#wsdl.interface(portTypeName), this is the WSDL 2.0 syntax + + int index = uri.indexOf('#'); + String namespace = uri.substring(0, index); + String fragment = uri.substring(index + 1); + String localName; + if (fragment.startsWith("wsdl.interface(") && fragment.endsWith(")")) { + localName = fragment.substring(15, fragment.length()-1); + } else { + localName = fragment; + } + QName qname = new QName(namespace, localName); + PortType portType = wsdlRegistry.getPortType(qname, resourceLoader); + if (portType == null) { + throw new MissingInterfaceException(uri); + } + return portType; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ModuleFragmentLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ModuleFragmentLoader.java new file mode 100644 index 0000000000..4b3e96cfab --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ModuleFragmentLoader.java @@ -0,0 +1,42 @@ +/** + * + * 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.assembly; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.model.assembly.ModuleFragment; +import org.osoa.sca.annotations.Scope; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class ModuleFragmentLoader extends CompositeLoader { + public QName getXMLType() { + return AssemblyConstants.MODULE_FRAGMENT; + } + + public ModuleFragment load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + ModuleFragment fragment = factory.createModuleFragment(); + loadComposite(reader, fragment, loaderContext); + return fragment; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ModuleLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ModuleLoader.java new file mode 100644 index 0000000000..08ab23b3a6 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ModuleLoader.java @@ -0,0 +1,50 @@ +/** + * + * 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.assembly; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.context.impl.CompositeContextImpl; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.system.context.SystemCompositeContextImpl; +import org.apache.tuscany.model.assembly.Module; +import org.osoa.sca.annotations.Scope; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class ModuleLoader extends CompositeLoader { + public QName getXMLType() { + return AssemblyConstants.MODULE; + } + + public Module load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + Module module = factory.createModule(); + loadComposite(reader, module, loaderContext); + // JFM Hack until recursive model in place + if (module.getName().startsWith("org.apache.tuscany.core.system")) { + module.setImplementationClass(SystemCompositeContextImpl.class); + } else { + module.setImplementationClass(CompositeContextImpl.class); + } + return module; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/PropertyLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/PropertyLoader.java new file mode 100644 index 0000000000..cbf1ca00df --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/PropertyLoader.java @@ -0,0 +1,79 @@ +/** + * + * 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.assembly; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.StAXUtil; +import org.apache.tuscany.core.loader.LoaderContext; +import static org.apache.tuscany.core.loader.assembly.AssemblyConstants.PROPERTY; +import org.apache.tuscany.model.assembly.Property; +import org.osoa.sca.annotations.Scope; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import java.util.HashMap; +import java.util.Map; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class PropertyLoader extends AbstractLoader { + private static final String XSD = "http://www.w3.org/2001/XMLSchema"; + + private static final Map> TYPE_MAP; + static { + // todo support more XSD types, or remove if we store the QName + TYPE_MAP = new HashMap>(17); + TYPE_MAP.put(new QName(XSD, "string"), String.class); + } + + public QName getXMLType() { + return PROPERTY; + } + + public Property load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert PROPERTY.equals(reader.getName()); + Property property = factory.createProperty(); + property.setName(reader.getAttributeValue(null, "name")); + String typeName = reader.getAttributeValue(null, "type"); + // support XSD type or Java class name + // todo perhaps we should just store the QName for the PropertyFactory to use + int index = typeName.indexOf(':'); + if (index != -1) { + String prefix = typeName.substring(0, index); + String namespaceURI = reader.getNamespaceURI(prefix); + QName qname = new QName(namespaceURI, typeName.substring(index+1)); + property.setType(TYPE_MAP.get(qname)); + } else { + try { + Class type = loaderContext.getResourceLoader().loadClass(typeName); + property.setType(type); + } catch (ClassNotFoundException e) { + throw new ConfigurationLoadException(e); + } + } + property.setMany(Boolean.parseBoolean(reader.getAttributeValue(null, "many"))); + property.setDefaultValue(reader.getAttributeValue(null, "default")); + String required = reader.getAttributeValue(null, "required"); + property.setRequired(required != null && Boolean.valueOf(required)); + + StAXUtil.skipToEndElement(reader); + return property; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ReferenceLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ReferenceLoader.java new file mode 100644 index 0000000000..aa95210757 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ReferenceLoader.java @@ -0,0 +1,64 @@ +/** + * + * 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.assembly; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.StAXUtil; +import org.apache.tuscany.core.loader.LoaderContext; +import static org.apache.tuscany.core.loader.assembly.AssemblyConstants.REFERENCE; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Multiplicity; +import org.apache.tuscany.model.assembly.Reference; +import org.apache.tuscany.model.assembly.ServiceContract; +import org.osoa.sca.annotations.Scope; + +import javax.xml.namespace.QName; +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class ReferenceLoader extends AbstractLoader { + public QName getXMLType() { + return REFERENCE; + } + + public Reference load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert REFERENCE.equals(reader.getName()); + Reference reference = factory.createReference(); + reference.setName(reader.getAttributeValue(null, "name")); + reference.setMultiplicity(StAXUtil.multiplicity(reader.getAttributeValue(null, "multiplicity"), Multiplicity.ONE_ONE)); + + while (true) { + switch (reader.next()) { + case START_ELEMENT: + AssemblyObject o = registry.load(reader, loaderContext); + if (o instanceof ServiceContract) { + reference.setServiceContract((ServiceContract) o); + } + reader.next(); + break; + case END_ELEMENT: + return reference; + } + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ServiceLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ServiceLoader.java new file mode 100644 index 0000000000..9cb31b55ff --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/ServiceLoader.java @@ -0,0 +1,61 @@ +/** + * + * 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.assembly; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import static org.apache.tuscany.core.loader.assembly.AssemblyConstants.SERVICE; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Service; +import org.apache.tuscany.model.assembly.ServiceContract; +import org.osoa.sca.annotations.Scope; + +import javax.xml.namespace.QName; +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class ServiceLoader extends AbstractLoader { + public QName getXMLType() { + return SERVICE; + } + + public Service load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert SERVICE.equals(reader.getName()); + Service service = factory.createService(); + service.setName(reader.getAttributeValue(null, "name")); + + while (true) { + switch (reader.next()) { + case START_ELEMENT: + AssemblyObject o = registry.load(reader, loaderContext); + if (o instanceof ServiceContract) { + service.setServiceContract((ServiceContract) o); + } + reader.next(); + break; + case END_ELEMENT: + return service; + } + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/WireLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/WireLoader.java new file mode 100644 index 0000000000..0ae3c4405d --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/WireLoader.java @@ -0,0 +1,84 @@ +/** + * + * 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.loader.assembly; + +import java.util.HashMap; +import java.util.Map; +import javax.xml.namespace.QName; +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.model.assembly.Wire; +import org.osoa.sca.annotations.Scope; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class WireLoader extends AbstractLoader { + private static final String XSD = "http://www.w3.org/2001/XMLSchema"; + + private static final Map> TYPE_MAP; + + static { + // todo support more XSD types, or remove if we store the QName + TYPE_MAP = new HashMap>(17); + TYPE_MAP.put(new QName(XSD, "string"), String.class); + } + + public QName getXMLType() { + return AssemblyConstants.WIRE; + } + + public Wire load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert AssemblyConstants.WIRE.equals(reader.getName()); + Wire wire = factory.createWire(); + while (true) { + switch (reader.next()) { + case START_ELEMENT: + QName qname = reader.getName(); + if (AssemblyConstants.WIRE_SOURCE.equals(qname)) { + String uri = reader.getElementText(); + int pos = uri.indexOf('/'); + if (pos < 1) { + throw new ConfigurationLoadException("Invalid source wire"); + } + String partName = uri.substring(0, pos); + String portName = uri.substring(pos + 1); + wire.setSource(factory.createServiceURI(null, partName, portName)); + } else if (AssemblyConstants.WIRE_TARGET.equals(qname)) { + String uri = reader.getElementText(); + int pos = uri.indexOf('/'); + if (pos < 1) { + wire.setTarget(factory.createServiceURI(null, uri)); + }else{ + String partName = uri.substring(0, pos); + String portName = uri.substring(pos + 1); + wire.setTarget(factory.createServiceURI(null, partName, portName)); + } + } + break; + case END_ELEMENT: + return wire; + } + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/AssemblyConstants.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/AssemblyConstants.java new file mode 100644 index 0000000000..81b047fd7d --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/AssemblyConstants.java @@ -0,0 +1,46 @@ +/** + * + * 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.assembly.recursive; + +import javax.xml.namespace.QName; + +/** + * @version $Rev$ $Date$ + */ +public final class AssemblyConstants { + public static final String SCA_NAMESPACE = "http://www.osoa.org/xmlns/sca/1.0"; + + public static final QName COMPONENT = new QName(SCA_NAMESPACE, "component"); + public static final QName COMPONENT_TYPE = new QName(SCA_NAMESPACE, "componentType"); + public static final QName COMPOSITE_SERVICE = new QName(SCA_NAMESPACE, "service"); + public static final QName COMPOSITE_REFERENCE = new QName(SCA_NAMESPACE, "reference"); + public static final QName IMPORT_WSDL = new QName(SCA_NAMESPACE, "import.wsdl"); + public static final QName INTERFACE_JAVA = new QName(SCA_NAMESPACE, "interface.java"); + public static final QName INTERFACE_WSDL = new QName(SCA_NAMESPACE, "interface.wsdl"); + public static final QName MODULE = new QName(SCA_NAMESPACE, "module"); + public static final QName COMPOSITE = new QName(SCA_NAMESPACE, "composite"); + public static final QName MODULE_FRAGMENT = new QName(SCA_NAMESPACE, "moduleFragment"); + public static final QName PROPERTY = new QName(SCA_NAMESPACE, "property"); + public static final QName REFERENCE = new QName(SCA_NAMESPACE, "reference"); + public static final QName SERVICE = new QName(SCA_NAMESPACE, "service"); + public static final QName WIRE = new QName(SCA_NAMESPACE, "wire"); + public static final QName WIRE_SOURCE = new QName(SCA_NAMESPACE, "source.uri"); + public static final QName WIRE_TARGET = new QName(SCA_NAMESPACE, "target.uri"); + + private AssemblyConstants() { + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ComponentLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ComponentLoader.java new file mode 100644 index 0000000000..3cb005ae5b --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ComponentLoader.java @@ -0,0 +1,181 @@ +/** + * + * 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.assembly.recursive; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import static org.apache.tuscany.core.loader.assembly.recursive.AssemblyConstants.COMPONENT; +import static org.apache.tuscany.core.loader.assembly.recursive.AssemblyConstants.PROPERTY; +import static org.apache.tuscany.core.loader.assembly.recursive.AssemblyConstants.REFERENCE; + +import java.util.List; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.common.resource.ResourceLoader; +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.InvalidPropertyFactoryException; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.loader.StAXPropertyFactory; +import org.apache.tuscany.core.loader.StAXUtil; +import org.apache.tuscany.core.loader.assembly.AbstractLoader; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.ComponentType; +import org.apache.tuscany.model.assembly.ConfiguredProperty; +import org.apache.tuscany.model.assembly.ConfiguredReference; +import org.apache.tuscany.model.assembly.Implementation; +import org.apache.tuscany.model.assembly.OverrideOption; +import org.apache.tuscany.model.assembly.Property; +import org.osoa.sca.annotations.Scope; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class ComponentLoader extends AbstractLoader { + private StAXPropertyFactory defaultPropertyFactory; + + @Autowire + public void setDefaultPropertyFactory(StAXPropertyFactory defaultPropertyFactory) { + this.defaultPropertyFactory = defaultPropertyFactory; + } + + public QName getXMLType() { + return COMPONENT; + } + + public Component load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert COMPONENT.equals(reader.getName()); + + Component component = factory.createSimpleComponent(); + component.setName(reader.getAttributeValue(null, "name")); + + while (true) { + switch (reader.next()) { + case START_ELEMENT: + QName name = reader.getName(); + if (PROPERTY.equals(name)) { + loadProperty(reader, loaderContext.getResourceLoader(), component); + } else if (REFERENCE.equals(name)) { + loadReference(reader, component); + } else { + AssemblyObject o = registry.load(reader, loaderContext); + if (o instanceof Implementation) { + Implementation impl = (Implementation) o; + impl.initialize(registry.getContext()); + component.setImplementation(impl); + } + reader.next(); + } + break; + case END_ELEMENT: + List props = component.getImplementation().getComponentType().getProperties(); + for (Property property : props) { + if (property.isRequired()) { + if (component.getConfiguredProperty(property.getName()) == null) { + ConfigurationLoadException e = new ConfigurationLoadException("Required property not configured"); + e.setIdentifier(property.getName()); + throw e; + } + } + } + return component; + } + } + } + + protected void loadProperty(XMLStreamReader reader, ResourceLoader resourceLoader, Component component) throws XMLStreamException, ConfigurationLoadException { + ComponentType componentType = component.getImplementation().getComponentType(); + List configuredProperties = component.getConfiguredProperties(); + + String name = reader.getLocalName(); + Property property = componentType.getProperty(name); + if (property == null) { + throw new ConfigurationLoadException(name); + } + OverrideOption override = StAXUtil.overrideOption(reader.getAttributeValue(null, "override"), OverrideOption.NO); + +// get a factory for the property + StAXPropertyFactory propertyFactory; + String factoryName = reader.getAttributeValue(null, "factory"); + if (factoryName == null) { + propertyFactory = defaultPropertyFactory; + } else { + propertyFactory = getPropertyFactory(factoryName, resourceLoader); + } + + // create the property value + // FIXME to support complex types we probably should store the factory in the ConfiguredProperty + // FIXME instead of the value as the value may be mutable and should not be shared between instances + ObjectFactory objectFactory = propertyFactory.createObjectFactory(reader, property); + Object value = objectFactory.getInstance(); + + // create the configured property definition + ConfiguredProperty configuredProperty = factory.createConfiguredProperty(); + configuredProperty.setName(name); + configuredProperty.setValue(value); + configuredProperty.setOverrideOption(override); + configuredProperties.add(configuredProperty); + + reader.next(); + } + + protected StAXPropertyFactory getPropertyFactory(String factoryName, ResourceLoader resourceLoader) throws InvalidPropertyFactoryException { + Class impl; + try { + // try to load factory from application classloader + impl = resourceLoader.loadClass(factoryName); + } catch (ClassNotFoundException e) { + try { + // try to load factory from container classloader + impl = Class.forName(factoryName); + } catch (ClassNotFoundException e1) { + throw new InvalidPropertyFactoryException(factoryName, e); + } + } + try { + return (StAXPropertyFactory) impl.newInstance(); + } catch (InstantiationException e) { + throw new InvalidPropertyFactoryException(factoryName, e); + } catch (IllegalAccessException e) { + throw new InvalidPropertyFactoryException(factoryName, e); + } catch (ClassCastException e) { + throw new InvalidPropertyFactoryException(factoryName, e); + } + } + + protected void loadReference(XMLStreamReader reader, Component component) throws XMLStreamException { + List configuredReferences = component.getConfiguredReferences(); + String name = reader.getAttributeValue(null, "name"); + String uri = reader.getElementText(); + + ConfiguredReference configuredReference = component.getConfiguredReference(name); + if (configuredReference == null) { + configuredReference = factory.createConfiguredReference(); + configuredReference.setName(name); + configuredReferences.add(configuredReference); + } + + configuredReference.getTargets().add(uri); + reader.next(); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ComponentTypeLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ComponentTypeLoader.java new file mode 100644 index 0000000000..4c40db11fa --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ComponentTypeLoader.java @@ -0,0 +1,66 @@ +/** + * + * 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.assembly.recursive; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import static org.apache.tuscany.core.loader.assembly.recursive.AssemblyConstants.COMPONENT_TYPE; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.loader.assembly.AbstractLoader; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.ComponentType; +import org.apache.tuscany.model.assembly.Property; +import org.apache.tuscany.model.assembly.Reference; +import org.apache.tuscany.model.assembly.Service; +import org.osoa.sca.annotations.Scope; + +import javax.xml.namespace.QName; +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class ComponentTypeLoader extends AbstractLoader { + public QName getXMLType() { + return COMPONENT_TYPE; + } + + public ComponentType load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert COMPONENT_TYPE.equals(reader.getName()); + ComponentType componentType = factory.createComponentType(); + + while (true) { + switch (reader.next()) { + case START_ELEMENT: + AssemblyObject o = registry.load(reader, loaderContext); + if (o instanceof Service) { + componentType.getServices().add((Service) o); + } else if (o instanceof Reference) { + componentType.getReferences().add((Reference) o); + } else if (o instanceof Property) { + componentType.getProperties().add((Property) o); + } + break; + case END_ELEMENT: + return componentType; + } + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/CompositeLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/CompositeLoader.java new file mode 100644 index 0000000000..d1acdd4c25 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/CompositeLoader.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.assembly.recursive; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.context.impl.CompositeContextImpl; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.loader.assembly.recursive.AssemblyConstants; +import org.apache.tuscany.core.system.context.SystemCompositeContextImpl; +import org.apache.tuscany.model.assembly.Module; +import org.osoa.sca.annotations.Scope; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class CompositeLoader extends org.apache.tuscany.core.loader.assembly.CompositeLoader { + public QName getXMLType() { + return AssemblyConstants.COMPOSITE; + } + + public Module load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + Module module = factory.createModule(); + loadComposite(reader, module, loaderContext); + // JFM Hack until recursive model in place + if (module.getName().startsWith("org.apache.tuscany.core.system")) { + module.setImplementationClass(SystemCompositeContextImpl.class); + } else { + module.setImplementationClass(CompositeContextImpl.class); + } + return module; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/CompositeReferenceLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/CompositeReferenceLoader.java new file mode 100644 index 0000000000..3fa78a252f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/CompositeReferenceLoader.java @@ -0,0 +1,77 @@ +/** + * + * 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.assembly.recursive; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.StAXUtil; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.loader.assembly.AbstractLoader; + +import static org.apache.tuscany.core.loader.assembly.recursive.AssemblyConstants.COMPOSITE_REFERENCE; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Binding; +import org.apache.tuscany.model.assembly.ConfiguredService; +import org.apache.tuscany.model.assembly.ExternalService; +import org.apache.tuscany.model.assembly.OverrideOption; +import org.apache.tuscany.model.assembly.Service; +import org.apache.tuscany.model.assembly.ServiceContract; +import org.osoa.sca.annotations.Scope; + +import javax.xml.namespace.QName; +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class CompositeReferenceLoader extends AbstractLoader { + public QName getXMLType() { + return COMPOSITE_REFERENCE; + } + + public ExternalService load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert COMPOSITE_REFERENCE.equals(reader.getName()); + String name = reader.getAttributeValue(null, "name"); + ExternalService externalService = factory.createExternalService(); + externalService.setName(name); + externalService.setOverrideOption(StAXUtil.overrideOption(reader.getAttributeValue(null, "overridable"), OverrideOption.NO)); + + while (true) { + switch (reader.next()) { + case START_ELEMENT: + AssemblyObject o = registry.load(reader, loaderContext); + if (o instanceof ServiceContract) { + Service service = factory.createService(); + service.setName(name); + service.setServiceContract((ServiceContract) o); + ConfiguredService configuredService = factory.createConfiguredService(); + configuredService.setPort(service); + externalService.setConfiguredService(configuredService); + } else if (o instanceof Binding) { + externalService.getBindings().add((Binding) o); + } + reader.next(); + break; + case END_ELEMENT: + return externalService; + } + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/CompositeServiceLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/CompositeServiceLoader.java new file mode 100644 index 0000000000..463388429b --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/CompositeServiceLoader.java @@ -0,0 +1,92 @@ +/** + * + * 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.assembly.recursive; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.StAXUtil; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.loader.assembly.AbstractLoader; + +import static org.apache.tuscany.core.loader.assembly.recursive.AssemblyConstants.COMPOSITE_SERVICE; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Binding; +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.Multiplicity; +import org.apache.tuscany.model.assembly.Reference; +import org.apache.tuscany.model.assembly.Service; +import org.apache.tuscany.model.assembly.ServiceContract; +import org.osoa.sca.annotations.Scope; + +import javax.xml.namespace.QName; +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class CompositeServiceLoader extends AbstractLoader { + public QName getXMLType() { + return COMPOSITE_SERVICE; + } + + public EntryPoint load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert COMPOSITE_SERVICE.equals(reader.getName()); + EntryPoint entryPoint = factory.createEntryPoint(); + String name = reader.getAttributeValue(null, "name"); + entryPoint.setName(name); + + Service service = factory.createService(); + service.setName(name); + ConfiguredService configuredService = factory.createConfiguredService(); + configuredService.setPort(service); + entryPoint.setConfiguredService(configuredService); + + Reference reference = factory.createReference(); + reference.setMultiplicity(StAXUtil.multiplicity(reader.getAttributeValue(null, "multiplicity"), Multiplicity.ONE_ONE)); + ConfiguredReference configuredReference = factory.createConfiguredReference(); + configuredReference.setPort(reference); + entryPoint.setConfiguredReference(configuredReference); + + while (true) { + switch (reader.next()) { + case START_ELEMENT: + QName qname = reader.getName(); + if (AssemblyConstants.REFERENCE.equals(qname)) { + String uri = reader.getElementText(); + configuredReference.getTargets().add(uri); + } else { + AssemblyObject o = registry.load(reader, loaderContext); + if (o instanceof Binding) { + entryPoint.getBindings().add((Binding) o); + } else if (o instanceof ServiceContract) { + service.setServiceContract((ServiceContract) o); + reference.setServiceContract((ServiceContract) o); + } + } + reader.next(); + break; + case END_ELEMENT: + return entryPoint; + } + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ImportWSDLLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ImportWSDLLoader.java new file mode 100644 index 0000000000..1b642704f0 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ImportWSDLLoader.java @@ -0,0 +1,96 @@ +/** + * + * Copyright 2006 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.assembly.recursive; + +import static org.apache.tuscany.core.loader.assembly.recursive.AssemblyConstants.IMPORT_WSDL; + +import java.io.IOException; +import java.net.URL; + +import javax.wsdl.Definition; +import javax.wsdl.WSDLException; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.common.resource.ResourceLoader; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.config.MissingResourceException; +import org.apache.tuscany.core.config.SidefileLoadException; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.loader.StAXUtil; +import org.apache.tuscany.core.loader.WSDLDefinitionRegistry; +import org.apache.tuscany.core.loader.assembly.AbstractLoader; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.model.assembly.ImportWSDL; +import org.osoa.sca.annotations.Scope; + +/** + * Loader that handles <import.wsdl> elements. + * + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class ImportWSDLLoader extends AbstractLoader { + private WSDLDefinitionRegistry wsdlRegistry; + + @Autowire + public void setWsdlRegistry(WSDLDefinitionRegistry wsdlRegistry) { + this.wsdlRegistry = wsdlRegistry; + } + + public QName getXMLType() { + return IMPORT_WSDL; + } + + public ImportWSDL load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert AssemblyConstants.IMPORT_WSDL.equals(reader.getName()); + String namespace = reader.getAttributeValue(null, "namespace"); + String location = reader.getAttributeValue(null, "location"); + if (location == null) + location = reader.getAttributeValue(null, "wsdlLocation"); + ImportWSDL importWSDL = factory.createImportWSDL(location, namespace); + + Definition definition = loadDefinition(namespace, location, loaderContext.getResourceLoader()); +// importWSDL.setDefinition(definition); + + StAXUtil.skipToEndElement(reader); + return importWSDL; + } + + protected Definition loadDefinition(String namespace, String location, ResourceLoader resourceLoader) throws MissingResourceException, SidefileLoadException { + Definition definition; + URL wsdlURL = resourceLoader.getResource(location); + if (wsdlURL == null) { + throw new MissingResourceException(location); + } + + try { + definition = wsdlRegistry.loadDefinition(namespace, wsdlURL, resourceLoader); + } catch (IOException e) { + SidefileLoadException sfe = new SidefileLoadException(e.getMessage()); + sfe.setResourceURI(location); + throw sfe; + } catch (WSDLException e) { + SidefileLoadException sfe = new SidefileLoadException(e.getMessage()); + sfe.setResourceURI(location); + throw sfe; + } + + return definition; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/InterfaceJavaLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/InterfaceJavaLoader.java new file mode 100644 index 0000000000..84d988be0a --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/InterfaceJavaLoader.java @@ -0,0 +1,46 @@ +/** + * + * Copyright 2006 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.assembly.recursive; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.loader.assembly.AbstractLoader; +import org.apache.tuscany.model.assembly.Scope; +import org.apache.tuscany.model.types.java.JavaServiceContract; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +/** + * @version $Rev$ $Date$ + */ +@org.osoa.sca.annotations.Scope("MODULE") +public class InterfaceJavaLoader extends AbstractLoader { + public QName getXMLType() { + return AssemblyConstants.INTERFACE_JAVA; + } + + public JavaServiceContract load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert AssemblyConstants.INTERFACE_JAVA.equals(reader.getName()); + JavaServiceContract serviceContract = factory.createJavaServiceContract(); + serviceContract.setScope(Scope.INSTANCE); + serviceContract.setInterfaceName(reader.getAttributeValue(null, "interface")); + serviceContract.setCallbackInterfaceName(reader.getAttributeValue(null, "callbackInterface")); + return serviceContract; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/InterfaceWSDLLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/InterfaceWSDLLoader.java new file mode 100644 index 0000000000..4da0261afa --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/InterfaceWSDLLoader.java @@ -0,0 +1,111 @@ +/** + * + * Copyright 2006 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.assembly.recursive; + +import java.io.IOException; + +import org.apache.tuscany.common.resource.ResourceLoader; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.config.MissingInterfaceException; +import org.apache.tuscany.core.loader.WSDLDefinitionRegistry; +import org.apache.tuscany.core.loader.StAXUtil; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.loader.assembly.AbstractLoader; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.model.assembly.Scope; +import org.apache.tuscany.model.types.wsdl.WSDLServiceContract; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.wsdl.PortType; +import javax.wsdl.WSDLException; + +/** + * @version $Rev$ $Date$ + */ +@org.osoa.sca.annotations.Scope("MODULE") +public class InterfaceWSDLLoader extends AbstractLoader { + private static final String WSDLI = "http://www.w3.org/2006/01/wsdl-instance"; + private static final String WSDLI_LOCATION = "wsdlLocation"; + + private WSDLDefinitionRegistry wsdlRegistry; + + @Autowire + public void setWsdlRegistry(WSDLDefinitionRegistry wsdlRegistry) { + this.wsdlRegistry = wsdlRegistry; + } + + public QName getXMLType() { + return AssemblyConstants.INTERFACE_WSDL; + } + + public WSDLServiceContract load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert AssemblyConstants.INTERFACE_WSDL.equals(reader.getName()); + WSDLServiceContract serviceContract = factory.createWSDLServiceContract(); + serviceContract.setScope(Scope.INSTANCE); + + ResourceLoader resourceLoader = loaderContext.getResourceLoader(); + + String location = reader.getAttributeValue(WSDLI, WSDLI_LOCATION); + if (location != null) { + try { + wsdlRegistry.loadDefinition(location, resourceLoader); + } catch (IOException e) { + throw new MissingInterfaceException(e); + } catch (WSDLException e) { + throw new MissingInterfaceException(e); + } + } + + String portTypeURI = reader.getAttributeValue(null, "interface"); + if (portTypeURI != null) { + serviceContract.setPortType(getPortType(portTypeURI, resourceLoader)); + } + + portTypeURI = reader.getAttributeValue(null, "callbackInterface"); + if (portTypeURI != null) { + serviceContract.setCallbackPortType(getPortType(portTypeURI, resourceLoader)); + } + StAXUtil.skipToEndElement(reader); + return serviceContract; + } + + protected PortType getPortType(String uri, ResourceLoader resourceLoader) throws MissingInterfaceException { + + // We currently support two syntaxes for specifying a WSDL portType: + // namespace#portTypeName, this is what we supported in the initial contribution, we will + // deprecate this after M1 + // namespace#wsdl.interface(portTypeName), this is the WSDL 2.0 syntax + + int index = uri.indexOf('#'); + String namespace = uri.substring(0, index); + String fragment = uri.substring(index + 1); + String localName; + if (fragment.startsWith("wsdl.interface(") && fragment.endsWith(")")) { + localName = fragment.substring(15, fragment.length()-1); + } else { + localName = fragment; + } + QName qname = new QName(namespace, localName); + PortType portType = wsdlRegistry.getPortType(qname, resourceLoader); + if (portType == null) { + throw new MissingInterfaceException(uri); + } + return portType; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/PropertyLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/PropertyLoader.java new file mode 100644 index 0000000000..5f4ffa5637 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/PropertyLoader.java @@ -0,0 +1,81 @@ +/** + * + * 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.assembly.recursive; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.StAXUtil; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.loader.assembly.AbstractLoader; + +import static org.apache.tuscany.core.loader.assembly.recursive.AssemblyConstants.PROPERTY; +import org.apache.tuscany.model.assembly.Property; +import org.osoa.sca.annotations.Scope; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import java.util.HashMap; +import java.util.Map; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class PropertyLoader extends AbstractLoader { + private static final String XSD = "http://www.w3.org/2001/XMLSchema"; + + private static final Map> TYPE_MAP; + static { + // todo support more XSD types, or remove if we store the QName + TYPE_MAP = new HashMap>(17); + TYPE_MAP.put(new QName(XSD, "string"), String.class); + } + + public QName getXMLType() { + return PROPERTY; + } + + public Property load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert PROPERTY.equals(reader.getName()); + Property property = factory.createProperty(); + property.setName(reader.getAttributeValue(null, "name")); + String typeName = reader.getAttributeValue(null, "type"); + // support XSD type or Java class name + // todo perhaps we should just store the QName for the PropertyFactory to use + int index = typeName.indexOf(':'); + if (index != -1) { + String prefix = typeName.substring(0, index); + String namespaceURI = reader.getNamespaceURI(prefix); + QName qname = new QName(namespaceURI, typeName.substring(index+1)); + property.setType(TYPE_MAP.get(qname)); + } else { + try { + Class type = loaderContext.getResourceLoader().loadClass(typeName); + property.setType(type); + } catch (ClassNotFoundException e) { + throw new ConfigurationLoadException(e); + } + } + property.setMany(Boolean.parseBoolean(reader.getAttributeValue(null, "many"))); + property.setDefaultValue(reader.getAttributeValue(null, "default")); + String required = reader.getAttributeValue(null, "required"); + property.setRequired(required != null && Boolean.valueOf(required)); + + StAXUtil.skipToEndElement(reader); + return property; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ReferenceLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ReferenceLoader.java new file mode 100644 index 0000000000..a254455092 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ReferenceLoader.java @@ -0,0 +1,66 @@ +/** + * + * 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.assembly.recursive; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import static org.apache.tuscany.core.loader.assembly.recursive.AssemblyConstants.REFERENCE; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.loader.StAXUtil; +import org.apache.tuscany.core.loader.assembly.AbstractLoader; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Multiplicity; +import org.apache.tuscany.model.assembly.Reference; +import org.apache.tuscany.model.assembly.ServiceContract; +import org.osoa.sca.annotations.Scope; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class ReferenceLoader extends AbstractLoader { + public QName getXMLType() { + return REFERENCE; + } + + public Reference load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert REFERENCE.equals(reader.getName()); + Reference reference = factory.createReference(); + reference.setName(reader.getAttributeValue(null, "name")); + reference.setMultiplicity(StAXUtil.multiplicity(reader.getAttributeValue(null, "multiplicity"), Multiplicity.ONE_ONE)); + + while (true) { + switch (reader.next()) { + case START_ELEMENT: + AssemblyObject o = registry.load(reader, loaderContext); + if (o instanceof ServiceContract) { + reference.setServiceContract((ServiceContract) o); + } + reader.next(); + break; + case END_ELEMENT: + return reference; + } + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ServiceLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ServiceLoader.java new file mode 100644 index 0000000000..614ab82d98 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/ServiceLoader.java @@ -0,0 +1,62 @@ +/** + * + * 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.assembly.recursive; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import static org.apache.tuscany.core.loader.assembly.recursive.AssemblyConstants.SERVICE; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.loader.assembly.AbstractLoader; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Service; +import org.apache.tuscany.model.assembly.ServiceContract; +import org.osoa.sca.annotations.Scope; + +import javax.xml.namespace.QName; +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class ServiceLoader extends AbstractLoader { + public QName getXMLType() { + return SERVICE; + } + + public Service load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert SERVICE.equals(reader.getName()); + Service service = factory.createService(); + service.setName(reader.getAttributeValue(null, "name")); + + while (true) { + switch (reader.next()) { + case START_ELEMENT: + AssemblyObject o = registry.load(reader, loaderContext); + if (o instanceof ServiceContract) { + service.setServiceContract((ServiceContract) o); + } + reader.next(); + break; + case END_ELEMENT: + return service; + } + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/WireLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/WireLoader.java new file mode 100644 index 0000000000..1d82ca195f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/assembly/recursive/WireLoader.java @@ -0,0 +1,85 @@ +/** + * + * 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.loader.assembly.recursive; + +import java.util.HashMap; +import java.util.Map; +import javax.xml.namespace.QName; +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.loader.assembly.AbstractLoader; +import org.apache.tuscany.model.assembly.Wire; +import org.osoa.sca.annotations.Scope; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class WireLoader extends AbstractLoader { + private static final String XSD = "http://www.w3.org/2001/XMLSchema"; + + private static final Map> TYPE_MAP; + + static { + // todo support more XSD types, or remove if we store the QName + TYPE_MAP = new HashMap>(17); + TYPE_MAP.put(new QName(XSD, "string"), String.class); + } + + public QName getXMLType() { + return AssemblyConstants.WIRE; + } + + public Wire load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert AssemblyConstants.WIRE.equals(reader.getName()); + Wire wire = factory.createWire(); + while (true) { + switch (reader.next()) { + case START_ELEMENT: + QName qname = reader.getName(); + if (AssemblyConstants.WIRE_SOURCE.equals(qname)) { + String uri = reader.getElementText(); + int pos = uri.indexOf('/'); + if (pos < 1) { + throw new ConfigurationLoadException("Invalid source wire"); + } + String partName = uri.substring(0, pos); + String portName = uri.substring(pos + 1); + wire.setSource(factory.createServiceURI(null, partName, portName)); + } else if (AssemblyConstants.WIRE_TARGET.equals(qname)) { + String uri = reader.getElementText(); + int pos = uri.indexOf('/'); + if (pos < 1) { + wire.setTarget(factory.createServiceURI(null, uri)); + }else{ + String partName = uri.substring(0, pos); + String portName = uri.substring(pos + 1); + wire.setTarget(factory.createServiceURI(null, partName, portName)); + } + } + break; + case END_ELEMENT: + return wire; + } + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/JNDIPropertyFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/JNDIPropertyFactory.java new file mode 100644 index 0000000000..763c88295c --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/JNDIPropertyFactory.java @@ -0,0 +1,62 @@ +/** + * + * Copyright 2006 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 javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamException; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import org.apache.tuscany.core.loader.StAXPropertyFactory; +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.injection.JNDIObjectFactory; +import org.apache.tuscany.model.assembly.Property; + +/** + * A StAXPropertyFactory that creates property values by looking them + * up in the default JNDI InitialContext. + * + * This can be used to locate resources in a J2EE environment and inject + * them as configuration properties. For example, to access a database + * a component could write: + * + * &at;Property DataSource myDB; + * + * and configure with + * + * <properties> + * <v:myDb>java:comp/env/jdbc/MyDatabase</v:myDB> + * </properties> + * + * + * @version $Rev$ $Date$ + */ +public class JNDIPropertyFactory implements StAXPropertyFactory { + public ObjectFactory createObjectFactory(XMLStreamReader reader, Property property) throws XMLStreamException, ConfigurationLoadException { + Class type = property.getType(); + assert type != null : "property type is null"; + String text = reader.getElementText(); + try { + Context context = new InitialContext(); + return new JNDIObjectFactory(context, text); + } catch (NamingException e) { + throw new ConfigurationLoadException(e); + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/StAXLoaderRegistryImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/StAXLoaderRegistryImpl.java new file mode 100644 index 0000000000..1e9e8ec8fb --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/StAXLoaderRegistryImpl.java @@ -0,0 +1,105 @@ +/** + * + * 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 org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.StAXElementLoader; +import org.apache.tuscany.core.loader.StAXLoaderRegistry; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.osoa.sca.annotations.Scope; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import java.util.HashMap; +import java.util.Map; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class StAXLoaderRegistryImpl implements StAXLoaderRegistry { + private final Map> loaders = new HashMap>(); + + private Monitor monitor; + + @org.apache.tuscany.core.system.annotation.Monitor + public void setMonitor(Monitor monitor) { + this.monitor = monitor; + } + + public void registerLoader(QName element, StAXElementLoader loader) { + monitor.registeringLoader(element); + loaders.put(element, loader); + } + + public void unregisterLoader(QName element, StAXElementLoader loader) { + monitor.unregisteringLoader(element); + loaders.remove(element); + } + + public AssemblyObject load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + QName name = reader.getName(); + monitor.elementLoad(name); + StAXElementLoader loader = loaders.get(name); + if (loader == null) { + ConfigurationLoadException e = new ConfigurationLoadException("Unrecognized element"); + e.setIdentifier(name.toString()); + throw e; + } else { + return loader.load(reader, loaderContext); + } + } + + + private final ThreadLocal modelContext = new ThreadLocal(); + + @Deprecated + public AssemblyContext getContext() { + return modelContext.get(); + } + + @Deprecated + public void setContext(AssemblyContext context) { + modelContext.set(context); + } + + public static interface Monitor { + /** + * Event emitted when a StAX element loader is registered. + * + * @param xmlType the QName of the element the loader will handle + */ + void registeringLoader(QName xmlType); + + /** + * Event emitted when a StAX element loader is unregistered. + * + * @param xmlType the QName of the element the loader will handle + */ + void unregisteringLoader(QName xmlType); + + /** + * Event emitted when a request is made to load an element. + * + * @param xmlType the QName of the element that should be loaded + */ + void elementLoad(QName xmlType); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/StringParserPropertyFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/StringParserPropertyFactory.java new file mode 100644 index 0000000000..2ed33f895c --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/StringParserPropertyFactory.java @@ -0,0 +1,110 @@ +/** + * + * Copyright 2006 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 org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.injection.SingletonObjectFactory; +import org.apache.tuscany.core.loader.StAXPropertyFactory; +import org.apache.tuscany.model.assembly.Property; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import java.beans.PropertyEditor; +import java.beans.PropertyEditorManager; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +@Service(interfaces = {StAXPropertyFactory.class}) +public class StringParserPropertyFactory implements StAXPropertyFactory { + public ObjectFactory createObjectFactory(XMLStreamReader reader, Property property) throws XMLStreamException, ConfigurationLoadException { + Class type = property.getType(); + assert type != null : "property type is null"; + String text = reader.getElementText(); + + // degenerate case where we are returning a String + if (String.class.equals(type)) { + return new SingletonObjectFactory(text); + } + + // special handler to convert hexBinary to a byte[] + if (byte[].class.equals(type)) { + byte[] instance = new byte[text.length() >> 1]; + for (int i = 0; i < instance.length; i++) { + instance[i] = (byte) (Character.digit(text.charAt(i << 1), 16) << 4 | Character.digit(text.charAt((i << 1) + 1), 16)); + } + return new SingletonObjectFactory(instance); + } + + // does this type have a static valueOf(String) method? + try { + Method valueOf = type.getMethod("valueOf", String.class); + if (Modifier.isStatic(valueOf.getModifiers())) { + try { + return new SingletonObjectFactory(valueOf.invoke(null, text)); + } catch (IllegalAccessException e) { + throw new AssertionError("getMethod returned an inaccessible method"); + } catch (InvocationTargetException e) { + // FIXME we should throw something better + throw new ConfigurationLoadException(e.getCause()); + } + } + } catch (NoSuchMethodException e) { + // try something else + } + + // does this type have a constructor that takes a String? + try { + Constructor ctr = type.getConstructor(String.class); + return new SingletonObjectFactory(ctr.newInstance(text)); + } catch (NoSuchMethodException e) { + // try something else + } catch (IllegalAccessException e) { + throw new AssertionError("getConstructor returned an inaccessible method"); + } catch (InstantiationException e) { + throw new ConfigurationLoadException("Property type cannot be instantiated: " + type.getName()); + } catch (InvocationTargetException e) { + // FIXME we should throw something better + throw new ConfigurationLoadException(e.getCause()); + } + + // do we have a property editor for it? + PropertyEditor editor = PropertyEditorManager.findEditor(type); + if (editor != null) { + try { + editor.setAsText(text); + return new SingletonObjectFactory(editor.getValue()); + } catch (IllegalArgumentException e) { + // FIXME we should throw something better + throw new ConfigurationLoadException(e); + + } + } + + // FIXME we should throw something better + throw new ConfigurationLoadException("Do not have a way to parse a String into a " + type.getName()); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/WSDLDefinitionRegistryImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/WSDLDefinitionRegistryImpl.java new file mode 100644 index 0000000000..1063dec3fc --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/impl/WSDLDefinitionRegistryImpl.java @@ -0,0 +1,202 @@ +/** + * + * Copyright 2006 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.io.IOException; +import java.net.URL; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; + +import javax.wsdl.Definition; +import javax.wsdl.PortType; +import javax.wsdl.Service; +import javax.wsdl.WSDLException; +import javax.wsdl.extensions.ExtensionRegistry; +import javax.wsdl.factory.WSDLFactory; +import javax.wsdl.xml.WSDLReader; +import javax.xml.namespace.QName; + +import org.apache.tuscany.common.resource.ResourceLoader; +import org.apache.tuscany.core.loader.WSDLDefinitionRegistry; +import org.osoa.sca.annotations.Scope; + +/** + * @version $Rev$ $Date$ + */ +@org.osoa.sca.annotations.Service(interfaces = {WSDLDefinitionRegistry.class}) +@Scope("MODULE") +public class WSDLDefinitionRegistryImpl implements WSDLDefinitionRegistry { + private final WSDLFactory wsdlFactory; + private final ExtensionRegistry registry; + + private final Map> definitionsByLocationByLoader = new WeakHashMap>(); + private final Map>> definitionsByNamespaceByLoader = new WeakHashMap>>(); + + private Monitor monitor; + + public WSDLDefinitionRegistryImpl() throws WSDLException { + wsdlFactory = WSDLFactory.newInstance(); + registry = wsdlFactory.newPopulatedExtensionRegistry(); + } + + @org.apache.tuscany.core.system.annotation.Monitor + public void setMonitor(Monitor monitor) { + this.monitor = monitor; + } + + public ExtensionRegistry getExtensionRegistry() { + return registry; + } + + public Definition loadDefinition(String wsdlLocation, ResourceLoader resourceLoader) throws IOException, WSDLException { + int index = wsdlLocation.indexOf(' '); + if (index == -1) { + throw new WSDLException(WSDLException.CONFIGURATION_ERROR, "Invalid wsdlLocation: " + wsdlLocation); + } + String namespace = wsdlLocation.substring(0, index).trim(); + URL url; + URI uri; + try { + uri = new URI(wsdlLocation.substring(index + 1).trim()); + } catch (URISyntaxException e) { + throw new WSDLException(WSDLException.CONFIGURATION_ERROR, "Invalid wsdlLocation: " + wsdlLocation); + } + if (uri.isAbsolute()) { + url = uri.toURL(); + } else { + url = resourceLoader.getResource(uri.toString()); + if (url == null) { + throw new WSDLException(WSDLException.CONFIGURATION_ERROR, "Resource not found: " + uri); + } + } + return loadDefinition(namespace, url, resourceLoader); + } + + public Definition loadDefinition(String namespace, URL location, ResourceLoader resourceLoader) throws IOException, WSDLException { + Map definitionsByLocation = getDefinitionsByLocation(resourceLoader); + Map> definitionsByNamespace = getDefinitionsByNamespace(resourceLoader); + + Definition definition = definitionsByLocation.get(location); + if (definition != null) { + // return cached copy + return definition; + } + + monitor.readingWSDL(namespace, location); + WSDLReader reader = wsdlFactory.newWSDLReader(); + reader.setFeature("javax.wsdl.verbose", false); + reader.setExtensionRegistry(registry); + + definition = reader.readWSDL(location.toString()); + String definitionNamespace = definition.getTargetNamespace(); + if (namespace != null && !namespace.equals(definitionNamespace)) { + throw new WSDLException(WSDLException.CONFIGURATION_ERROR, namespace + " != " + definition.getTargetNamespace()); + } + + monitor.cachingDefinition(definitionNamespace, location); + definitionsByLocation.put(location, definition); + List definitions = definitionsByNamespace.get(definitionNamespace); + if (definitions == null) { + definitions = new ArrayList(); + definitionsByNamespace.put(definitionNamespace, definitions); + } + definitions.add(definition); + + return definition; + } + + public List getDefinitionsForNamespace(String namespace, ResourceLoader resourceLoader) { + Map> definitionsByNamespace = getDefinitionsByNamespace(resourceLoader); + return definitionsByNamespace.get(namespace); + } + + public PortType getPortType(QName name, ResourceLoader resourceLoader) { + Map> definitionsByNamespace = getDefinitionsByNamespace(resourceLoader); + String namespace = name.getNamespaceURI(); + List definitions = definitionsByNamespace.get(namespace); + if (definitions == null) { + return null; + } + for (Definition definition : definitions) { + PortType portType = definition.getPortType(name); + if (portType != null) { + return portType; + } + } + return null; + } + + public Service getService(QName name, ResourceLoader resourceLoader) { + Map> definitionsByNamespace = getDefinitionsByNamespace(resourceLoader); + String namespace = name.getNamespaceURI(); + List definitions = definitionsByNamespace.get(namespace); + if (definitions == null) { + return null; + } + for (Definition definition : definitions) { + Service service = definition.getService(name); + if (service != null) { + return service; + } + } + return null; + } + + private Map> getDefinitionsByNamespace(ResourceLoader resourceLoader) { + Map> map = definitionsByNamespaceByLoader.get(resourceLoader); + if (map == null) { + map = new HashMap>(); + definitionsByNamespaceByLoader.put(resourceLoader, map); + } + return map; + } + + private Map getDefinitionsByLocation(ResourceLoader resourceLoader) { + Map map = definitionsByLocationByLoader.get(resourceLoader); + if (map == null) { + map = new HashMap(); + definitionsByLocationByLoader.put(resourceLoader, map); + } + return map; + } + + public static interface Monitor { + /** + * Monitor event emitted immediately before an attempt is made to + * read WSDL for the supplied namespace from the supplied location. + * + * @param namespace the target namespace expected in the WSDL; may be null + * @param location the location where we will attempt to read the WSDL definition from + */ + void readingWSDL(String namespace, URL location); + + /** + * Monitor event emitted immediately before registering a WSDL definition + * in the cache. + * + * @param namespace the target namespace for the WSDL + * @param location the location where the WSDL definition was read from + */ + void cachingDefinition(String namespace, URL location); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/system/SystemBindingLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/system/SystemBindingLoader.java new file mode 100644 index 0000000000..d75f25a232 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/system/SystemBindingLoader.java @@ -0,0 +1,47 @@ +/** + * + * Copyright 2006 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.system; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.StAXUtil; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.loader.assembly.AbstractLoader; +import org.apache.tuscany.core.system.assembly.SystemBinding; +import org.osoa.sca.annotations.Scope; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class SystemBindingLoader extends AbstractLoader { + public static final QName SYSTEM_BINDING = new QName("http://org.apache.tuscany/xmlns/system/0.9", "binding.system"); + + protected QName getXMLType() { + return SYSTEM_BINDING; + } + + public SystemBinding load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert SystemBindingLoader.SYSTEM_BINDING.equals(reader.getName()); + SystemBinding binding = factory.createSystemBinding(); + StAXUtil.skipToEndElement(reader); + return binding; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/system/SystemImplementationLoader.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/system/SystemImplementationLoader.java new file mode 100644 index 0000000000..b9f35d8656 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/loader/system/SystemImplementationLoader.java @@ -0,0 +1,68 @@ +/** + * + * 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.system; + +import org.apache.tuscany.core.config.ComponentTypeIntrospector; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.StAXUtil; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.loader.assembly.AbstractLoader; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.core.system.assembly.SystemImplementation; +import org.osoa.sca.annotations.Scope; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class SystemImplementationLoader extends AbstractLoader { + public static final QName SYSTEM_IMPLEMENTATION = new QName("http://org.apache.tuscany/xmlns/system/0.9", "implementation.system"); + + private ComponentTypeIntrospector introspector; + + @Autowire + public void setIntrospector(ComponentTypeIntrospector introspector) { + this.introspector = introspector; + } + + protected QName getXMLType() { + return SYSTEM_IMPLEMENTATION; + } + + public SystemImplementation load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assert SYSTEM_IMPLEMENTATION.equals(reader.getName()); + SystemImplementation implementation = factory.createSystemImplementation(); + String implClass = reader.getAttributeValue(null, "class"); + Class implementationClass; + try { + implementationClass = loaderContext.getResourceLoader().loadClass(implClass); + implementation.setImplementationClass(implementationClass); + } catch (ClassNotFoundException e) { + throw new ConfigurationLoadException(e); + } + + // todo we should allow componentType sidefiles for system implementations + implementation.setComponentType(introspector.introspect(implementationClass)); + + StAXUtil.skipToEndElement(reader); + return implementation; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/message/Message.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/message/Message.java new file mode 100644 index 0000000000..dc623af1fc --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/message/Message.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.message; + +import org.apache.tuscany.core.wire.MessageChannel; +import org.apache.tuscany.core.wire.TargetInvoker; + +/** + * Represents a request, response, or exception flowing through a wire + * + * @version $Rev $Date + */ +public interface Message { + + /** + * Returns the body of the message, which will be the payload or parameters associated with the wire + */ + Object getBody(); + + /** + * Sets the body of the message. + */ + void setBody(Object body); + + /** + * Sets the target invoker to dispatch to when the message passes through the request side of the invocation chain + */ + public void setTargetInvoker(TargetInvoker invoker); + + /** + * Sets the target invoker to dispatch to when the message passes through the request side of the invocation chain + */ + public TargetInvoker getTargetInvoker(); + + /** + * Returns the callback channel + */ + public MessageChannel getCallbackChannel(); + + /** + * + */ + public Message getRelatedCallbackMessage(); +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/message/MessageFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/message/MessageFactory.java new file mode 100644 index 0000000000..265e4ba601 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/message/MessageFactory.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.message; + +/** + * A factory for creating messages flowed through a wire during an invocation + */ +public interface MessageFactory { + + /** + * Returns a new message. + */ + Message createMessage(); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/message/impl/MessageFactoryImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/message/impl/MessageFactoryImpl.java new file mode 100644 index 0000000000..a30f17a938 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/message/impl/MessageFactoryImpl.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.message.impl; + +import org.apache.tuscany.core.message.Message; +import org.apache.tuscany.core.message.MessageFactory; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Init; + +/** + * The default message factory + * + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class MessageFactoryImpl implements MessageFactory { + + public MessageFactoryImpl() { + super(); + } + + @Init(eager = true) + public void init(){ + } + + public Message createMessage() { + return new MessageImpl(); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/message/impl/MessageImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/message/impl/MessageImpl.java new file mode 100644 index 0000000000..f7f365952c --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/message/impl/MessageImpl.java @@ -0,0 +1,86 @@ +/** + * + * 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.wire.MessageChannel; +import org.apache.tuscany.core.wire.TargetInvoker; + +/** + * The default implementation of a message flowed through a wire during an invocation + * + * @version $Rev $Date + */ +public class MessageImpl implements Message, MessageChannel { + + private Object body; + private Message relatedCallbackMessage; + private TargetInvoker invoker; + + protected MessageImpl() { + super(); + } + + /** + * @see org.apache.tuscany.core.message.Message#getBody() + */ + public Object getBody() { + return body; + } + + /** + * @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#getCallbackChannel() + */ + public MessageChannel getCallbackChannel() { + return this; + } + + /** + * @see org.apache.tuscany.core.wire.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.wire.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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeContext.java new file mode 100644 index 0000000000..16e1fc6483 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeContext.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.runtime; + +import org.apache.tuscany.core.builder.WireBuilder; +import org.apache.tuscany.core.context.AutowireContext; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.ConfigurationContext; +import org.apache.tuscany.core.context.SystemCompositeContext; + +/** + * 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 composite context containing all system components in the runtime */ + public static final String SYSTEM = "tuscany.system"; + + /* the symbolic name of the composite 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 CompositeContext 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 SystemCompositeContext getSystemContext(); + + /** + * Adds a wire builder to the runtime + */ + @Deprecated + public void addBuilder(WireBuilder builder); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeContextImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeContextImpl.java new file mode 100644 index 0000000000..0ebc063b90 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeContextImpl.java @@ -0,0 +1,221 @@ +/** + * + * 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.List; + +import org.apache.tuscany.common.monitor.MonitorFactory; +import org.apache.tuscany.core.builder.BuilderConfigException; +import org.apache.tuscany.core.builder.ContextFactoryBuilderRegistry; +import org.apache.tuscany.core.builder.HierarchicalWireBuilder; +import org.apache.tuscany.core.builder.WireBuilder; +import org.apache.tuscany.core.builder.impl.AssemblyVisitorImpl; +import org.apache.tuscany.core.builder.impl.ContextFactoryBuilderRegistryImpl; +import org.apache.tuscany.core.config.ConfigurationException; +import org.apache.tuscany.core.context.AutowireContext; +import org.apache.tuscany.core.context.AutowireResolutionException; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.ConfigurationContext; +import org.apache.tuscany.core.context.Context; +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.ScopeContext; +import org.apache.tuscany.core.context.SystemCompositeContext; +import org.apache.tuscany.core.context.TargetException; +import org.apache.tuscany.core.context.impl.AbstractContext; +import org.apache.tuscany.core.context.impl.CompositeContextImpl; +import org.apache.tuscany.core.context.impl.EventContextImpl; +import org.apache.tuscany.core.system.context.SystemCompositeContextImpl; +import org.apache.tuscany.core.system.context.SystemScopeStrategy; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Composite; +import org.apache.tuscany.model.assembly.Extensible; + +/** + * Implementation of a RuntimeContext that forms the foundation for a Tuscany environment. + * + * @version $Rev$ $Date$ + */ +public class RuntimeContextImpl extends AbstractContext implements RuntimeContext { + + // the top-level wire builder in the runtime + private final HierarchicalWireBuilder wireBuilder; + + //private final List listeners = new ArrayList(1); + + private final CompositeContext rootContext; + + private final SystemCompositeContext systemContext; + + private final MonitorFactory monitorFactory; + + private final ContextFactoryBuilderRegistryImpl builderRegistry; + + public RuntimeContextImpl(MonitorFactory monitorFactory, ContextFactoryBuilderRegistry builderRegistry, HierarchicalWireBuilder wireBuilder) { + super(RUNTIME); + this.monitorFactory = monitorFactory; + this.builderRegistry = (ContextFactoryBuilderRegistryImpl) builderRegistry; + this.wireBuilder = wireBuilder; + + rootContext = new CompositeContextImpl(ROOT, this, this, new RuntimeScopeStrategy(), new EventContextImpl(), this); + systemContext = new SystemCompositeContextImpl(SYSTEM, this, this, new SystemScopeStrategy(), new EventContextImpl(), this); + } + + 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(WireBuilder builder) { + assert (builder != null) : "Builder was null"; + wireBuilder.addWireBuilder(builder); + } + + public Context getContext(String ctxName) { + checkRunning(); + if (ROOT.equals(ctxName)) { + return rootContext; + } else if (SYSTEM.equals(ctxName)) { + return systemContext; + } + return rootContext.getContext(ctxName); + } + + public CompositeContext getRootContext() { + checkRunning(); + return rootContext; + } + + public SystemCompositeContext getSystemContext() { + checkRunning(); + return systemContext; + } + + public void registerModelObject(Extensible model) throws ConfigurationException { + assert (model != null) : "Model was null"; + // note do not configure or buildSource model object since the root context will perform a call back + rootContext.registerModelObject(model); + } + + public void registerModelObjects(List models) throws ConfigurationException { + for (Extensible model : models) { + registerModelObject(model); + } + } + + public CompositeContext getParent() { + return null; // there is no parent + } + + public void setParent(CompositeContext parent) { + throw new UnsupportedOperationException(); + } + + public String getURI() { + return null; + } + + public void setURI(String uri) { + } + + public void setAssemblyContext(AssemblyContext context) { + + } + + //TODO remove + public void fireEvent(int pEventType, Object pMessage) throws EventException { + throw new UnsupportedOperationException(); + } + + public Object locateService(QualifiedName serviceName) { + return null; + } + + public Object locateInstance(QualifiedName serviceName) { + return null; + } + + public Object getInstance(QualifiedName qName) throws TargetException { + return getSystemContext().getInstance(qName); + } + + public synchronized void build(AssemblyObject model) throws BuilderConfigException { + AssemblyVisitorImpl visitor = new AssemblyVisitorImpl(builderRegistry.getBuilders()); + visitor.start(model); + } + + public void connect(SourceWireFactory sourceFactory, TargetWireFactory targetFactory, Class targetType, boolean downScope, + ScopeContext targetScopeContext) throws BuilderConfigException { + wireBuilder.connect(sourceFactory, targetFactory, targetType, downScope, targetScopeContext); + } + + public void completeTargetChain(TargetWireFactory targetFactory, Class targetType, ScopeContext targetScopeContext) + throws BuilderConfigException { + wireBuilder.completeTargetChain(targetFactory, targetType, targetScopeContext); + } + + public T resolveInstance(Class 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 if (ContextFactoryBuilderRegistry.class.equals(instanceInterface)) { + return instanceInterface.cast(builderRegistry); + } else { + // autowire to system components + return instanceInterface.cast(getSystemContext().resolveExternalInstance(instanceInterface)); + } + } + + public T resolveExternalInstance(Class instanceInterface) throws AutowireResolutionException { + return systemContext.resolveExternalInstance(instanceInterface); + } + + public Composite getComposite() { + return systemContext.getComposite(); + } + + public void removeContext(String name) { + + } + + private void checkRunning() { + if (lifecycleState != RUNNING) { + throw new IllegalStateException("Context must be in RUNNING state"); + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeMonitor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeMonitor.java new file mode 100644 index 0000000000..c1b87d6a13 --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeScopeStrategy.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/runtime/RuntimeScopeStrategy.java new file mode 100644 index 0000000000..5051c2674d --- /dev/null +++ b/branches/java-post-M1/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 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.CompositeScopeContext; +import org.apache.tuscany.model.assembly.Scope; + +import java.util.HashMap; +import java.util.Map; + +/** + * 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 getScopeContexts(EventContext eventContext) { + ScopeContext aggregrateScope = new CompositeScopeContext(eventContext); + Map scopes = new HashMap(); + scopes.put(Scope.AGGREGATE, aggregrateScope); + return scopes; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/DataFactoryObjectFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/DataFactoryObjectFactory.java new file mode 100644 index 0000000000..6b35115e1f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/DataFactoryObjectFactory.java @@ -0,0 +1,61 @@ +/** + * + * 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.sdo; + +import commonj.sdo.helper.DataFactory; +import org.apache.tuscany.core.builder.ContextResolver; +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.context.AutowireContext; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.injection.ObjectCreationException; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.sdo.util.SDOUtil; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class DataFactoryObjectFactory implements ObjectFactory { + + private ContextResolver resolver; + + /** + * @throws org.apache.tuscany.core.injection.FactoryInitException + * + */ + public DataFactoryObjectFactory(ContextResolver resolver) { + this.resolver = resolver; + } + + + public DataFactory getInstance() throws ObjectCreationException { + CompositeContext parent = resolver.getCurrentContext(); + if (parent == null) { + return null;// FIXME semantic here means required is not followed + } + if (!(parent instanceof AutowireContext)) { + ObjectCreationException e = new ObjectCreationException("Parent does not implement " + + AutowireContext.class.getName()); + e.setIdentifier(parent.getName()); + throw e; + } + AutowireContext ctx = (AutowireContext) parent; + AssemblyContext assemblyContext = ctx.resolveInstance(AssemblyContext.class); + return SDOUtil.createDataFactory(assemblyContext.getTypeHelper()); + } + + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/TypeHelperObjectFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/TypeHelperObjectFactory.java new file mode 100644 index 0000000000..d345e7be95 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/TypeHelperObjectFactory.java @@ -0,0 +1,61 @@ +/** + * + * 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.sdo; + +import commonj.sdo.helper.TypeHelper; +import org.apache.tuscany.core.builder.ContextResolver; +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.context.AutowireContext; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.injection.ObjectCreationException; +import org.apache.tuscany.model.assembly.AssemblyContext; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class TypeHelperObjectFactory implements ObjectFactory { + + + private ContextResolver resolver; + + /** + * @throws org.apache.tuscany.core.injection.FactoryInitException + * + */ + public TypeHelperObjectFactory(ContextResolver resolver) { + this.resolver = resolver; + } + + + public TypeHelper getInstance() throws ObjectCreationException { + CompositeContext parent = resolver.getCurrentContext(); + if (parent == null) { + return null;// FIXME semantic here means required is not followed + } + if (!(parent instanceof AutowireContext)) { + ObjectCreationException e = new ObjectCreationException("Parent does not implement " + + AutowireContext.class.getName()); + e.setIdentifier(parent.getName()); + throw e; + } + AutowireContext ctx = (AutowireContext) parent; + AssemblyContext assemblyContext = ctx.resolveInstance(AssemblyContext.class); + return assemblyContext.getTypeHelper(); + } + + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/XMLHelperObjectFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/XMLHelperObjectFactory.java new file mode 100644 index 0000000000..04773f9770 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/XMLHelperObjectFactory.java @@ -0,0 +1,61 @@ +/** + * + * 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.sdo; + +import commonj.sdo.helper.XMLHelper; +import org.apache.tuscany.core.builder.ContextResolver; +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.context.AutowireContext; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.injection.ObjectCreationException; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.sdo.util.SDOUtil; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class XMLHelperObjectFactory implements ObjectFactory { + + + private ContextResolver resolver; + + /** + * @throws org.apache.tuscany.core.injection.FactoryInitException + * + */ + public XMLHelperObjectFactory(ContextResolver resolver) { + this.resolver = resolver; + } + + + public XMLHelper getInstance() throws ObjectCreationException { + CompositeContext parent = resolver.getCurrentContext(); + if (parent == null) { + return null;// FIXME semantic here means required is not followed + } + if (!(parent instanceof AutowireContext)) { + ObjectCreationException e = new ObjectCreationException("Parent does not implement " + + AutowireContext.class.getName()); + e.setIdentifier(parent.getName()); + throw e; + } + AutowireContext ctx = (AutowireContext) parent; + AssemblyContext assemblyContext = ctx.resolveInstance(AssemblyContext.class); + return SDOUtil.createXMLHelper(assemblyContext.getTypeHelper()); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/XSDHelperObjectFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/XSDHelperObjectFactory.java new file mode 100644 index 0000000000..eaddf15cb2 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/XSDHelperObjectFactory.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.sdo; + +import commonj.sdo.helper.XSDHelper; +import org.apache.tuscany.core.builder.ContextResolver; +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.context.AutowireContext; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.injection.ObjectCreationException; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.sdo.util.SDOUtil; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class XSDHelperObjectFactory implements ObjectFactory { + + + private ContextResolver resolver; + + /** + * @throws org.apache.tuscany.core.injection.FactoryInitException + * + */ + public XSDHelperObjectFactory(ContextResolver resolver) { + this.resolver = resolver; + } + + + public XSDHelper getInstance() throws ObjectCreationException { + CompositeContext parent = resolver.getCurrentContext(); + if (parent == null) { + return null;// FIXME semantic here means required is not followed + } + if (!(parent instanceof AutowireContext)) { + ObjectCreationException e = new ObjectCreationException("Parent does not implement " + + AutowireContext.class.getName()); + e.setIdentifier(parent.getName()); + throw e; + } + AutowireContext ctx = (AutowireContext) parent; + AssemblyContext assemblyContext = ctx.resolveInstance(AssemblyContext.class); + return SDOUtil.createXSDHelper(assemblyContext.getTypeHelper()); + } + + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/helper/SDOHelper.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/helper/SDOHelper.java new file mode 100644 index 0000000000..a804fc51b4 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/helper/SDOHelper.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.sdo.helper; + +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; + +/** + * Annotation used to indicate a field or method that is used to inject an SDO helper. + * + * The following helpers are supported: + * commonj.sdo.helper.TypeHelper + * commonj.sdo.helper.DataFactory + * commonj.sdo.helper.XSDHelper + * commonj.sdo.helper.XMLHelper + * + */ +@Target({METHOD, FIELD}) +@Retention(RUNTIME) +public @interface SDOHelper { + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/helper/SDOHelperExtensibilityElement.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/helper/SDOHelperExtensibilityElement.java new file mode 100644 index 0000000000..c6f84fa485 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/helper/SDOHelperExtensibilityElement.java @@ -0,0 +1,80 @@ +/** + * + * 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.sdo.helper; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import commonj.sdo.helper.DataFactory; +import commonj.sdo.helper.TypeHelper; +import commonj.sdo.helper.XMLHelper; +import commonj.sdo.helper.XSDHelper; +import org.apache.tuscany.core.builder.ContextResolver; +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.extension.config.InjectorExtensibilityElement; +import org.apache.tuscany.core.injection.FieldInjector; +import org.apache.tuscany.core.injection.Injector; +import org.apache.tuscany.core.injection.MethodInjector; +import org.apache.tuscany.core.injection.ObjectCreationException; +import org.apache.tuscany.core.sdo.DataFactoryObjectFactory; +import org.apache.tuscany.core.sdo.TypeHelperObjectFactory; +import org.apache.tuscany.core.sdo.XMLHelperObjectFactory; +import org.apache.tuscany.core.sdo.XSDHelperObjectFactory; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class SDOHelperExtensibilityElement implements InjectorExtensibilityElement { + + private Method method; + private Field field; + private Class type; + + public SDOHelperExtensibilityElement(Method m) { + method = m; + assert(method != null); + assert(method.getParameterTypes().length == 1); + type = method.getParameterTypes()[0]; + } + + public SDOHelperExtensibilityElement(Field field) { + assert (field != null); + this.field = field; + this.type = field.getType(); + } + + public Injector getInjector(ContextResolver resolver) { + ObjectFactory factory; + if (TypeHelper.class.equals(type)) { + factory = new TypeHelperObjectFactory(resolver); + } else if (DataFactory.class.equals(type)) { + factory = new DataFactoryObjectFactory(resolver); + } else if (XSDHelper.class.equals(type)) { + factory = new XSDHelperObjectFactory(resolver); + } else if (XMLHelper.class.equals(type)) { + factory = new XMLHelperObjectFactory(resolver); + } else { + ObjectCreationException e = new ObjectCreationException("Unknown type"); + e.setIdentifier(type.getName()); + throw e; + } + if (method != null) { + return new MethodInjector(method, factory); + } + return new FieldInjector(field, factory); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/helper/SDOHelperProcessor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/helper/SDOHelperProcessor.java new file mode 100644 index 0000000000..dc8d97779f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/sdo/helper/SDOHelperProcessor.java @@ -0,0 +1,78 @@ +/** + * + * 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.sdo.helper; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.config.InvalidSetterException; +import org.apache.tuscany.core.config.processor.ImplementationProcessorSupport; +import org.apache.tuscany.model.assembly.ComponentType; +import org.osoa.sca.annotations.Scope; + +/** + * @version $$Rev$$ $$Date$$ + */ +@Scope("Module") +public class SDOHelperProcessor extends ImplementationProcessorSupport { + + @Override + public void visitMethod(Method method, ComponentType type) throws ConfigurationLoadException { + if (method.getDeclaringClass().equals(Object.class)) { + return; + } + SDOHelper annotation = method.getAnnotation(SDOHelper.class); + if (annotation != null) { + if (!Modifier.isPublic(method.getModifiers())) { + InvalidSetterException e = new InvalidSetterException("SDO setter method is not public"); + e.setIdentifier(method.toString()); + throw e; + } + Class[] params = method.getParameterTypes(); + if (params.length != 1) { + InvalidSetterException e = new InvalidSetterException("SDO setter method must have one parameter"); + e.setIdentifier(method.toString()); + throw e; + } + type.getExtensibilityElements().add(new SDOHelperExtensibilityElement(method)); + + } + + + } + + @Override + public void visitField(Field field, ComponentType type) throws ConfigurationLoadException { + if (field.getDeclaringClass().equals(Object.class)) { + return; + } + int modifiers = field.getModifiers(); + SDOHelper annotation = field.getAnnotation(SDOHelper.class); + if (annotation != null) { + if (!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers)) { + InvalidSetterException e = new InvalidSetterException("Property field is not public or protected"); + e.setIdentifier(field.getName()); + throw e; + } + type.getExtensibilityElements().add(new SDOHelperExtensibilityElement(field)); + } + } + + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/Autowire.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/Autowire.java new file mode 100644 index 0000000000..5eb1f6b926 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/Autowire.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.system.annotation; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Target; + +/** + * A system annotation to inject an autowired instance + * + * @version $Rev$ $Date$ + */ +@Target( { METHOD, FIELD }) +@Retention(RUNTIME) +public @interface Autowire { + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/Monitor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/Monitor.java new file mode 100644 index 0000000000..aa552b8e0d --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/Monitor.java @@ -0,0 +1,32 @@ +/** + * + * Copyright 2006 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.system.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.Retention; +import java.lang.annotation.ElementType; +import java.lang.annotation.RetentionPolicy; + +/** + * A system annotation to inject a monitor + * + * @version $Rev: 392146 $ $Date: 2006-04-06 18:11:28 -0700 (Thu, 06 Apr 2006) $ + */ +@Target( { ElementType.METHOD, ElementType.FIELD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface Monitor { +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/ParentContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/ParentContext.java new file mode 100644 index 0000000000..a9d07dbb5f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/annotation/ParentContext.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.system.annotation; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemAssemblyFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemAssemblyFactory.java new file mode 100644 index 0000000000..fea8d24ba6 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemAssemblyFactory.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.system.assembly; + +import org.apache.tuscany.model.assembly.AssemblyFactory; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.EntryPoint; +import org.apache.tuscany.model.assembly.Scope; + +/** + * 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 module + */ + SystemModule createSystemModule(); + + /** + * Returns an assembly model artifact representing a system binding + */ + SystemBinding createSystemBinding(); + + /** + * Helper method for creating a typical system component. + * + * @param name the name of the component + * @param service the service that the component provides + * @param impl the component implementation + * @param scope the component's scope + * @return a Component model object with the appropriate system implementation + */ + Component createSystemComponent(String name, Class service, Class impl, Scope scope); + + /** + * Helper method for creating a system entry point wired to a component. + * + * @param entryPointName the name of the entry point + * @param serviceContract the service contract exposed + * @param targetName the component to wire the entry point to + * @return a EntryPoint model object that exposes the service contract and is wired to the named component + */ + EntryPoint createSystemEntryPoint(String entryPointName, Class serviceContract, String targetName); +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemBinding.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemBinding.java new file mode 100644 index 0000000000..edc7c87c85 --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemImplementation.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemImplementation.java new file mode 100644 index 0000000000..a6a024ceca --- /dev/null +++ b/branches/java-post-M1/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.AtomicImplementation; + +/** + * Represents a system component implementation + * + * @version $Rev$ $Date$ + */ +public interface SystemImplementation extends AtomicImplementation { + + /** + * 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemModule.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemModule.java new file mode 100644 index 0000000000..a43aca67a2 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/SystemModule.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.system.assembly; + +/** + * + */ +import org.apache.tuscany.model.assembly.Module; + +public interface SystemModule extends Module { + + /** + * 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemAssemblyFactoryImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemAssemblyFactoryImpl.java new file mode 100644 index 0000000000..c0d97c9a35 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemAssemblyFactoryImpl.java @@ -0,0 +1,84 @@ +/** + * + * 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.core.system.assembly.SystemModule; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.ComponentType; +import org.apache.tuscany.model.assembly.EntryPoint; +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.types.java.JavaServiceContract; + +/** + * 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(); + } + + public Component createSystemComponent(String name, Class service, Class impl, Scope scope) { + JavaServiceContract jsc = createJavaServiceContract(); + jsc.setInterface(service); + jsc.setScope(scope); + Service s = createService(); + s.setServiceContract(jsc); + + ComponentType componentType = createComponentType(); + componentType.getServices().add(s); + + SystemImplementation sysImpl = createSystemImplementation(); + sysImpl.setImplementationClass(impl); + sysImpl.setComponentType(componentType); + + Component sc = createSimpleComponent(); + sc.setName(name); + sc.setImplementation(sysImpl); + return sc; + } + + public EntryPoint createSystemEntryPoint(String entryPointName, Class serviceContract, String targetName) { + // create the system binding + SystemBinding systemBinding = createSystemBinding(); + + // define the EP's service contract + JavaServiceContract javaServiceContract = createJavaServiceContract(); + javaServiceContract.setInterface(serviceContract); + + return createEntryPoint(entryPointName, javaServiceContract, systemBinding, targetName); + } + + public SystemModule createSystemModule() { + return new SystemModuleImpl(); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemBindingImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemBindingImpl.java new file mode 100644 index 0000000000..a9996065e2 --- /dev/null +++ b/branches/java-post-M1/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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemImplementationImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemImplementationImpl.java new file mode 100644 index 0000000000..cca3aef1bb --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemImplementationImpl.java @@ -0,0 +1,45 @@ +/** + * + * 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.SystemImplementation; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.model.assembly.impl.AtomicImplementationImpl; + +/** + * The default implementation of the system implementation assembly artifact + * + * @version $Rev$ $Date$ + */ +public class SystemImplementationImpl extends AtomicImplementationImpl implements SystemImplementation { + + private Class implementationClass; + + private AssemblyContext modelContext; + + protected SystemImplementationImpl() { + } + + public Class getImplementationClass() { + return implementationClass; + } + + public void setImplementationClass(Class value) { + checkNotFrozen(); + implementationClass = value; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemModuleImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemModuleImpl.java new file mode 100644 index 0000000000..98198cba85 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/assembly/impl/SystemModuleImpl.java @@ -0,0 +1,174 @@ +/** + * + * 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.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.core.system.assembly.SystemModule; +import org.apache.tuscany.core.system.context.SystemCompositeContextImpl; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.model.assembly.AssemblyFactory; +import org.apache.tuscany.model.assembly.AssemblyVisitor; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.ComponentType; +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.EntryPoint; +import org.apache.tuscany.model.assembly.ExternalService; +import org.apache.tuscany.model.assembly.Implementation; +import org.apache.tuscany.model.assembly.ModuleFragment; +import org.apache.tuscany.model.assembly.Multiplicity; +import org.apache.tuscany.model.assembly.OverrideOption; +import org.apache.tuscany.model.assembly.Reference; +import org.apache.tuscany.model.assembly.Service; +import org.apache.tuscany.model.assembly.ServiceContract; +import org.apache.tuscany.model.assembly.ServiceURI; +import org.apache.tuscany.model.assembly.Wire; +import org.apache.tuscany.model.assembly.impl.CompositeImpl; + +/** + * An implementation of Module. + */ +public class SystemModuleImpl extends CompositeImpl implements SystemModule { + + private List moduleFragments = new ArrayList(); + private Map moduleFragmentsMap; + private ComponentType componentType; + private Object contextFactory; + + /** + * Constructor + */ + protected SystemModuleImpl() { + } + + /** + * @see org.apache.tuscany.model.assembly.Implementation#getComponentType() + */ + public ComponentType getComponentType() { + return componentType; + } + + /** + * @see org.apache.tuscany.model.assembly.Implementation#setComponentType(org.apache.tuscany.model.assembly.ComponentType) + */ + public void setComponentType(ComponentType componentType) { + checkNotFrozen(); + this.componentType = componentType; + } + + /** + * @see org.apache.tuscany.model.assembly.Module#getModuleFragments() + */ + public List getModuleFragments() { + return moduleFragments; + } + + /** + * @see org.apache.tuscany.model.assembly.Module#getModuleFragment(java.lang.String) + */ + public ModuleFragment getModuleFragment(String name) { + checkInitialized(); + return moduleFragmentsMap.get(name); + } + + /** + * @see org.apache.tuscany.model.assembly.AssemblyObject#initialize(org.apache.tuscany.model.assembly.AssemblyContext) + */ + public void initialize(AssemblyContext modelContext) { + if (isInitialized()) + return; + + // Initialize module fragments + for (ModuleFragment moduleFragment : moduleFragments) { + + // Add all WSDL imports, components, entry points and external services from the module fragments + getWSDLImports().addAll(moduleFragment.getWSDLImports()); + getComponents().addAll(moduleFragment.getComponents()); + getEntryPoints().addAll(moduleFragment.getEntryPoints()); + getExternalServices().addAll(moduleFragment.getExternalServices()); + + // Add all the wires from the module fragments + getWires().addAll(moduleFragment.getWires()); + + moduleFragment.initialize(modelContext); + } + + // Initialize the composite + super.initialize(modelContext); + } + + /** + * @see org.apache.tuscany.model.assembly.AssemblyObject#freeze() + */ + public void freeze() { + if (isFrozen()) + return; + super.freeze(); + + // Freeze component type and module fragments + if (componentType != null) + componentType.freeze(); + moduleFragments = Collections.unmodifiableList(moduleFragments); + freeze(moduleFragments); + } + + /** + * @see org.apache.tuscany.model.assembly.ContextFactoryHolder#getContextFactory() + */ + public Object getContextFactory() { + return contextFactory; + } + + /** + * @see org.apache.tuscany.model.assembly.ContextFactoryHolder#setContextFactory(java.lang.Object) + */ + public void setContextFactory(Object configuration) { + checkNotFrozen(); + this.contextFactory = configuration; + } + + /** + * @see org.apache.tuscany.model.assembly.impl.CompositeImpl#accept(org.apache.tuscany.model.assembly.AssemblyVisitor) + */ + public boolean accept(AssemblyVisitor visitor) { + if (!super.accept(visitor)) + return false; + + if (componentType != null) { + if (!componentType.accept(visitor)) + return false; + } + + return accept(moduleFragments, visitor); + + } + + public Class getImplementationClass() { + return SystemCompositeContextImpl.class; // FIXME hack + } + + public void setImplementationClass(Class clazz) { + // do nothing + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemContextFactoryBuilder.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemContextFactoryBuilder.java new file mode 100644 index 0000000000..835324c392 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemContextFactoryBuilder.java @@ -0,0 +1,343 @@ +/** + * + * 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.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.ContextFactoryBuilder; +import org.apache.tuscany.core.builder.ContextResolver; +import org.apache.tuscany.core.builder.NoAccessorException; +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.builder.UnknownTypeException; +import org.apache.tuscany.core.builder.impl.ArrayMultiplicityObjectFactory; +import org.apache.tuscany.core.builder.impl.ListMultiplicityObjectFactory; +import org.apache.tuscany.core.config.JavaIntrospectionHelper; +import org.apache.tuscany.core.context.impl.CompositeContextImpl; +import org.apache.tuscany.core.extension.config.InjectorExtensibilityElement; +import org.apache.tuscany.core.extension.config.extensibility.ComponentNameExtensibilityElement; +import org.apache.tuscany.core.extension.config.extensibility.ContextExtensibilityElement; +import org.apache.tuscany.core.extension.config.extensibility.DestroyInvokerExtensibilityElement; +import org.apache.tuscany.core.extension.config.extensibility.InitInvokerExtensibilityElement; +import org.apache.tuscany.core.injection.EventInvoker; +import org.apache.tuscany.core.injection.FactoryInitException; +import org.apache.tuscany.core.injection.FieldInjector; +import org.apache.tuscany.core.injection.Injector; +import org.apache.tuscany.core.injection.MethodInjector; +import org.apache.tuscany.core.injection.NonProxiedTargetFactory; +import org.apache.tuscany.core.injection.SingletonObjectFactory; +import org.apache.tuscany.core.system.assembly.SystemImplementation; +import org.apache.tuscany.core.system.assembly.SystemModule; +import org.apache.tuscany.core.system.config.SystemContextFactory; +import org.apache.tuscany.core.system.config.SystemInjectorExtensibilityElement; +import org.apache.tuscany.core.system.config.extensibility.MonitorExtensibilityElement; +import org.apache.tuscany.core.system.context.SystemCompositeContextImpl; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.Composite; +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.Implementation; +import org.apache.tuscany.model.assembly.Module; +import org.apache.tuscany.model.assembly.Multiplicity; +import org.apache.tuscany.model.assembly.Scope; +import org.apache.tuscany.model.assembly.Service; + +/** + * Decorates components whose implementation type is a {@link org.apache.tuscany.core.system.assembly.SystemImplementation} + * with the appropriate runtime configuration. This builder handles both system composite components as well + * as system leaf or "simple" components. Consequently, both simple and composite component types may be + * injected and autowired. + *

+ * Note that system component references are not proxied. + * + * @version $Rev$ $Date$ + */ +public class SystemContextFactoryBuilder implements ContextFactoryBuilder { + + private final MonitorFactory monitorFactory; + + public SystemContextFactoryBuilder(MonitorFactory monitorFactory) { + this.monitorFactory = monitorFactory; + } + + @SuppressWarnings("unchecked") + public void build(AssemblyObject modelObject) throws BuilderException { + if (!(modelObject instanceof Component)) { + return; + } + Component component = (Component) modelObject; + + Class implClass; + Scope scope; + // Get the component implementation + Implementation componentImplementation = component.getImplementation(); + if (componentImplementation instanceof SystemImplementation + && component.getContextFactory() == null) { + + // The component is a system component, implemented by a Java class + SystemImplementation implementation = (SystemImplementation) componentImplementation; + if (componentImplementation.getComponentType().getServices() == null + || componentImplementation.getComponentType().getServices().size() < 1) { + BuilderConfigException e = new BuilderConfigException("No service configured on component type"); + e.setIdentifier(component.getName()); + throw e; + } + implClass = implementation.getImplementationClass(); + Scope previous = null; + scope = Scope.MODULE; + List services = component.getImplementation().getComponentType().getServices(); + for (Service service : services) { + // calculate and validate the scope of the component; ensure that all service scopes are the same unless + // a scope is stateless + Scope current = service.getServiceContract().getScope(); + if (previous != null && current != null && current != previous + && (current != Scope.INSTANCE && previous != Scope.INSTANCE)) { + BuilderException e = new BuilderConfigException("Incompatible scopes specified for services on component"); + e.setIdentifier(component.getName()); + throw e; + } + if (current != null && current != Scope.MODULE) { + scope = current; + } + } + + } else if (componentImplementation instanceof Composite) { + implClass = ((Composite) componentImplementation).getImplementationClass(); + if (implClass == null) { + // FIXME this is a hack + 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 = SystemCompositeContextImpl.class; + } else if (componentImplementation instanceof SystemModule) { + implClass = SystemCompositeContextImpl.class; + } else { + // The component is an app module component, fix the implementation class to our implementation + // of app module component context + //FIXME this should be extensible, i.e. the model should specify the impl class of the module + implClass = CompositeContextImpl.class; + } + //END hack + } + scope = Scope.AGGREGATE; + } else { + return; + } + Set fields; + Set methods; + SystemContextFactory contextFactory; + try { + fields = JavaIntrospectionHelper.getAllFields(implClass); + methods = JavaIntrospectionHelper.getAllUniqueMethods(implClass); + String name = component.getName(); + if (componentImplementation instanceof Module) { + Module module = (Module) componentImplementation; + contextFactory = new SystemContextFactory(name, module, JavaIntrospectionHelper.getDefaultConstructor(implClass), scope); + + } else { + contextFactory = new SystemContextFactory(name, JavaIntrospectionHelper.getDefaultConstructor(implClass), scope); + } + + //ContextObjectFactory contextObjectFactory = new ContextObjectFactory(contextFactory); + + List injectors = new ArrayList(); + + // handle properties + List 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 != CompositeContextImpl.class) { + // handle references + List configuredReferences = component.getConfiguredReferences(); + if (configuredReferences != null) { + for (ConfiguredReference reference : configuredReferences) { + Injector injector = createReferenceInjector(reference, fields, methods, contextFactory); + injectors.add(injector); + } + } + } + List elements = componentImplementation.getComponentType().getExtensibilityElements(); + for (Object element : elements) { + if (element instanceof InitInvokerExtensibilityElement) { + InitInvokerExtensibilityElement invokerElement = (InitInvokerExtensibilityElement) element; + EventInvoker initInvoker = invokerElement.getEventInvoker(); + boolean eagerInit = invokerElement.isEager(); + contextFactory.setEagerInit(eagerInit); + contextFactory.setInitInvoker(initInvoker); + } else if (element instanceof DestroyInvokerExtensibilityElement) { + DestroyInvokerExtensibilityElement invokerElement = (DestroyInvokerExtensibilityElement) element; + EventInvoker destroyInvoker = invokerElement.getEventInvoker(); + contextFactory.setDestroyInvoker(destroyInvoker); + } else if (element instanceof ComponentNameExtensibilityElement) { + ComponentNameExtensibilityElement nameElement = (ComponentNameExtensibilityElement) element; + injectors.add(nameElement.getEventInvoker(name)); + } else if (element instanceof ContextExtensibilityElement) { + ContextExtensibilityElement contextElement = (ContextExtensibilityElement) element; + injectors.add(contextElement.getInjector(contextFactory)); + } else if (element instanceof InjectorExtensibilityElement) { + InjectorExtensibilityElement injectorElement = (InjectorExtensibilityElement) element; + injectors.add(injectorElement.getInjector(contextFactory)); + } else if (element instanceof SystemInjectorExtensibilityElement) { + SystemInjectorExtensibilityElement injectorElement = (SystemInjectorExtensibilityElement) element; + injectors.add(injectorElement.getInjector(contextFactory)); + } else if (element instanceof MonitorExtensibilityElement) { + MonitorExtensibilityElement monitorElement = (MonitorExtensibilityElement) element; + injectors.add(monitorElement.getInjector(monitorFactory)); + } + } + contextFactory.setSetters(injectors); + // decorate the logical model + component.setContextFactory(contextFactory); + } catch (BuilderConfigException e) { + e.addContextName(component.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; + } catch (FactoryInitException e) { + BuilderConfigException ce = new BuilderConfigException("Error building component", e); + ce.addContextName(component.getName()); + throw ce; + } + } + + /** + * Creates an Injector for component properties + */ + private Injector createPropertyInjector(ConfiguredProperty property, Set fields, Set 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; + // FIXME support types other than String + 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 object factories that resolve target(s) of a reference and an Injector responsible + * for injecting them into the reference + */ + private Injector createReferenceInjector(ConfiguredReference reference, Set fields, Set methods, + ContextResolver resolver) { + + List objectFactories = new ArrayList(); + String refName = reference.getPort().getName(); + Class refClass = reference.getPort().getServiceContract().getInterface(); + for (ConfiguredService configuredService : reference.getTargetConfiguredServices()) { + objectFactories.add(new NonProxiedTargetFactory(configuredService, resolver)); + } + boolean multiplicity = reference.getPort().getMultiplicity() == Multiplicity.ONE_N + || reference.getPort().getMultiplicity() == Multiplicity.ZERO_N; + return createInjector(refName, refClass, multiplicity, objectFactories, fields, methods); + + } + + /** + * Creates an Injector for an object factories associated with a reference. + */ + private Injector createInjector(String refName, Class refClass, boolean multiplicity, List objectFactories, + Set fields, Set methods) throws NoAccessorException, BuilderConfigException { + Field field; + Method method = null; + if (multiplicity) { + // since this is a multiplicity, we cannot match on business interface type, so scan through the fields, + // matching on name and List or Array + field = JavaIntrospectionHelper.findMultiplicityFieldByName(refName, fields); + if (field == null) { + // No fields found. Again, since this is a multiplicity, we cannot match on interface type, so + // scan through the fields, matching on name and List or Array + method = JavaIntrospectionHelper.findMultiplicityMethodByName(refName, methods); + if (method == null) { + throw new NoAccessorException(refName); + } + } + Injector injector; + if (field != null) { + // for multiplicities, we need to inject the target or targets using an object factory + // which first delegates to create the proxies and then returns them in the appropriate List or array + // type + if (field.getType().isArray()) { + injector = new FieldInjector(field, new ArrayMultiplicityObjectFactory(refClass, objectFactories)); + } else { + injector = new FieldInjector(field, new ListMultiplicityObjectFactory(objectFactories)); + } + } else { + if (method.getParameterTypes()[0].isArray()) { + injector = new MethodInjector(method, new ArrayMultiplicityObjectFactory(refClass, objectFactories)); + } else { + injector = new MethodInjector(method, new ListMultiplicityObjectFactory(objectFactories)); + } + } + return injector; + } else { + field = JavaIntrospectionHelper.findClosestMatchingField(refName, refClass, fields); + if (field == null) { + method = JavaIntrospectionHelper.findClosestMatchingMethod(refName, new Class[]{refClass}, methods); + if (method == null) { + throw new NoAccessorException(refName); + } + } + Injector injector; + if (field != null) { + injector = new FieldInjector(field, objectFactories.get(0)); + } else { + injector = new MethodInjector(method, objectFactories.get(0)); + } + return injector; + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemEntryPointBuilder.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemEntryPointBuilder.java new file mode 100644 index 0000000000..c366da53d6 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemEntryPointBuilder.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.system.builder; + +import org.apache.tuscany.core.builder.BuilderException; +import org.apache.tuscany.core.builder.BuilderInitException; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.core.injection.FactoryInitException; +import org.apache.tuscany.core.system.assembly.SystemBinding; +import org.apache.tuscany.core.system.config.SystemEntryPointContextFactory; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.ConfiguredService; +import org.apache.tuscany.model.assembly.EntryPoint; + +/** + * Decorates the logical model with entry point context configuration builders + * + * @version $Rev: 385747 $ $Date: 2006-03-13 22:12:53 -0800 (Mon, 13 Mar 2006) $ + */ +public class SystemEntryPointBuilder implements ContextFactoryBuilder { + + public SystemEntryPointBuilder() { + } + + public void build(AssemblyObject modelObject) throws BuilderException { + if (!(modelObject instanceof EntryPoint)) { + return; + } + EntryPoint entryPoint = (EntryPoint) modelObject; + if (!(entryPoint.getBindings().get(0) instanceof SystemBinding) + || entryPoint.getContextFactory() != null) { + return; + } + try { + String targetName; + ConfiguredService targetService = entryPoint.getConfiguredReference().getTargetConfiguredServices().get(0); + Class serviceInterface = entryPoint.getConfiguredReference().getPort().getServiceContract().getInterface(); + if (targetService.getPart() == null) { + // FIXME not correct + if (targetService.getPort() == null) { + BuilderInitException e = new BuilderInitException("No target service specified on "); + e.setIdentifier(entryPoint.getName()); + } + targetName = targetService.getPort().getName(); + } else { + targetName = targetService.getPart().getName(); + } + SystemEntryPointContextFactory contextFactory = new SystemEntryPointContextFactory(entryPoint.getName(), + targetName, serviceInterface); + entryPoint.setContextFactory(contextFactory); + } catch (FactoryInitException e) { + e.addContextName(entryPoint.getName()); + throw e; + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemExternalServiceBuilder.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemExternalServiceBuilder.java new file mode 100644 index 0000000000..a568e9aa2f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/builder/SystemExternalServiceBuilder.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.system.builder; + +import org.apache.tuscany.core.builder.BuilderConfigException; +import org.apache.tuscany.core.builder.BuilderException; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.core.injection.InterCompositeReferenceFactory; +import org.apache.tuscany.core.system.assembly.SystemBinding; +import org.apache.tuscany.core.system.config.SystemExternalServiceContextFactory; +import org.apache.tuscany.core.system.injection.AutowireObjectFactory; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.ExternalService; + +/** + * Creates runtime configurations for system type external services + * + * @version $Rev$ $Date$ + */ +public class SystemExternalServiceBuilder implements ContextFactoryBuilder { + + public SystemExternalServiceBuilder() { + } + + public void build(AssemblyObject modelObject) throws BuilderException { + if (!(modelObject instanceof ExternalService)) { + return; + } + ExternalService externalService = (ExternalService) modelObject; + if (externalService.getConfiguredService() != null + && externalService.getContextFactory() != 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) { + SystemExternalServiceContextFactory contextFactory = new SystemExternalServiceContextFactory(externalService + .getName(), new InterCompositeReferenceFactory(binding.getTargetName())); + externalService.setContextFactory(contextFactory); + } else if (externalService.getConfiguredService().getPort().getServiceContract().getInterface() != null) { + // autowire + Class claz = externalService.getConfiguredService().getPort().getServiceContract().getInterface(); + if (claz == null) { + BuilderException e = new BuilderConfigException("Interface type not specified"); + e.setIdentifier(externalService.getName()); + e.addContextName(externalService.getName()); + throw e; + } + SystemExternalServiceContextFactory config = new SystemExternalServiceContextFactory(externalService + .getName(), new AutowireObjectFactory(claz)); + externalService.setContextFactory(config); + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemContextFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemContextFactory.java new file mode 100644 index 0000000000..2e4a2916ce --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemContextFactory.java @@ -0,0 +1,208 @@ +/** + * + * 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.system.config; + +import org.apache.tuscany.common.TuscanyRuntimeException; +import org.apache.tuscany.core.builder.ContextCreationException; +import org.apache.tuscany.core.builder.ContextFactory; +import org.apache.tuscany.core.builder.ContextResolver; +import org.apache.tuscany.core.config.ConfigurationException; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.Context; +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.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.core.system.context.SystemAtomicContext; +import org.apache.tuscany.model.assembly.Module; +import org.apache.tuscany.model.assembly.Scope; + +import java.lang.reflect.Constructor; +import java.util.List; +import java.util.Map; + +/** + * A ContextFactory that handles system component implementation types, which may be either simple, leaf + * types or an composites. + *

+ * For composite types, this factory delegates to an {@link org.apache.tuscany.core.builder.ObjectFactory} to create an + * instance of the composite implementation and perform injection of configuration and references. Once an composite + * instance is created, the factory will register the composite's children. This process may be done recursively in a + * lazy fashion, descending down an composite hierarchy as a child composite is instantiated. + * + * @version $Rev$ $Date$ + */ +public class SystemContextFactory implements ContextFactory, ContextResolver { + + // the component name as configured in the hosting module + private String name; + + // if this factory produces composites, the module will be the logical model associated with its children + private Module module; + + private CompositeContext parentContext; + + // the implementation type constructor + private Constructor ctr; + + // injectors for properties, references and other metadata values such as @Context + private List 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 composite context + private boolean isComposite; + + /** + * Creates the runtime configuration + * + * @param name the SCDL name of the component the context refers to + * @param ctr the implementation type constructor + * @param scope the scope of the component implementation type + */ + public SystemContextFactory(String name, Constructor ctr, Scope scope) { + this(name, null, ctr, scope); + } + + /** + * Creates the runtime configuration + * + * @param name the SCDL name of the component the context refers to + * @param module if this factory produces aggregagtes, the logical model associated with its children; otherwise + * null + * @param ctr the implementation type constructor + * @param scope the scope of the component implementation type + */ + public SystemContextFactory(String name, Module module, Constructor ctr, Scope scope) { + assert (name != null) : "Name was null"; + assert (ctr != null) : "Constructor was null"; + this.name = name; + this.module = module; + this.ctr = ctr; + this.isComposite = CompositeContext.class.isAssignableFrom(ctr.getDeclaringClass()); + this.scope = scope; + if (isComposite) { + scope = Scope.AGGREGATE; + } else { + stateless = (scope == Scope.INSTANCE); + } + } + + public String getName() { + return name; + } + + public void addProperty(String propertyName, Object value) { + + } + + public Scope getScope() { + return scope; + } + + public Context createContext() throws ContextCreationException { + if (isComposite) { + try { + // composite context types are themselves an instance context + PojoObjectFactory objectFactory = new PojoObjectFactory(ctr, null, setters); + CompositeContext ctx = objectFactory.getInstance(); + ctx.setName(name); + // the composite has been created, now register its children + if (module != null) { + try { + ctx.registerModelObject(module); + } catch (ConfigurationException e) { + ContextCreationException cce = new ContextCreationException("Error creating context", e); + cce.setIdentifier(getName()); + throw cce; + } + + } + return ctx; + } catch (TuscanyRuntimeException e) { + e.addContextName(name); + throw e; + } + } else { + PojoObjectFactory objectFactory = new PojoObjectFactory(ctr, null, setters); + return new SystemAtomicContext(name, objectFactory, eagerInit, init, destroy, stateless); + } + } + + public void addTargetWireFactory(String serviceName, TargetWireFactory factory) { + throw new UnsupportedOperationException(); + } + + public TargetWireFactory getTargetWireFactory(String serviceName) { + return null; + } + + public Map getTargetWireFactories() { + return null; + } + + public void addSourceWireFactory(String referenceName, SourceWireFactory factory) { + throw new UnsupportedOperationException(); + } + + public void addSourceWireFactories(String referenceName, Class referenceInterface, List factory, boolean multiplicity) { + + } + + public List getSourceWireFactories() { + return null; + } + + public void setSetters(List setters) { + this.setters = setters; + } + + public void setEagerInit(boolean val) { + eagerInit = val; + } + + public void setInitInvoker(EventInvoker invoker) { + init = invoker; + } + + public void setDestroyInvoker(EventInvoker invoker) { + destroy = invoker; + } + + public void prepare(CompositeContext parent) { + parentContext = parent; + } + + public CompositeContext getCurrentContext() { + return parentContext; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemEntryPointContextFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemEntryPointContextFactory.java new file mode 100644 index 0000000000..c9cfeccd6b --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemEntryPointContextFactory.java @@ -0,0 +1,99 @@ +/** + * + * 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 org.apache.tuscany.core.builder.ContextCreationException; +import org.apache.tuscany.core.builder.ContextFactory; +import org.apache.tuscany.core.builder.ContextResolver; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.EntryPointContext; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.system.context.SystemEntryPointContext; +import org.apache.tuscany.model.assembly.Scope; + +import java.util.List; +import java.util.Map; + +/** + * Creates {@link SystemEntryPointContext} instances based on an entry point configuration in an assembly model + * + * @version $Rev$ $Date$ + */ +public class SystemEntryPointContextFactory implements ContextFactory, ContextResolver { + + // the name of the entry point + private String name; + + private CompositeContext parentContext; + + private String targetName; + + private Class serviceInterface; + + public SystemEntryPointContextFactory(String name, String targetName, Class serviceInterface) { + this.name = name; + this.targetName = targetName; + this.serviceInterface = serviceInterface; + } + + public EntryPointContext createContext() throws ContextCreationException { + return new SystemEntryPointContext(name, targetName, serviceInterface, this); + } + + public Scope getScope() { + return Scope.MODULE; + } + + public String getName() { + return name; + } + + + public void addTargetWireFactory(String serviceName, TargetWireFactory pFactory) { + throw new UnsupportedOperationException(); + } + + public TargetWireFactory getTargetWireFactory(String serviceName) { + return null; + } + + public Map getTargetWireFactories() { + return null; + } + + public void addSourceWireFactory(String referenceName, SourceWireFactory pFactory) { + throw new UnsupportedOperationException(); + } + + public void addSourceWireFactories(String referenceName, Class referenceInterface, List factory, boolean multiplicity) { + throw new UnsupportedOperationException(); + } + public void addProperty(String propertyName, Object value) { + + } + + public List getSourceWireFactories() { + return null; + } + + public void prepare(CompositeContext parent) { + this.parentContext = parent; + } + + public CompositeContext getCurrentContext() { + return parentContext; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemExtensibilityElement.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemExtensibilityElement.java new file mode 100644 index 0000000000..14655c2393 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemExtensibilityElement.java @@ -0,0 +1,23 @@ +/** + * + * 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; + +/** + * Base marker for system metadata extensions + * + * @version $$Rev$$ $$Date$$ + */ +public interface SystemExtensibilityElement { + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemExternalServiceContextFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemExternalServiceContextFactory.java new file mode 100644 index 0000000000..d62afa4425 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemExternalServiceContextFactory.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.system.config; + +import org.apache.tuscany.core.builder.ContextCreationException; +import org.apache.tuscany.core.builder.ContextFactory; +import org.apache.tuscany.core.builder.ContextResolver; +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.ExternalServiceContext; +import org.apache.tuscany.core.injection.InterCompositeReferenceFactory; +import org.apache.tuscany.core.system.context.SystemExternalServiceContext; +import org.apache.tuscany.core.system.injection.AutowireObjectFactory; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.model.assembly.Scope; + +import java.util.List; +import java.util.Map; + +/** + * Creates system type external service contexts + * + * @version $Rev$ $Date$ + * @see org.apache.tuscany.core.context.ExternalServiceContext + * @see org.apache.tuscany.core.system.context.SystemExternalServiceContext + */ +public class SystemExternalServiceContextFactory implements ContextFactory, ContextResolver { + + // 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; + + private CompositeContext parentContext; + + public SystemExternalServiceContextFactory(String name, ObjectFactory factory) { + assert (name != null) : "Name was null"; + assert (factory != null) : "Object factory was null"; + this.name = name; + this.factory = factory; + } + + public Scope getScope() { + return Scope.MODULE; + } + + public String getName() { + return name; + } + + public void addProperty(String propertyName, Object value) { + throw new UnsupportedOperationException(); + } + + public ExternalServiceContext createContext() throws ContextCreationException { + return new SystemExternalServiceContext(name, factory); + } + + public void addTargetWireFactory(String serviceName, TargetWireFactory pFactory) { + throw new UnsupportedOperationException(); + } + + public TargetWireFactory getTargetWireFactory(String serviceName) { + return null; + } + + public Map getTargetWireFactories() { + return null; + } + + public void addSourceWireFactory(String referenceName, SourceWireFactory pFactory) { + throw new UnsupportedOperationException(); + } + + public void addSourceWireFactories(String referenceName, Class referenceInterface, List factory, boolean multiplicity) { + + } + + public List getSourceWireFactories() { + return null; + } + + public void prepare(CompositeContext parent) { + parentContext = parent; + if (factory instanceof InterCompositeReferenceFactory) { + ((InterCompositeReferenceFactory) factory).setContextResolver(this); + } else if (factory instanceof AutowireObjectFactory) { + ((AutowireObjectFactory) factory).setContextResolver(this); + } + } + + public CompositeContext getCurrentContext() { + return parentContext; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemInjectorExtensibilityElement.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemInjectorExtensibilityElement.java new file mode 100644 index 0000000000..7fca219399 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemInjectorExtensibilityElement.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.system.config; + +import org.apache.tuscany.core.builder.ContextResolver; +import org.apache.tuscany.core.injection.Injector; + +/** + * An extensiblity element which provides {@link org.apache.tuscany.core.injection.Injector}s based on + * component type metadata specific to system services + * + * @version $$Rev$$ $$Date$$ + */ +public interface SystemInjectorExtensibilityElement { + /** + * Creates an injector + * + * @param resolver that returns the current composite context + */ + public Injector getInjector(ContextResolver resolver); + +} + diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemObjectContextFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemObjectContextFactory.java new file mode 100644 index 0000000000..d4a21dd427 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemObjectContextFactory.java @@ -0,0 +1,98 @@ +/** + * + * 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.system.config; + +import org.apache.tuscany.core.builder.ContextCreationException; +import org.apache.tuscany.core.builder.ContextFactory; +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.Context; +import org.apache.tuscany.core.injection.SingletonObjectFactory; +import org.apache.tuscany.core.wire.WireFactory; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.core.system.context.SystemAtomicContext; +import org.apache.tuscany.model.assembly.Scope; + +import java.util.List; +import java.util.Map; + +/** + * A ContextFactory 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 SystemObjectContextFactory implements ContextFactory { + private final String name; + private final ObjectFactory objectFactory; + + /** + * Construct a ContextFactory 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 SystemObjectContextFactory(String name, Object instance) { + this.name = name; + objectFactory = new SingletonObjectFactory(instance); + } + + public Context createContext() throws ContextCreationException { + return new SystemAtomicContext(name, objectFactory, false, null, null, false); + } + + public Scope getScope() { + return Scope.MODULE; + } + + public String getName() { + return name; + } + + public void addProperty(String propertyName, Object value) { + + } + + public void addTargetWireFactory(String serviceName, TargetWireFactory factory) { + throw new UnsupportedOperationException(); + } + + public TargetWireFactory getTargetWireFactory(String serviceName) { + throw new UnsupportedOperationException(); + } + + public Map getTargetWireFactories() { + throw new UnsupportedOperationException(); + } + + public void addSourceWireFactory(String referenceName, SourceWireFactory factory) { + throw new UnsupportedOperationException(); + } + + public void addSourceWireFactories(String referenceName, Class referenceInterface, List factory, boolean multiplicity) { + + } + + public List getSourceWireFactories() { + throw new UnsupportedOperationException(); + } + + public void prepare(CompositeContext parent) { + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/extensibility/AutowireExtensibilityElement.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/extensibility/AutowireExtensibilityElement.java new file mode 100644 index 0000000000..42d3151c78 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/extensibility/AutowireExtensibilityElement.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.system.config.extensibility; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.apache.tuscany.core.builder.ContextResolver; +import org.apache.tuscany.core.injection.FieldInjector; +import org.apache.tuscany.core.injection.Injector; +import org.apache.tuscany.core.injection.MethodInjector; +import org.apache.tuscany.core.system.config.SystemInjectorExtensibilityElement; +import org.apache.tuscany.core.system.injection.AutowireObjectFactory; + +/** + * A metadata extensbility element for autowires; creates injectors which return the target of an autowire + * + * @version $$Rev$$ $$Date$$ + */ +public class AutowireExtensibilityElement implements SystemInjectorExtensibilityElement { + + private Method method; + private Field field; + + public AutowireExtensibilityElement(Method m) { + assert(m == null || m.getParameterTypes().length == 1): "Illegal number of parameters"; + method = m; + } + + public AutowireExtensibilityElement(Field f) { + field = f; + } + + @SuppressWarnings("unchecked") + public Injector getInjector(ContextResolver resolver) { + if (method != null) { + return new MethodInjector(method, new AutowireObjectFactory(method.getParameterTypes()[0], resolver)); + } else { + return new FieldInjector(field, new AutowireObjectFactory(field.getType(), resolver)); + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/extensibility/MonitorExtensibilityElement.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/extensibility/MonitorExtensibilityElement.java new file mode 100644 index 0000000000..61c89d991b --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/extensibility/MonitorExtensibilityElement.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.system.config.extensibility; + +import java.lang.reflect.Method; +import java.lang.reflect.Field; + +import org.apache.tuscany.core.system.config.SystemExtensibilityElement; +import org.apache.tuscany.core.injection.Injector; +import org.apache.tuscany.core.injection.MethodInjector; +import org.apache.tuscany.core.injection.ContextObjectFactory; +import org.apache.tuscany.core.injection.FieldInjector; +import org.apache.tuscany.core.injection.SingletonObjectFactory; +import org.apache.tuscany.core.builder.ContextResolver; +import org.apache.tuscany.common.monitor.MonitorFactory; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class MonitorExtensibilityElement implements SystemExtensibilityElement { + + private Method method; + private Field field; + + public MonitorExtensibilityElement(Method m) { + assert(m.getParameterTypes().length == 1): "Illegal number of parameters"; + method = m; + } + + public MonitorExtensibilityElement(Field f) { + field = f; + } + + public Injector getInjector(MonitorFactory factory) { + if (method != null) { + Object monitor = factory.getMonitor(method.getParameterTypes()[0]); + return new MethodInjector(method, new SingletonObjectFactory(monitor)); + } else { + Object monitor = factory.getMonitor(field.getType()); + return new FieldInjector(field, new SingletonObjectFactory(monitor)); + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/extensibility/ParentContextExtensibilityElement.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/extensibility/ParentContextExtensibilityElement.java new file mode 100644 index 0000000000..b95b87c8de --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/extensibility/ParentContextExtensibilityElement.java @@ -0,0 +1,54 @@ +/** + * + * 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.system.config.extensibility; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.apache.tuscany.core.builder.ContextResolver; +import org.apache.tuscany.core.injection.ContextObjectFactory; +import org.apache.tuscany.core.injection.FieldInjector; +import org.apache.tuscany.core.injection.Injector; +import org.apache.tuscany.core.injection.MethodInjector; +import org.apache.tuscany.core.system.config.SystemInjectorExtensibilityElement; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class ParentContextExtensibilityElement implements SystemInjectorExtensibilityElement { + + private Method method; + private Field field; + + public ParentContextExtensibilityElement(Method m) { + assert(m.getParameterTypes().length == 1): "Illegal number of parameters"; + method = m; + } + + public ParentContextExtensibilityElement(Field f) { + field = f; + } + + public Injector getInjector(ContextResolver resolver) { + if (method != null) { + return new MethodInjector(method, new ContextObjectFactory(resolver)); + } else { + return new FieldInjector(field, new ContextObjectFactory(resolver)); + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/processor/AutowireProcessor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/processor/AutowireProcessor.java new file mode 100644 index 0000000000..1885a5eaaa --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/processor/AutowireProcessor.java @@ -0,0 +1,90 @@ +/** + * + * 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.system.config.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.config.InvalidSetterException; +import org.apache.tuscany.core.config.processor.ImplementationProcessorSupport; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.core.system.config.extensibility.AutowireExtensibilityElement; +import org.apache.tuscany.core.context.SystemCompositeContext; +import org.apache.tuscany.core.context.ConfigurationContext; +import org.apache.tuscany.core.context.AutowireContext; +import org.apache.tuscany.core.runtime.RuntimeContext; +import org.apache.tuscany.core.builder.BuilderConfigException; +import org.apache.tuscany.model.assembly.ComponentType; +import org.apache.tuscany.common.monitor.MonitorFactory; + +/** + * Processes {@link Autowire} annotations + * + * @version $$Rev$$ $$Date$$ + */ +public class AutowireProcessor extends ImplementationProcessorSupport { + + @Override + public void visitMethod(Method method, ComponentType type) throws ConfigurationLoadException { + Autowire annotation = method.getAnnotation(Autowire.class); + if (annotation != null) { + if (!Modifier.isPublic(method.getModifiers())) { + InvalidSetterException e = new InvalidSetterException("Autowire setter method is not public"); + e.setIdentifier(method.toString()); + throw e; + } + if (method.getParameterTypes().length != 1){ + InvalidSetterException e = new InvalidSetterException("Autowire setter method must have one parameter"); + e.setIdentifier(method.toString()); + throw e; + } + checkAutowireType(method.getParameterTypes()[0],method.getDeclaringClass()); + type.getExtensibilityElements().add(new AutowireExtensibilityElement(method)); + } + } + + @Override + public void visitField(Field field, ComponentType type) throws ConfigurationLoadException { + checkAutowireType(field.getType(),field.getDeclaringClass()); + int modifiers = field.getModifiers(); + Autowire annotation = field.getAnnotation(Autowire.class); + if (annotation != null) { + if (!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers)) { + InvalidSetterException e = new InvalidSetterException("Autowire field is not public or protected"); + e.setIdentifier(field.getName()); + throw e; + } + type.getExtensibilityElements().add(new AutowireExtensibilityElement(field)); + } + } + + + + private void checkAutowireType(Class paramClass, Class declaringClass) throws BuilderConfigException{ + if (SystemCompositeContext.class.isAssignableFrom(declaringClass) + && !(paramClass.equals(ConfigurationContext.class) + || paramClass.equals(MonitorFactory.class) + || paramClass.equals(RuntimeContext.class) || paramClass.equals( + AutowireContext.class))) { + BuilderConfigException e = new BuilderConfigException("Illegal autowire type for system context"); + e.setIdentifier(paramClass.getName()); + throw e; + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/processor/MonitorProcessor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/processor/MonitorProcessor.java new file mode 100644 index 0000000000..9d7f535cc8 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/processor/MonitorProcessor.java @@ -0,0 +1,69 @@ +/** + * + * 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.system.config.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.config.InvalidSetterException; +import org.apache.tuscany.core.config.processor.ImplementationProcessorSupport; +import org.apache.tuscany.core.system.annotation.Monitor; +import org.apache.tuscany.core.system.config.extensibility.MonitorExtensibilityElement; +import org.apache.tuscany.model.assembly.ComponentType; + +/** + * Processes {@link org.apache.tuscany.core.system.annotation.Autowire} annotations + * + * @version $$Rev$$ $$Date$$ + */ +public class MonitorProcessor extends ImplementationProcessorSupport { + + @Override + public void visitMethod(Method method, ComponentType type) throws ConfigurationLoadException { + Monitor annotation = method.getAnnotation(Monitor.class); + if (annotation != null) { + if (!Modifier.isPublic(method.getModifiers())) { + InvalidSetterException e = new InvalidSetterException("Monitor setter method is not public"); + e.setIdentifier(method.toString()); + throw e; + } + if (method.getParameterTypes().length != 1) { + InvalidSetterException e = new InvalidSetterException("Monitor setter method must have one parameter"); + e.setIdentifier(method.toString()); + throw e; + } + type.getExtensibilityElements().add(new MonitorExtensibilityElement(method)); + } + } + + @Override + public void visitField(Field field, ComponentType type) throws ConfigurationLoadException { + int modifiers = field.getModifiers(); + Monitor annotation = field.getAnnotation(Monitor.class); + if (annotation != null) { + if (!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers)) { + InvalidSetterException e = new InvalidSetterException("Monitor field is not public or protected"); + e.setIdentifier(field.getName()); + throw e; + } + type.getExtensibilityElements().add(new MonitorExtensibilityElement(field)); + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/processor/ParentContextProcessor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/processor/ParentContextProcessor.java new file mode 100644 index 0000000000..1ddc68e3e8 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/config/processor/ParentContextProcessor.java @@ -0,0 +1,72 @@ +/** + * + * 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.system.config.processor; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.config.InvalidSetterException; +import org.apache.tuscany.core.config.processor.ImplementationProcessorSupport; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.system.annotation.ParentContext; +import org.apache.tuscany.core.system.config.extensibility.ParentContextExtensibilityElement; +import org.apache.tuscany.model.assembly.ComponentType; + +/** + * Processes {@link org.apache.tuscany.core.system.annotation.Autowire} annotations + * + * @version $$Rev$$ $$Date$$ + */ +public class ParentContextProcessor extends ImplementationProcessorSupport { + + @Override + public void visitMethod(Method method, ComponentType type) throws ConfigurationLoadException { + ParentContext annotation = method.getAnnotation(ParentContext.class); + if (annotation != null) { + if (!Modifier.isPublic(method.getModifiers())) { + InvalidSetterException e = new InvalidSetterException("ParentContext setter method is not public"); + e.setIdentifier(method.toString()); + throw e; + } + if (method.getParameterTypes().length != 1 + && !CompositeContext.class.isAssignableFrom(method.getParameterTypes()[0])) { + InvalidSetterException e = new InvalidSetterException("ParentContext setter method must have one parameter of type " + CompositeContext.class.getName()); + e.setIdentifier(method.toString()); + throw e; + } + type.getExtensibilityElements().add(new ParentContextExtensibilityElement(method)); + } + } + + @Override + public void visitField(Field field, ComponentType type) throws ConfigurationLoadException { + int modifiers = field.getModifiers(); + ParentContext annotation = field.getAnnotation(ParentContext.class); + if (annotation != null) { + if (!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers)) { + InvalidSetterException e = new InvalidSetterException("ParentContext field is not public or protected"); + e.setIdentifier(field.getName()); + throw e; + } + type.getExtensibilityElements().add(new ParentContextExtensibilityElement(field)); + } + } + + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemAtomicContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemAtomicContext.java new file mode 100644 index 0000000000..374555bfb6 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemAtomicContext.java @@ -0,0 +1,159 @@ +/** + * + * 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.injection.EventInvoker; +import org.apache.tuscany.core.injection.ObjectCallbackException; +import org.apache.tuscany.core.injection.ObjectCreationException; +import org.apache.tuscany.core.context.AtomicContext; +import org.apache.tuscany.core.context.impl.AbstractContext; +import org.apache.tuscany.core.context.TargetException; +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.core.context.ContextInitException; +import org.apache.tuscany.core.context.event.InstanceCreated; + +/** + * Manages system component implementation instances + * + * @version $Rev$ $Date$ + */ +public class SystemAtomicContext extends AbstractContext implements AtomicContext { + + private boolean eagerInit; + + private EventInvoker initInvoker; + + private EventInvoker destroyInvoker; + + 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; + + public SystemAtomicContext(String name, ObjectFactory objectFactory, boolean eagerInit, EventInvoker initInvoker, + EventInvoker destroyInvoker, boolean stateless) { + super(name); + assert (objectFactory != null) : "Object factory was null"; + if (eagerInit && 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; + } + + 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 void init() throws TargetException{ + getInstance(null); + } + + public void destroy() throws TargetException { + if (cachedTargetInstance != null) { + if (destroyInvoker != null) { + try { + destroyInvoker.invokeEvent(cachedTargetInstance); + } catch (ObjectCallbackException e) { + throw new TargetException(e.getCause()); + } + } + } + lifecycleState = STARTED; + } + + public synchronized Object getInstance(QualifiedName qName) 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(); + // handle @Init + if (initInvoker != null) { + initInvoker.invokeEvent(instance); + } + publish(new InstanceCreated(this)); + lifecycleState = RUNNING; + if (stateless) { + return instance; + } else { + // cache the actual instance + cachedTargetInstance = instance; + return cachedTargetInstance; + } + } catch (ObjectCreationException e) { + lifecycleState = ERROR; + TargetException te = new TargetException("Error creating component instance", e); + te.setIdentifier(getName()); + throw te; + } + } + + } + + public Object getTargetInstance() throws TargetException { + return getInstance(null); + } + + public boolean isEagerInit() { + return eagerInit; + } + + public boolean isDestroyable() { + return (destroyInvoker != null); + } + + public void start() throws ContextInitException { + if (getLifecycleState() != UNINITIALIZED && getLifecycleState() != STOPPED) { + throw new IllegalStateException("Component must be in UNINITIALIZED state [" + getLifecycleState() + "]"); + } + if (objectFactory == null) { + lifecycleState = ERROR; + ContextInitException e = new ContextInitException("Object factory not found "); + e.setIdentifier(getName()); + throw e; + } + lifecycleState = INITIALIZED; + } + + public void stop() { + lifecycleState = STOPPED; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemCompositeContextImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemCompositeContextImpl.java new file mode 100644 index 0000000000..9ac0abe38a --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemCompositeContextImpl.java @@ -0,0 +1,91 @@ +/** + * + * 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.concurrent.ConcurrentHashMap; + +import org.apache.tuscany.core.config.ConfigurationException; +import org.apache.tuscany.core.context.AutowireContext; +import org.apache.tuscany.core.context.AutowireResolutionException; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.ConfigurationContext; +import org.apache.tuscany.core.context.EventContext; +import org.apache.tuscany.core.context.ScopeContext; +import org.apache.tuscany.core.context.ScopeStrategy; +import org.apache.tuscany.core.context.SystemCompositeContext; +import org.apache.tuscany.core.context.impl.AbstractCompositeContext; +import org.apache.tuscany.core.context.impl.EventContextImpl; +import org.apache.tuscany.core.message.MessageFactory; +import org.apache.tuscany.core.message.impl.MessageFactoryImpl; +import org.apache.tuscany.core.system.config.SystemObjectContextFactory; +import org.apache.tuscany.core.wire.WireFactoryFactory; +import org.apache.tuscany.core.wire.jdk.JDKWireFactoryFactory; + + +/** + * Implements an composite 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 composite 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 SystemCompositeContextImpl extends AbstractCompositeContext implements SystemCompositeContext { + public SystemCompositeContextImpl() { + super(); + eventContext = new EventContextImpl(); + scopeStrategy = new SystemScopeStrategy(); + } + + public SystemCompositeContextImpl(String name, + CompositeContext parent, + AutowireContext autowire, + ScopeStrategy strategy, + EventContext ctx, + ConfigurationContext configCtx + ) { + super(name, parent, strategy, ctx, configCtx); + setAutowireContext(autowire); + scopeIndex = new ConcurrentHashMap(); + } + + public void registerJavaObject(String componentName, Class service, Object instance) throws ConfigurationException { + SystemObjectContextFactory configuration = new SystemObjectContextFactory(componentName, instance); + registerConfiguration(configuration); + ScopeContext scope = scopeContexts.get(configuration.getScope()); + registerAutowireInternal(service, componentName, scope); + } + + // FIXME These should be removed and configured + private static final MessageFactory messageFactory = new MessageFactoryImpl(); + + private static final WireFactoryFactory WIRE_FACTORY_FACTORY = new JDKWireFactoryFactory(); + + public T resolveInstance(Class instanceInterface) throws AutowireResolutionException { + if (CompositeContext.class.equals(instanceInterface)) { + return instanceInterface.cast(this); + } else if (MessageFactory.class.equals(instanceInterface)) { + return instanceInterface.cast(messageFactory); + } else if (WireFactoryFactory.class.equals(instanceInterface)) { + return instanceInterface.cast(WIRE_FACTORY_FACTORY); + } else { + return super.resolveInstance(instanceInterface); + } + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemEntryPointContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemEntryPointContext.java new file mode 100644 index 0000000000..107e676c47 --- /dev/null +++ b/branches/java-post-M1/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.ContextResolver; +import org.apache.tuscany.core.context.impl.AbstractContext; +import org.apache.tuscany.core.context.Context; +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; + +/** + * 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 { + + // a reference to the component's implementation instance exposed by the entry point + private Object cachedInstance; + + private ContextResolver resolver; + + private QualifiedName targetName; + + private Class serviceInterface; + + public SystemEntryPointContext(String name, String targetName, Class serviceInterface, ContextResolver resolver) { + super(name); + assert (resolver != null) : "Context resolver was null"; + assert (targetName != null) : "Target name was null"; + assert (serviceInterface != null) : "Service interface is null"; + this.serviceInterface = serviceInterface; + this.resolver = resolver; + this.targetName = new QualifiedName(targetName); + } + + public Object getInstance(QualifiedName qName) throws TargetException { + try { + if (cachedInstance == null) { + Context ctx = resolver.getCurrentContext().getContext(targetName.getPartName()); + if (ctx == null){ + return null; + } + cachedInstance = ctx.getInstance(targetName); + } + 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 getHandler() throws TargetException { + return getInstance(null); + } + + public Class getServiceInterface() { + return serviceInterface; + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemExternalServiceContext.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemExternalServiceContext.java new file mode 100644 index 0000000000..b85bd2722b --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemExternalServiceContext.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.system.context; + +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.context.impl.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; + + public SystemExternalServiceContext(String name, ObjectFactory factory) { + super(name); + assert (factory != null) : "Object factory was null"; + this.factory = factory; + } + + public Object getInstance(QualifiedName qName) 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 getHandler() throws TargetException { + return this; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemScopeStrategy.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/context/SystemScopeStrategy.java new file mode 100644 index 0000000000..76b9f2856d --- /dev/null +++ b/branches/java-post-M1/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 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.CompositeScopeContext; +import org.apache.tuscany.core.context.scope.ModuleScopeContext; +import org.apache.tuscany.core.context.scope.StatelessScopeContext; +import org.apache.tuscany.model.assembly.Scope; + +import java.util.HashMap; +import java.util.Map; + +/** + * Implements a {@link org.apache.tuscany.core.context.ScopeStrategy} for a system composite context with the following scopes: + *
    + *
  • {@link org.apache.tuscany.model.assembly.Scope#AGGREGATE}
  • + *
  • {@link org.apache.tuscany.model.assembly.Scope#MODULE}
  • + *
  • {@link org.apache.tuscany.model.assembly.Scope#INSTANCE}
  • + *
+ * + * @version $Rev$ $Date$ + */ +public class SystemScopeStrategy extends AbstractScopeStrategy { + + public SystemScopeStrategy() { + } + + public Map getScopeContexts(EventContext eventContext) { + ScopeContext aggregrateScope = new CompositeScopeContext(eventContext); + ScopeContext moduleScoper = new ModuleScopeContext(eventContext); + ScopeContext statelessScope = new StatelessScopeContext(eventContext); + Map scopes = new HashMap(); + scopes.put(Scope.AGGREGATE, aggregrateScope); + scopes.put(Scope.MODULE, moduleScoper); + scopes.put(Scope.INSTANCE, statelessScope); + return scopes; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/injection/AutowireObjectFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/injection/AutowireObjectFactory.java new file mode 100644 index 0000000000..6c1d291673 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/system/injection/AutowireObjectFactory.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.system.injection; + +import org.apache.tuscany.core.builder.ContextResolver; +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.AutowireContext; +import org.apache.tuscany.core.injection.FactoryInitException; +import org.apache.tuscany.core.injection.ObjectCreationException; + +/** + * Returns an instance by resolving against an AutowireContext. + * + * @version $Rev: 385139 $ $Date: 2006-03-11 11:03:11 -0800 (Sat, 11 Mar 2006) $ + */ +public class AutowireObjectFactory implements ObjectFactory { + + private ContextResolver resolver; + + private Class autowireType; + + /** + * + * @throws FactoryInitException + */ + public AutowireObjectFactory(Class autowireType,ContextResolver resolver) { + assert (autowireType != null) : "Target interface was null"; + this.resolver = resolver; + this.autowireType = autowireType; + } + + /** + * Creates a new factory that resolves against the cuurent context using the given implementation type + * + * @throws FactoryInitException + */ + public AutowireObjectFactory(Class implementationType) { + this(implementationType, null); + } + + public T getInstance() throws ObjectCreationException { + CompositeContext parent = resolver.getCurrentContext(); + if (parent == null) { + return null;// FIXME semantic here means required is not followed + } + if (!(parent instanceof AutowireContext)) { + ObjectCreationException e = new ObjectCreationException("Parent does not implement " + + AutowireContext.class.getName()); + e.setIdentifier(parent.getName()); + throw e; + } + AutowireContext ctx = (AutowireContext) parent; + return ctx.resolveInstance(autowireType); + } + + public void setContextResolver(ContextResolver resolver) { + this.resolver = resolver; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/ContextBinder.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/ContextBinder.java new file mode 100644 index 0000000000..70b40e7269 --- /dev/null +++ b/branches/java-post-M1/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.ModuleContext; +import org.osoa.sca.SCA; + +/** + * @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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/LazyHTTPSessionId.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/LazyHTTPSessionId.java new file mode 100644 index 0000000000..c9e69eaa82 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/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.webapp; + +import org.apache.tuscany.core.context.ScopeIdentifier; + +import javax.servlet.http.HttpServletRequest; + +/** + * Implements a ScopeIdentifier for a Servlet-based transport. + * Wraps an HttpServletRequest 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/ServletHost.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/ServletHost.java new file mode 100644 index 0000000000..85a4a180c5 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/ServletHost.java @@ -0,0 +1,58 @@ +/** + * + * Copyright 2006 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 javax.servlet.Servlet; + +/** + * Service interface implemented by host environments that allow Servlets + * to be registered. + *

+ * This interface allows an SCA system component to register a servlet to handle + * inbound requests. + * + * @version $Rev$ $Date$ + */ +public interface ServletHost { + /** + * Register a mapping for an instance of a Servlet. + * This requests that the servlet container direct all requests to the + * designated mapping to the supplied Servlet instance. + * + * @param mapping the uri-mapping for the Servlet + * @param servlet the Servlet that should be invoked + */ + void registerMapping(String mapping, Servlet servlet); + + /** + * Unregister a servlet mapping. + * This directs the servlet contain not to direct any more requests to + * a previously registered Servlet. + * + * @param mapping the uri-mapping for the Servlet + */ + void unregisterMapping(String mapping); + + /** + * Get the servlet instance registered for the mapping. + * + * @param mapping the uri-mapping for the Servlet + * @return the Servelt for the mapping or null if there is no Servlet registered for the mapping + */ + @Deprecated + Servlet getMapping(String mapping); +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/TuscanyRequestFilter.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/TuscanyRequestFilter.java new file mode 100644 index 0000000000..6637448204 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/TuscanyRequestFilter.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.webapp; + +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.event.HttpSessionBound; +import org.apache.tuscany.core.context.event.RequestStart; +import org.apache.tuscany.core.context.event.RequestEnd; +import org.osoa.sca.CurrentModuleContext; +import org.osoa.sca.ModuleContext; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.Filter; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.FilterConfig; +import javax.servlet.ServletResponse; +import javax.servlet.FilterChain; +import javax.servlet.ServletRequest; +import java.io.IOException; + +/** + * Notifies the {@link org.apache.tuscany.core.context.CompositeContext} 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 LazyServletSessionId as the session id. The LazyServletSessionId is a + * wrapper for the servlet request which may be called by the ModuleContext 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 CompositeContext moduleContext; + + public TuscanyRequestFilter() { + } + + public void init(FilterConfig filterConfig) throws ServletException { + ServletContext servletContext = filterConfig.getServletContext(); + moduleContext = (CompositeContext) 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.publish(new HttpSessionBound(this, ((HttpServletRequest) request).getSession(true))); + } else { + // Create a lazy wrapper since a session is not yet active + moduleContext.publish(new HttpSessionBound(this, new LazyHTTPSessionId((HttpServletRequest) request))); + } + } else { + moduleContext.publish(new HttpSessionBound(this, request)); + } + // Start processing the request + moduleContext.publish(new RequestStart(this, request)); + // Dispatch to the next filter + filterChain.doFilter(request, response); + } catch (Exception e) { + throw new ServletException(e); + + } finally { + try { + // End processing the request + moduleContext.publish(new RequestEnd(this, request)); + } catch (Exception e) { + throw new ServletException(e); + } + ContextBinder.BINDER.setContext(oldContext); + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/TuscanyServletListener.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/TuscanyServletListener.java new file mode 100644 index 0000000000..8c9c215d64 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/webapp/TuscanyServletListener.java @@ -0,0 +1,129 @@ +/** + * + * 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 org.apache.tuscany.common.monitor.MonitorFactory; +import org.apache.tuscany.common.monitor.impl.NullMonitorFactory; +import org.apache.tuscany.core.builder.ContextFactoryBuilderRegistry; +import org.apache.tuscany.core.builder.impl.DefaultWireBuilder; +import org.apache.tuscany.core.client.BootstrapHelper; +import org.apache.tuscany.core.config.ConfigurationException; +import org.apache.tuscany.core.config.ModuleComponentConfigurationLoader; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.SystemCompositeContext; +import org.apache.tuscany.core.context.event.ModuleStop; +import org.apache.tuscany.core.context.event.ModuleStart; +import org.apache.tuscany.core.context.event.HttpSessionEnd; +import org.apache.tuscany.core.runtime.RuntimeContext; +import org.apache.tuscany.core.runtime.RuntimeContextImpl; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.model.assembly.ModuleComponent; +import org.osoa.sca.CurrentModuleContext; +import org.osoa.sca.ModuleContext; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.http.HttpSessionEvent; +import javax.servlet.http.HttpSessionListener; + +/** + * 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 RuntimeContext runtime; + private CompositeContext 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, runtime); + servletContext.setAttribute(MODULE_COMPONENT_NAME, moduleContext); + } + + public void contextDestroyed(ServletContextEvent servletContextEvent) { + moduleContext.publish(new ModuleStop(this)); + moduleContext.stop(); + SystemCompositeContext systemContext = runtime.getSystemContext(); + systemContext.publish(new ModuleStop(this)); + systemContext.stop(); + runtime.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.publish(new HttpSessionEnd(this, event.getSession())); + } finally{ + ContextBinder.BINDER.setContext(oldContext); + } + } + + private void bootRuntime(String name, String uri, MonitorFactory monitorFactory) throws ConfigurationException { + + // Create an assembly model context + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + AssemblyContext modelContext = BootstrapHelper.getModelContext(classLoader); + + // Create a runtime context and start it + ContextFactoryBuilderRegistry builderRegistry = BootstrapHelper.bootstrapContextFactoryBuilders(monitorFactory); + runtime = new RuntimeContextImpl(monitorFactory, builderRegistry, new DefaultWireBuilder()); + runtime.start(); + + // Load and start the system configuration + SystemCompositeContext systemContext = runtime.getSystemContext(); + BootstrapHelper.bootstrapStaxLoader(systemContext, modelContext); + ModuleComponentConfigurationLoader loader = BootstrapHelper.getConfigurationLoader(systemContext, modelContext); + ModuleComponent systemModuleComponent = loader.loadSystemModuleComponent(SYSTEM_MODULE_COMPONENT, SYSTEM_MODULE_COMPONENT); + CompositeContext context = BootstrapHelper.registerModule(systemContext, systemModuleComponent); + context.publish(new ModuleStart(this)); + + // Load the SCDL configuration of the application module + CompositeContext rootContext = runtime.getRootContext(); + ModuleComponent moduleComponent = loader.loadModuleComponent(name, uri); + moduleContext = BootstrapHelper.registerModule(rootContext, moduleComponent); + + moduleContext.publish(new ModuleStart(this)); + } +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/Interceptor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/Interceptor.java new file mode 100644 index 0000000000..1e87e45616 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/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.wire; + +import org.apache.tuscany.core.message.Message; + +/** + * Synchronous, around-style mediation associated with a client- or target- side wire. + * + * @version $Rev$ $Date$ + */ +public interface Interceptor { + + /** + * Process a synchronous wire. + * + * @param msg the request Message for the wire + * @return the response Message from the wire + */ + Message invoke(Message msg); + + /** + * Sets the next interceptor. + * + * @param next + */ + void setNext(Interceptor next); +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/InvocationConfiguration.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/InvocationConfiguration.java new file mode 100644 index 0000000000..94e8d91ba5 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/InvocationConfiguration.java @@ -0,0 +1,181 @@ +/** + * + * 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.wire; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +/** + * Contains a source- or target-side invocation pipeline for a service operation. The runtime framework creates invocation chains + * on a per-operation, per-service basis. Further, invocation chains are further distinguished by being part of the source or + * target sides of a wire. Chains are "bridged" together by the runtime by a set of {@link + * org.apache.tuscany.core.builder.WireBuilder}s with the source-side holding references to the target. + *

+ * InvocationChains are managed by {@link WireConfiguration}s, which are used by {@link + * org.apache.tuscany.core.wire.WireFactory}s to buildSource wires and proxies. + *

+ * Invocation configurations must contain at least one interceptor and may have 0 to N handlers. Handlers process a wire request + * or response in a one-way fashion. A typical wire sequence where interceptors and handlers are configured for both the source + * and target-side will proceed as follows: + *

+ * 
    + *
  1. The first source interceptor will be called with a message, which will in + * turn invoke the next interceptor in the chain
  2. The last source interceptor, which must be of type {@link + * org.apache.tuscany.core.wire.impl.RequestResponseInterceptor} if there are handlers present, will be invoked. The RR + * interceptor will in turn pass the message to a {@link MessageChannel} which will invoke all source-side request handlers. + *
  3. The RR interceptor will then invoke the target-side request MessageChannel. + *
  4. The last source-side handler, an instance of {@link org.apache.tuscany.core.wire.impl.MessageDispatcher}, will invoke the + * first source-side interceptor, which in turn will pass the message down the target-side interceptor chain. + *
  5. If the target is a component instance the last target-side interceptor, an instance of + * {@link org.apache.tuscany.core.wire.impl.InvokerInterceptor} will retrieve the {@link TargetInvoker} from the message and + * call it to invoke the operation on a target instance. TargetInvokers are help by + * the source proxy to enable optimizations such as caching of target instances.
  6. The response is returned up the wire + * stack + * until it reaches the source-side RequestResponseInterceptor, which invokes the target and source-side response + * channels respectively. + *
  7. The response is then passed back up the rest of the wire stack.
+ *
+ *

+ * The source-to-target bridge may be constructed in any of the following ways: + *

+ * 
    + *
  • Source handler-to-target handler + *
  • Source handler-to-target interceptor + *
  • Source interceptor-to-target handler + *
  • Source interceptor-to-target interceptor + *
+ *
+ *

+ * 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 wire chains and the target + * invoker will be held by the target-side and passed down the pipeline. + * + * @version $Rev$ $Date$ + * @see org.apache.tuscany.core.builder.WireBuilder + * @see WireFactory + * @see TargetInvoker + * @see org.apache.tuscany.core.wire.impl.MessageDispatcher + */ +public abstract class InvocationConfiguration { + + // the operation on the target that will utlimately be invoked + protected Method operation; + + // responsible for invoking a target instance + protected TargetInvoker targetInvoker; + + protected Interceptor interceptorChainHead; + + protected Interceptor interceptorChainTail; + + protected List requestHandlers; + + protected List responseHandlers; + + public InvocationConfiguration(Method operation) { + assert (operation != null) : "No operation type specified"; + this.operation = operation; + } + + /** + * Returns the target operation for this invocation chain + */ + public Method getMethod() { + return operation; + } + + /** + * Adds an request handler to the invocation chain + */ + public void addRequestHandler(MessageHandler handler) { + if (requestHandlers == null) { + requestHandlers = new ArrayList(); + } + requestHandlers.add(handler); + } + + /** + * Adds an response handler to the invocation chain + */ + public void addResponseHandler(MessageHandler handler) { + if (responseHandlers == null) { + responseHandlers = new ArrayList(); + } + responseHandlers.add(handler); + } + + /** + * Returns the request handler chain + */ + public List getRequestHandlers() { + return requestHandlers; + } + + /** + * Returns the response handler chain + */ + public List getResponseHandlers() { + return responseHandlers; + } + + /** + * Sets the target invoker to pass down the chain + */ + public void setTargetInvoker(TargetInvoker invoker) { + this.targetInvoker = invoker; + } + + /** + * Returns the target invoker that is passed down the chain + */ + public TargetInvoker getTargetInvoker() { + return targetInvoker; + } + + /** + * Adds an interceptor to the chain + */ + public void addInterceptor(Interceptor interceptor) { + if (interceptorChainHead == null) { + interceptorChainHead = interceptor; + } else { + interceptorChainTail.setNext(interceptor); + } + interceptorChainTail = interceptor; + } + + /** + * Returns the last interceptor in the chain + */ + public Interceptor getTailInterceptor() { + return interceptorChainTail; + } + + /** + * Returns the first interceptor in the chain + */ + public Interceptor getHeadInterceptor() { + return interceptorChainHead; + } + + /** + * Signals to the chain that its configuration is complete. Implementations may use this callback to prepare there invocation + * chains. + */ + public abstract void build(); +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/InvocationRuntimeException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/InvocationRuntimeException.java new file mode 100644 index 0000000000..5e3dbaa204 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/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.wire; + +import org.osoa.sca.ServiceRuntimeException; + +/** + * Denotes a runtime exception thrown during an invocation over a wire + * + * @version $Rev$ $Date$ + */ +public class InvocationRuntimeException extends ServiceRuntimeException { + + public InvocationRuntimeException() { + super(); + } + + public InvocationRuntimeException(String message) { + super(message); + } + + public InvocationRuntimeException(String message, Throwable cause) { + super(message, cause); + } + + public InvocationRuntimeException(Throwable cause) { + super(cause); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/MessageChannel.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/MessageChannel.java new file mode 100644 index 0000000000..07a7594849 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/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.wire; + +import org.apache.tuscany.core.message.Message; + +/** + * Represents a one-way pipeline through which messages are sent during an invocation over a wire + * + * @see org.apache.tuscany.core.message.Message + */ +public interface MessageChannel { + + /** + * Sends a message + */ + void send(Message message); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/MessageHandler.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/MessageHandler.java new file mode 100644 index 0000000000..19442f3663 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/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.wire; + +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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/MethodHashMap.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/MethodHashMap.java new file mode 100644 index 0000000000..c0e40e0644 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/MethodHashMap.java @@ -0,0 +1,55 @@ +/** + * + * 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.wire; + +import org.apache.tuscany.core.config.JavaIntrospectionHelper; + +import java.lang.reflect.Method; +import java.util.HashMap; + +/** + * A Map implementation that performs a lookup on a collection of methods by method name. This implementation is used + * to map methods on one interface to compatible methods on another interface, for example, when flowing an invocation from a + * proxy injected on a source reference to a target service instance. + * + * @version $Rev$ $Date$ + */ +public class MethodHashMap extends HashMap { + + public MethodHashMap() { + super(); + } + + public MethodHashMap(int size) { + super(size); + } + + /** + * @see java.util.HashMap#get(java.lang.Object) + */ + public T get(Object key) { + if (key instanceof Method) { + Method m = (Method) key; + //FIXME find a more efficient way to find a matching method + Method closestMethod = JavaIntrospectionHelper.findClosestMatchingMethod(m.getName(), m.getParameterTypes(), super.keySet()); + return super.get(closestMethod); + } else { + throw new IllegalArgumentException("Key must be a method"); + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/ProxyCreationException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/ProxyCreationException.java new file mode 100644 index 0000000000..2caa613b8f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/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.wire; + +/** + * Denotes an error creating a proxy representing for a wire + * + * @version $Rev: 394379 $ $Date: 2006-04-15 15:01:36 -0700 (Sat, 15 Apr 2006) $ + */ +public class ProxyCreationException extends WireException { + + 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/SourceInvocationConfiguration.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/SourceInvocationConfiguration.java new file mode 100644 index 0000000000..80e1450a0d --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/SourceInvocationConfiguration.java @@ -0,0 +1,131 @@ +/** + * + * 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.wire; + +import org.apache.tuscany.core.wire.impl.MessageChannelImpl; +import org.apache.tuscany.core.wire.impl.MessageDispatcher; +import org.apache.tuscany.core.wire.impl.RequestResponseInterceptor; + +import java.lang.reflect.Method; + +/** + * Contains a source-side invocation pipeline for a service operation. + * + * @version $Rev: 394379 $ $Date: 2006-04-15 15:01:36 -0700 (Sat, 15 Apr 2006) $ + */ +public class SourceInvocationConfiguration extends InvocationConfiguration { + + // the pointer to the bridged target head interceptor or null if the target has no interceptors + private Interceptor targetInterceptorChainHead; + + // the pointer to bridged target request channel, or null if the target has an interceptor + private MessageChannel targetRequestChannel; + + // the pointer to bridged target response channel, or null if the target has an interceptor + private MessageChannel targetResponseChannel; + + /** + * Creates an new wire configuration for the given service reference operation + * + * @param operation the method on the interface representing specified by the reference, where the method corresponds to the + * service operation + */ + public SourceInvocationConfiguration(Method operation) { + super(operation); + } + + /** + * Sets the head interceptor of the target-side configuration for the wire. Used when the runtime bridges source and target + * chains. + * + * @param interceptor + */ + public void setTargetInterceptor(Interceptor interceptor) { + targetInterceptorChainHead = interceptor; + } + + /** + * Returns the head target-side interceptor. This will be the head interceptor of the "bridged" target configuration. + */ + public Interceptor getTargetInterceptor() { + return targetInterceptorChainHead; + } + + /** + * Sets the target-side request channel. Used when the runtime bridges source and target chains. + */ + public void setTargetRequestChannel(MessageChannel channel) { + targetRequestChannel = channel; + } + + /** + * Sets the target-side response channel. Used when the runtime bridges source and target chains. + */ + public void setTargetResponseChannel(MessageChannel channel) { + targetResponseChannel = channel; + } + + /** + * Prepares the configuration by linking interceptors and handlers + */ + @Override + 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 (interceptorChainHead != null) { + interceptorChainTail.setNext(channelInterceptor); + } else { + interceptorChainHead = channelInterceptor; + } + + } else { + // no request handlers + if (interceptorChainHead != null) { + if (targetInterceptorChainHead != null) { + // Connect source interceptor chain directly to target interceptor chain + interceptorChainTail.setNext(targetInterceptorChainHead); + // interceptorChainTail = targetInterceptorChainHead; + } else { + // Connect source interceptor chain to the target request channel + Interceptor channelInterceptor = new RequestResponseInterceptor(null, targetRequestChannel, null, + targetResponseChannel); + interceptorChainTail.setNext(channelInterceptor); + } + } else { + // no source interceptor chain or source handlers, conntect to target interceptor chain or channel + if (targetInterceptorChainHead != null) { + interceptorChainHead = targetInterceptorChainHead; + interceptorChainTail = targetInterceptorChainHead; + } else { + Interceptor channelInterceptor = new RequestResponseInterceptor(null, targetRequestChannel, null, + targetResponseChannel); + interceptorChainHead = channelInterceptor; + interceptorChainTail = channelInterceptor; + } + } + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/SourceWireFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/SourceWireFactory.java new file mode 100644 index 0000000000..c460c71bd5 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/SourceWireFactory.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.wire; + +/** + * Implementations are responsible for managing the source side of a wire. + * + * @version $$Rev$$ $$Date$$ + */ +public interface SourceWireFactory extends WireFactory{ + + /** + * Returns the configuration information used to create the source-side of a wire, including invocation chains + */ + public WireSourceConfiguration getConfiguration(); + + /** + * Sets the configuration information used to create the source-side of a wire, including invocation chains + */ + public void setConfiguration(WireSourceConfiguration config); + + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/TargetInvocationConfiguration.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/TargetInvocationConfiguration.java new file mode 100644 index 0000000000..fc7810763d --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/TargetInvocationConfiguration.java @@ -0,0 +1,49 @@ +/** + * + * 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.wire; + +import org.apache.tuscany.core.wire.impl.MessageDispatcher; + +import java.lang.reflect.Method; + +/** + * Contains a target-side invocation pipeline for a service operation. + * + * @version $Rev: 394379 $ $Date: 2006-04-15 15:01:36 -0700 (Sat, 15 Apr 2006) $ + */ +public class TargetInvocationConfiguration extends InvocationConfiguration { + + /** + * Creates an new target-side pipeline for the given operation + * + * @param operation the method on the interface representing target service, where the method corresponds to the service + * operation + */ + public TargetInvocationConfiguration(Method operation) { + super(operation); + } + + /** + * Prepares the configuration by linking interceptors and handlers + */ + @Override + public void build() { + if (requestHandlers != null && interceptorChainHead != null) { + // on target-side, connect existing handlers and interceptors + MessageHandler messageDispatcher = new MessageDispatcher(interceptorChainHead); + requestHandlers.add(messageDispatcher); + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/TargetInvoker.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/TargetInvoker.java new file mode 100644 index 0000000000..387da1bca3 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/TargetInvoker.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.wire; + +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(); + + /** + * Implementations must support deep cloning + */ + public Object clone() throws CloneNotSupportedException; +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/TargetWireFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/TargetWireFactory.java new file mode 100644 index 0000000000..f46754b975 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/TargetWireFactory.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.wire; + +/** + * Implementations are responsible for managing the target side of a wire + * + * @version $$Rev$$ $$Date$$ + */ +public interface TargetWireFactory extends WireFactory { + + /** + * Returns the configuration information used to create the target-side of a wire, including invocation chains + */ + public WireTargetConfiguration getConfiguration(); + + /** + * Sets the configuration information used to create the target-side of a wire, including invocation chains + */ + public void setConfiguration(WireTargetConfiguration config); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireConfiguration.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireConfiguration.java new file mode 100644 index 0000000000..78ab6ee3c7 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireConfiguration.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.wire; + +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.core.message.MessageFactory; + +import java.lang.reflect.Method; +import java.util.Map; + +/** + * Contains configuration for a wire, including its invocation chains. Invocation chains are accessed from the collection of + * {@link InvocationConfiguration}s keyed by operation on the service specified by the source reference or target service. + * WireConfiguration subtypes distinguish between source and target sides of a wire and hence return corresponding + * InvocationChain subtypes. Operations are represented using JDK reflection, i.e. as a Method + * corresponding to the Java interface representing the service. + *

+ * Wire configurations are created from an assembly model by the runtime during the buildSource phase. + * + * @version $Rev$ $Date$ + */ +public abstract class WireConfiguration { + + protected Map configurations; + + protected ClassLoader proxyClassLoader; + + protected MessageFactory messageFactory; + + protected QualifiedName targetName; + + /** + * Creates the configuration + * + * @param targetName the qualified name of the target service specified by the wire + * @param proxyClassLoader the classloader to use when creating a proxy + * @param messageFactory the factory used to create wire messages + */ + public WireConfiguration(QualifiedName targetName, ClassLoader proxyClassLoader, MessageFactory messageFactory) { + this.targetName = targetName; + this.messageFactory = messageFactory; + if (proxyClassLoader == null) { + this.proxyClassLoader = Thread.currentThread().getContextClassLoader(); + } else { + this.proxyClassLoader = proxyClassLoader; + } + } + + /** + * Returns the qualified name of the target service specified by the wire + */ + public QualifiedName getTargetName() { + return targetName; + } + + /** + * Returns the classloader used for creating proxies + */ + public ClassLoader getProxyClassLoader() { + return proxyClassLoader; + } + + /** + * Returns the factory used to create invocation messages + */ + public MessageFactory getMessageFactory() { + return messageFactory; + } + + /** + * Returns the invocation configuration for each operation on a service specified by a reference or a target service. + */ + public Map getInvocationConfigurations() { + return configurations; + } + + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireException.java new file mode 100644 index 0000000000..0bada0bbfc --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireException.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.wire; + +import org.apache.tuscany.common.TuscanyException; + +/** + * Denotes a top-level exception dealing with a wire + */ +public abstract class WireException extends TuscanyException { + + public WireException() { + super(); + } + + public WireException(String message) { + super(message); + } + + public WireException(String message, Throwable cause) { + super(message, cause); + } + + public WireException(Throwable cause) { + super(cause); + } + +} + diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireFactory.java new file mode 100644 index 0000000000..55cab31adf --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireFactory.java @@ -0,0 +1,76 @@ +/** + * + * 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.wire; + +/** + * Implementations are responsible for managing source or target sides of a wire, including creation of service proxies. + * Source-side wires are injected on references and may contain policy interceptors and/or handlers specified by them. Target-side + * wires may contain policy interceptors and/or handlers specified by the service the wire is targeted to or one of its + * operations. Source- and target-side WireFactorys are held in the {@link org.apache.tuscany.core.builder.ContextFactory} + * associated with the source reference or target service. + *

+ * When an assembly is built by the runtime, source-side and target-side wires are "bridged" on the source side (i.e. a reference + * to the target-side is stored in the source-side). This bridging process is done by a series of {@link + * org.apache.tuscany.core.builder.WireBuilder}s configured in the runtime. When a new component implementation instance is + * created, it will be injected with a proxy for each reference containing the bridged source- and target-side wires. + *

+ * Unmanaged code, i.e. clients that are not components, that perform a locate operation are handled differently. In this case, a + * target-side proxy will be returned by the locate operation created by the WireFactory associated with the target + * service. This target-side proxy will only contain the target-side wire and its handlers/interceptors.Ê + *

+ * Wires are structured by operation; that is, they contain an invocation chain per operation on a service. Note that the service + * specified by a reference may differ in type from the target service specified by the wire. In this case, a mediation may be + * performed by the runtime. Hence, source-to-target bridging is done on a per operation basis. Source- and target-side Invocation + * chains are accessible through the subtypes of WireFactory. + * + * @version $Rev$ $Date$ + */ +public interface WireFactory { + + /** + * Prepares the factory. This will typically be called at buildSource time, after bridging source- and target-side invocation chains. + * + * @throws WireFactoryInitException if an error is encountered during initialization + */ + public void initialize() throws WireFactoryInitException; + + /** + * Returns a proxy for a service specified by a reference or target + */ + public T createProxy() throws ProxyCreationException; + + /** + * Sets the primary interface type generated proxies implement + */ + public void setBusinessInterface(Class interfaze); + + /** + * Returns the primary interface type implemented by generated proxies + */ + public Class getBusinessInterface(); + + /** + * Adds an interface type generated proxies implement + */ + public void addInterface(Class claz); + + /** + * Returns an array of all interfaces implemented by generated proxies + */ + public Class[] getImplementatedInterfaces(); + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireFactoryFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireFactoryFactory.java new file mode 100644 index 0000000000..f055ecd427 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireFactoryFactory.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.wire; + +import java.lang.reflect.InvocationHandler; + +/** + * Implementations provide a runtime system service that creates {@link WireFactory}s + * + * @version $Rev$ $Date$ + */ +public interface WireFactoryFactory { + + /** + * Creates a target-side wire factory + */ + public TargetWireFactory createTargetWireFactory(); + + /** + * Creates a source-side wire factory + */ + public SourceWireFactory createSourceWireFactory(); + + /** + * Determines whether the given object is a proxy + */ + public boolean isProxy(Object object); + + /** + * Returns an wire handler fronting the wire 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireFactoryInitException.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireFactoryInitException.java new file mode 100644 index 0000000000..caf535ee00 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireFactoryInitException.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.wire; + +/** + * Denotes an error initializing a wire factory + * + * @version $Rev$ $Date$ + */ +public class WireFactoryInitException extends WireException { + + public WireFactoryInitException() { + super(); + } + + public WireFactoryInitException(String message) { + super(message); + } + + public WireFactoryInitException(String message, Throwable cause) { + super(message, cause); + } + + public WireFactoryInitException(Throwable cause) { + super(cause); + } + +} + diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireSourceConfiguration.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireSourceConfiguration.java new file mode 100644 index 0000000000..d9408b2fb0 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireSourceConfiguration.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.wire; + +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.core.message.MessageFactory; + +import java.lang.reflect.Method; +import java.util.Map; + +/** + * Contains configuration for the source side of a wire + * + * @version $Rev: 394379 $ $Date: 2006-04-15 15:01:36 -0700 (Sat, 15 Apr 2006) $ + */ +public class WireSourceConfiguration extends WireConfiguration { + + private String referenceName; + + /** + * Creates the source side of a wire + * + * @param referenceName the name of the reference the wire is associated with + * @param targetName the qualified name of the target service specified by the wire + * @param invocationConfigs a collection of service operation-to-invocation chain mappings + * @param proxyClassLoader the classloader to use when creating a proxy + * @param messageFactory the factory used to create wire messages + */ + public WireSourceConfiguration(String referenceName, QualifiedName targetName, + Map invocationConfigs, ClassLoader proxyClassLoader, MessageFactory messageFactory) { + super(targetName, proxyClassLoader, messageFactory); + this.referenceName = referenceName; + this.configurations = invocationConfigs; + } + + /** + * Creates the source side of a wire where the reference is "anonymous", i.e. on an entry point + * + * @param targetName the qualified name of the target service specified by the wire + * @param invocationConfigs a collection of service operation-to-invocation chain mappings + * @param proxyClassLoader the classloader to use when creating a proxy + * @param messageFactory the factory used to create wire messages + */ + public WireSourceConfiguration(QualifiedName targetName, + Map invocationConfigs, ClassLoader proxyClassLoader, MessageFactory messageFactory) { + this(null, targetName, invocationConfigs, proxyClassLoader, messageFactory); + } + + + /** + * Returns the name of the source reference + */ + public String getReferenceName() { + return referenceName; + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireTargetConfiguration.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireTargetConfiguration.java new file mode 100644 index 0000000000..ce6ebade0c --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/WireTargetConfiguration.java @@ -0,0 +1,48 @@ +/** + * + * 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.wire; + +import org.apache.tuscany.core.message.MessageFactory; +import org.apache.tuscany.core.context.QualifiedName; + +import java.lang.reflect.Method; +import java.util.Map; + +/** + * Contains configuration for the target side of a wire + * + * @version $$Rev$$ $$Date$$ + */ +public class WireTargetConfiguration extends WireConfiguration { + + /** + * Creates the source side of a wire + * + * @param targetName the qualified name of the target service specified by the wire + * @param invocationConfigs a collection of target service operation-to-invocation chain mappings + * @param proxyClassLoader the classloader to use when creating a proxy + * @param messageFactory the factory used to create wire messages + */ + public WireTargetConfiguration(QualifiedName targetName, Map invocationConfigs, + ClassLoader proxyClassLoader, MessageFactory messageFactory) { + super(targetName, proxyClassLoader, messageFactory); + assert (invocationConfigs != null) : "No wire configuration map specified"; + configurations = invocationConfigs; + + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/InvokerInterceptor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/InvokerInterceptor.java new file mode 100644 index 0000000000..9c114c013e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/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.wire.impl; + +import org.apache.tuscany.core.wire.Interceptor; +import org.apache.tuscany.core.wire.InvocationRuntimeException; +import org.apache.tuscany.core.wire.TargetInvoker; +import org.apache.tuscany.core.message.Message; + +/** + * Serves as a tail interceptor on a target wire chain. This implementation dispatches to the target invoker + * passed inside the wire message. Target invokers are passed from the source in order to allow for caching of + * target instances. + * + * @see org.apache.tuscany.core.wire.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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/MessageChannelImpl.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/MessageChannelImpl.java new file mode 100644 index 0000000000..8b9d484313 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/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.wire.impl; + +import org.apache.tuscany.core.wire.MessageChannel; +import org.apache.tuscany.core.wire.MessageHandler; +import org.apache.tuscany.core.message.Message; + +import java.util.List; + +/** + * 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 pipeline; + + //---------------------------------- + // Constructors + //---------------------------------- + + /** + * Construct a new channel comprising the supplied list of handlers. + * + * @param pipeline the Handlers in the channel + */ + public MessageChannelImpl(List 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/MessageDispatcher.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/MessageDispatcher.java new file mode 100644 index 0000000000..ada01b7f91 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/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.wire.impl; + +import org.apache.tuscany.core.wire.Interceptor; +import org.apache.tuscany.core.wire.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 wire 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/NullWireFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/NullWireFactory.java new file mode 100644 index 0000000000..e46ed26184 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/NullWireFactory.java @@ -0,0 +1,71 @@ +/** + * + * 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.wire.impl; + +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.wire.WireConfiguration; +import org.apache.tuscany.core.wire.ProxyCreationException; +import org.apache.tuscany.core.wire.WireFactory; +import org.apache.tuscany.core.wire.WireFactoryInitException; + +/** + * 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 NullWireFactory implements WireFactory { + + private CompositeContext parentContext; + + private String targetName; + + private Class businessInterface; + + public NullWireFactory(String componentName, CompositeContext parentContext) { + assert (parentContext != null) : "Parent context was null"; + this.targetName = componentName; + this.parentContext = parentContext; + } + + public void initialize(Class businessInterface, WireConfiguration config) throws WireFactoryInitException { + this.businessInterface = businessInterface; + } + + public Object createProxy() throws ProxyCreationException { + return parentContext.getContext(targetName); + } + + public void initialize() throws WireFactoryInitException { + } + + public void setBusinessInterface(Class interfaze) { + businessInterface = interfaze; + } + + public Class getBusinessInterface() { + return businessInterface; + } + + public void addInterface(Class claz) { + throw new UnsupportedOperationException(); + } + + public Class[] getImplementatedInterfaces() { + throw new UnsupportedOperationException(); + } + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/OneWayInterceptor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/OneWayInterceptor.java new file mode 100644 index 0000000000..4e3bb460aa --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/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.wire.impl; + +import org.apache.tuscany.core.wire.Interceptor; +import org.apache.tuscany.core.wire.MessageChannel; +import org.apache.tuscany.core.message.Message; + +/** + * An interceptor that sends the wire 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/RequestResponseInterceptor.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/impl/RequestResponseInterceptor.java new file mode 100644 index 0000000000..ae1c69fc12 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/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.wire.impl; + +import org.apache.tuscany.core.wire.Interceptor; +import org.apache.tuscany.core.wire.MessageChannel; +import org.apache.tuscany.core.message.Message; + +/** + * An interceptor that first sends a 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandler.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandler.java new file mode 100644 index 0000000000..2cef096a5e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandler.java @@ -0,0 +1,137 @@ +/** + * + * 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.wire.jdk; + +import org.apache.tuscany.core.context.TargetException; +import org.apache.tuscany.core.wire.Interceptor; +import org.apache.tuscany.core.wire.InvocationConfiguration; +import org.apache.tuscany.core.wire.TargetInvoker; +import org.apache.tuscany.core.message.Message; +import org.apache.tuscany.core.message.MessageFactory; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +/** + * 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 wire 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 wire configuration will be used. + */ + private Map configuration; + + public JDKInvocationHandler(MessageFactory messageFactory, Map configuration) { + assert (messageFactory != null) : "Message factory was null"; + assert (configuration != null) : "Configuration not specified"; + this.configuration = new HashMap(configuration.size()); + for (Map.Entry entry : configuration.entrySet()) { + this.configuration.put(entry.getKey(), new ConfigHolder(entry.getValue())); + } + this.messageFactory = messageFactory; + } + + /** + * 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.getHeadInterceptor(); + } + + TargetInvoker invoker; + + if (holder.cachedInvoker == null) { + assert config != 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 { + assert config != null; + 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); + msg.setBody(args); + // dispatch the wire 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 wire 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKSourceWireFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKSourceWireFactory.java new file mode 100644 index 0000000000..dbaab87fce --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKSourceWireFactory.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.wire.jdk; + +import org.apache.tuscany.core.wire.MethodHashMap; +import org.apache.tuscany.core.wire.WireFactoryInitException; +import org.apache.tuscany.core.wire.SourceInvocationConfiguration; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.WireSourceConfiguration; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Map; + +/** + * Creates proxies that are injected on references using JDK dynamic proxy facilities and front a wire. The proxies implement the + * business interface associated with the service required by reference. + * + * @version $Rev: 394431 $ $Date: 2006-04-15 21:27:44 -0700 (Sat, 15 Apr 2006) $ + */ +public class JDKSourceWireFactory implements SourceWireFactory { + + private static final int UNINITIALIZED = 0; + + private static final int INITIALIZED = 1; + + private int state = UNINITIALIZED; + + private Class[] businessInterfaceArray; + + private Map methodToInvocationConfig; + + private WireSourceConfiguration configuration; + + public void initialize() throws WireFactoryInitException { + if (state != UNINITIALIZED) { + throw new IllegalStateException("Proxy factory in wrong state [" + state + "]"); + } + Map invocationConfigs = configuration.getInvocationConfigurations(); + methodToInvocationConfig = new MethodHashMap(invocationConfigs.size()); + for (Map.Entry entry : invocationConfigs.entrySet()) { + Method method = entry.getKey(); + methodToInvocationConfig.put(method, 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 WireSourceConfiguration getConfiguration() { + return configuration; + } + + public void setConfiguration(WireSourceConfiguration 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKTargetWireFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKTargetWireFactory.java new file mode 100644 index 0000000000..76f3b0389c --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKTargetWireFactory.java @@ -0,0 +1,95 @@ +/** + * + * 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.wire.jdk; + +import org.apache.tuscany.core.wire.MethodHashMap; +import org.apache.tuscany.core.wire.WireFactoryInitException; +import org.apache.tuscany.core.wire.TargetInvocationConfiguration; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.core.wire.WireTargetConfiguration; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Map; + +/** + * Creates proxies that are returned to non-SCA clients using JDK dynamic proxy facilities and front a wire. The proxies implement + * the business interface associated with the target service of the wire and are typically returned by a locate operation. + * + * @version $Rev: 394431 $ $Date: 2006-04-15 21:27:44 -0700 (Sat, 15 Apr 2006) $ + */ +public class JDKTargetWireFactory implements TargetWireFactory { + + private static final int UNINITIALIZED = 0; + + private static final int INITIALIZED = 1; + + private int state = UNINITIALIZED; + + private Class[] businessInterfaceArray; + + private Map methodToInvocationConfig; + + private WireTargetConfiguration configuration; + + public void initialize() throws WireFactoryInitException { + if (state != UNINITIALIZED) { + throw new IllegalStateException("Proxy factory in wrong state [" + state + "]"); + } + Map invocationConfigs = configuration.getInvocationConfigurations(); + methodToInvocationConfig = new MethodHashMap(invocationConfigs.size()); + for (Map.Entry entry : invocationConfigs.entrySet()) { + Method method = entry.getKey(); + methodToInvocationConfig.put(method, 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 WireTargetConfiguration getConfiguration() { + return configuration; + } + + public void setConfiguration(WireTargetConfiguration 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKWireFactoryFactory.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKWireFactoryFactory.java new file mode 100644 index 0000000000..3eaffb9ba8 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/jdk/JDKWireFactoryFactory.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.wire.jdk; + +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.core.wire.WireFactoryFactory; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; + +/** + * A system service that creates JDK dynamic proxy-based {@link org.apache.tuscany.core.wire.WireFactory}s + * + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +@Service(interfaces = {WireFactoryFactory.class}) +public class JDKWireFactoryFactory implements WireFactoryFactory { + + public JDKWireFactoryFactory() { + } + + @Init(eager = true) + public void init() { + } + + public TargetWireFactory createTargetWireFactory() { + return new JDKTargetWireFactory(); + } + + public SourceWireFactory createSourceWireFactory() { + return new JDKSourceWireFactory(); + } + + 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/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/service/DefaultWireFactoryService.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/service/DefaultWireFactoryService.java new file mode 100644 index 0000000000..3c61081caf --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/service/DefaultWireFactoryService.java @@ -0,0 +1,157 @@ +/** + * + * 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.wire.service; + +import org.apache.tuscany.core.config.JavaIntrospectionHelper; +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.core.message.MessageFactory; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.core.wire.MethodHashMap; +import org.apache.tuscany.core.wire.WireFactoryFactory; +import org.apache.tuscany.core.wire.SourceInvocationConfiguration; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.TargetInvocationConfiguration; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.core.wire.WireSourceConfiguration; +import org.apache.tuscany.core.wire.WireTargetConfiguration; +import org.apache.tuscany.core.wire.impl.InvokerInterceptor; +import org.apache.tuscany.core.builder.system.PolicyBuilderRegistry; +import org.apache.tuscany.core.builder.BuilderConfigException; +import org.apache.tuscany.model.assembly.ConfiguredService; +import org.apache.tuscany.model.assembly.ConfiguredReference; +import org.apache.tuscany.model.assembly.EntryPoint; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.List; +import java.util.ArrayList; + +/** + * The default implementation of a WireFactoryFactory + * + * @version $$Rev$$ $$Date$$ + */ +@Scope("MODULE") +@Service(interfaces = {org.apache.tuscany.core.wire.service.WireFactoryService.class}) +public class DefaultWireFactoryService implements org.apache.tuscany.core.wire.service.WireFactoryService { + + private MessageFactory messageFactory; + private WireFactoryFactory wireFactoryFactory; + private PolicyBuilderRegistry policyRegistry; + + + public DefaultWireFactoryService() { + + } + + public DefaultWireFactoryService(MessageFactory messageFactory, WireFactoryFactory wireFactoryFactory, PolicyBuilderRegistry registry) { + this.messageFactory = messageFactory; + this.wireFactoryFactory = wireFactoryFactory; + this.policyRegistry = registry; + } + + @Autowire + public void setMessageFactory(MessageFactory messageFactory) { + this.messageFactory = messageFactory; + } + + @Autowire + public void setWireFactoryService(WireFactoryFactory wireFactoryFactory) { + this.wireFactoryFactory = wireFactoryFactory; + } + + @Autowire + public void setPolicyRegistry(PolicyBuilderRegistry policyRegistry) { + this.policyRegistry = policyRegistry; + } + + @Init(eager = true) + public void init() { + } + + public List createSourceFactory(ConfiguredReference configuredReference) throws BuilderConfigException{ + String referenceName = configuredReference.getPort().getName(); + Class interfaze; + // FIXME hack for NPE when entry points with no set service contract on their configuredReference + if (configuredReference.getPort().getServiceContract() != null){ + interfaze = configuredReference.getPort().getServiceContract().getInterface(); + }else if(configuredReference.getPart() instanceof EntryPoint){ + interfaze = ((EntryPoint)configuredReference.getPart()).getConfiguredService().getPort().getServiceContract().getInterface(); + }else{ + BuilderConfigException bce = new BuilderConfigException("No interface found on configured reference"); + bce.setIdentifier(configuredReference.getName()); + throw bce; + } + List wireFactories = new ArrayList(); + List wireConfigurations = new ArrayList(); + for (ConfiguredService configuredService : configuredReference.getTargetConfiguredServices()) { + String targetCompName = configuredService.getPart().getName(); + String targetSerivceName = configuredService.getPort().getName(); + QualifiedName targetName = new QualifiedName(targetCompName + QualifiedName.NAME_SEPARATOR + targetSerivceName); + SourceWireFactory wireFactory = wireFactoryFactory.createSourceWireFactory(); + Map iConfigMap = new HashMap(); + Set javaMethods = JavaIntrospectionHelper.getAllUniqueMethods(interfaze); + for (Method method : javaMethods) { + SourceInvocationConfiguration iConfig = new SourceInvocationConfiguration(method); + iConfigMap.put(method, iConfig); + } + WireSourceConfiguration wireConfiguration = new WireSourceConfiguration(referenceName, targetName, iConfigMap, interfaze.getClassLoader(), + messageFactory); + wireConfigurations.add(wireConfiguration); + wireFactory.setBusinessInterface(interfaze); + wireFactory.setConfiguration(wireConfiguration); + wireFactories.add(wireFactory); + } + if (policyRegistry != null) { + // invoke policy builders + policyRegistry.buildSource(configuredReference, wireConfigurations); + } + return wireFactories; + + } + + public TargetWireFactory createTargetFactory(ConfiguredService configuredService) { + org.apache.tuscany.model.assembly.Service service = configuredService.getPort(); + Class interfaze = service.getServiceContract().getInterface(); + QualifiedName targetName = new QualifiedName(configuredService.getPart().getName() + QualifiedName.NAME_SEPARATOR + + service.getName()); + + Map iConfigMap = new MethodHashMap(); + TargetWireFactory wireFactory = wireFactoryFactory.createTargetWireFactory(); + Set javaMethods = JavaIntrospectionHelper.getAllUniqueMethods(interfaze); + for (Method method : javaMethods) { + TargetInvocationConfiguration iConfig = new TargetInvocationConfiguration(method); + iConfigMap.put(method, iConfig); + } + WireTargetConfiguration wireConfiguration = new WireTargetConfiguration(targetName, iConfigMap, interfaze.getClassLoader(), messageFactory); + wireFactory.setBusinessInterface(interfaze); + wireFactory.setConfiguration(wireConfiguration); + if (policyRegistry != null) { + // invoke policy builders + policyRegistry.buildTarget(configuredService, wireConfiguration); + } + // add tail interceptor + for (TargetInvocationConfiguration iConfig : wireFactory.getConfiguration().getInvocationConfigurations().values()) { + iConfig.addInterceptor(new InvokerInterceptor()); + } + return wireFactory; + } + + +} diff --git a/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/service/WireFactoryService.java b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/service/WireFactoryService.java new file mode 100644 index 0000000000..eb41baf69a --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/java/org/apache/tuscany/core/wire/service/WireFactoryService.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.wire.service; + +import org.apache.tuscany.core.builder.BuilderConfigException; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.model.assembly.ConfiguredReference; +import org.apache.tuscany.model.assembly.ConfiguredService; + +import java.util.List; + +/** + * Implementations provide a system service that creates {@link org.apache.tuscany.core.wire.SourceWireFactory}s + * and {@link org.apache.tuscany.core.wire.TargetWireFactory}s. This service is used by {@link + * org.apache.tuscany.core.builder.ContextFactoryBuilder}s to provide {@link org.apache.tuscany.core.builder.ContextFactory}s with + * {@link org.apache.tuscany.core.wire.WireFactory}s for their references and target services. This service is typically autowired + * to. + * + * @version $$Rev$$ $$Date$$ + */ +public interface WireFactoryService { + + /** + * Creates the source-side wire factory for a reference + * + * @param configuredReference the configured reference to create the wire factory for + * @throws BuilderConfigException + */ + public List createSourceFactory(ConfiguredReference configuredReference) throws BuilderConfigException; + + /** + * Creates a target-side wire factory for a service implementing a given interface + * + * @param configuredService the configured service to create the wire factory for + * @throws BuilderConfigException + */ + public TargetWireFactory createTargetFactory(ConfiguredService configuredService) throws BuilderConfigException; + +} diff --git a/branches/java-post-M1/sca/core/src/main/resources/META-INF/LICENSE.txt b/branches/java-post-M1/sca/core/src/main/resources/META-INF/LICENSE.txt new file mode 100644 index 0000000000..25d78feeac --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/resources/META-INF/LICENSE.txt @@ -0,0 +1,1277 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +APACHE TUSCANY SUBCOMPONENTS: + +The Apache Tuscany distribution includes a number of subcomponents with +separate copyright notices and license terms. Your use of the source +code for the these subcomponents is subject to the terms and +conditions of the following licenses. + +=============================================================================== + +For the Eclipse Modeling Framework component and the Celtix binding: + +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE +PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF +THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and +documentation distributed under this Agreement, and +b) in the case of each subsequent Contributor: + +i) changes to the Program, and + +ii) additions to the Program; + +where such changes and/or additions to the Program originate from and +are distributed by that particular Contributor. A Contribution +'originates' from a Contributor if it was added to the Program by such +Contributor itself or anyone acting on such Contributor's behalf. +Contributions do not include additions to the Program which: (i) are +separate modules of software distributed in conjunction with the +Program under their own license agreement, and (ii) are not derivative +works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents " mean patent claims licensable by a Contributor +which are necessarily infringed by the use or sale of its Contribution +alone or when combined with the Program. + +"Program" means the Contributions distributed in accordance with this +Agreement. + +"Recipient" means anyone who receives the Program under this +Agreement, including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby +grants Recipient a non-exclusive, worldwide, royalty-free copyright +license to reproduce, prepare derivative works of, publicly display, +publicly perform, distribute and sublicense the Contribution of such +Contributor, if any, and such derivative works, in source code and +object code form. + +b) Subject to the terms of this Agreement, each Contributor hereby +grants Recipient a non-exclusive, worldwide, royalty-free patent +license under Licensed Patents to make, use, sell, offer to sell, +import and otherwise transfer the Contribution of such Contributor, if +any, in source code and object code form. This patent license shall +apply to the combination of the Contribution and the Program if, at +the time the Contribution is added by the Contributor, such addition +of the Contribution causes such combination to be covered by the +Licensed Patents. The patent license shall not apply to any other +combinations which include the Contribution. No hardware per se is +licensed hereunder. + +c) Recipient understands that although each Contributor grants the +licenses to its Contributions set forth herein, no assurances are +provided by any Contributor that the Program does not infringe the +patent or other intellectual property rights of any other entity. Each +Contributor disclaims any liability to Recipient for claims brought by +any other entity based on infringement of intellectual property rights +or otherwise. As a condition to exercising the rights and licenses +granted hereunder, each Recipient hereby assumes sole responsibility +to secure any other intellectual property rights needed, if any. For +example, if a third party patent license is required to allow +Recipient to distribute the Program, it is Recipient's responsibility +to acquire that license before distributing the Program. + +d) Each Contributor represents that to its knowledge it has sufficient +copyright rights in its Contribution, if any, to grant the copyright +license set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form +under its own license agreement, provided that: + +a) it complies with the terms and conditions of this Agreement; and + +b) its license agreement: + +i) effectively disclaims on behalf of all Contributors all warranties +and conditions, express and implied, including warranties or +conditions of title and non-infringement, and implied warranties or +conditions of merchantability and fitness for a particular purpose; + +ii) effectively excludes on behalf of all Contributors all liability +for damages, including direct, indirect, special, incidental and +consequential damages, such as lost profits; + +iii) states that any provisions which differ from this Agreement are +offered by that Contributor alone and not by any other party; and + +iv) states that source code for the Program is available from such +Contributor, and informs licensees how to obtain it in a reasonable +manner on or through a medium customarily used for software exchange. + +When the Program is made available in source code form: + +a) it must be made available under this Agreement; and + +b) a copy of this Agreement must be included with each copy of the +Program. + +Contributors may not remove or alter any copyright notices contained +within the Program. + +Each Contributor must identify itself as the originator of its +Contribution, if any, in a manner that reasonably allows subsequent +Recipients to identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain +responsibilities with respect to end users, business partners and the +like. While this license is intended to facilitate the commercial use +of the Program, the Contributor who includes the Program in a +commercial product offering should do so in a manner which does not +create potential liability for other Contributors. Therefore, if a +Contributor includes the Program in a commercial product offering, +such Contributor ("Commercial Contributor") hereby agrees to defend +and indemnify every other Contributor ("Indemnified Contributor") +against any losses, damages and costs (collectively "Losses") arising +from claims, lawsuits and other legal actions brought by a third party +against the Indemnified Contributor to the extent caused by the acts +or omissions of such Commercial Contributor in connection with its +distribution of the Program in a commercial product offering. The +obligations in this section do not apply to any claims or Losses +relating to any actual or alleged intellectual property infringement. +In order to qualify, an Indemnified Contributor must: a) promptly +notify the Commercial Contributor in writing of such claim, and b) +allow the Commercial Contributor to control, and cooperate with the +Commercial Contributor in, the defense and any related settlement +negotiations. The Indemnified Contributor may participate in any such +claim at its own expense. + +For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's responsibility +alone. Under this section, the Commercial Contributor would have to +defend claims against the other Contributors related to those +performance claims and warranties, and if a court requires any other +Contributor to pay any damages as a result, the Commercial Contributor +must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS +PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY +WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY +OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely +responsible for determining the appropriateness of using and +distributing the Program and assumes all risks associated with its +exercise of rights under this Agreement , including but not limited to +the risks and costs of program errors, compliance with applicable +laws, damage to or loss of data, programs or equipment, and +unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR +ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING +WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR +DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED +HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under +applicable law, it shall not affect the validity or enforceability of +the remainder of the terms of this Agreement, and without further +action by the parties hereto, such provision shall be reformed to the +minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that +the Program itself (excluding combinations of the Program with other +software or hardware) infringes such Recipient's patent(s), then such +Recipient's rights granted under Section 2(b) shall terminate as of +the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it +fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of +time after becoming aware of such noncompliance. If all Recipient's +rights under this Agreement terminate, Recipient agrees to cease use +and distribution of the Program as soon as reasonably practicable. +However, Recipient's obligations under this Agreement and any licenses +granted by Recipient relating to the Program shall continue and +survive. + +Everyone is permitted to copy and distribute copies of this Agreement, +but in order to avoid inconsistency the Agreement is copyrighted and +may only be modified in the following manner. The Agreement Steward +reserves the right to publish new versions (including revisions) of +this Agreement from time to time. No one other than the Agreement +Steward has the right to modify this Agreement. The Eclipse Foundation +is the initial Agreement Steward. The Eclipse Foundation may assign +the responsibility to serve as the Agreement Steward to a suitable +separate entity. Each new version of the Agreement will be given a +distinguishing version number. The Program (including Contributions) +may always be distributed subject to the version of the Agreement +under which it was received. In addition, after a new version of the +Agreement is published, Contributor may elect to distribute the +Program (including its Contributions) under the new version. Except as +expressly stated in Sections 2(a) and 2(b) above, Recipient receives +no rights or licenses to the intellectual property of any Contributor +under this Agreement, whether expressly, by implication, estoppel or +otherwise. All rights in the Program not expressly granted under this +Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and +the intellectual property laws of the United States of America. No +party to this Agreement will bring a legal action under this Agreement +more than one year after the cause of action arose. Each party waives +its rights to a jury trial in any resulting litigation. + +=============================================================================== + +For the Rhino JavaScript container component: + +Mozilla Public License 1.1 (MPL 1.1) + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the +Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to +the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original Code, +prior Modifications used by a Contributor, and the Modifications made by that +particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the +combination of the Original Code and Modifications, in each case including +portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally +accepted in the software development community for the electronic transfer of +data. + + 1.5. "Executable" means Covered Code in any form other than Source +Code. + + 1.6. "Initial Developer" means the individual or entity identified as +the Initial Developer in the Source Code notice required by Exhibit A. + + 1.7. "Larger Work" means a work which combines Covered Code or +portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum +extent possible, whether at the time of the initial grant or subsequently +acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the +substance or structure of either the Original Code or any previous +Modifications. When Covered Code is released as a series of files, a +Modification is: + A. Any addition to or deletion from the contents of a file +containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or +previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code +which is described in the Source Code notice required by Exhibit A as Original +Code, and which, at the time of its release under this License is not already +Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or +hereafter acquired, including without limitation, method, process, and +apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for +making modifications to it, including all modules it contains, plus any +associated interface definition files, scripts used to control compilation and +installation of an Executable, or source code differential comparisons against +either the Original Code or another well known, available Covered Code of the +Contributor's choice. The Source Code can be in a compressed or archival form, +provided the appropriate decompression or de-archiving software is widely +available for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity +exercising rights under, and complying with all of the terms of, this License +or a future version of this License issued under Section 6.1. For legal +entities, "You" includes any entity which controls, is controlled by, or is +under common control with You. For purposes of this definition, "control" +means (a) the power, direct or indirect, to cause the direction or management +of such entity, whether by contract or otherwise, or (b) ownership of more +than fifty percent (50%) of the outstanding shares or beneficial ownership of +such entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, +non-exclusive license, subject to third party intellectual property claims: + (a) under intellectual property rights (other than patent or +trademark) Licensable by Initial Developer to use, reproduce, modify, display, +perform, sublicense and distribute the Original Code (or portions thereof) +with or without Modifications, and/or as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or selling +of Original Code, to make, have made, use, practice, sell, and offer for sale, +and/or otherwise dispose of the Original Code (or portions thereof). + (c) the licenses granted in this Section 2.1(a) and +(b) are effective on the date Initial Developer first distributes Original +Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is +granted: 1) for code that You delete from the Original Code; 2) separate from +the Original Code; or 3) for infringements caused by: i) the modification of +the Original Code or ii) the combination of the Original Code with other +software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor +hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or +trademark) Licensable by Contributor, to use, reproduce, modify, display, +perform, sublicense and distribute the Modifications created by such +Contributor (or portions thereof) either on an unmodified basis, with other +Modifications, as Covered Code and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or selling +of Modifications made by that Contributor either alone and/or in combination +with its Contributor Version (or portions of such combination), to make, use, +sell, offer for sale, have made, and/or otherwise dispose of: 1) Modifications +made by that Contributor (or portions thereof); and 2) the combination of +Modifications made by that Contributor with its Contributor Version (or +portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are +effective on the date Contributor first makes Commercial Use of the Covered +Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is +granted: 1) for any code that Contributor has deleted from the Contributor +Version; 2) separate from the Contributor Version; 3) for infringements +caused by: i) third party modifications of Contributor Version or ii) the +combination of Modifications made by that Contributor with other software +(except as part of the Contributor Version) or other devices; or 4) under +Patent Claims infringed by Covered Code in the absence of Modifications made +by that Contributor. + + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are +governed by the terms of this License, including without limitation Section +2.2. The Source Code version of Covered Code may be distributed only under the +terms of this License or a future version of this License released under +Section 6.1, and You must include a copy of this License with every copy of +the Source Code You distribute. You may not offer or impose any terms on any +Source Code version that alters or restricts the applicable version of this +License or the recipients' rights hereunder. However, You may include an +additional document offering the additional rights described in Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be +made available in Source Code form under the terms of this License either on +the same media as an Executable version or via an accepted Electronic +Distribution Mechanism to anyone to whom you made an Executable version +available; and if made available via Electronic Distribution Mechanism, must +remain available for at least twelve (12) months after the date it initially +became available, or at least six (6) months after a subsequent version of +that particular Modification has been made available to such recipients. You +are responsible for ensuring that the Source Code version remains available +even if the Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a +file documenting the changes You made to create that Covered Code and the date +of any change. You must include a prominent statement that the Modification is +derived, directly or indirectly, from Original Code provided by the Initial +Developer and including the name of the Initial Developer in (a) the Source +Code, and (b) in any notice in an Executable version or related documentation +in which You describe the origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's +intellectual property rights is required to exercise the rights granted by +such Contributor under Sections 2.1 or 2.2, Contributor must include a text +file with the Source Code distribution titled "LEGAL" which describes the +claim and the party making the claim in sufficient detail that a recipient +will know whom to contact. If Contributor obtains such knowledge after the +Modification is made available as described in Section 3.2, Contributor shall +promptly modify the LEGAL file in all copies Contributor makes available +thereafter and shall take other steps (such as notifying appropriate mailing +lists or newsgroups) reasonably calculated to inform those who received the +Covered Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming +interface and Contributor has knowledge of patent licenses which are +reasonably necessary to implement that API, Contributor must also include this +information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to +Section 3.4(a) above, Contributor believes that Contributor's Modifications +are Contributor's original creation(s) and/or Contributor has sufficient +rights to grant the rights conveyed by this License. + + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source +Code. If it is not possible to put such notice in a particular Source Code +file due to its structure, then You must include such notice in a location +(such as a relevant directory) where a user would be likely to look for such a +notice. If You created one or more Modification(s) You may add your name as a +Contributor to the notice described in Exhibit A. You must also duplicate +this License in any documentation for the Source Code where You describe +recipients' rights or ownership rights relating to Covered Code. You may +choose to offer, and to charge a fee for, warranty, support, indemnity or +liability obligations to one or more recipients of Covered Code. However, You +may do so only on Your own behalf, and not on behalf of the Initial Developer +or any Contributor. You must make it absolutely clear than any such warranty, +support, indemnity or liability obligation is offered by You alone, and You +hereby agree to indemnify the Initial Developer and every Contributor for any +liability incurred by the Initial Developer or such Contributor as a result of +warranty, support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the +requirements of Section 3.1-3.5 have been met for that Covered Code, and if +You include a notice stating that the Source Code version of the Covered Code +is available under the terms of this License, including a description of how +and where You have fulfilled the obligations of Section 3.2. The notice must +be conspicuously included in any notice in an Executable version, related +documentation or collateral in which You describe recipients' rights relating +to the Covered Code. You may distribute the Executable version of Covered Code +or ownership rights under a license of Your choice, which may contain terms +different from this License, provided that You are in compliance with the +terms of this License and that the license for the Executable version does not +attempt to limit or alter the recipient's rights in the Source Code version +from the rights set forth in this License. If You distribute the Executable +version under a different license You must make it absolutely clear that any +terms which differ from this License are offered by You alone, not by the +Initial Developer or any Contributor. You hereby agree to indemnify the +Initial Developer and every Contributor for any liability incurred by the +Initial Developer or such Contributor as a result of any such terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code +not governed by the terms of this License and distribute the Larger Work as a +single product. In such a case, You must make sure the requirements of this +License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Code due to statute, +judicial order, or regulation then You must: (a) comply with the terms of this +License to the maximum extent possible; and (b) describe the limitations and +the code they affect. Such description must be included in the LEGAL file +described in Section 3.4 and must be included with all distributions of the +Source Code. Except to the extent prohibited by statute or regulation, such +description must be sufficiently detailed for a recipient of ordinary skill to +be able to understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has attached +the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised +and/or new versions of the License from time to time. Each version will be +given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the +License, You may always continue to use it under the terms of that version. +You may also choose to use such Covered Code under the terms of any subsequent +version of the License published by Netscape. No one other than Netscape has +the right to modify the terms applicable to Covered Code created under this +License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may +only do in order to apply it to code which is not already Covered Code +governed by this License), You must (a) rename Your license so that the +phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", "MPL", "NPL" or +any confusingly similar phrase do not appear in your license (except to note +that your license differs from this License) and (b) otherwise make it clear +that Your version of the license contains terms which differ from the Mozilla +Public License and Netscape Public License. (Filling in the name of the +Initial Developer, Original Code or Contributor in the notice described in +Exhibit A shall not of themselves be deemed to be modifications of this +License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT +LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, +FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE +QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED +CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY +OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR +CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS +LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS +DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate +automatically if You fail to comply with terms herein and fail to cure such +breach within 30 days of becoming aware of the breach. All sublicenses to the +Covered Code which are properly granted shall survive any termination of this +License. Provisions which, by their nature, must remain in effect beyond the +termination of this License shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement +claim (excluding declatory judgment actions) against Initial Developer or a +Contributor (the Initial Developer or Contributor against whom You file such +action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly +infringes any patent, then any and all rights granted by such Participant to +You under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice +from Participant terminate prospectively, unless if within 60 days after +receipt of notice You either: (i) agree in writing to pay Participant a +mutually agreeable reasonable royalty for Your past and future use of +Modifications made by such Participant, or (ii) withdraw Your litigation claim +with respect to the Contributor Version against such Participant. If within +60 days of notice, a reasonable royalty and payment arrangement are not +mutually agreed upon in writing by the parties or the litigation claim is not +withdrawn, the rights granted by Participant to You under Sections 2.1 and/or +2.2 automatically terminate at the expiration of the 60 day notice period +specified above. + + (b) any software, hardware, or device, other than such Participant's +Contributor Version, directly or indirectly infringes any patent, then any +rights granted to You by such Participant under Sections 2.1(b) and 2.2(b) are +revoked effective as of the date You first made, used, sold, distributed, or +had made, Modifications made by that Participant. + + 8.3. If You assert a patent infringement claim against Participant +alleging that such Participant's Contributor Version directly or indirectly +infringes any patent where such claim is resolved (such as by license or +settlement) prior to the initiation of patent infringement litigation, then +the reasonable value of the licenses granted by such Participant under +Sections 2.1 or 2.2 shall be taken into account in determining the amount or +value of any payment or license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, all +end user license agreements (excluding distributors and resellers) which have +been validly granted by You or any distributor hereunder prior to termination +shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT +(INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL +DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY +SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, +SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, +WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER +FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, +EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH +DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH +OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT +APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE +EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS +EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in 48 +C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" and +"commercial computer software documentation," as such terms are used in 48 +C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. +227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users +acquire Covered Code with only those rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject matter +hereof. If any provision of this License is held to be unenforceable, such +provision shall be reformed only to the extent necessary to make it +enforceable. This License shall be governed by California law provisions +(except to the extent applicable law, if any, provides otherwise), excluding +its conflict-of-law provisions. With respect to disputes in which at least one +party is a citizen of, or an entity chartered or registered to do business in +the United States of America, any litigation relating to this License shall be +subject to the jurisdiction of the Federal Courts of the Northern District of +California, with venue lying in Santa Clara County, California, with the +losing party responsible for costs, including without limitation, court costs +and reasonable attorneys' fees and expenses. The application of the United +Nations Convention on Contracts for the International Sale of Goods is +expressly excluded. Any law or regulation which provides that the language of +a contract shall be construed against the drafter shall not apply to this +License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is +responsible for claims and damages arising, directly or indirectly, out of its +utilization of rights under this License and You agree to work with Initial +Developer and Contributors to distribute such responsibility on an equitable +basis. Nothing herein is intended or shall be deemed to constitute any +admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as +Multiple-Licensed. Multiple-Licensed means that the Initial Developer permits +you to utilize portions of the Covered Code under Your choice of the MPL or +the alternative licenses, if any, specified by the Initial Developer in the +file described in Exhibit A. + + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF + ANY KIND, either express or implied. See the License for the specific +language governing rights and + limitations under the License. + + The Original Code is ______________________________________. + + The Initial Developer of the Original Code is ________________________. +Portions created by + ______________________ are Copyright (C) ______ +_______________________. All Rights + Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the terms of +the _____ license (the [___] License), in which case the provisions of +[______] License are applicable instead of those above. If you wish to allow +use of your version of this file only under the terms of the [____] License +and not to allow others to use your version of this file under the MPL, +indicate your decision by deleting the provisions above and replace them +with the notice and other provisions required by the [___] License. If you do +not delete the provisions above, a recipient may use your version of this file +under either the MPL or the [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the text of +the notices in the Source Code files of the Original Code. You should use the +text of this Exhibit A rather than the text found in the Original Code Source +Code for Your Modifications.] + + +=============================================================================== + +For the JAX-WS Reference Implementation component: + +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + + + 1. Definitions. + + 1.1. "Contributor" means each individual or entity that + creates or contributes to the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the + Original Software, prior Modifications used by a + Contributor (if any), and the Modifications made by that + particular Contributor. + + 1.3. "Covered Software" means (a) the Original Software, or + (b) Modifications, or (c) the combination of files + containing Original Software with files containing + Modifications, in each case including portions thereof. + + 1.4. "Executable" means the Covered Software in any form + other than Source Code. + + 1.5. "Initial Developer" means the individual or entity + that first makes Original Software available under this + License. + + 1.6. "Larger Work" means a work which combines Covered + Software or portions thereof with code not governed by the + terms of this License. + + 1.7. "License" means this document. + + 1.8. "Licensable" means having the right to grant, to the + maximum extent possible, whether at the time of the initial + grant or subsequently acquired, any and all of the rights + conveyed herein. + + 1.9. "Modifications" means the Source Code and Executable + form of any of the following: + + A. Any file that results from an addition to, + deletion from or modification of the contents of a + file containing Original Software or previous + Modifications; + + B. Any new file that contains any part of the + Original Software or previous Modification; or + + C. Any new file that is contributed or otherwise made + available under the terms of this License. + + 1.10. "Original Software" means the Source Code and + Executable form of computer software code that is + originally released under this License. + + 1.11. "Patent Claims" means any patent claim(s), now owned + or hereafter acquired, including without limitation, + method, process, and apparatus claims, in any patent + Licensable by grantor. + + 1.12. "Source Code" means (a) the common form of computer + software code in which modifications are made and (b) + associated documentation included in or with such code. + + 1.13. "You" (or "Your") means an individual or a legal + entity exercising rights under, and complying with all of + the terms of, this License. For legal entities, "You" + includes any entity which controls, is controlled by, or is + under common control with You. For purposes of this + definition, "control" means (a) the power, direct or + indirect, to cause the direction or management of such + entity, whether by contract or otherwise, or (b) ownership + of more than fifty percent (50%) of the outstanding shares + or beneficial ownership of such entity. + + 2. License Grants. + + 2.1. The Initial Developer Grant. + + Conditioned upon Your compliance with Section 3.1 below and + subject to third party intellectual property claims, the + Initial Developer hereby grants You a world-wide, + royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than + patent or trademark) Licensable by Initial Developer, + to use, reproduce, modify, display, perform, + sublicense and distribute the Original Software (or + portions thereof), with or without Modifications, + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, + using or selling of Original Software, to make, have + made, use, practice, sell, and offer for sale, and/or + otherwise dispose of the Original Software (or + portions thereof). + + (c) The licenses granted in Sections 2.1(a) and (b) + are effective on the date Initial Developer first + distributes or otherwise makes the Original Software + available to a third party under the terms of this + License. + + (d) Notwithstanding Section 2.1(b) above, no patent + license is granted: (1) for code that You delete from + the Original Software, or (2) for infringements + caused by: (i) the modification of the Original + Software, or (ii) the combination of the Original + Software with other software or devices. + + 2.2. Contributor Grant. + + Conditioned upon Your compliance with Section 3.1 below and + subject to third party intellectual property claims, each + Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + (a) under intellectual property rights (other than + patent or trademark) Licensable by Contributor to + use, reproduce, modify, display, perform, sublicense + and distribute the Modifications created by such + Contributor (or portions thereof), either on an + unmodified basis, with other Modifications, as + Covered Software and/or as part of a Larger Work; and + + + (b) under Patent Claims infringed by the making, + using, or selling of Modifications made by that + Contributor either alone and/or in combination with + its Contributor Version (or portions of such + combination), to make, use, sell, offer for sale, + have made, and/or otherwise dispose of: (1) + Modifications made by that Contributor (or portions + thereof); and (2) the combination of Modifications + made by that Contributor with its Contributor Version + (or portions of such combination). + + (c) The licenses granted in Sections 2.2(a) and + 2.2(b) are effective on the date Contributor first + distributes or otherwise makes the Modifications + available to a third party. + + (d) Notwithstanding Section 2.2(b) above, no patent + license is granted: (1) for any code that Contributor + has deleted from the Contributor Version; (2) for + infringements caused by: (i) third party + modifications of Contributor Version, or (ii) the + combination of Modifications made by that Contributor + with other software (except as part of the + Contributor Version) or other devices; or (3) under + Patent Claims infringed by Covered Software in the + absence of Modifications made by that Contributor. + + 3. Distribution Obligations. + + 3.1. Availability of Source Code. + + Any Covered Software that You distribute or otherwise make + available in Executable form must also be made available in + Source Code form and that Source Code form must be + distributed only under the terms of this License. You must + include a copy of this License with every copy of the + Source Code form of the Covered Software You distribute or + otherwise make available. You must inform recipients of any + such Covered Software in Executable form as to how they can + obtain such Covered Software in Source Code form in a + reasonable manner on or through a medium customarily used + for software exchange. + + 3.2. Modifications. + + The Modifications that You create or to which You + contribute are governed by the terms of this License. You + represent that You believe Your Modifications are Your + original creation(s) and/or You have sufficient rights to + grant the rights conveyed by this License. + + 3.3. Required Notices. + + You must include a notice in each of Your Modifications + that identifies You as the Contributor of the Modification. + You may not remove or alter any copyright, patent or + trademark notices contained within the Covered Software, or + any notices of licensing or any descriptive text giving + attribution to any Contributor or the Initial Developer. + + 3.4. Application of Additional Terms. + + You may not offer or impose any terms on any Covered + Software in Source Code form that alters or restricts the + applicable version of this License or the recipients' + rights hereunder. You may choose to offer, and to charge a + fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Software. + However, you may do so only on Your own behalf, and not on + behalf of the Initial Developer or any Contributor. You + must make it absolutely clear that any such warranty, + support, indemnity or liability obligation is offered by + You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred + by the Initial Developer or such Contributor as a result of + warranty, support, indemnity or liability terms You offer. + + + 3.5. Distribution of Executable Versions. + + You may distribute the Executable form of the Covered + Software under the terms of this License or under the terms + of a license of Your choice, which may contain terms + different from this License, provided that You are in + compliance with the terms of this License and that the + license for the Executable form does not attempt to limit + or alter the recipient's rights in the Source Code form + from the rights set forth in this License. If You + distribute the Covered Software in Executable form under a + different license, You must make it absolutely clear that + any terms which differ from this License are offered by You + alone, not by the Initial Developer or Contributor. You + hereby agree to indemnify the Initial Developer and every + Contributor for any liability incurred by the Initial + Developer or such Contributor as a result of any such terms + You offer. + + 3.6. Larger Works. + + You may create a Larger Work by combining Covered Software + with other code not governed by the terms of this License + and distribute the Larger Work as a single product. In such + a case, You must make sure the requirements of this License + are fulfilled for the Covered Software. + + 4. Versions of the License. + + 4.1. New Versions. + + Sun Microsystems, Inc. is the initial license steward and + may publish revised and/or new versions of this License + from time to time. Each version will be given a + distinguishing version number. Except as provided in + Section 4.3, no one other than the license steward has the + right to modify this License. + + 4.2. Effect of New Versions. + + You may always continue to use, distribute or otherwise + make the Covered Software available under the terms of the + version of the License under which You originally received + the Covered Software. If the Initial Developer includes a + notice in the Original Software prohibiting it from being + distributed or otherwise made available under any + subsequent version of the License, You must distribute and + make the Covered Software available under the terms of the + version of the License under which You originally received + the Covered Software. Otherwise, You may also choose to + use, distribute or otherwise make the Covered Software + available under the terms of any subsequent version of the + License published by the license steward. + + 4.3. Modified Versions. + + When You are an Initial Developer and You want to create a + new license for Your Original Software, You may create and + use a modified version of this License if You: (a) rename + the license and remove any references to the name of the + license steward (except to note that the license differs + from this License); and (b) otherwise make it clear that + the license contains terms which differ from this License. + + + 5. DISCLAIMER OF WARRANTY. + + COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" + BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, + INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED + SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR + PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND + PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY + COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE + INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF + ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF + WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS + DISCLAIMER. + + 6. TERMINATION. + + 6.1. This License and the rights granted hereunder will + terminate automatically if You fail to comply with terms + herein and fail to cure such breach within 30 days of + becoming aware of the breach. Provisions which, by their + nature, must remain in effect beyond the termination of + this License shall survive. + + 6.2. If You assert a patent infringement claim (excluding + declaratory judgment actions) against Initial Developer or + a Contributor (the Initial Developer or Contributor against + whom You assert such claim is referred to as "Participant") + alleging that the Participant Software (meaning the + Contributor Version where the Participant is a Contributor + or the Original Software where the Participant is the + Initial Developer) directly or indirectly infringes any + patent, then any and all rights granted directly or + indirectly to You by such Participant, the Initial + Developer (if the Initial Developer is not the Participant) + and all Contributors under Sections 2.1 and/or 2.2 of this + License shall, upon 60 days notice from Participant + terminate prospectively and automatically at the expiration + of such 60 day notice period, unless if within such 60 day + period You withdraw Your claim with respect to the + Participant Software against such Participant either + unilaterally or pursuant to a written agreement with + Participant. + + 6.3. In the event of termination under Sections 6.1 or 6.2 + above, all end user licenses that have been validly granted + by You or any distributor hereunder prior to termination + (excluding licenses granted to You by any distributor) + shall survive termination. + + 7. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE + INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF + COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE + LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR + CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT + LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK + STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL + INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT + APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO + NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR + CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT + APPLY TO YOU. + + 8. U.S. GOVERNMENT END USERS. + + The Covered Software is a "commercial item," as that term is + defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial + computer software" (as that term is defined at 48 C.F.R. + 252.227-7014(a)(1)) and "commercial computer software + documentation" as such terms are used in 48 C.F.R. 12.212 (Sept. + 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 + through 227.7202-4 (June 1995), all U.S. Government End Users + acquire Covered Software with only those rights set forth herein. + This U.S. Government Rights clause is in lieu of, and supersedes, + any other FAR, DFAR, or other clause or provision that addresses + Government rights in computer software under this License. + + 9. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the + extent necessary to make it enforceable. This License shall be + governed by the law of the jurisdiction specified in a notice + contained within the Original Software (except to the extent + applicable law, if any, provides otherwise), excluding such + jurisdiction's conflict-of-law provisions. Any litigation + relating to this License shall be subject to the jurisdiction of + the courts located in the jurisdiction and venue specified in a + notice contained within the Original Software, with the losing + party responsible for costs, including, without limitation, court + costs and reasonable attorneys' fees and expenses. The + application of the United Nations Convention on Contracts for the + International Sale of Goods is expressly excluded. Any law or + regulation which provides that the language of a contract shall + be construed against the drafter shall not apply to this License. + You agree that You alone are responsible for compliance with the + United States export administration regulations (and the export + control laws and regulation of any other countries) when You use, + distribute or otherwise make available any Covered Software. + + 10. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or + indirectly, out of its utilization of rights under this License + and You agree to work with Initial Developer and Contributors to + distribute such responsibility on an equitable basis. Nothing + herein is intended or shall be deemed to constitute any admission + of liability. + diff --git a/branches/java-post-M1/sca/core/src/main/resources/META-INF/NOTICE b/branches/java-post-M1/sca/core/src/main/resources/META-INF/NOTICE new file mode 100644 index 0000000000..d48810c0ec --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/resources/META-INF/NOTICE @@ -0,0 +1,18 @@ +========================================================================= +== NOTICE file corresponding to the section 4 d of == +== the Apache License, Version 2.0, == +== in this case for the Apache Tuscany distribution. == +========================================================================= + +This product includes software developed by the Apache Software Foundation +(http://www.apache.org/). + +This product also includes software developed by: +- the Eclipse Modeling Framework project (http://www.eclipse.org/emf/) +- the Celtix project (http://celtix.objectweb.org/) +- the Mozilla Rhino project (http://www.mozilla.org/rhino/) +- the GlassFish JAX-WS project (https://jax-ws.dev.java.net/) + +Please read the LICENSE.txt file present in the root directory of this +distribution. + diff --git a/branches/java-post-M1/sca/core/src/main/resources/META-INF/README.txt b/branches/java-post-M1/sca/core/src/main/resources/META-INF/README.txt new file mode 100644 index 0000000000..9b26d1690a --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/resources/META-INF/README.txt @@ -0,0 +1,35 @@ +Apache Tuscany M1 build (May, 2006) +=================================== + +http://incubator.apache.org/tuscany/ + +Tuscany is an effort undergoing incubation at the Apache Software Foundation +(ASF), sponsored by the Web Services PMC. + +Incubation is required of all newly accepted projects until a further review +indicates that the infrastructure, communications, and decision making process +have stabilized in a manner consistent with other successful ASF projects. + +While incubation status is not necessarily a reflection of the completeness or +stability of the code, it does indicate that the project has yet to be fully +endorsed by the ASF. + + +Support +------- + +Any problem with this release can be reported to the Tuscany mailing list +or in the JIRA issue tracker. + +Mailing list subscription: + tuscany-dev-subscribe@ws.apache.org + +Jira: + http://issues.apache.org/jira/browse/Tuscany + + +Thank you for using Tuscany! + + +The Tuscany Team. + diff --git a/branches/java-post-M1/sca/core/src/main/resources/META-INF/services/org.apache.tuscany.core.runtime.proxy.ServiceProxyFactory b/branches/java-post-M1/sca/core/src/main/resources/META-INF/services/org.apache.tuscany.core.runtime.proxy.ServiceProxyFactory new file mode 100644 index 0000000000..9b2d05d734 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/resources/META-INF/services/org.apache.tuscany.core.runtime.proxy.ServiceProxyFactory @@ -0,0 +1 @@ +org.apache.tuscany.core.runtime.proxy.impl.ServiceProxyFactoryImpl \ No newline at end of file diff --git a/branches/java-post-M1/sca/core/src/main/resources/model/anyobject.xsd b/branches/java-post-M1/sca/core/src/main/resources/model/anyobject.xsd new file mode 100644 index 0000000000..47f45d61d7 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/resources/model/anyobject.xsd @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + diff --git a/branches/java-post-M1/sca/core/src/main/resources/model/tuscany-system.xsd b/branches/java-post-M1/sca/core/src/main/resources/model/tuscany-system.xsd new file mode 100644 index 0000000000..9c85db8c37 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/resources/model/tuscany-system.xsd @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/branches/java-post-M1/sca/core/src/main/resources/org/apache/tuscany/core/MonitorMessages.properties b/branches/java-post-M1/sca/core/src/main/resources/org/apache/tuscany/core/MonitorMessages.properties new file mode 100644 index 0000000000..e3b2ff9a4f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/resources/org/apache/tuscany/core/MonitorMessages.properties @@ -0,0 +1,23 @@ +# Copyright (c) 2006 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. +# +# $Rev$ $Date$ +# + +org.apache.tuscany.core.client.TuscanyRuntime$Monitor#moduleStarted = Started application module [{0}] +org.apache.tuscany.core.client.TuscanyRuntime$Monitor#moduleStartFailed = Fatal exception starting application module [{0}] +org.apache.tuscany.core.client.TuscanyRuntime$Monitor#moduleStopped = Stopped application module [{0}] + +org.apache.tuscany.core.loader.impl.StAXLoaderRegistryImpl$Monitor#registeringLoader = Registering StAXElementLoader for {0} +org.apache.tuscany.core.loader.impl.StAXLoaderRegistryImpl$Monitor#elementLoad = Processing element {0} \ No newline at end of file diff --git a/branches/java-post-M1/sca/core/src/main/resources/system.module b/branches/java-post-M1/sca/core/src/main/resources/system.module new file mode 100644 index 0000000000..a00c8a53ff --- /dev/null +++ b/branches/java-post-M1/sca/core/src/main/resources/system.module @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/invocation/AsyncInvocationConfigurationTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/invocation/AsyncInvocationConfigurationTestCase.java new file mode 100644 index 0000000000..6f55182c2b --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/invocation/AsyncInvocationConfigurationTestCase.java @@ -0,0 +1,197 @@ +/** + * + * 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.async.invocation; + +import java.lang.reflect.Method; +import java.util.concurrent.CountDownLatch; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.tuscany.core.async.wire.mock.MockHandler; +import org.apache.tuscany.core.async.wire.mock.MockStaticInvoker; +import org.apache.tuscany.core.async.wire.mock.MockSyncInterceptor; +import org.apache.tuscany.core.async.wire.mock.SimpleTarget; +import org.apache.tuscany.core.async.wire.mock.SimpleTargetImpl; +import org.apache.tuscany.core.async.work.DefaultWorkManager; +import org.apache.tuscany.core.message.Message; +import org.apache.tuscany.core.message.MessageFactory; +import org.apache.tuscany.core.message.impl.MessageFactoryImpl; +import org.apache.tuscany.core.wire.SourceInvocationConfiguration; +import org.apache.tuscany.core.wire.TargetInvocationConfiguration; +import org.apache.tuscany.core.wire.impl.InvokerInterceptor; +import org.apache.tuscany.core.wire.impl.MessageChannelImpl; + +public class AsyncInvocationConfigurationTestCase extends TestCase { + + private DefaultWorkManager workManager; + private Method hello; + + private MessageFactory factory = new MessageFactoryImpl(); + + public AsyncInvocationConfigurationTestCase() { + super(); + } + + public AsyncInvocationConfigurationTestCase(String arg0) { + super(arg0); + } + + protected void setUp() throws Exception { + hello = SimpleTarget.class.getMethod("hello", String.class); + + workManager=new DefaultWorkManager(); + workManager.setScheduledMaximumPoolSize(5); + workManager.init(); + } + + protected void tearDown() throws Exception { + workManager.destroy(); + + super.tearDown(); + } + + /** + * Tests basic wiring of a source to a target, including handlers and interceptors + */ + public void testInvokeWithHandlers() throws Exception { + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + + source.addInterceptor(new AsyncInterceptor(workManager, factory)); + + MockHandler sourceRequestHandler = new MockHandler(); + MockHandler sourceResponseHandler = new MockHandler(); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addRequestHandler(sourceRequestHandler); + source.addResponseHandler(sourceResponseHandler); + source.addInterceptor(sourceInterceptor); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + MockHandler targetRequestHandler = new MockHandler(); + MockHandler targetResponseHandler = new MockHandler(); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addRequestHandler(targetRequestHandler); + target.addResponseHandler(targetResponseHandler); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + // connect the source to the target + source.setTargetRequestChannel(new MessageChannelImpl(target.getRequestHandlers())); + source.setTargetResponseChannel(new MessageChannelImpl(target.getResponseHandlers())); + source.build(); + target.build(); + + CountDownLatch startSignal = new CountDownLatch(1); + CountDownLatch doneSignal = new CountDownLatch(1); + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl(startSignal, doneSignal)); + source.setTargetInvoker(invoker); + + Message msg = factory.createMessage(); + msg.setBody("foo"); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + startSignal.countDown(); + doneSignal.await(); + + Assert.assertEquals(null, response.getBody()); + Assert.assertEquals(1, sourceRequestHandler.getCount()); + //FIXME why isn't the responseHandler invoked? + //Assert.assertEquals(1, sourceResponseHandler.getCount()); + Assert.assertEquals(1, sourceInterceptor.getCount()); + Assert.assertEquals(1, targetRequestHandler.getCount()); + //FIXME + //Assert.assertEquals(1, targetResponseHandler.getCount()); + Assert.assertEquals(1, targetInterceptor.getCount()); + } + + public void testInvokeWithRequestHandlers() throws Exception { + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + + source.addInterceptor(new AsyncInterceptor(workManager, factory)); + + MockHandler sourceRequestHandler = new MockHandler(); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addRequestHandler(sourceRequestHandler); + source.addInterceptor(sourceInterceptor); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + MockHandler targetRequestHandler = new MockHandler(); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addRequestHandler(targetRequestHandler); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + // connect the source to the target + source.setTargetRequestChannel(new MessageChannelImpl(target.getRequestHandlers())); + source.setTargetResponseChannel(new MessageChannelImpl(target.getResponseHandlers())); + source.build(); + target.build(); + + CountDownLatch startSignal = new CountDownLatch(1); + CountDownLatch doneSignal = new CountDownLatch(1); + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl(startSignal, doneSignal)); + source.setTargetInvoker(invoker); + + Message msg = factory.createMessage(); + msg.setBody("foo"); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + startSignal.countDown(); + doneSignal.await(); + + Assert.assertEquals(null, response.getBody()); + Assert.assertEquals(1, sourceRequestHandler.getCount()); + Assert.assertEquals(1, sourceInterceptor.getCount()); + Assert.assertEquals(1, targetRequestHandler.getCount()); + Assert.assertEquals(1, targetInterceptor.getCount()); + } + + /** + * Tests basic wiring of a source to a target, including handlers and interceptors + */ + public void testInvokeWithInterceptorsOnly() throws Exception { + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + + source.addInterceptor(new AsyncInterceptor(workManager, factory)); + + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addInterceptor(sourceInterceptor); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + // connect the source to the target + source.setTargetInterceptor(target.getHeadInterceptor()); + source.build(); + target.build(); + + CountDownLatch startSignal = new CountDownLatch(1); + CountDownLatch doneSignal = new CountDownLatch(1); + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl(startSignal, doneSignal)); + source.setTargetInvoker(invoker); + + Message msg = factory.createMessage(); + msg.setBody("foo"); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + startSignal.countDown(); + doneSignal.await(); + + Assert.assertEquals(null, response.getBody()); + Assert.assertEquals(1, sourceInterceptor.getCount()); + Assert.assertEquals(1, targetInterceptor.getCount()); + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/MockHandler.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/MockHandler.java new file mode 100644 index 0000000000..4f17dc2a76 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/MockHandler.java @@ -0,0 +1,38 @@ +/** + * + * 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.async.wire.mock; + +import org.apache.tuscany.core.wire.MessageHandler; +import org.apache.tuscany.core.message.Message; + +/** + * + */ +public class MockHandler implements MessageHandler { + + private int count =0; + + public boolean processMessage(Message message) { + //System.out.println("Invoking handler"); + count++; + return true; + } + + public int getCount(){ + return count; + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/MockStaticInvoker.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/MockStaticInvoker.java new file mode 100644 index 0000000000..e32de0eec1 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/MockStaticInvoker.java @@ -0,0 +1,86 @@ +/** + * + * 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.async.wire.mock; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.tuscany.core.message.Message; +import org.apache.tuscany.core.wire.Interceptor; +import org.apache.tuscany.core.wire.InvocationRuntimeException; +import org.apache.tuscany.core.wire.TargetInvoker; + +/** + * Caches component instances that do not need to be resolved for every wire, e.g. an wire originating from + * a lesser scope intended for a target with a wider scope + * + * @version $Rev: 377006 $ $Date: 2006-02-11 09:41:59 -0800 (Sat, 11 Feb 2006) $ + */ +public class MockStaticInvoker implements TargetInvoker { + + private Object instance; + + private Method operation; + + public MockStaticInvoker(Method operation, Object instance) { + this.operation = operation; + this.instance = instance; + } + + public boolean isCacheable() { + return true; + } + + public Object invokeTarget(Object payload) throws InvocationTargetException { + try { + if (payload != null && !payload.getClass().isArray()) { + return operation.invoke(instance, payload); + } else { + return operation.invoke(instance, (Object[]) payload); + } + } catch (IllegalAccessException e) { + throw new InvocationRuntimeException(e); + } + } + + public Message invoke(Message msg) { + try { + Object resp = invokeTarget(msg.getBody()); + msg.setBody(resp); + } catch (InvocationTargetException e) { + msg.setBody(e.getCause()); + } catch (Throwable e) { + msg.setBody(e); + } + return msg; + } + + public void setNext(Interceptor next) { + throw new IllegalStateException("This interceptor must be the last interceptor in an interceptor chain"); + } + + public Object clone() throws CloneNotSupportedException { + try { + MockStaticInvoker invoker = (MockStaticInvoker) super.clone(); + invoker.instance = this.instance; + invoker.operation = this.operation; + return invoker; + } catch (CloneNotSupportedException e) { + return null; // will not happen + } + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/MockSyncInterceptor.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/MockSyncInterceptor.java new file mode 100644 index 0000000000..5b70848d06 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/MockSyncInterceptor.java @@ -0,0 +1,45 @@ +/** + * + * 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.async.wire.mock; + +import org.apache.tuscany.core.wire.Interceptor; +import org.apache.tuscany.core.message.Message; + +public class MockSyncInterceptor implements Interceptor { + + private int count; + + private Interceptor next; + + public MockSyncInterceptor() { + } + + public Message invoke(Message msg) { + ++count; + //System.out.println("Invoking interceptor"); + return next.invoke(msg); + } + + public int getCount() { + return count; + } + + public void setNext(Interceptor next) { + this.next=next; + } +} + diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/SimpleTarget.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/SimpleTarget.java new file mode 100644 index 0000000000..2147a3a4db --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/SimpleTarget.java @@ -0,0 +1,28 @@ +/** + * + * 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.async.wire.mock; + +public interface SimpleTarget { + + public void hello(String message) throws Exception; + + public void goodbye(String message) throws Exception; + + public void echo(String message) throws Exception; + +} + diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/SimpleTargetImpl.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/SimpleTargetImpl.java new file mode 100644 index 0000000000..e6f76494f6 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/wire/mock/SimpleTargetImpl.java @@ -0,0 +1,54 @@ +/** + * + * 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.async.wire.mock; + +import java.util.concurrent.CountDownLatch; + +public class SimpleTargetImpl implements SimpleTarget { + + private final CountDownLatch startSignal; + private final CountDownLatch doneSignal; + + public SimpleTargetImpl(CountDownLatch startSignal, CountDownLatch doneSignal) { + this.startSignal = startSignal; + this.doneSignal = doneSignal; + } + + public void hello(String message) throws Exception { + try { + startSignal.await(); + doneSignal.countDown(); + } catch (InterruptedException ex) {} + } + + public void goodbye(String message) throws Exception { + try { + startSignal.await(); + doneSignal.countDown(); + } catch (InterruptedException ex) {} + } + + public void echo(String message) throws Exception { + try { + startSignal.await(); + doneSignal.countDown(); + } catch (InterruptedException ex) {} + } + + +} + diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/work/DefaultWorkManagerTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/work/DefaultWorkManagerTestCase.java new file mode 100644 index 0000000000..964564f3ee --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/work/DefaultWorkManagerTestCase.java @@ -0,0 +1,98 @@ +/** + * + * 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.async.work; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.CountDownLatch; + +import javax.resource.spi.work.Work; + +import junit.framework.TestCase; + +import org.apache.tuscany.core.async.work.DefaultWorkManager; + +/** + * Test the PooledWorkManager. + */ +public class DefaultWorkManagerTestCase extends TestCase { + + private Set done; + private int count; + + public void testScheduleWork() throws Exception { + + DefaultWorkManager workManager = new DefaultWorkManager(); + workManager.setScheduledMaximumPoolSize(3); + workManager.init(); + + int max=workManager.getScheduledMaximumPoolSize()*5; + done=Collections.synchronizedSet(new HashSet()); + count=0; + + CountDownLatch startSignal = new CountDownLatch(1); + CountDownLatch doneSignal = new CountDownLatch(max); + for (int i = 0; i < max; ++i) { + workManager.scheduleWork(new Worker(startSignal, doneSignal)); + } + startSignal.countDown(); + doneSignal.await(); + + assertFalse(done.contains(Thread.currentThread())); + assert(done.size()==workManager.getScheduledMaximumPoolSize()); + assert(count==max); + + done=null; + count=0; + + workManager.destroy(); + + } + + private synchronized void done(Thread thread) { + done.add(thread); + count++; + } + + private class Worker implements Work { + private final CountDownLatch startSignal; + private final CountDownLatch doneSignal; + + Worker(CountDownLatch startSignal, CountDownLatch doneSignal) { + this.startSignal = startSignal; + this.doneSignal = doneSignal; + } + + public void run() { + try { + startSignal.await(); + + DefaultWorkManagerTestCase.this.done(Thread.currentThread()); + //System.out.println(Thread.currentThread()); + + doneSignal.countDown(); + } catch (InterruptedException ex) { + } + } + + public void release() { + } + + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/work/GeronimoWorkManagerTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/work/GeronimoWorkManagerTestCase.java new file mode 100644 index 0000000000..18570d54c3 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/async/work/GeronimoWorkManagerTestCase.java @@ -0,0 +1,138 @@ +/** + * + * 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.async.work; + +import javax.resource.spi.work.Work; +import javax.resource.spi.work.WorkEvent; +import javax.resource.spi.work.WorkListener; + +import junit.framework.TestCase; + +import org.apache.geronimo.connector.work.GeronimoWorkManager; +import org.apache.geronimo.transaction.context.TransactionContextManager; + +/** + * Tests the Geronimo work manager + * + * @version $Rev$ $Date$ + */ +public class GeronimoWorkManagerTestCase extends TestCase { + + private GeronimoWorkManager workManager; + + protected void setUp() throws Exception { + TransactionContextManager transactionContextManager = new TransactionContextManager(); + + workManager = new GeronimoWorkManager(2, transactionContextManager); + workManager.doStart(); + } + + public void testScheduleWork() throws Exception { + TestThread threads[] = startTestThreads(5, 10000, 100); + int accepted = 0; + int started = 0; + for (int i = 0; i < threads.length; i++) { + if (null != threads[i].listener.acceptedEvent) { + accepted++; + } else if (null != threads[i].listener.startedEvent) { + started++; + } else { + fail("incorrect state, expecting accepted or started"); + } + } + assertTrue(accepted > 0); + } + + private TestThread[] startTestThreads(int count, int timeout, int delay) throws Exception { + TestThread threads[] = new TestThread[count]; + for (int i = 0; i < count; i++) { + TestWorkListener listener=new TestWorkListener(); + threads[i] = new TestThread(listener, timeout, delay); + } + for (int i = 0; i < count; i++) { + threads[i].start(); + } + for (int i = 0; i < count; i++) { + threads[i].join(); + } + return threads; + } + + private class TestThread extends Thread { + public final TestWorkListener listener; + private final int timeout; + private final int delay; + + public TestThread(TestWorkListener listener, int timeout, int delay) { + this.listener = listener; + this.timeout = timeout; + this.delay = delay; + } + + public void run() { + try { + workManager.scheduleWork(new TestWorker(delay), timeout, null, listener); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } + + public class TestWorker implements Work { + private final int delay; + + public TestWorker(int delay) { + this.delay = delay; + } + + public void release() { + } + + public void run() { + try { + Thread.sleep(delay); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + } + + public class TestWorkListener implements WorkListener { + public WorkEvent acceptedEvent; + public WorkEvent rejectedEvent; + public WorkEvent startedEvent; + public WorkEvent completedEvent; + + public void workAccepted(WorkEvent e) { + acceptedEvent = e; + } + + public void workRejected(WorkEvent e) { + rejectedEvent = e; + } + + public void workStarted(WorkEvent e) { + startedEvent = e; + } + + public void workCompleted(WorkEvent e) { + completedEvent = e; + } + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/builder/impl/DefaultWireBuilderTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/builder/impl/DefaultWireBuilderTestCase.java new file mode 100644 index 0000000000..e4aaad62d1 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/builder/impl/DefaultWireBuilderTestCase.java @@ -0,0 +1,465 @@ +/** + * + * 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.builder.impl; + +import junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.core.wire.MethodHashMap; +import org.apache.tuscany.core.wire.WireSourceConfiguration; +import org.apache.tuscany.core.wire.WireTargetConfiguration; +import org.apache.tuscany.core.wire.SourceInvocationConfiguration; +import org.apache.tuscany.core.wire.TargetInvocationConfiguration; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.WireFactoryFactory; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.core.wire.mock.SimpleTarget; +import org.apache.tuscany.core.wire.mock.MockHandler; +import org.apache.tuscany.core.wire.mock.MockSyncInterceptor; +import org.apache.tuscany.core.wire.mock.MockStaticInvoker; +import org.apache.tuscany.core.wire.mock.SimpleTargetImpl; +import org.apache.tuscany.core.wire.impl.InvokerInterceptor; +import org.apache.tuscany.core.wire.jdk.JDKWireFactoryFactory; +import org.apache.tuscany.core.message.Message; +import org.apache.tuscany.core.message.MessageFactory; +import org.apache.tuscany.core.message.impl.MessageFactoryImpl; + +import java.lang.reflect.Method; +import java.util.Map; + +public class DefaultWireBuilderTestCase extends TestCase { + + private Method hello; + + private WireFactoryFactory wireFactoryFactory = new JDKWireFactoryFactory(); + + public DefaultWireBuilderTestCase() { + super(); + } + + public DefaultWireBuilderTestCase(String arg0) { + super(arg0); + } + + public void setUp() throws Exception { + hello = SimpleTarget.class.getMethod("hello", String.class); + } + + public void testWireWithInterceptorsAndHandlers() throws Exception { + MessageFactory msgFactory = new MessageFactoryImpl(); + + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + MockHandler sourceRequestHandler = new MockHandler(); + MockHandler sourceResponseHandler = new MockHandler(); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addRequestHandler(sourceRequestHandler); + source.addResponseHandler(sourceResponseHandler); + source.addInterceptor(sourceInterceptor); + + SourceWireFactory sourceFactory = wireFactoryFactory.createSourceWireFactory(); + Map sourceInvocationConfigs = new MethodHashMap(); + sourceInvocationConfigs.put(hello, source); + WireSourceConfiguration sourceConfig = new WireSourceConfiguration("foo",new QualifiedName("target/SimpleTarget"), + sourceInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + sourceFactory.setConfiguration(sourceConfig); + sourceFactory.setBusinessInterface(SimpleTarget.class); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + MockHandler targetRequestHandler = new MockHandler(); + MockHandler targetResponseHandler = new MockHandler(); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addRequestHandler(targetRequestHandler); + target.addResponseHandler(targetResponseHandler); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + TargetWireFactory targetFactory = wireFactoryFactory.createTargetWireFactory(); + Map targetInvocationConfigs = new MethodHashMap(); + targetInvocationConfigs.put(hello, target); + WireTargetConfiguration targetConfig = new WireTargetConfiguration(new QualifiedName("target/SimpleTarget"), + targetInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + targetFactory.setConfiguration(targetConfig); + targetFactory.setBusinessInterface(SimpleTarget.class); + + // connect the source to the target + DefaultWireBuilder builder = new DefaultWireBuilder(); + // no need for scopes since we use a static invoker + builder.connect(sourceFactory, targetFactory, null, true, null); + // source.buildSource(); + target.build(); + // set a static invoker + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Message msg = msgFactory.createMessage(); + msg.setBody("foo"); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + Assert.assertEquals("foo", response.getBody()); + Assert.assertEquals(1, sourceRequestHandler.getCount()); + Assert.assertEquals(1, sourceResponseHandler.getCount()); + Assert.assertEquals(1, sourceInterceptor.getCount()); + Assert.assertEquals(1, targetRequestHandler.getCount()); + Assert.assertEquals(1, targetResponseHandler.getCount()); + Assert.assertEquals(1, targetInterceptor.getCount()); + } + + public void testWireWithSourceInterceptorTargetHandlersAndTargetInterceptor() throws Exception { + MessageFactory msgFactory = new MessageFactoryImpl(); + + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addInterceptor(sourceInterceptor); + + SourceWireFactory sourceFactory = new JDKWireFactoryFactory().createSourceWireFactory(); + Map sourceInvocationConfigs = new MethodHashMap(); + sourceInvocationConfigs.put(hello, source); + WireSourceConfiguration sourceConfig = new WireSourceConfiguration("foo",new QualifiedName("target/SimpleTarget"), + sourceInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + sourceFactory.setConfiguration(sourceConfig); + sourceFactory.setBusinessInterface(SimpleTarget.class); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + MockHandler targetRequestHandler = new MockHandler(); + MockHandler targetResponseHandler = new MockHandler(); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addRequestHandler(targetRequestHandler); + target.addResponseHandler(targetResponseHandler); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + TargetWireFactory targetFactory = wireFactoryFactory.createTargetWireFactory(); + Map targetInvocationConfigs = new MethodHashMap(); + targetInvocationConfigs.put(hello, target); + WireTargetConfiguration targetConfig = new WireTargetConfiguration(new QualifiedName("target/SimpleTarget"), + targetInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + targetFactory.setConfiguration(targetConfig); + targetFactory.setBusinessInterface(SimpleTarget.class); + + // connect the source to the target + DefaultWireBuilder builder = new DefaultWireBuilder(); + // no need for scopes since we use a static invoker + builder.connect(sourceFactory, targetFactory, null, true, null); + // source.buildSource(); + target.build(); + // set a static invoker + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Message msg = msgFactory.createMessage(); + msg.setBody("foo"); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + Assert.assertEquals("foo", response.getBody()); + Assert.assertEquals(1, sourceInterceptor.getCount()); + Assert.assertEquals(1, targetRequestHandler.getCount()); + Assert.assertEquals(1, targetResponseHandler.getCount()); + Assert.assertEquals(1, targetInterceptor.getCount()); + } + + public void testWireWithInterceptorsAndRequestHandlers() throws Exception { + MessageFactory msgFactory = new MessageFactoryImpl(); + + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + MockHandler sourceRequestHandler = new MockHandler(); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addRequestHandler(sourceRequestHandler); + source.addInterceptor(sourceInterceptor); + + SourceWireFactory sourceFactory = new JDKWireFactoryFactory().createSourceWireFactory(); + Map sourceInvocationConfigs = new MethodHashMap(); + sourceInvocationConfigs.put(hello, source); + WireSourceConfiguration sourceConfig = new WireSourceConfiguration("foo",new QualifiedName("target/SimpleTarget"), + sourceInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + sourceFactory.setConfiguration(sourceConfig); + sourceFactory.setBusinessInterface(SimpleTarget.class); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + MockHandler targetRequestHandler = new MockHandler(); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addRequestHandler(targetRequestHandler); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + TargetWireFactory targetFactory = wireFactoryFactory.createTargetWireFactory(); + Map targetInvocationConfigs = new MethodHashMap(); + targetInvocationConfigs.put(hello, target); + WireTargetConfiguration targetConfig = new WireTargetConfiguration(new QualifiedName("target/SimpleTarget"), + targetInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + targetFactory.setConfiguration(targetConfig); + targetFactory.setBusinessInterface(SimpleTarget.class); + + // connect the source to the target + DefaultWireBuilder builder = new DefaultWireBuilder(); + // no need for scopes since we use a static invoker + builder.connect(sourceFactory, targetFactory, null, true, null); + // source.buildSource(); + target.build(); + // set a static invoker + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Message msg = msgFactory.createMessage(); + msg.setBody("foo"); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + Assert.assertEquals("foo", response.getBody()); + Assert.assertEquals(1, sourceRequestHandler.getCount()); + Assert.assertEquals(1, sourceInterceptor.getCount()); + Assert.assertEquals(1, targetRequestHandler.getCount()); + Assert.assertEquals(1, targetInterceptor.getCount()); + } + + public void testWireWithSourceAndTargetInterceptors() throws Exception { + MessageFactory msgFactory = new MessageFactoryImpl(); + + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addInterceptor(sourceInterceptor); + + SourceWireFactory sourceFactory = new JDKWireFactoryFactory().createSourceWireFactory(); + Map sourceInvocationConfigs = new MethodHashMap(); + sourceInvocationConfigs.put(hello, source); + WireSourceConfiguration sourceConfig = new WireSourceConfiguration("foo",new QualifiedName("target/SimpleTarget"), + sourceInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + sourceFactory.setConfiguration(sourceConfig); + sourceFactory.setBusinessInterface(SimpleTarget.class); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + TargetWireFactory targetFactory = wireFactoryFactory.createTargetWireFactory(); + Map targetInvocationConfigs = new MethodHashMap(); + targetInvocationConfigs.put(hello, target); + WireTargetConfiguration targetConfig = new WireTargetConfiguration(new QualifiedName("target/SimpleTarget"), + targetInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + targetFactory.setConfiguration(targetConfig); + targetFactory.setBusinessInterface(SimpleTarget.class); + + // connect the source to the target + DefaultWireBuilder builder = new DefaultWireBuilder(); + // no need for scopes since we use a static invoker + builder.connect(sourceFactory, targetFactory, null, true, null); + // source.buildSource(); + target.build(); + // set a static invoker + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Message msg = msgFactory.createMessage(); + msg.setBody("foo"); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + Assert.assertEquals("foo", response.getBody()); + Assert.assertEquals(1, sourceInterceptor.getCount()); + Assert.assertEquals(1, targetInterceptor.getCount()); + } + + public void testWireWithSourceInterceptorSourceHandlersAndTargetInterceptor() throws Exception { + MessageFactory msgFactory = new MessageFactoryImpl(); + + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + MockHandler sourceRequestHandler = new MockHandler(); + MockHandler sourceResponseHandler = new MockHandler(); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addRequestHandler(sourceRequestHandler); + source.addResponseHandler(sourceResponseHandler); + source.addInterceptor(sourceInterceptor); + + SourceWireFactory sourceFactory = new JDKWireFactoryFactory().createSourceWireFactory(); + Map sourceInvocationConfigs = new MethodHashMap(); + sourceInvocationConfigs.put(hello, source); + WireSourceConfiguration sourceConfig = new WireSourceConfiguration("foo",new QualifiedName("target/SimpleTarget"), + sourceInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + sourceFactory.setConfiguration(sourceConfig); + sourceFactory.setBusinessInterface(SimpleTarget.class); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + TargetWireFactory targetFactory = wireFactoryFactory.createTargetWireFactory(); + Map targetInvocationConfigs = new MethodHashMap(); + targetInvocationConfigs.put(hello, target); + WireTargetConfiguration targetConfig = new WireTargetConfiguration(new QualifiedName("target/SimpleTarget"), + targetInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + targetFactory.setConfiguration(targetConfig); + targetFactory.setBusinessInterface(SimpleTarget.class); + + // connect the source to the target + DefaultWireBuilder builder = new DefaultWireBuilder(); + // no need for scopes since we use a static invoker + builder.connect(sourceFactory, targetFactory, null, true, null); + // source.buildSource(); + target.build(); + // set a static invoker + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Message msg = msgFactory.createMessage(); + msg.setBody("foo"); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + Assert.assertEquals("foo", response.getBody()); + Assert.assertEquals(1, sourceRequestHandler.getCount()); + Assert.assertEquals(1, sourceResponseHandler.getCount()); + Assert.assertEquals(1, sourceInterceptor.getCount()); + Assert.assertEquals(1, targetInterceptor.getCount()); + } + + public void testWireWithTargetInterceptorAndTargetHandlers() throws Exception { + MessageFactory msgFactory = new MessageFactoryImpl(); + + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + + SourceWireFactory sourceFactory = new JDKWireFactoryFactory().createSourceWireFactory(); + Map sourceInvocationConfigs = new MethodHashMap(); + sourceInvocationConfigs.put(hello, source); + WireSourceConfiguration sourceConfig = new WireSourceConfiguration("foo",new QualifiedName("target/SimpleTarget"), + sourceInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + sourceFactory.setConfiguration(sourceConfig); + sourceFactory.setBusinessInterface(SimpleTarget.class); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + MockHandler targetRequestHandler = new MockHandler(); + MockHandler targetResponseHandler = new MockHandler(); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addRequestHandler(targetRequestHandler); + target.addResponseHandler(targetResponseHandler); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + TargetWireFactory targetFactory = wireFactoryFactory.createTargetWireFactory(); + Map targetInvocationConfigs = new MethodHashMap(); + targetInvocationConfigs.put(hello, target); + WireTargetConfiguration targetConfig = new WireTargetConfiguration(new QualifiedName("target/SimpleTarget"), + targetInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + targetFactory.setConfiguration(targetConfig); + targetFactory.setBusinessInterface(SimpleTarget.class); + + // connect the source to the target + DefaultWireBuilder builder = new DefaultWireBuilder(); + // no need for scopes since we use a static invoker + builder.connect(sourceFactory, targetFactory, null, true, null); + // source.buildSource(); + target.build(); + // set a static invoker + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Message msg = msgFactory.createMessage(); + msg.setBody("foo"); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + Assert.assertEquals("foo", response.getBody()); + Assert.assertEquals(1, targetRequestHandler.getCount()); + Assert.assertEquals(1, targetResponseHandler.getCount()); + Assert.assertEquals(1, targetInterceptor.getCount()); + } + + public void testWireWithTargetInterceptor() throws Exception { + MessageFactory msgFactory = new MessageFactoryImpl(); + + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + + SourceWireFactory sourceFactory = new JDKWireFactoryFactory().createSourceWireFactory(); + Map sourceInvocationConfigs = new MethodHashMap(); + sourceInvocationConfigs.put(hello, source); + WireSourceConfiguration sourceConfig = new WireSourceConfiguration("foo",new QualifiedName("target/SimpleTarget"), + sourceInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + sourceFactory.setConfiguration(sourceConfig); + sourceFactory.setBusinessInterface(SimpleTarget.class); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + TargetWireFactory targetFactory = wireFactoryFactory.createTargetWireFactory(); + Map targetInvocationConfigs = new MethodHashMap(); + targetInvocationConfigs.put(hello, target); + WireTargetConfiguration targetConfig = new WireTargetConfiguration(new QualifiedName("target/SimpleTarget"), + targetInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + targetFactory.setConfiguration(targetConfig); + targetFactory.setBusinessInterface(SimpleTarget.class); + + // connect the source to the target + DefaultWireBuilder builder = new DefaultWireBuilder(); + // no need for scopes since we use a static invoker + builder.connect(sourceFactory, targetFactory, null, true, null); + target.build(); + // set a static invoker + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Message msg = msgFactory.createMessage(); + msg.setBody("foo"); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + Assert.assertEquals("foo", response.getBody()); + Assert.assertEquals(1, targetInterceptor.getCount()); + } + + /** + * When there are only {@link InvokerInterceptor}s in the source and target chain, we need to bypass one during + * wire up so they are not chained together + */ + public void testWireWithOnlyInvokerInterceptors() throws Exception { + MessageFactory msgFactory = new MessageFactoryImpl(); + + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + source.setTargetInterceptor(new InvokerInterceptor()); + + SourceWireFactory sourceFactory = new JDKWireFactoryFactory().createSourceWireFactory(); + Map sourceInvocationConfigs = new MethodHashMap(); + sourceInvocationConfigs.put(hello, source); + WireSourceConfiguration sourceConfig = new WireSourceConfiguration("foo",new QualifiedName("target/SimpleTarget"), + sourceInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + sourceFactory.setConfiguration(sourceConfig); + sourceFactory.setBusinessInterface(SimpleTarget.class); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + target.addInterceptor(new InvokerInterceptor()); + + TargetWireFactory targetFactory = wireFactoryFactory.createTargetWireFactory(); + Map targetInvocationConfigs = new MethodHashMap(); + targetInvocationConfigs.put(hello, target); + WireTargetConfiguration targetConfig = new WireTargetConfiguration(new QualifiedName("target/SimpleTarget"), + targetInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + targetFactory.setConfiguration(targetConfig); + targetFactory.setBusinessInterface(SimpleTarget.class); + + // connect the source to the target + DefaultWireBuilder builder = new DefaultWireBuilder(); + // no need for scopes since we use a static invoker + builder.connect(sourceFactory, targetFactory, null, true, null); + target.build(); + // set a static invoker + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Message msg = msgFactory.createMessage(); + msg.setBody("foo"); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + Assert.assertEquals("foo", response.getBody()); + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/builder/impl/NegativeDefaultWireBuilderTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/builder/impl/NegativeDefaultWireBuilderTestCase.java new file mode 100644 index 0000000000..983dc577c4 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/builder/impl/NegativeDefaultWireBuilderTestCase.java @@ -0,0 +1,89 @@ +/** + * + * 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.builder.impl; + +import junit.framework.TestCase; +import org.apache.tuscany.core.builder.BuilderConfigException; +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.core.wire.MethodHashMap; +import org.apache.tuscany.core.wire.WireSourceConfiguration; +import org.apache.tuscany.core.wire.WireTargetConfiguration; +import org.apache.tuscany.core.wire.SourceInvocationConfiguration; +import org.apache.tuscany.core.wire.TargetInvocationConfiguration; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.core.wire.WireFactoryFactory; +import org.apache.tuscany.core.wire.jdk.JDKWireFactoryFactory; +import org.apache.tuscany.core.wire.mock.SimpleTarget; +import org.apache.tuscany.core.message.MessageFactory; +import org.apache.tuscany.core.message.impl.MessageFactoryImpl; + +import java.lang.reflect.Method; +import java.util.Map; + +public class NegativeDefaultWireBuilderTestCase extends TestCase { + + private Method hello; + + private WireFactoryFactory wireFactoryFactory = new JDKWireFactoryFactory(); + + public NegativeDefaultWireBuilderTestCase() { + super(); + } + + public NegativeDefaultWireBuilderTestCase(String arg0) { + super(arg0); + } + + public void setUp() throws Exception { + hello = SimpleTarget.class.getMethod("hello", String.class); + } + + public void testNoTargetInterceptorOrHandler() throws Exception { + MessageFactory msgFactory = new MessageFactoryImpl(); + + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + + SourceWireFactory sourceFactory = new JDKWireFactoryFactory().createSourceWireFactory(); + Map sourceInvocationConfigs = new MethodHashMap(); + sourceInvocationConfigs.put(hello, source); + WireSourceConfiguration sourceConfig = new WireSourceConfiguration("foo",new QualifiedName("target/SimpleTarget"), + sourceInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + sourceFactory.setConfiguration(sourceConfig); + sourceFactory.setBusinessInterface(SimpleTarget.class); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + + TargetWireFactory targetFactory = wireFactoryFactory.createTargetWireFactory(); + Map targetInvocationConfigs = new MethodHashMap(); + targetInvocationConfigs.put(hello, target); + WireTargetConfiguration targetConfig = new WireTargetConfiguration(new QualifiedName("target/SimpleTarget"), + targetInvocationConfigs, Thread.currentThread().getContextClassLoader(), msgFactory); + targetFactory.setConfiguration(targetConfig); + targetFactory.setBusinessInterface(SimpleTarget.class); + + // connect the source to the target + DefaultWireBuilder builder = new DefaultWireBuilder(); + try { + builder.connect(sourceFactory, targetFactory, null, true, null); + fail("Expected " + BuilderConfigException.class.getName()); + } catch (BuilderConfigException e) { + // success + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/Bean1.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/Bean1.java new file mode 100644 index 0000000000..c02961e5f4 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/Bean1.java @@ -0,0 +1,45 @@ +/** + * + * 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.config; + + +public class Bean1 extends SuperBean { + + public static final int ALL_BEAN1_FIELDS = 6 + ALL_SUPER_FIELDS; + public static final int ALL_BEAN1_PUBLIC_PROTECTED_FIELDS = 5 + ALL_SUPER_PUBLIC_PROTECTED_FIELDS; + + public static final int ALL__BEAN1_METHODS = 4 + ALL_SUPER_METHODS - 1; + + private String field1; + protected String field2; + public String field3; + + public void setMethod1(String param) { + } + + public void setMethod1(int param) { + } + + public void override(String param) throws Exception { + } + + + public void noOverride(String param) throws Exception { + } + + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/Bean2.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/Bean2.java new file mode 100644 index 0000000000..eaba545d8e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/Bean2.java @@ -0,0 +1,46 @@ +/** + * + * 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.config; + +import junit.framework.AssertionFailedError; + +import java.util.List; + +public class Bean2 { + + private List methodList; + + public List getMethodList() { + return methodList; + } + + public void setMethodList(List list) { + methodList = list; + } + + private List fieldList; + + public List getfieldList() { + return fieldList; + } + + public void setfieldList(List list) { + throw new AssertionFailedError("setter inadvertantly called"); + } + + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/JavaIntrospectionHelperTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/JavaIntrospectionHelperTestCase.java new file mode 100644 index 0000000000..8a95a6c7b0 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/JavaIntrospectionHelperTestCase.java @@ -0,0 +1,163 @@ +/** + * + * 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.config; + +import junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.tuscany.core.mock.component.Target; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class JavaIntrospectionHelperTestCase extends TestCase { + + public JavaIntrospectionHelperTestCase() { + super(); + } + + public JavaIntrospectionHelperTestCase(String arg0) { + super(arg0); + } + + public void testGetSuperAllFields() throws Exception { + Set superBeanFields = JavaIntrospectionHelper.getAllFields(SuperBean.class); + Assert.assertEquals(SuperBean.ALL_SUPER_FIELDS, superBeanFields.size()); + } + + public void testBean1AllPublicProtectedFields() throws Exception { + Set beanFields = JavaIntrospectionHelper.getAllPublicAndProtectedFields(Bean1.class); + Assert.assertEquals(4, beanFields.size()); //Bean1.ALL_BEAN1_PUBLIC_PROTECTED_FIELDS + } + + public void testBean1AllFields() throws Exception { + Set beanFields = JavaIntrospectionHelper.getAllFields(Bean1.class); + Assert.assertEquals(Bean1.ALL_BEAN1_FIELDS, beanFields.size()); + } + + public void testGetSuperAllMethods() throws Exception { + Set superBeanMethods = JavaIntrospectionHelper.getAllUniqueMethods(SuperBean.class); + Assert.assertEquals(SuperBean.ALL_SUPER_METHODS, superBeanMethods.size()); + } + + public void testGetBean1AllMethods() throws Exception { + Set beanMethods = JavaIntrospectionHelper.getAllUniqueMethods(Bean1.class); + Assert.assertEquals(Bean1.ALL__BEAN1_METHODS, beanMethods.size()); + } + + public void testOverrideMethod() throws Exception { + Set beanFields = JavaIntrospectionHelper.getAllUniqueMethods(Bean1.class); + boolean invoked = false; + for (Method method : beanFields) { + if (method.getName().equals("override")) { + method.invoke(new Bean1(), "foo"); + invoked = true; + } + } + if (!invoked) { + throw new Exception("Override never invoked"); + } + } + + public void testNoOverrideMethod() throws Exception { + Set beanFields = JavaIntrospectionHelper.getAllUniqueMethods(Bean1.class); + boolean found = false; + for (Method method : beanFields) { + if (method.getName().equals("noOverride") && method.getParameterTypes().length == 0) { + found = true; + } + } + if (!found) { + throw new Exception("No override not found"); + } + } + + public void testGetBean1AllFields() throws Exception { + Set bean1 = JavaIntrospectionHelper.getAllFields(Bean1.class); + Assert.assertEquals(Bean1.ALL_BEAN1_FIELDS, bean1.size()); + } + + public void testDefaultConstructor() throws Exception { + Constructor ctr = JavaIntrospectionHelper.getDefaultConstructor(Bean2.class); + Assert.assertEquals(ctr, Bean2.class.getConstructor()); + Assert.assertTrue(Bean2.class == ctr.newInstance((Object[]) null).getClass()); + } + + + public void testFindMultiplicityByFieldName() throws Exception{ + Set fields = JavaIntrospectionHelper.getAllFields(getClass()); + Set methods = JavaIntrospectionHelper.getAllUniqueMethods(getClass()); + + Assert.assertNotNull(JavaIntrospectionHelper.findMultiplicityFieldByName("testList",fields)); + Assert.assertNotNull(JavaIntrospectionHelper.findMultiplicityMethodByName("fooMethod",methods)); + + // this array is not an interface + Assert.assertNull(JavaIntrospectionHelper.findMultiplicityFieldByName("testStringArray",fields)); + Assert.assertNotNull(JavaIntrospectionHelper.findMultiplicityFieldByName("testArray",fields)); + Assert.assertNotNull(JavaIntrospectionHelper.findMultiplicityMethodByName("setTestArray",methods)); + } + + /** + * Tests generics introspection capabilities + */ + public void testGenerics() throws Exception{ + + List classes = JavaIntrospectionHelper.getGenerics(getClass().getDeclaredField("testList").getGenericType()); + Assert.assertEquals(1,classes.size()); + Assert.assertEquals(String.class,classes.get(0)); + + classes = JavaIntrospectionHelper.getGenerics(getClass().getDeclaredField("testNoGenericsList").getGenericType()); + Assert.assertEquals(0,classes.size()); + + classes = JavaIntrospectionHelper.getGenerics(getClass().getDeclaredField("testMap").getGenericType()); + Assert.assertEquals(2,classes.size()); + Assert.assertEquals(String.class,classes.get(0)); + Assert.assertEquals(Bean1.class,classes.get(1)); + + classes = JavaIntrospectionHelper.getGenerics(getClass().getDeclaredMethod("fooMethod", Map.class).getGenericParameterTypes()[0]); + Assert.assertEquals(2,classes.size()); + Assert.assertEquals(String.class,classes.get(0)); + Assert.assertEquals(Bean1.class,classes.get(1)); + + classes = JavaIntrospectionHelper.getGenerics(getClass().getDeclaredMethod("fooMethod", List.class).getGenericParameterTypes()[0]); + Assert.assertEquals(1,classes.size()); + Assert.assertEquals(String.class,classes.get(0)); + + } + + private List testNoGenericsList; + + private List testList; + + private Map testMap; + + private void fooMethod(List foo){ + + } + + private void fooMethod(Map foo){ + + } + + private Target[] testArray; + private String[] testStringArray; + + public void setTestArray(Target[] array){} +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/SuperBean.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/SuperBean.java new file mode 100644 index 0000000000..0a4e0cca0c --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/SuperBean.java @@ -0,0 +1,48 @@ +/** + * + * 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.config; + +/** + * @version $Rev: 368822 $ $Date: 2006-01-13 10:54:38 -0800 (Fri, 13 Jan 2006) $ + */ +public class SuperBean { + + public static final int ALL_SUPER_FIELDS = 6; + public static final int ALL_SUPER_PUBLIC_PROTECTED_FIELDS = 5; + + public static final int ALL_SUPER_METHODS = 4; + + private String superField1; + + public String superField2; + + protected String superField3; + + public void setSuperMethod1(String param) { + } + + public void setSuperMethod1(int param) { + } + + public void override(String param) throws Exception { + throw new Exception("Override not handled"); + } + + public void noOverride() throws Exception { + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/CoreAnnotationsProcessingTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/CoreAnnotationsProcessingTestCase.java new file mode 100644 index 0000000000..aeb614e9c6 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/CoreAnnotationsProcessingTestCase.java @@ -0,0 +1,173 @@ +/** + * + * 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.util.List; + +import junit.framework.TestCase; +import org.apache.tuscany.core.config.ComponentTypeIntrospector; +import org.apache.tuscany.core.config.JavaIntrospectionHelper; +import org.apache.tuscany.core.config.processor.ProcessorUtils; +import org.apache.tuscany.core.system.assembly.impl.SystemAssemblyFactoryImpl; +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.Reference; +import org.apache.tuscany.model.assembly.Scope; +import org.apache.tuscany.model.assembly.Service; +import org.apache.tuscany.model.assembly.ServiceContract; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class CoreAnnotationsProcessingTestCase extends TestCase { + + private ComponentTypeIntrospector introspector; + private AssemblyFactory factory; + + public void testServiceBasicProcessing() throws Exception { + ComponentType type = factory.createComponentType(); + introspector.introspect(TestComponentImpl.class, type); + assertEquals(1, type.getServices().size()); + ServiceContract contract = type.getServices().get(0).getServiceContract(); + assertEquals(TestComponent.class, contract.getInterface()); + assertEquals(Scope.MODULE, contract.getScope()); + } + + public void testServiceNameSet() throws Exception { + ComponentType type = factory.createComponentType(); + introspector.introspect(TestComponentImpl.class, type); + assertEquals(1, type.getServices().size()); + Service service = type.getServices().get(0); + assertEquals(JavaIntrospectionHelper.getBaseName(TestComponent.class), service.getName()); + } + + /** + * Tests the case where a class implements one interface not marked as with Remotable + */ + public void testSingleServiceProcessing() throws Exception { + ComponentType type = factory.createComponentType(); + introspector.introspect(TestLocalComponentImpl.class, type); + assertEquals(1, type.getServices().size()); + ServiceContract contract = type.getServices().get(0).getServiceContract(); + assertEquals(TestLocalComponent.class, contract.getInterface()); + assertEquals(Scope.MODULE, contract.getScope()); + } + + /** + * Tests the case where an implementation specifies a service interface of its parent as opposed to the + * single interface it directly implements + */ + public void testInteraceHierarchyServiceProcessing() throws Exception { + ComponentType type = factory.createComponentType(); + introspector.introspect(SuperFooImpl.class, type); + assertEquals(1, type.getServices().size()); + ServiceContract contract = type.getServices().get(0).getServiceContract(); + assertEquals(SuperSuperFoo.class, contract.getInterface()); + } + + /** + * Tests the case where a class implements two interfaces, with one specified using @Service + * and one marked with @Remotable + */ + public void testMutlipleServiceProcessing() throws Exception { + ComponentType type = factory.createComponentType(); + introspector.introspect(TestMultipleInterfacesComponentImpl.class, type); + assertEquals(2, type.getServices().size()); + for (Service service : type.getServices()) { + if (!service.getServiceContract().equals(TestComponent.class) && + service.getServiceContract().equals(TestLocalComponent.class)) { + fail("Expected multiple interfaces not found"); + } + } + } + + /** + * Test case when an class implements two non-Remotable interfaces and does not specify one with + * @Service + */ + public void testNonServiceProcessing() throws Exception { + ComponentType type = factory.createComponentType(); + introspector.introspect(TestNonServiceInterfacesImpl.class, type); + assertEquals(1, type.getServices().size()); + ServiceContract contract = type.getServices().get(0).getServiceContract(); + assertEquals(TestNonServiceInterfacesImpl.class, contract.getInterface()); + assertEquals(Scope.MODULE, contract.getScope()); + } + + /** + * Tests the case where a class implements two non-Remotable interfaces, with one specified using + * @Service + */ + public void testNonServiceSpecifiedProcessing() throws Exception { + ComponentType type = factory.createComponentType(); + introspector.introspect(TestNonServiceSpecifiedImpl.class, type); + assertEquals(1, type.getServices().size()); + ServiceContract contract = type.getServices().get(0).getServiceContract(); + assertEquals(TestNonServiceInterface.class, contract.getInterface()); + assertEquals(Scope.MODULE, contract.getScope()); + } + + /** + * Tests the case where a component's scope is specified by its superclass + */ + public void testParentScopeEvaluation() throws Exception { + ComponentType type = factory.createComponentType(); + introspector.introspect(ScopeTestComponent.class, type); + assertEquals(1, type.getServices().size()); + ServiceContract contract = type.getServices().get(0).getServiceContract(); + assertEquals(Scope.MODULE, contract.getScope()); + } + + /** + * FIXME JFM - temporarily disabled until non-annotated properties are fixed public void + * testPropertyProcessing() throws Exception { ComponentType type = factory.createComponentType(); + * introspector.introspect(TestComponentImpl.class, type); Listproperties = + * type.getProperties(); assertEquals(3, properties.size()); for (Property property : properties) { if + * (!property.getName().equals("foo") && !property.getName().equals("fooRequired") && + * !property.getName().equals("baz")) { fail("Property names not handled properly"); } if + * (property.getName().equals("fooRequired")) { assertTrue(property.isRequired()); } else { + * assertFalse(property.isRequired()); } } } * + */ + + public void testReferenceProcessing() throws Exception { + ComponentType type = factory.createComponentType(); + introspector.introspect(TestComponentImpl.class, type); + Listreferences = type.getReferences(); + assertEquals(5, references.size()); + for (Reference reference : references) { + if (reference.getName().equals("setBarRequired")) { + assertTrue(reference.getMultiplicity() == Multiplicity.ONE_N); + } else if (reference.getName().equals("setBar")) { + assertTrue(reference.getMultiplicity() == Multiplicity.ZERO_N); + } else if (reference.getName().equals("bazRefeference")) { + assertTrue(reference.getMultiplicity() == Multiplicity.ZERO_ONE); + } else if (reference.getName().equals("wombat")) { + assertTrue(reference.getMultiplicity() == Multiplicity.ONE_ONE); + } else if (reference.getName().equals("bar")) { + assertTrue(reference.getMultiplicity() == Multiplicity.ZERO_ONE); + } else { + fail("Reference names not handled properly"); + } + } + } + + + protected void setUp() throws Exception { + super.setUp(); + factory = new SystemAssemblyFactoryImpl(); + introspector = ProcessorUtils.createCoreIntrospector(factory); + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/ScopeTestComponent.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/ScopeTestComponent.java new file mode 100644 index 0000000000..1ae24b6b74 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/ScopeTestComponent.java @@ -0,0 +1,24 @@ +/** + * + * 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.config.impl; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class ScopeTestComponent extends ScopedParent { + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/ScopedParent.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/ScopedParent.java new file mode 100644 index 0000000000..0507af1a8a --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/ScopedParent.java @@ -0,0 +1,26 @@ +/** + * + * 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.config.impl; + +import org.osoa.sca.annotations.Scope; + +/** + * @version $$Rev$$ $$Date$$ + */ +@Scope("MODULE") +public class ScopedParent { +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/SuperFoo.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/SuperFoo.java new file mode 100644 index 0000000000..e8a5079184 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/SuperFoo.java @@ -0,0 +1,23 @@ +/** + * + * 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.config.impl; + +/** + * @version $$Rev$$ $$Date$$ + */ +public interface SuperFoo { +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/SuperFooImpl.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/SuperFooImpl.java new file mode 100644 index 0000000000..1d964cca8d --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/SuperFooImpl.java @@ -0,0 +1,26 @@ +/** + * + * 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.config.impl; + +import org.osoa.sca.annotations.Service; + +/** + * @version $$Rev$$ $$Date$$ + */ +@Service(SuperSuperFoo.class) +public class SuperFooImpl extends SuperSuperFooImpl implements SuperFoo{ +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/SuperSuperFoo.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/SuperSuperFoo.java new file mode 100644 index 0000000000..893c2c5607 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/SuperSuperFoo.java @@ -0,0 +1,23 @@ +/** + * + * 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.config.impl; + +/** + * @version $$Rev$$ $$Date$$ + */ +public interface SuperSuperFoo { +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/SuperSuperFooImpl.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/SuperSuperFooImpl.java new file mode 100644 index 0000000000..2025dd1cdd --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/SuperSuperFooImpl.java @@ -0,0 +1,20 @@ +/** + * + * 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; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class SuperSuperFooImpl implements SuperSuperFoo { +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestComponent.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestComponent.java new file mode 100644 index 0000000000..8a462ff405 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestComponent.java @@ -0,0 +1,30 @@ +/** + * + * 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.config.impl; + +import org.osoa.sca.annotations.Remotable; +import org.osoa.sca.annotations.Scope; + +/** + * @version $$Rev$$ $$Date$$ + */ +@Remotable +@Scope("MODULE") +public interface TestComponent { + + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestComponentImpl.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestComponentImpl.java new file mode 100644 index 0000000000..691bf18b3f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestComponentImpl.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.config.impl; + +import java.util.List; + +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Service; + +/** + * @version $$Rev$$ $$Date$$ + */ +@Service(interfaces = {TestComponent.class}) +public class TestComponentImpl implements TestComponent { + + @Property + protected String baz; + + @Reference (name="bazRefeference") + protected TestComponent bazRef; + + @Reference (required = true) + protected TestComponent wombat; + + @Property + public void setFoo(String foo){ + + } + + @Property(name = "fooRequired",required = true) + public void setFooRequiredRename(String foo){ + + } + + @Reference + public void bar(String bar){ + + } + + @Reference(name ="setBarRequired", required = true) + public void setBar(List bar){ + + } + + @Reference(name ="setBar", required = false) + public void setBarNonRequired(List bar){ + + } + + public void someSetter(String val){ + + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestLocalComponent.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestLocalComponent.java new file mode 100644 index 0000000000..15b88547f7 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestLocalComponent.java @@ -0,0 +1,29 @@ +/** + * + * 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.config.impl; + +import org.osoa.sca.annotations.Remotable; +import org.osoa.sca.annotations.Scope; + +/** + * @version $$Rev$$ $$Date$$ + */ +@Scope("MODULE") +public interface TestLocalComponent { + + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestLocalComponentImpl.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestLocalComponentImpl.java new file mode 100644 index 0000000000..86aca3b1bf --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestLocalComponentImpl.java @@ -0,0 +1,32 @@ +/** + * + * 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.config.impl; + +import java.util.List; + +import org.osoa.sca.annotations.Service; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; + +/** + * @version $$Rev$$ $$Date$$ + */ + +public class TestLocalComponentImpl implements TestLocalComponent { + + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestMultipleInterfacesComponentImpl.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestMultipleInterfacesComponentImpl.java new file mode 100644 index 0000000000..b395fd5442 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestMultipleInterfacesComponentImpl.java @@ -0,0 +1,29 @@ +/** + * + * 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.config.impl; + +import org.osoa.sca.annotations.Service; + +/** + * @version $$Rev$$ $$Date$$ + */ + +@Service(interfaces = {TestLocalComponent.class}) +public class TestMultipleInterfacesComponentImpl implements TestComponent, TestLocalComponent { + + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestNonServiceInterface.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestNonServiceInterface.java new file mode 100644 index 0000000000..1a595573ae --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestNonServiceInterface.java @@ -0,0 +1,20 @@ +/** + * + * 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; + +/** + * @version $$Rev$$ $$Date$$ + */ +public interface TestNonServiceInterface { +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestNonServiceInterface2.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestNonServiceInterface2.java new file mode 100644 index 0000000000..8aa6e6cb19 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestNonServiceInterface2.java @@ -0,0 +1,23 @@ +/** + * + * 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.config.impl; + +/** + * @version $$Rev$$ $$Date$$ + */ +public interface TestNonServiceInterface2 { +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestNonServiceInterfacesImpl.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestNonServiceInterfacesImpl.java new file mode 100644 index 0000000000..4f6f07b239 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestNonServiceInterfacesImpl.java @@ -0,0 +1,23 @@ +/** + * + * 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 org.osoa.sca.annotations.Scope; + +/** + * @version $$Rev$$ $$Date$$ + */ +@Scope("MODULE") +public class TestNonServiceInterfacesImpl implements TestNonServiceInterface, TestNonServiceInterface2{ +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestNonServiceSpecifiedImpl.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestNonServiceSpecifiedImpl.java new file mode 100644 index 0000000000..b8c0d6a7e8 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/config/impl/TestNonServiceSpecifiedImpl.java @@ -0,0 +1,28 @@ +/** + * + * 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.config.impl; + +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * @version $$Rev$$ $$Date$$ + */ +@Scope("MODULE") +@Service(TestNonServiceInterface.class) +public class TestNonServiceSpecifiedImpl implements TestNonServiceInterface, TestNonServiceInterface2{ +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/AbstractCompositeHierarchyTests.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/AbstractCompositeHierarchyTests.java new file mode 100644 index 0000000000..f529595dae --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/AbstractCompositeHierarchyTests.java @@ -0,0 +1,109 @@ +/** + * + * 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 junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.core.context.impl.CompositeContextImpl; +import org.apache.tuscany.core.context.impl.EventContextImpl; +import org.apache.tuscany.core.context.scope.DefaultScopeStrategy; +import org.apache.tuscany.core.context.event.ModuleStart; +import org.apache.tuscany.core.context.event.ModuleStop; +import org.apache.tuscany.core.mock.MockConfigContext; +import org.apache.tuscany.core.mock.MockFactory; +import org.apache.tuscany.core.mock.component.ModuleScopeSystemComponent; +import org.apache.tuscany.core.mock.component.ModuleScopeSystemComponentImpl; +import org.apache.tuscany.core.system.assembly.SystemAssemblyFactory; +import org.apache.tuscany.core.system.assembly.impl.SystemAssemblyFactoryImpl; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.EntryPoint; +import org.apache.tuscany.model.assembly.Scope; +import org.osoa.sca.ModuleContext; + +import java.util.List; + +/** + * Performs testing of various hierarchical scenarios + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractCompositeHierarchyTests extends TestCase { + protected List builders; + protected SystemAssemblyFactory factory; + + public void testParentContextIsolation() throws Exception { + CompositeContext parent = createContextHierachy(); + CompositeContext child = (CompositeContext) parent.getContext("test.child"); + Component component = factory.createSystemComponent("TestService1", ModuleScopeSystemComponent.class, ModuleScopeSystemComponentImpl.class, Scope.MODULE); + parent.registerModelObject(component); + EntryPoint ep = MockFactory.createEPSystemBinding("TestService1EP", ModuleScopeSystemComponent.class, "TestService1", component); + parent.registerModelObject(ep); + parent.publish(new ModuleStart(this)); + child.publish(new ModuleStart(this)); + Assert.assertNotNull(parent.getContext("TestService1EP").getInstance(null)); + try { + ((ModuleContext) child).locateService("TestService1EP"); + fail("Expexcted " + ServiceNotFoundException.class.getName()); + } catch (ServiceNotFoundException e) { + // expect exception to be thrown + } + parent.publish(new ModuleStop(this)); + child.publish(new ModuleStop(this)); + parent.stop(); + + } + + /** + * Checks that registration of duplicate named model objects before context start throws an exception + */ + public void testRegisterSameName() throws Exception { + CompositeContext parent = new CompositeContextImpl("test.parent", null, new DefaultScopeStrategy(), + new EventContextImpl(), new MockConfigContext(builders)); + parent.registerModelObject(MockFactory.createSystemCompositeComponent("test.child")); + try { + parent.registerModelObject(MockFactory.createSystemCompositeComponent("test.child")); + parent.start(); + fail("Expected " + DuplicateNameException.class.getName()); + } catch (DuplicateNameException e) { + // expected + } + } + + /** + * Checks that registration of duplicate named model objects after context start throws an exception + */ + public void testRegisterSameNameAfterStart() throws Exception { + CompositeContext parent = new CompositeContextImpl("test.parent", null, new DefaultScopeStrategy(), + new EventContextImpl(), new MockConfigContext(builders)); + parent.registerModelObject(MockFactory.createSystemCompositeComponent("test.child")); + parent.start(); + CompositeContext child = (CompositeContext) parent.getContext("test.child"); + Assert.assertNotNull(child); + try { + parent.registerModelObject(MockFactory.createSystemCompositeComponent("test.child")); + fail("Expected " + DuplicateNameException.class.getName()); + } catch (DuplicateNameException e) { + // expected + } + } + + protected abstract CompositeContext createContextHierachy() throws Exception; + + protected void setUp() throws Exception { + super.setUp(); + factory = new SystemAssemblyFactoryImpl(); + builders = MockFactory.createSystemBuilders(); + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/CompositeContextRegisterTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/CompositeContextRegisterTestCase.java new file mode 100644 index 0000000000..b6e7f69daf --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/CompositeContextRegisterTestCase.java @@ -0,0 +1,132 @@ +/** + * + * 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 junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.core.context.impl.CompositeContextImpl; +import org.apache.tuscany.core.context.impl.EventContextImpl; +import org.apache.tuscany.core.context.scope.DefaultScopeStrategy; +import org.apache.tuscany.core.context.event.ModuleStart; +import org.apache.tuscany.core.context.event.ModuleStop; +import org.apache.tuscany.core.mock.MockConfigContext; +import org.apache.tuscany.core.mock.MockFactory; +import org.apache.tuscany.core.mock.component.GenericSystemComponent; +import org.apache.tuscany.core.mock.component.ModuleScopeSystemComponent; +import org.apache.tuscany.core.mock.component.ModuleScopeSystemComponentImpl; +import org.apache.tuscany.core.system.assembly.SystemAssemblyFactory; +import org.apache.tuscany.core.system.assembly.impl.SystemAssemblyFactoryImpl; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.EntryPoint; +import org.apache.tuscany.model.assembly.Module; +import org.apache.tuscany.model.assembly.Scope; + +import java.util.List; + +/** + * Tests registration of model objects for an composite context + * + * @version $Rev$ $Date$ + */ +public class CompositeContextRegisterTestCase extends TestCase { + private SystemAssemblyFactory factory; + + public void testModuleRegistration() throws Exception { + CompositeContext moduleContext = createContext(); + Module module = MockFactory.createSystemModule(); + moduleContext.registerModelObject(module); + moduleContext.start(); + moduleContext.publish(new ModuleStart(this)); + GenericSystemComponent component = (GenericSystemComponent) moduleContext.getContext("TestService1").getInstance(null); + Assert.assertNotNull(component); + GenericSystemComponent ep = (GenericSystemComponent) moduleContext.getContext("TestService1EP").getInstance(null); + Assert.assertNotNull(ep); + moduleContext.publish(new ModuleStop(this)); + moduleContext.stop(); + } + + public void testModuleRegistrationAfterStart() throws Exception { + CompositeContext moduleContext = createContext(); + moduleContext.start(); + Module module = MockFactory.createSystemModule(); + moduleContext.registerModelObject(module); + moduleContext.publish(new ModuleStart(this)); + GenericSystemComponent component = (GenericSystemComponent) moduleContext.getContext("TestService1").getInstance(null); + Assert.assertNotNull(component); + GenericSystemComponent ep = (GenericSystemComponent) moduleContext.getContext("TestService1EP").getInstance(null); + Assert.assertNotNull(ep); + moduleContext.publish(new ModuleStop(this)); + moduleContext.stop(); + } + + public void testRegistration() throws Exception { + CompositeContext moduleContext = createContext(); + Component component = factory.createSystemComponent("TestService1", ModuleScopeSystemComponent.class, ModuleScopeSystemComponentImpl.class, Scope.MODULE); + moduleContext.registerModelObject(component); + EntryPoint ep = MockFactory.createEPSystemBinding("TestService1EP", ModuleScopeSystemComponent.class, "TestService1", component); + moduleContext.registerModelObject(ep); + moduleContext.start(); + moduleContext.publish(new ModuleStart(this)); + GenericSystemComponent test = (GenericSystemComponent) moduleContext.getContext("TestService1").getInstance(null); + Assert.assertNotNull(test); + GenericSystemComponent testEP = (GenericSystemComponent) moduleContext.getContext("TestService1EP").getInstance(null); + Assert.assertNotNull(testEP); + moduleContext.publish(new ModuleStop(this)); + moduleContext.stop(); + } + + public void testRegistrationAfterStart() throws Exception { + CompositeContext moduleContext = createContext(); + Component component = factory.createSystemComponent("TestService1", ModuleScopeSystemComponent.class, ModuleScopeSystemComponentImpl.class, Scope.MODULE); + moduleContext.start(); + moduleContext.registerModelObject(component); + EntryPoint ep = MockFactory.createEPSystemBinding("TestService1EP", ModuleScopeSystemComponent.class, "TestService1", component); + moduleContext.registerModelObject(ep); + moduleContext.publish(new ModuleStart(this)); + GenericSystemComponent test = (GenericSystemComponent) moduleContext.getContext("TestService1").getInstance(null); + Assert.assertNotNull(test); + GenericSystemComponent testEP = (GenericSystemComponent) moduleContext.getContext("TestService1EP").getInstance(null); + Assert.assertNotNull(testEP); + moduleContext.publish(new ModuleStop(this)); + moduleContext.stop(); + } + + public void testEPRegistrationAfterModuleStart() throws Exception { + CompositeContext moduleContext = createContext(); + Component component = factory.createSystemComponent("TestService1", ModuleScopeSystemComponent.class, ModuleScopeSystemComponentImpl.class, Scope.MODULE); + moduleContext.start(); + moduleContext.registerModelObject(component); + moduleContext.publish(new ModuleStart(this)); + GenericSystemComponent test = (GenericSystemComponent) moduleContext.getContext("TestService1").getInstance(null); + Assert.assertNotNull(test); + EntryPoint ep = MockFactory.createEPSystemBinding("TestService1EP", ModuleScopeSystemComponent.class, "TestService1", component); + moduleContext.registerModelObject(ep); + GenericSystemComponent testEP = (GenericSystemComponent) moduleContext.getContext("TestService1EP").getInstance(null); + Assert.assertNotNull(testEP); + moduleContext.publish(new ModuleStop(this)); + moduleContext.stop(); + } + + protected CompositeContext createContext() { + List builders = MockFactory.createSystemBuilders(); + return new CompositeContextImpl("test.context", null, new DefaultScopeStrategy(), new EventContextImpl(), + new MockConfigContext(builders)); + } + + protected void setUp() throws Exception { + factory = new SystemAssemblyFactoryImpl(); + super.setUp(); + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/CompositeHierarchyTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/CompositeHierarchyTestCase.java new file mode 100644 index 0000000000..bd56a88658 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/CompositeHierarchyTestCase.java @@ -0,0 +1,99 @@ +/** + * + * 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 junit.framework.Assert; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.core.context.impl.CompositeContextImpl; +import org.apache.tuscany.core.context.impl.EventContextImpl; +import org.apache.tuscany.core.context.scope.DefaultScopeStrategy; +import org.apache.tuscany.core.context.event.ModuleStop; +import org.apache.tuscany.core.context.event.ModuleStart; +import org.apache.tuscany.core.mock.MockConfigContext; +import org.apache.tuscany.core.mock.MockFactory; +import org.apache.tuscany.core.mock.component.ModuleScopeSystemComponent; +import org.apache.tuscany.core.mock.component.ModuleScopeSystemComponentImpl; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.EntryPoint; +import org.apache.tuscany.model.assembly.Scope; +import org.apache.tuscany.model.assembly.impl.AssemblyContextImpl; +import org.osoa.sca.ModuleContext; +import org.osoa.sca.ServiceUnavailableException; +import org.osoa.sca.ServiceRuntimeException; + +import java.util.List; + +/** + * Performs testing of various hierarchical scenarios + * + * @version $Rev$ $Date$ + */ +public class CompositeHierarchyTestCase extends AbstractCompositeHierarchyTests { + + /** + * FIXME model Tests adding a component, accessing it and then exposing it as an entry point after the first access + * + * @throws Exception + */ + public void testChildContextIsolation() throws Exception { + CompositeContext parent = createContextHierachy(); + CompositeContext child = (CompositeContext) parent.getContext("test.child"); + Component component = factory.createSystemComponent("TestService1", ModuleScopeSystemComponent.class, ModuleScopeSystemComponentImpl.class, Scope.MODULE); + + component.initialize(new AssemblyContextImpl(factory, null, null)); + child.registerModelObject(component); + parent.publish(new ModuleStart(this)); + child.publish(new ModuleStart(this)); + Assert.assertNotNull(child.getContext("TestService1").getInstance(null)); + try { + ((ModuleContext) parent).locateService("test.child/TestService1"); + fail("Expected " + ServiceUnavailableException.class.getName() + + " since [test.child/TestService1] is not an entry point"); + } catch (ServiceRuntimeException e) { + // should throw an exception since it is not an entry point + } + + // now expose the service as an entry point + // FIXME hack to get around initialization of component - just create another one ;-) + component = factory.createSystemComponent("TestService1", ModuleScopeSystemComponent.class, ModuleScopeSystemComponentImpl.class, Scope.MODULE); + EntryPoint ep = MockFactory.createEPSystemBinding("TestService1EP", ModuleScopeSystemComponent.class, "TestService1", + component); + child.registerModelObject(ep); + Assert.assertNotNull(child.getContext("TestService1EP").getInstance(null)); + Assert.assertNotNull(parent.getContext("test.child").getInstance(new QualifiedName("./TestService1EP"))); + + // now expose the child entry point from the parent context + EntryPoint parentEp = MockFactory.createEntryPointWithStringRef("TestService1EP", ModuleScopeSystemComponent.class, + "TestService1", "test.child/TestService1EP"); + parent.registerModelObject(parentEp); + Assert.assertNotNull(parent.getContext("TestService1EP").getInstance(null)); + + parent.publish(new ModuleStop(this)); + child.publish(new ModuleStop(this)); + parent.stop(); + } + + protected CompositeContext createContextHierachy() throws Exception { + List systemBuilders = MockFactory.createSystemBuilders(); + CompositeContext parent = new CompositeContextImpl("test.parent", null, new DefaultScopeStrategy(), + new EventContextImpl(), new MockConfigContext(systemBuilders)); + Component component = MockFactory.createCompositeComponent("test.child"); + parent.registerModelObject(component); + parent.start(); + CompositeContext child = (CompositeContext) parent.getContext("test.child"); + Assert.assertNotNull(child); + return parent; + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/QualifiedNameTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/QualifiedNameTestCase.java new file mode 100644 index 0000000000..4f86d1aed5 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/QualifiedNameTestCase.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; + +import junit.framework.TestCase; + +/** + * Tests parsing of naming patters + * + * @version $Rev$ $Date$ + */ +public class QualifiedNameTestCase extends TestCase { + + public void testSimpleName() throws Exception { + QualifiedName name = new QualifiedName("Foo"); + assertEquals("Foo", name.getPartName()); + assertEquals(null, name.getPortName()); + } + + public void testCompoundName() throws Exception { + QualifiedName name = new QualifiedName("Foo/Bar"); + assertEquals("Foo", name.getPartName()); + assertEquals("Bar", name.getPortName()); + } + + public void testCompoundMultiName() throws Exception { + QualifiedName name = new QualifiedName("Foo/Bar/Baz"); + assertEquals("Foo", name.getPartName()); + assertEquals("Bar/Baz", name.getPortName()); + } + + public void testInvalidName() throws Exception { + try { + QualifiedName name = new QualifiedName("/Foo/Bar"); + fail("Invalid name exception not thrown"); + } catch (InvalidNameException e) { + + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/scope/DefaultScopeStrategyTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/scope/DefaultScopeStrategyTestCase.java new file mode 100644 index 0000000000..c9e6736833 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/context/scope/DefaultScopeStrategyTestCase.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.context.scope; + +import junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.tuscany.model.assembly.Scope; + +/** + * Basic scope strategy tests, including downscope referencing + * + * @version $Rev$ $Date$ + */ +public class DefaultScopeStrategyTestCase extends TestCase { + + public void testDownScopeReferences() throws Exception{ + DefaultScopeStrategy strategy = new DefaultScopeStrategy(); + + Assert.assertTrue(!strategy.downScopeReference(Scope.MODULE,Scope.MODULE)); + Assert.assertTrue(strategy.downScopeReference(Scope.MODULE,Scope.SESSION)); + Assert.assertTrue(strategy.downScopeReference(Scope.MODULE,Scope.REQUEST)); + Assert.assertTrue(strategy.downScopeReference(Scope.MODULE,Scope.INSTANCE)); + + Assert.assertTrue(!strategy.downScopeReference(Scope.SESSION,Scope.MODULE)); + Assert.assertTrue(!strategy.downScopeReference(Scope.SESSION,Scope.SESSION)); + Assert.assertTrue(strategy.downScopeReference(Scope.SESSION,Scope.REQUEST)); + Assert.assertTrue(strategy.downScopeReference(Scope.SESSION,Scope.INSTANCE)); + + Assert.assertTrue(!strategy.downScopeReference(Scope.REQUEST,Scope.MODULE)); + Assert.assertTrue(!strategy.downScopeReference(Scope.REQUEST,Scope.SESSION)); + Assert.assertTrue(!strategy.downScopeReference(Scope.REQUEST,Scope.REQUEST)); + Assert.assertTrue(strategy.downScopeReference(Scope.REQUEST,Scope.INSTANCE)); + + Assert.assertTrue(!strategy.downScopeReference(Scope.REQUEST,Scope.MODULE)); + Assert.assertTrue(!strategy.downScopeReference(Scope.REQUEST,Scope.SESSION)); + Assert.assertTrue(!strategy.downScopeReference(Scope.REQUEST,Scope.REQUEST)); + Assert.assertTrue(!strategy.downScopeReference(Scope.INSTANCE,Scope.INSTANCE)); + } +} + diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/extension/ContextFactorySupportTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/extension/ContextFactorySupportTestCase.java new file mode 100644 index 0000000000..765d6efee4 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/extension/ContextFactorySupportTestCase.java @@ -0,0 +1,80 @@ +/** + * + * 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.extension; + +import junit.framework.TestCase; +import org.apache.tuscany.core.builder.ContextFactory; +import org.apache.tuscany.model.assembly.Implementation; +import org.apache.tuscany.model.assembly.Scope; +import org.apache.tuscany.model.assembly.impl.AtomicImplementationImpl; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class ContextFactorySupportTestCase extends TestCase { + + public void testGenericReflection() throws Exception { + TestFactoryBuilder b = new TestFactoryBuilder(); + assertEquals(TestImplementation.class, b.getImplementationClass()); + } + + public void testNegativeGenericReflection() throws Exception { + try { + new NonGenericFactoryBuilder(); + fail("AssertionError expected on non-genericized subclass of " + ContextFactoryBuilderSupport.class.getName()); + } catch (AssertionError e) { + // indicates success + } + } + + protected void setUp() throws Exception { + super.setUp(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + + private class TestFactoryBuilder extends ContextFactoryBuilderSupport { + + + public Class getImplementationClass() { + return implementationClass; + } + + protected ContextFactory createContextFactory(String componentName, TestImplementation implementation, Scope scope) { + return null; + } + } + + private class NonGenericFactoryBuilder extends ContextFactoryBuilderSupport { + + + public Class getImplementationClass() { + return implementationClass; + } + + protected ContextFactory createContextFactory(String componentName, Implementation implementation, Scope scope) { + return null; + } + } + + private class TestImplementation extends AtomicImplementationImpl { + + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/extension/EntryPointBuilderSupportTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/extension/EntryPointBuilderSupportTestCase.java new file mode 100644 index 0000000000..2f911fefa5 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/extension/EntryPointBuilderSupportTestCase.java @@ -0,0 +1,78 @@ +/** + * + * 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.extension; + +import junit.framework.TestCase; +import org.apache.tuscany.core.extension.EntryPointContextFactory; +import org.apache.tuscany.core.message.MessageFactory; +import org.apache.tuscany.model.assembly.Binding; +import org.apache.tuscany.model.assembly.EntryPoint; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class EntryPointBuilderSupportTestCase extends TestCase { + + public void testGenericReflection() throws Exception { + EntryPointBuilderSupportTestCase.TestEntryPointBuilder b = new EntryPointBuilderSupportTestCase.TestEntryPointBuilder(); + assertEquals(EntryPointBuilderSupportTestCase.TestBinding.class, b.getImplementationClass()); + } + + public void testNegativeGenericReflection() throws Exception { + try { + new EntryPointBuilderSupportTestCase.NonGenericFactoryBuilder(); + fail("AssertionError expected on non-genericized subclass of " + ContextFactoryBuilderSupport.class.getName()); + } catch (AssertionError e) { + // indicates success + } + } + + protected void setUp() throws Exception { + super.setUp(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + + private class TestEntryPointBuilder extends EntryPointBuilderSupport { + + public Class getImplementationClass() { + return bindingClass; + } + + protected EntryPointContextFactory createEntryPointContextFactory(EntryPoint entryPoint, MessageFactory msgFactory) { + return null; + } + } + + private class NonGenericFactoryBuilder extends EntryPointBuilderSupport { + + public Class getImplementationClass() { + return bindingClass; + } + + protected EntryPointContextFactory createEntryPointContextFactory(EntryPoint entryPoint, MessageFactory msgFactory) { + return null; + } + } + + private interface TestBinding extends Binding { + + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/extension/ExternalServiceBuilderSupportTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/extension/ExternalServiceBuilderSupportTestCase.java new file mode 100644 index 0000000000..a1c758c526 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/extension/ExternalServiceBuilderSupportTestCase.java @@ -0,0 +1,80 @@ +/** + * + * 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.extension; + +import junit.framework.TestCase; +import org.apache.tuscany.core.extension.ExternalServiceContextFactory; +import org.apache.tuscany.model.assembly.Binding; +import org.apache.tuscany.model.assembly.ExternalService; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class ExternalServiceBuilderSupportTestCase extends TestCase { + + public void testGenericReflection() throws Exception { + ExternalServiceBuilderSupportTestCase.TestExternalServiceBuilder b = new ExternalServiceBuilderSupportTestCase.TestExternalServiceBuilder(); + assertEquals(ExternalServiceBuilderSupportTestCase.TestBinding.class, b.getImplementationClass()); + } + + public void testNegativeGenericReflection() throws Exception { + try { + new ExternalServiceBuilderSupportTestCase.NonGenericFactoryBuilder(); + fail("AssertionError expected on non-genericized subclass of " + ContextFactoryBuilderSupport.class.getName()); + } catch (AssertionError e) { + // indicates success + } + } + + protected void setUp() throws Exception { + super.setUp(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + + private class TestExternalServiceBuilder extends ExternalServiceBuilderSupport { + + + public Class getImplementationClass() { + return bindingClass; + } + + protected ExternalServiceContextFactory createExternalServiceContextFactory(ExternalService externalService) { + return null; + } + } + + private class NonGenericFactoryBuilder extends ExternalServiceBuilderSupport { + + + public Class getImplementationClass() { + return bindingClass; + } + + + protected ExternalServiceContextFactory createExternalServiceContextFactory(ExternalService externalService) { + return null; + } + } + + private interface TestBinding extends Binding { + + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/extension/WireBuilderSupportTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/extension/WireBuilderSupportTestCase.java new file mode 100644 index 0000000000..0fd80c51af --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/extension/WireBuilderSupportTestCase.java @@ -0,0 +1,261 @@ +/** + * + * 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.extension; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; +import org.apache.tuscany.core.builder.ContextCreationException; +import org.apache.tuscany.core.builder.ContextFactory; +import org.apache.tuscany.core.builder.impl.DefaultWireBuilder; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.Context; +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.core.context.ScopeContext; +import org.apache.tuscany.core.context.AtomicContext; +import org.apache.tuscany.core.message.Message; +import org.apache.tuscany.core.wire.Interceptor; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.TargetInvocationConfiguration; +import org.apache.tuscany.core.wire.TargetInvoker; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.core.wire.WireTargetConfiguration; +import org.apache.tuscany.core.wire.jdk.JDKTargetWireFactory; +import org.apache.tuscany.core.wire.mock.MockScopeContext; +import org.apache.tuscany.model.assembly.Implementation; +import org.apache.tuscany.model.assembly.Scope; + +/** + * @version $$Rev$$ $$Date$$ + */ +public class WireBuilderSupportTestCase extends TestCase { + private Method m; + + /** + * Tests that {@link WireBuilderSupport} only processes connect operations and sets target invokers for + * the correct target type. + *

+ * Verifies TUSCANY-218 + * + * @throws Exception + */ + public void testTargetInvokerSet() throws Exception { + FooWireBuilder fooBuilder = new FooWireBuilder(); + BarWireBuilder barBuilder = new BarWireBuilder(); + DefaultWireBuilder defaultBuilder = new DefaultWireBuilder(); + defaultBuilder.addWireBuilder(fooBuilder); + defaultBuilder.addWireBuilder(barBuilder); + TargetWireFactory targetFooFactory = new JDKTargetWireFactory(); + Map fooConfigs = new HashMap(); + TargetInvocationConfiguration fooInvocation = new TargetInvocationConfiguration(m); + fooConfigs.put(m, fooInvocation); + Map barConfigs = new HashMap(); + TargetInvocationConfiguration barInvocation = new TargetInvocationConfiguration(m); + barConfigs.put(m, barInvocation); + targetFooFactory.setConfiguration(new WireTargetConfiguration(null, fooConfigs, null, null)); + TargetWireFactory targetBarFactory = new JDKTargetWireFactory(); + targetBarFactory.setConfiguration(new WireTargetConfiguration(null, barConfigs, null, null)); + ScopeContext ctx = new MockScopeContext(); + defaultBuilder.completeTargetChain(targetFooFactory, FooContextFactory.class, ctx); + defaultBuilder.completeTargetChain(targetBarFactory, BarContextFactory.class, ctx); + assertEquals(FooInvoker.class, targetFooFactory.getConfiguration().getInvocationConfigurations().get(m).getTargetInvoker().getClass()); + assertEquals(BarInvoker.class, targetBarFactory.getConfiguration().getInvocationConfigurations().get(m).getTargetInvoker().getClass()); + + } + + + protected void setUp() throws Exception { + super.setUp(); + m = SomeInterface.class.getMethod("test", (Class[]) null); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + private interface SomeInterface { + void test(); + } + + private interface Foo extends Implementation { + + } + + private interface Bar extends Implementation { + + } + + private class FooWireBuilder extends WireBuilderSupport { + + protected TargetInvoker createInvoker(QualifiedName targetName, Method operation, ScopeContext context, boolean downScope) { + return new FooInvoker(); + } + } + + private class BarWireBuilder extends WireBuilderSupport { + + protected TargetInvoker createInvoker(QualifiedName targetName, Method operation, ScopeContext context, boolean downScope) { + return new BarInvoker(); + } + } + + private class FooInvoker implements TargetInvoker { + + public Object invokeTarget(Object payload) throws InvocationTargetException { + return null; + } + + public boolean isCacheable() { + return false; + } + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + public Message invoke(Message msg) { + return null; + } + + public void setNext(Interceptor next) { + + } + } + + + private class BarInvoker implements TargetInvoker { + + public Object invokeTarget(Object payload) throws InvocationTargetException { + return null; + } + + public boolean isCacheable() { + return false; + } + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + public Message invoke(Message msg) { + return null; + } + + public void setNext(Interceptor next) { + + } + } + + private class FooContextFactory implements ContextFactory { + + public AtomicContext createContext() throws ContextCreationException { + return null; + } + + public Scope getScope() { + return null; + } + + public String getName() { + return null; + } + + public void addProperty(String propertyName, Object value) { + + } + + public void addTargetWireFactory(String serviceName, TargetWireFactory factory) { + + } + + public TargetWireFactory getTargetWireFactory(String serviceName) { + return null; + } + + public Map getTargetWireFactories() { + return null; + } + + public void addSourceWireFactory(String referenceName, SourceWireFactory factory) { + + } + + public List getSourceWireFactories() { + return null; + } + + public void prepare(CompositeContext parent) { + + } + + public void addSourceWireFactories(String referenceName, Class referenceInterface, List factory, boolean multiplicity) { + + } + } + + + private class BarContextFactory implements ContextFactory { + public Context createContext() throws ContextCreationException { + return null; + } + + public Scope getScope() { + return null; + } + + public String getName() { + return null; + } + + public void addProperty(String propertyName, Object value) { + + } + + public void addTargetWireFactory(String serviceName, TargetWireFactory factory) { + + } + + public TargetWireFactory getTargetWireFactory(String serviceName) { + return null; + } + + public Map getTargetWireFactories() { + return null; + } + + public void addSourceWireFactory(String referenceName, SourceWireFactory factory) { + + } + + public void addSourceWireFactories(String referenceName, Class referenceInterface, List factory, boolean multiplicity) { + + } + + public List getSourceWireFactories() { + return null; + } + + public void prepare(CompositeContext parent) { + + } + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/integration/IntraCompositeWireIntegrationTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/integration/IntraCompositeWireIntegrationTestCase.java new file mode 100644 index 0000000000..44be759b69 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/integration/IntraCompositeWireIntegrationTestCase.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.integration; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.tuscany.core.config.ConfigurationException; +import org.apache.tuscany.core.context.AtomicContext; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.event.ModuleStop; +import org.apache.tuscany.core.context.event.ModuleStart; +import org.apache.tuscany.core.mock.MockFactory; +import org.apache.tuscany.core.mock.component.Source; +import org.apache.tuscany.core.mock.component.Target; +import org.apache.tuscany.core.runtime.RuntimeContext; +import org.apache.tuscany.core.system.assembly.SystemAssemblyFactory; +import org.apache.tuscany.core.system.assembly.SystemModule; +import org.apache.tuscany.core.system.assembly.impl.SystemAssemblyFactoryImpl; +import org.apache.tuscany.core.system.context.SystemCompositeContextImpl; +import org.apache.tuscany.model.assembly.Module; +import org.apache.tuscany.model.assembly.ModuleComponent; +import org.apache.tuscany.model.assembly.Scope; +import org.apache.tuscany.model.assembly.Service; +import org.apache.tuscany.model.types.java.JavaServiceContract; + +/** + * Tests intra-composite system wires are properly constructed in the runtime + * + * @version $Rev$ $Date$ + */ +public class IntraCompositeWireIntegrationTestCase extends TestCase { + + + public void testWireConstruction2() throws Exception { + RuntimeContext runtime = MockFactory.createCoreRuntime(); + ModuleComponent moduleComponent = createSystemCompositeComponent("test.system"); + Module module = MockFactory.createSystemModuleWithWiredComponents("system.module",Scope.MODULE, Scope.MODULE); + moduleComponent.setImplementation(module); + runtime.getSystemContext().registerModelObject(moduleComponent); + CompositeContext context = (CompositeContext) runtime.getSystemContext().getContext("test.system"); + context.publish(new ModuleStart(this)); + //context.registerModelObject(module); + Source source = (Source) ((AtomicContext)context.getContext("source")).getTargetInstance(); + Assert.assertNotNull(source); + Target targetRef = source.getTarget(); + Assert.assertNotNull(targetRef); + Target target = (Target) ((AtomicContext)context.getContext("target")).getTargetInstance(); + Assert.assertSame(target, targetRef); + Source source2 = (Source) ((AtomicContext)context.getContext("source")).getTargetInstance(); + Assert.assertSame(target, source2.getTarget()); + context.publish(new ModuleStop(this)); + context.stop(); + } + + private static SystemAssemblyFactory systemFactory = new SystemAssemblyFactoryImpl(); + + /** + * Creates an composite component with the given name + */ + public static ModuleComponent createSystemCompositeComponent(String name) { + ModuleComponent sc = systemFactory.createModuleComponent(); + SystemModule impl = systemFactory.createSystemModule(); + impl.setImplementationClass(SystemCompositeContextImpl.class); + sc.setImplementation(impl); + Service s = systemFactory.createService(); + JavaServiceContract ji = systemFactory.createJavaServiceContract(); + s.setServiceContract(ji); + ji.setScope(Scope.AGGREGATE); + impl.setComponentType(systemFactory.createComponentType()); + impl.getComponentType().getServices().add(s); + sc.setName(name); + sc.setImplementation(impl); + return sc; + } + + + public void testWireConstruction() throws ConfigurationException { + RuntimeContext runtime = MockFactory.createCoreRuntime(); + runtime.getSystemContext().registerModelObject(MockFactory.createSystemCompositeComponent("test.system")); + CompositeContext context = (CompositeContext) runtime.getSystemContext().getContext("test.system"); + + context.publish(new ModuleStart(this)); + context.registerModelObject(MockFactory.createSystemModuleWithWiredComponents("system.module",Scope.MODULE,Scope.MODULE)); + Source source = (Source) ((AtomicContext)context.getContext("source")).getTargetInstance(); + Assert.assertNotNull(source); + Target targetRef = source.getTarget(); + Assert.assertNotNull(targetRef); + Target target = (Target) ((AtomicContext)context.getContext("target")).getTargetInstance(); + Assert.assertSame(target, targetRef); + Source source2 = (Source) ((AtomicContext)context.getContext("source")).getTargetInstance(); + Assert.assertSame(target, source2.getTarget()); + context.publish(new ModuleStop(this)); + context.stop(); + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/JNDIPropertyFactoryTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/JNDIPropertyFactoryTestCase.java new file mode 100644 index 0000000000..c17d96a145 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/JNDIPropertyFactoryTestCase.java @@ -0,0 +1,210 @@ +/** + * + * Copyright 2006 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 static javax.naming.Context.INITIAL_CONTEXT_FACTORY; +import java.io.StringReader; +import java.util.Hashtable; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.Name; +import javax.naming.NameClassPair; +import javax.naming.NamingEnumeration; +import javax.naming.Binding; +import javax.naming.NameParser; +import javax.naming.spi.InitialContextFactory; + +import junit.framework.TestCase; + +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.impl.JNDIPropertyFactory; +import org.apache.tuscany.model.assembly.AssemblyFactory; +import org.apache.tuscany.model.assembly.Property; +import org.apache.tuscany.model.assembly.impl.AssemblyFactoryImpl; + +/** + * @version $Rev$ $Date$ + */ +@SuppressWarnings({"AccessOfSystemProperties"}) +public class JNDIPropertyFactoryTestCase extends TestCase { + private JNDIPropertyFactory factory; + private XMLInputFactory xmlFactory; + private Property property; + private String oldICF; + + public void testLookup() throws XMLStreamException, ConfigurationLoadException { + String instance = getInstance(String.class, "foo:/hello"); + assertEquals("Hello World", instance); + } + + private T getInstance(Class type, String xml) throws XMLStreamException, ConfigurationLoadException { + property.setType(type); + XMLStreamReader reader = xmlFactory.createXMLStreamReader(new StringReader(xml)); + reader.next(); + ObjectFactory objectFactory = (ObjectFactory) factory.createObjectFactory(reader, property); + return objectFactory.getInstance(); + } + + protected void setUp() throws Exception { + super.setUp(); + factory = new JNDIPropertyFactory(); + xmlFactory = XMLInputFactory.newInstance(); + AssemblyFactory assemblyFactory = new AssemblyFactoryImpl(); + property = assemblyFactory.createProperty(); + + oldICF = System.getProperty(INITIAL_CONTEXT_FACTORY); + System.setProperty(INITIAL_CONTEXT_FACTORY, MockContextFactory.class.getName()); + } + + protected void tearDown() throws Exception { + if (oldICF != null) { + System.getProperty(INITIAL_CONTEXT_FACTORY, oldICF); + } + super.tearDown(); + } + + public static class MockContextFactory implements InitialContextFactory { + public Context getInitialContext(Hashtable environment) throws NamingException { + return new MockContext(); + } + } + + public static class MockContext implements Context { + public Object lookup(String name) throws NamingException { + if ("foo:/hello".equals(name)) { + return "Hello World"; + } + throw new AssertionError(); + } + + public Object lookup(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + public void bind(Name name, Object obj) throws NamingException { + throw new UnsupportedOperationException(); + } + + public void bind(String name, Object obj) throws NamingException { + throw new UnsupportedOperationException(); + } + + public void rebind(Name name, Object obj) throws NamingException { + throw new UnsupportedOperationException(); + } + + public void rebind(String name, Object obj) throws NamingException { + throw new UnsupportedOperationException(); + } + + public void unbind(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + public void unbind(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + public void rename(Name oldName, Name newName) throws NamingException { + throw new UnsupportedOperationException(); + } + + public void rename(String oldName, String newName) throws NamingException { + throw new UnsupportedOperationException(); + } + + public NamingEnumeration list(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + public NamingEnumeration list(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + public NamingEnumeration listBindings(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + public NamingEnumeration listBindings(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + public void destroySubcontext(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + public void destroySubcontext(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + public Context createSubcontext(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + public Context createSubcontext(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + public Object lookupLink(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + public Object lookupLink(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + public NameParser getNameParser(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + public NameParser getNameParser(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + public Name composeName(Name name, Name prefix) throws NamingException { + throw new UnsupportedOperationException(); + } + + public String composeName(String name, String prefix) throws NamingException { + throw new UnsupportedOperationException(); + } + + public Object addToEnvironment(String propName, Object propVal) throws NamingException { + throw new UnsupportedOperationException(); + } + + public Object removeFromEnvironment(String propName) throws NamingException { + throw new UnsupportedOperationException(); + } + + public Hashtable getEnvironment() throws NamingException { + throw new UnsupportedOperationException(); + } + + public void close() throws NamingException { + throw new UnsupportedOperationException(); + } + + public String getNameInNamespace() throws NamingException { + throw new UnsupportedOperationException(); + } + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/MockReaderSupport.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/MockReaderSupport.java new file mode 100644 index 0000000000..542a4d7b2b --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/MockReaderSupport.java @@ -0,0 +1,210 @@ +/** + * + * Copyright 2006 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 javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.Location; +import javax.xml.namespace.QName; +import javax.xml.namespace.NamespaceContext; + +/** + * Base class for a mock XMLStreamReader. + * + * @version $Rev$ $Date$ + */ +public class MockReaderSupport implements XMLStreamReader { + public QName getName() { + throw new UnsupportedOperationException(); + } + + public Object getProperty(String name) throws IllegalArgumentException { + throw new UnsupportedOperationException(); + } + + public int next() throws XMLStreamException { + throw new UnsupportedOperationException(); + } + + public void require(int i, String name, String name1) throws XMLStreamException { + throw new UnsupportedOperationException(); + } + + public String getElementText() throws XMLStreamException { + throw new UnsupportedOperationException(); + } + + public int nextTag() throws XMLStreamException { + throw new UnsupportedOperationException(); + } + + public boolean hasNext() throws XMLStreamException { + throw new UnsupportedOperationException(); + } + + public void close() throws XMLStreamException { + throw new UnsupportedOperationException(); + } + + public String getNamespaceURI(String name) { + throw new UnsupportedOperationException(); + } + + public boolean isStartElement() { + throw new UnsupportedOperationException(); + } + + public boolean isEndElement() { + throw new UnsupportedOperationException(); + } + + public boolean isCharacters() { + throw new UnsupportedOperationException(); + } + + public boolean isWhiteSpace() { + throw new UnsupportedOperationException(); + } + + public String getAttributeValue(String name, String name1) { + throw new UnsupportedOperationException(); + } + + public int getAttributeCount() { + throw new UnsupportedOperationException(); + } + + public QName getAttributeName(int i) { + throw new UnsupportedOperationException(); + } + + public String getAttributeNamespace(int i) { + throw new UnsupportedOperationException(); + } + + public String getAttributeLocalName(int i) { + throw new UnsupportedOperationException(); + } + + public String getAttributePrefix(int i) { + throw new UnsupportedOperationException(); + } + + public String getAttributeType(int i) { + throw new UnsupportedOperationException(); + } + + public String getAttributeValue(int i) { + throw new UnsupportedOperationException(); + } + + public boolean isAttributeSpecified(int i) { + throw new UnsupportedOperationException(); + } + + public int getNamespaceCount() { + throw new UnsupportedOperationException(); + } + + public String getNamespacePrefix(int i) { + throw new UnsupportedOperationException(); + } + + public String getNamespaceURI(int i) { + throw new UnsupportedOperationException(); + } + + public NamespaceContext getNamespaceContext() { + throw new UnsupportedOperationException(); + } + + public int getEventType() { + throw new UnsupportedOperationException(); + } + + public String getText() { + throw new UnsupportedOperationException(); + } + + public char[] getTextCharacters() { + throw new UnsupportedOperationException(); + } + + public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException { + throw new UnsupportedOperationException(); + } + + public int getTextStart() { + throw new UnsupportedOperationException(); + } + + public int getTextLength() { + throw new UnsupportedOperationException(); + } + + public String getEncoding() { + throw new UnsupportedOperationException(); + } + + public boolean hasText() { + throw new UnsupportedOperationException(); + } + + public Location getLocation() { + throw new UnsupportedOperationException(); + } + + public String getLocalName() { + throw new UnsupportedOperationException(); + } + + public boolean hasName() { + throw new UnsupportedOperationException(); + } + + public String getNamespaceURI() { + throw new UnsupportedOperationException(); + } + + public String getPrefix() { + throw new UnsupportedOperationException(); + } + + public String getVersion() { + throw new UnsupportedOperationException(); + } + + public boolean isStandalone() { + throw new UnsupportedOperationException(); + } + + public boolean standaloneSet() { + throw new UnsupportedOperationException(); + } + + public String getCharacterEncodingScheme() { + throw new UnsupportedOperationException(); + } + + public String getPITarget() { + throw new UnsupportedOperationException(); + } + + public String getPIData() { + throw new UnsupportedOperationException(); + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/StAXLoaderRegistryTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/StAXLoaderRegistryTestCase.java new file mode 100644 index 0000000000..177e4e5005 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/StAXLoaderRegistryTestCase.java @@ -0,0 +1,145 @@ +/** + * + * Copyright 2006 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 java.util.ArrayList; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamException; + +import junit.framework.TestCase; + +import org.apache.tuscany.core.loader.impl.StAXLoaderRegistryImpl; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.model.assembly.AssemblyInitializationException; +import org.apache.tuscany.model.assembly.AssemblyVisitor; +import org.apache.tuscany.common.resource.impl.ResourceLoaderImpl; + +/** + * @version $Rev$ $Date$ + */ +public class StAXLoaderRegistryTestCase extends TestCase { + private StAXLoaderRegistryImpl registry; + private MockElementLoader loader; + private MockObject mockObject; + private MockReader reader; + private MockMonitor monitor; + private QName qname; + private ResourceLoaderImpl rl; + private LoaderContext loaderContext; + + public void testRegistrationEvents() throws XMLStreamException, ConfigurationLoadException { + reader.name = qname; + registry.registerLoader(qname, loader); + assertTrue(monitor.registered.contains(qname)); + assertEquals(1, monitor.registered.size()); + assertTrue(monitor.unregistered.isEmpty()); + assertTrue(monitor.loading.isEmpty()); + + registry.unregisterLoader(qname, loader); + assertTrue(monitor.registered.contains(qname)); + assertEquals(1, monitor.registered.size()); + assertTrue(monitor.unregistered.contains(qname)); + assertEquals(1, monitor.unregistered.size()); + assertTrue(monitor.loading.isEmpty()); + } + + public void testSuccessfulLoad() throws XMLStreamException, ConfigurationLoadException { + reader.name = qname; + registry.registerLoader(qname, loader); + assertSame(mockObject, registry.load(reader, loaderContext)); + assertEquals(1, monitor.loading.size()); + assertTrue(monitor.loading.contains(qname)); + } + + public void testFailedLoad() throws XMLStreamException, ConfigurationLoadException { + registry.registerLoader(qname, loader); + reader.name = new QName("foo"); + try { + registry.load(reader, loaderContext); + fail(); + } catch (ConfigurationLoadException e) { + assertEquals(1, monitor.loading.size()); + assertTrue(monitor.loading.contains(reader.name)); + } + } + + protected void setUp() throws Exception { + super.setUp(); + qname = new QName("test"); + monitor = new MockMonitor(); + registry = new StAXLoaderRegistryImpl(); + registry.setMonitor(monitor); + mockObject = new MockObject(); + loader = new MockElementLoader(); + reader = new MockReader(); + rl = new ResourceLoaderImpl(getClass().getClassLoader()); + loaderContext = new LoaderContext(rl); + } + + public static class MockMonitor implements StAXLoaderRegistryImpl.Monitor { + private List registered = new ArrayList(); + private List unregistered = new ArrayList(); + private List loading = new ArrayList(); + + public void registeringLoader(QName xmlType) { + registered.add(xmlType); + } + + public void unregisteringLoader(QName xmlType) { + unregistered.add(xmlType); + } + + public void elementLoad(QName xmlType) { + loading.add(xmlType); + } + } + + @SuppressWarnings({"NonStaticInnerClassInSecureContext"}) + public class MockElementLoader implements StAXElementLoader { + public AssemblyObject load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + assertEquals(qname, reader.getName()); + assertSame(rl, loaderContext.getResourceLoader()); + return mockObject; + } + } + + public static class MockObject implements AssemblyObject { + public void initialize(AssemblyContext modelContext) throws AssemblyInitializationException { + throw new UnsupportedOperationException(); + } + + public void freeze() { + throw new UnsupportedOperationException(); + } + + public boolean accept(AssemblyVisitor visitor) { + throw new UnsupportedOperationException(); + } + } + + private static class MockReader extends MockReaderSupport { + private QName name; + + public QName getName() { + return name; + } + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/StringParserPropertyFactoryTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/StringParserPropertyFactoryTestCase.java new file mode 100644 index 0000000000..0efe1ae82a --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/StringParserPropertyFactoryTestCase.java @@ -0,0 +1,111 @@ +/** + * + * Copyright 2006 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 junit.framework.TestCase; +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.impl.StringParserPropertyFactory; +import org.apache.tuscany.model.assembly.AssemblyFactory; +import org.apache.tuscany.model.assembly.Property; +import org.apache.tuscany.model.assembly.impl.AssemblyFactoryImpl; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import java.beans.PropertyEditorManager; +import java.beans.PropertyEditorSupport; +import java.io.StringReader; +import java.net.URI; +import java.util.Arrays; + +/** + * @version $Rev$ $Date$ + */ +public class StringParserPropertyFactoryTestCase extends TestCase { + private StringParserPropertyFactory factory; + private XMLInputFactory xmlFactory; + private Property property; + + public void testSimpleString() throws XMLStreamException, ConfigurationLoadException { + String instance = getInstance(String.class, "Hello World"); + assertEquals("Hello World", instance); + } + + public void testByteArray() throws XMLStreamException, ConfigurationLoadException { + byte[] instance = getInstance(byte[].class, "01020304"); + assertTrue(Arrays.equals(new byte[]{1, 2, 3, 4}, instance)); + } + + public void testInteger() throws XMLStreamException, ConfigurationLoadException { + Integer instance = getInstance(Integer.class, "1234"); + assertEquals(Integer.valueOf(1234), instance); + } + + public void testInt() throws XMLStreamException, ConfigurationLoadException { + int instance = getInstance(Integer.TYPE, "1234"); + assertEquals(1234, instance); + } + + public void testBoolean() throws XMLStreamException, ConfigurationLoadException { + Boolean instance = getInstance(Boolean.class, "true"); + assertSame(Boolean.TRUE, instance); + } + + public void testConstructor() throws XMLStreamException, ConfigurationLoadException { + // java.net.URI has a ctr that takes a String + URI instance = getInstance(URI.class, "http://www.apache.org"); + assertEquals(URI.create("http://www.apache.org"), instance); + } + + public void testPropertyEditor() throws XMLStreamException, ConfigurationLoadException { + // register a property editor for java.lang.Class + PropertyEditorManager.registerEditor(Class.class, ClassEditor.class); + try { + Class instance = getInstance(Class.class, "java.lang.Integer"); + assertEquals(Integer.class, instance); + } finally{ + PropertyEditorManager.registerEditor(Class.class, null); + } + } + + private T getInstance(Class type, String xml) throws XMLStreamException, ConfigurationLoadException { + property.setType(type); + XMLStreamReader reader = xmlFactory.createXMLStreamReader(new StringReader(xml)); + reader.next(); + ObjectFactory objectFactory = (ObjectFactory) factory.createObjectFactory(reader, property); + return objectFactory.getInstance(); + } + + protected void setUp() throws Exception { + super.setUp(); + factory = new StringParserPropertyFactory(); + xmlFactory = XMLInputFactory.newInstance(); + AssemblyFactory assemblyFactory = new AssemblyFactoryImpl(); + property = assemblyFactory.createProperty(); + } + + public static class ClassEditor extends PropertyEditorSupport { + public void setAsText(String text) throws IllegalArgumentException { + try { + setValue(Class.forName(text)); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException(text); + } + } + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/ComponentLoaderTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/ComponentLoaderTestCase.java new file mode 100644 index 0000000000..37056b3283 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/ComponentLoaderTestCase.java @@ -0,0 +1,151 @@ +/** + * + * Copyright 2006 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.assembly; + +import java.util.List; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.config.ComponentTypeIntrospector; +import org.apache.tuscany.core.config.ConfigurationException; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.extension.config.ImplementationProcessor; +import org.apache.tuscany.core.config.impl.Java5ComponentTypeIntrospector; +import org.apache.tuscany.core.config.processor.ProcessorUtils; +import org.apache.tuscany.core.injection.SingletonObjectFactory; +import org.apache.tuscany.core.loader.StAXPropertyFactory; +import org.apache.tuscany.core.loader.impl.StringParserPropertyFactory; +import org.apache.tuscany.core.system.assembly.SystemImplementation; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.ConfiguredProperty; +import org.apache.tuscany.model.assembly.Property; +import org.apache.tuscany.model.assembly.AtomicComponent; + +/** + * @version $Rev$ $Date$ + */ +public class ComponentLoaderTestCase extends LoaderTestSupport { + private ComponentLoader loader; + private ComponentTypeIntrospector introspector; + + public void testStringProperty() throws XMLStreamException, ConfigurationLoadException { + String xml = "HelloWorld"; + Component component = createFooComponent(); + loadProperties(xml, component); + ConfiguredProperty prop = component.getConfiguredProperty("propString"); + assertEquals("HelloWorld", prop.getValue()); + } + + public void testIntProperty() throws XMLStreamException, ConfigurationLoadException { + String xml = "1234"; + Component component = createFooComponent(); + loadProperties(xml, component); + ConfiguredProperty prop = component.getConfiguredProperty("propInt"); + assertEquals(1234, prop.getValue()); + } + + public void testIntegerProperty() throws XMLStreamException, ConfigurationLoadException { + String xml = "1234"; + Component component = createFooComponent(); + loadProperties(xml, component); + ConfiguredProperty prop = component.getConfiguredProperty("propInteger"); + assertEquals(Integer.valueOf(1234), prop.getValue()); + } + + public void testCustomProperty() throws XMLStreamException, ConfigurationLoadException { + String xml = "Hello"; + Component component = createFooComponent(); + loadProperties(xml, component); + ConfiguredProperty prop = component.getConfiguredProperty("propFoo"); + Foo instance = (Foo) prop.getValue(); + assertEquals("Hello", instance.name); + } + + private void loadProperties(String xml, Component component) throws XMLStreamException, ConfigurationLoadException { + XMLStreamReader reader = getReader(xml); + loader.loadProperties(reader, resourceLoader, component); + component.initialize(modelContext); + } + + private Component createFooComponent() { + SystemImplementation impl = assemblyFactory.createSystemImplementation(); + impl.setImplementationClass(ServiceImpl.class); + try { + impl.setComponentType(introspector.introspect(ServiceImpl.class)); + } catch (ConfigurationException e) { + throw new AssertionError(); + } + impl.initialize(null); + AtomicComponent component = assemblyFactory.createSimpleComponent(); + component.setImplementation(impl); + return component; + } + + protected void setUp() throws Exception { + super.setUp(); + loader = new ComponentLoader(); + loader.setFactory(assemblyFactory); + loader.setDefaultPropertyFactory(new StringParserPropertyFactory()); + introspector = ProcessorUtils.createCoreIntrospector(assemblyFactory); + } + + public static interface Service { + } + + public static class ServiceImpl implements Service { + public String propString; + public int propInt; + public Integer propInteger; + public Foo propFoo; + } + + public static class Foo { + public Foo() { + } + + private String name; + private Foo foo; + + public void setName(String val) { + name = val; + } + + public void setFoo(Foo val) { + foo = val; + } +/* + + private MyJaxBThing jaxBThing; + + public void setMyJaxBThing(MyJaxBThing thing) { + jaxBthing = thing; + } +*/ + } + + public static class FooFactory implements StAXPropertyFactory { + public ObjectFactory createObjectFactory(XMLStreamReader reader, Property property) throws XMLStreamException, ConfigurationLoadException { + reader.nextTag(); + String name = reader.getElementText(); + reader.next(); + Foo foo = new Foo(); + foo.setName(name); + return new SingletonObjectFactory(foo); + } + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/ComponentTypeLoaderTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/ComponentTypeLoaderTestCase.java new file mode 100644 index 0000000000..43b5bec143 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/ComponentTypeLoaderTestCase.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.assembly; + +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.model.assembly.ComponentType; +import org.apache.tuscany.model.assembly.Service; + +/** + * @version $Rev$ $Date$ + */ +public class ComponentTypeLoaderTestCase extends LoaderTestSupport { + + public void testMinimal() throws XMLStreamException, ConfigurationLoadException { + XMLStreamReader reader = getReader(""); + ComponentType type = (ComponentType) registry.load(reader, loaderContext); + type.initialize(null); + assertNotNull(type); + assertEquals(1, type.getServices().size()); + Service service = type.getService("service1"); + assertEquals("service1", service.getName()); + assertEquals(XMLStreamConstants.END_DOCUMENT, reader.next()); + } + + protected void setUp() throws Exception { + super.setUp(); + registerLoader(new ComponentTypeLoader()); + registerLoader(new ServiceLoader()); + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/EntryPointLoaderTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/EntryPointLoaderTestCase.java new file mode 100644 index 0000000000..8f207261fb --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/EntryPointLoaderTestCase.java @@ -0,0 +1,63 @@ +/** + * + * Copyright 2006 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.assembly; + +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import static org.apache.tuscany.core.loader.assembly.AssemblyConstants.ENTRY_POINT; +import org.apache.tuscany.model.assembly.ConfiguredService; +import org.apache.tuscany.model.assembly.EntryPoint; +import org.apache.tuscany.model.types.java.JavaServiceContract; + +/** + * @version $Rev$ $Date$ + */ +public class EntryPointLoaderTestCase extends LoaderTestSupport { + + public void testMinimal() throws XMLStreamException, ConfigurationLoadException { + String xml = ""; + XMLStreamReader reader = getReader(xml); + EntryPoint ep = (EntryPoint) registry.load(reader, loaderContext); + reader.require(XMLStreamConstants.END_ELEMENT, ENTRY_POINT.getNamespaceURI(), ENTRY_POINT.getLocalPart()); + assertEquals(XMLStreamConstants.END_DOCUMENT, reader.next()); + assertNotNull(ep); + assertEquals("test", ep.getName()); + } + + public void testInterface() throws XMLStreamException, ConfigurationLoadException { + String interfaceName = MockService.class.getName(); + String xml = ""; + XMLStreamReader reader = getReader(xml); + EntryPoint ep = (EntryPoint) registry.load(reader, loaderContext); + reader.require(XMLStreamConstants.END_ELEMENT, ENTRY_POINT.getNamespaceURI(), ENTRY_POINT.getLocalPart()); + assertEquals(XMLStreamConstants.END_DOCUMENT, reader.next()); + assertNotNull(ep); + assertEquals("test", ep.getName()); + ConfiguredService configuredService = ep.getConfiguredService(); + JavaServiceContract serviceContract = (JavaServiceContract) configuredService.getPort().getServiceContract(); + assertEquals(interfaceName, serviceContract.getInterfaceName()); + } + + protected void setUp() throws Exception { + super.setUp(); + registerLoader(new EntryPointLoader()); + registerLoader(new InterfaceJavaLoader()); + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/ExternalServiceLoaderTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/ExternalServiceLoaderTestCase.java new file mode 100644 index 0000000000..1fc5b367d5 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/ExternalServiceLoaderTestCase.java @@ -0,0 +1,64 @@ +/** + * + * Copyright 2006 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.assembly; + +import static org.apache.tuscany.core.loader.assembly.AssemblyConstants.EXTERNAL_SERVICE; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamConstants; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.model.assembly.ConfiguredService; +import org.apache.tuscany.model.assembly.ExternalService; +import org.apache.tuscany.model.types.java.JavaServiceContract; + +/** + * @version $Rev$ $Date$ + */ +public class ExternalServiceLoaderTestCase extends LoaderTestSupport { + + public void testMinimal() throws XMLStreamException, ConfigurationLoadException { + String xml = ""; + XMLStreamReader reader = getReader(xml); + ExternalService es = (ExternalService) registry.load(reader, loaderContext); + assertNotNull(es); + assertEquals("test", es.getName()); + reader.require(XMLStreamConstants.END_ELEMENT, EXTERNAL_SERVICE.getNamespaceURI(), EXTERNAL_SERVICE.getLocalPart()); + assertEquals(XMLStreamConstants.END_DOCUMENT, reader.next()); + } + + public void testInterface() throws XMLStreamException, ConfigurationLoadException { + String interfaceName = MockService.class.getName(); + String xml = ""; + XMLStreamReader reader = getReader(xml); + ExternalService es = (ExternalService) registry.load(reader, loaderContext); + reader.require(XMLStreamConstants.END_ELEMENT, EXTERNAL_SERVICE.getNamespaceURI(), EXTERNAL_SERVICE.getLocalPart()); + assertEquals(XMLStreamConstants.END_DOCUMENT, reader.next()); + assertNotNull(es); + assertEquals("test", es.getName()); + ConfiguredService configuredService = es.getConfiguredService(); + JavaServiceContract serviceContract = (JavaServiceContract) configuredService.getPort().getServiceContract(); + assertEquals(interfaceName, serviceContract.getInterfaceName()); + } + + protected void setUp() throws Exception { + super.setUp(); + registerLoader(new ExternalServiceLoader()); + registerLoader(new InterfaceJavaLoader()); + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/InterfaceWSDLLoaderInterfaceStylesTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/InterfaceWSDLLoaderInterfaceStylesTestCase.java new file mode 100644 index 0000000000..8b4f840f71 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/InterfaceWSDLLoaderInterfaceStylesTestCase.java @@ -0,0 +1,101 @@ +/** + * + * Copyright 2006 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.assembly; + +import static org.apache.tuscany.core.loader.assembly.AssemblyConstants.INTERFACE_WSDL; + +import java.io.InputStream; +import java.net.URL; + +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.common.resource.ResourceLoader; +import org.apache.tuscany.common.resource.impl.ResourceLoaderImpl; +import org.apache.tuscany.core.loader.impl.WSDLDefinitionRegistryImpl; +import org.apache.tuscany.model.types.wsdl.WSDLServiceContract; +import org.apache.tuscany.sdo.util.SDOUtil; + +import commonj.sdo.helper.XSDHelper; + +/** + * @version $Rev$ $Date$ + */ +public class InterfaceWSDLLoaderInterfaceStylesTestCase extends LoaderTestSupport { + private WSDLDefinitionRegistryImpl wsdlRegistry; + private ResourceLoader resourceLoader; + private ClassLoader oldCL; + + public void testInterface() throws Exception { + wsdlRegistry.loadDefinition("http://www.interfacestyles.org", getClass().getResource("interfacestyles.wsdl"), resourceLoader); + String xml = ""; + XMLStreamReader reader = getReader(xml); + WSDLServiceContract sc = (WSDLServiceContract) registry.load(reader, loaderContext); + reader.require(XMLStreamConstants.END_ELEMENT, INTERFACE_WSDL.getNamespaceURI(), INTERFACE_WSDL.getLocalPart()); + assertEquals(XMLStreamConstants.END_DOCUMENT, reader.next()); + assertNotNull(sc); + + sc.initialize(modelContext); + + Class scInterface = sc.getInterface(); + assertNotNull(scInterface); + + assertNotNull(scInterface.getMethod("getAccountReportWrapped0", new Class[0])); + assertNotNull(scInterface.getMethod("getAccountReportWrapped1", new Class[] {String.class})); + assertNotNull(scInterface.getMethod("getAccountReportWrappedN", new Class[] {String.class, int.class})); + assertNotNull(scInterface.getMethod("getAccountReportBare0", new Class[0])); + assertNotNull(scInterface.getMethod("getAccountReportBare1Simple", new Class[]{String.class})); + assertNotNull(scInterface.getMethod("getAccountReportBare1Complex", new Class[]{Object.class})); + + } + + protected void setUp() throws Exception { + oldCL = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); + resourceLoader = new ResourceLoaderImpl(getClass().getClassLoader()); + super.setUp(); + + wsdlRegistry = new WSDLDefinitionRegistryImpl(); + wsdlRegistry.setMonitor(NULL_MONITOR); + URL wsdlURL = getClass().getResource("interfacestyles.wsdl"); + wsdlRegistry.loadDefinition("http://www.interfacestyles.org", wsdlURL, resourceLoader); + InterfaceWSDLLoader loader = new InterfaceWSDLLoader(); + loader.setWsdlRegistry(wsdlRegistry); + registerLoader(loader); + + InputStream xsdInputStream = wsdlURL.openStream(); + try { + XSDHelper xsdHelper = SDOUtil.createXSDHelper(modelContext.getTypeHelper()); + xsdHelper.define(xsdInputStream, null); + } finally { + xsdInputStream.close(); + } + } + + protected void tearDown() throws Exception { + Thread.currentThread().setContextClassLoader(oldCL); + super.tearDown(); + } + + private static final WSDLDefinitionRegistryImpl.Monitor NULL_MONITOR = new WSDLDefinitionRegistryImpl.Monitor() { + public void readingWSDL(String namespace, URL location) { + } + + public void cachingDefinition(String namespace, URL location) { + } + }; +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/InterfaceWSDLLoaderTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/InterfaceWSDLLoaderTestCase.java new file mode 100644 index 0000000000..f97f13a1f7 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/InterfaceWSDLLoaderTestCase.java @@ -0,0 +1,88 @@ +/** + * + * Copyright 2006 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.assembly; + +import java.net.URL; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.common.resource.ResourceLoader; +import org.apache.tuscany.common.resource.impl.ResourceLoaderImpl; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import static org.apache.tuscany.core.loader.assembly.AssemblyConstants.INTERFACE_WSDL; +import org.apache.tuscany.core.loader.impl.WSDLDefinitionRegistryImpl; +import org.apache.tuscany.model.types.wsdl.WSDLServiceContract; + +/** + * @version $Rev$ $Date$ + */ +public class InterfaceWSDLLoaderTestCase extends LoaderTestSupport { + private WSDLDefinitionRegistryImpl wsdlRegistry; + private ResourceLoader resourceLoader; + + public void testMinimal() throws XMLStreamException, ConfigurationLoadException { + String xml = ""; + XMLStreamReader reader = getReader(xml); + WSDLServiceContract sc = (WSDLServiceContract) registry.load(reader, loaderContext); + reader.require(XMLStreamConstants.END_ELEMENT, INTERFACE_WSDL.getNamespaceURI(), INTERFACE_WSDL.getLocalPart()); + assertEquals(XMLStreamConstants.END_DOCUMENT, reader.next()); + assertNotNull(sc); + } + + public void testInterface() throws Exception { + wsdlRegistry.loadDefinition("http://www.example.org", getClass().getResource("example.wsdl"), resourceLoader); + String xml = ""; + XMLStreamReader reader = getReader(xml); + WSDLServiceContract sc = (WSDLServiceContract) registry.load(reader, loaderContext); + reader.require(XMLStreamConstants.END_ELEMENT, INTERFACE_WSDL.getNamespaceURI(), INTERFACE_WSDL.getLocalPart()); + assertEquals(XMLStreamConstants.END_DOCUMENT, reader.next()); + assertNotNull(sc); + } + + public void testInterfaceWithLocation() throws Exception { + wsdlRegistry.loadDefinition("http://www.example.org", getClass().getResource("example.wsdl"), resourceLoader); + String xml = ""; + XMLStreamReader reader = getReader(xml); + WSDLServiceContract sc = (WSDLServiceContract) registry.load(reader, loaderContext); + reader.require(XMLStreamConstants.END_ELEMENT, INTERFACE_WSDL.getNamespaceURI(), INTERFACE_WSDL.getLocalPart()); + assertEquals(XMLStreamConstants.END_DOCUMENT, reader.next()); + assertNotNull(sc); + } + + protected void setUp() throws Exception { + super.setUp(); + wsdlRegistry = new WSDLDefinitionRegistryImpl(); + wsdlRegistry.setMonitor(NULL_MONITOR); + resourceLoader = new ResourceLoaderImpl(getClass().getClassLoader()); + wsdlRegistry.loadDefinition("http://www.example.org", getClass().getResource("example.wsdl"), resourceLoader); + InterfaceWSDLLoader loader = new InterfaceWSDLLoader(); + loader.setWsdlRegistry(wsdlRegistry); + registerLoader(loader); + } + + private static final WSDLDefinitionRegistryImpl.Monitor NULL_MONITOR = new WSDLDefinitionRegistryImpl.Monitor() { + public void readingWSDL(String namespace, URL location) { + } + + public void cachingDefinition(String namespace, URL location) { + } + }; +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/LoaderTestSupport.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/LoaderTestSupport.java new file mode 100644 index 0000000000..4e2aea5e83 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/LoaderTestSupport.java @@ -0,0 +1,82 @@ +/** + * + * Copyright 2006 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.assembly; + +import java.io.StringReader; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.namespace.QName; + +import junit.framework.TestCase; + +import org.apache.tuscany.common.resource.ResourceLoader; +import org.apache.tuscany.common.resource.impl.ResourceLoaderImpl; +import org.apache.tuscany.core.system.assembly.SystemAssemblyFactory; +import org.apache.tuscany.core.system.assembly.impl.SystemAssemblyFactoryImpl; +import org.apache.tuscany.core.loader.impl.StAXLoaderRegistryImpl; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.model.assembly.impl.AssemblyContextImpl; + +/** + * Base class for loader tests with common fixture elements. + * + * @version $Rev$ $Date$ + */ +public abstract class LoaderTestSupport extends TestCase { + protected SystemAssemblyFactory assemblyFactory; + protected ResourceLoader resourceLoader; + protected LoaderContext loaderContext; + protected AssemblyContext modelContext; + protected XMLInputFactory xmlFactory; + protected StAXLoaderRegistryImpl registry; + + protected static final StAXLoaderRegistryImpl.Monitor NULL_MONITOR = new StAXLoaderRegistryImpl.Monitor() { + public void registeringLoader(QName xmlType) { + } + + public void unregisteringLoader(QName xmlType) { + } + + public void elementLoad(QName xmlType) { + } + }; + + protected void setUp() throws Exception { + super.setUp(); + assemblyFactory = new SystemAssemblyFactoryImpl(); + resourceLoader = new ResourceLoaderImpl(getClass().getClassLoader()); + loaderContext = new LoaderContext(resourceLoader); + modelContext = new AssemblyContextImpl(assemblyFactory, null, resourceLoader); + xmlFactory = XMLInputFactory.newInstance(); + registry = new StAXLoaderRegistryImpl(); + registry.setMonitor(NULL_MONITOR); + } + + protected XMLStreamReader getReader(String xml) throws XMLStreamException { + XMLStreamReader reader = xmlFactory.createXMLStreamReader(new StringReader(xml)); + reader.next(); + return reader; + } + + protected void registerLoader(AbstractLoader loader) { + loader.setFactory(assemblyFactory); + loader.setRegistry(registry); + loader.start(); + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/MockService.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/MockService.java new file mode 100644 index 0000000000..c1ea3dbc1e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/MockService.java @@ -0,0 +1,23 @@ +/** + * + * Copyright 2006 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.assembly; + +/** + * @version $Rev$ $Date$ + */ +public interface MockService { +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/WSDLDefinitionRegistryTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/WSDLDefinitionRegistryTestCase.java new file mode 100644 index 0000000000..5543a41f91 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/WSDLDefinitionRegistryTestCase.java @@ -0,0 +1,76 @@ +/** + * + * Copyright 2006 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.loader.assembly; + +import java.net.URL; +import java.io.IOException; + +import javax.wsdl.Definition; +import javax.wsdl.WSDLException; +import javax.xml.namespace.QName; + +import junit.framework.TestCase; +import org.apache.tuscany.core.loader.impl.WSDLDefinitionRegistryImpl; +import org.apache.tuscany.common.resource.ResourceLoader; +import org.apache.tuscany.common.resource.impl.ResourceLoaderImpl; + +/** + * @version $Rev$ $Date$ + */ +public class WSDLDefinitionRegistryTestCase extends TestCase { + private static final String NS = "http://www.example.org"; + private WSDLDefinitionRegistryImpl wsdlRegistry; + private ResourceLoader rl; + + + public void testLoadFromAbsoluteWSDLLocation() { + try { + Definition def = wsdlRegistry.loadDefinition(NS + ' ' + rl.getResource("org/apache/tuscany/core/loader/assembly/example.wsdl"), rl); + assertNotNull(def.getPortType(new QName(NS, "HelloWorld"))); + } catch (IOException e) { + fail(e.getMessage()); + } catch (WSDLException e) { + fail(e.getMessage()); + } + } + + public void testLoadFromRelativeWSDLLocation() { + try { + Definition def = wsdlRegistry.loadDefinition(NS + " org/apache/tuscany/core/loader/assembly/example.wsdl", rl); + assertNotNull(def.getPortType(new QName(NS, "HelloWorld"))); + } catch (IOException e) { + fail(e.getMessage()); + } catch (WSDLException e) { + fail(e.getMessage()); + } + } + + protected void setUp() throws Exception { + super.setUp(); + wsdlRegistry = new WSDLDefinitionRegistryImpl(); + wsdlRegistry.setMonitor(NULL_MONITOR); + rl = new ResourceLoaderImpl(getClass().getClassLoader()); + } + + private static final WSDLDefinitionRegistryImpl.Monitor NULL_MONITOR = new WSDLDefinitionRegistryImpl.Monitor() { + public void readingWSDL(String namespace, URL location) { + } + + public void cachingDefinition(String namespace, URL location) { + } + }; +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/WireLoaderTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/WireLoaderTestCase.java new file mode 100644 index 0000000000..3a0331150d --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/loader/assembly/WireLoaderTestCase.java @@ -0,0 +1,60 @@ +/** + * + * 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.assembly; + +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.model.assembly.Wire; + +/** + * @version $Rev$ $Date$ + */ +public class WireLoaderTestCase extends LoaderTestSupport { + + public void testMinimal() throws XMLStreamException, ConfigurationLoadException { + String xml = "foo/fooServicebar"; + XMLStreamReader reader = getReader(xml); + Wire wire = (Wire) registry.load(reader, loaderContext); + reader.require(XMLStreamConstants.END_ELEMENT, AssemblyConstants.WIRE.getNamespaceURI(), AssemblyConstants.WIRE.getLocalPart()); + assertEquals(XMLStreamConstants.END_DOCUMENT, reader.next()); + assertNotNull(wire); + assertEquals("foo", wire.getSource().getPartName()); + assertEquals("fooService", wire.getSource().getServiceName()); + assertEquals("bar", wire.getTarget().getPartName()); + } + + public void testCompound() throws XMLStreamException, ConfigurationLoadException { + String xml = "foo/fooServicebar/bazService"; + XMLStreamReader reader = getReader(xml); + Wire wire = (Wire) registry.load(reader, loaderContext); + reader.require(XMLStreamConstants.END_ELEMENT, AssemblyConstants.WIRE.getNamespaceURI(), AssemblyConstants.WIRE.getLocalPart()); + assertEquals(XMLStreamConstants.END_DOCUMENT, reader.next()); + assertNotNull(wire); + assertEquals("foo", wire.getSource().getPartName()); + assertEquals("fooService", wire.getSource().getServiceName()); + assertEquals("bar", wire.getTarget().getPartName()); + assertEquals("bazService", wire.getTarget().getServiceName()); + } + + protected void setUp() throws Exception { + super.setUp(); + registerLoader(new WireLoader()); + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/MockConfigContext.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/MockConfigContext.java new file mode 100644 index 0000000000..820e4d36d8 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/MockConfigContext.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.mock; + +import org.apache.tuscany.core.builder.BuilderConfigException; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.core.builder.impl.AssemblyVisitorImpl; +import org.apache.tuscany.core.context.ConfigurationContext; +import org.apache.tuscany.core.context.ScopeContext; +import org.apache.tuscany.core.wire.SourceWireFactory; +import org.apache.tuscany.core.wire.TargetWireFactory; +import org.apache.tuscany.model.assembly.AssemblyObject; + +import java.util.ArrayList; +import java.util.List; + +/** + * A mock configuration context + * + * @version $Rev$ $Date$ + */ +public class MockConfigContext implements ConfigurationContext { + + private List builders = new ArrayList(); + + public MockConfigContext(List builders) { + this.builders = builders; + } + + public void build(AssemblyObject model) throws BuilderConfigException { + AssemblyVisitorImpl visitor = new AssemblyVisitorImpl(builders); + visitor.start(model); + } + + public void connect(SourceWireFactory sourceFactory, TargetWireFactory targetFactory, Class targetType, boolean downScope, + ScopeContext targetScopeContext) throws BuilderConfigException { + } + + public void completeTargetChain(TargetWireFactory targetFactory, Class targetType, ScopeContext targetScopeContext) throws BuilderConfigException { + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/MockFactory.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/MockFactory.java new file mode 100644 index 0000000000..87e92d783c --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/MockFactory.java @@ -0,0 +1,413 @@ +/** + * + * 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.mock; + +import java.util.ArrayList; +import java.util.List; +import java.lang.reflect.Method; + +import org.apache.tuscany.common.monitor.impl.NullMonitorFactory; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.core.client.BootstrapHelper; +import org.apache.tuscany.core.config.ComponentTypeIntrospector; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.config.impl.Java5ComponentTypeIntrospector; +import org.apache.tuscany.core.config.processor.ProcessorUtils; +import org.apache.tuscany.core.context.impl.CompositeContextImpl; +import org.apache.tuscany.core.extension.config.ImplementationProcessor; +import org.apache.tuscany.core.extension.config.extensibility.DestroyInvokerExtensibilityElement; +import org.apache.tuscany.core.mock.component.ModuleScopeSystemComponent; +import org.apache.tuscany.core.mock.component.ModuleScopeSystemComponentImpl; +import org.apache.tuscany.core.mock.component.Source; +import org.apache.tuscany.core.mock.component.SourceImpl; +import org.apache.tuscany.core.mock.component.Target; +import org.apache.tuscany.core.mock.component.TargetImpl; +import org.apache.tuscany.core.runtime.RuntimeContext; +import org.apache.tuscany.core.runtime.RuntimeContextImpl; +import org.apache.tuscany.core.system.assembly.SystemAssemblyFactory; +import org.apache.tuscany.core.system.assembly.SystemBinding; +import org.apache.tuscany.core.system.assembly.SystemModule; +import org.apache.tuscany.core.system.assembly.impl.SystemAssemblyFactoryImpl; +import org.apache.tuscany.core.system.builder.SystemContextFactoryBuilder; +import org.apache.tuscany.core.system.builder.SystemEntryPointBuilder; +import org.apache.tuscany.core.system.builder.SystemExternalServiceBuilder; +import org.apache.tuscany.core.system.context.SystemCompositeContextImpl; +import org.apache.tuscany.core.injection.MethodEventInvoker; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.ComponentType; +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; +import org.apache.tuscany.model.assembly.Module; +import org.apache.tuscany.model.assembly.ModuleComponent; +import org.apache.tuscany.model.assembly.Multiplicity; +import org.apache.tuscany.model.assembly.Part; +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.impl.AssemblyContextImpl; +import org.apache.tuscany.model.types.java.JavaServiceContract; + +/** + * Generates test components, modules, and runtime artifacts + * + * @version $Rev$ $Date$ + */ +public class MockFactory { + + private static SystemAssemblyFactory systemFactory = new SystemAssemblyFactoryImpl(); + private static AssemblyContext assemblyContext = new AssemblyContextImpl(systemFactory, null, null); + private static ComponentTypeIntrospector introspector; + private static ComponentType systemComponentType; + private static ComponentType compositeComponentType; + + private MockFactory() { + } + + public static ComponentType getComponentType() throws ConfigurationLoadException { + if (systemComponentType == null) { + systemComponentType = getIntrospector().introspect(SystemCompositeContextImpl.class); + } + return systemComponentType; + } + + public static ComponentType getCompositeComponentType() throws ConfigurationLoadException { + if (compositeComponentType == null) { + compositeComponentType = getIntrospector().introspect(CompositeContextImpl.class); + } + return compositeComponentType; + } + + public static ComponentTypeIntrospector getIntrospector() { + if (introspector == null) { + introspector = ProcessorUtils.createCoreIntrospector(systemFactory); + } + return introspector; + } + + /** + * Creates an composite component with the given name + */ + public static ModuleComponent createCompositeComponent(String name) throws ConfigurationLoadException { + ModuleComponent sc = systemFactory.createModuleComponent(); + Module impl = systemFactory.createModule(); + impl.setName(name); + //impl.setImplementationClass(CompositeContextImpl.class); + sc.setImplementation(impl); + impl.setImplementationClass(CompositeContextImpl.class); + impl.setComponentType(getCompositeComponentType()); + Service s = systemFactory.createService(); + JavaServiceContract ji = systemFactory.createJavaServiceContract(); + s.setServiceContract(ji); + ji.setScope(Scope.AGGREGATE); +// impl.setComponentType(systemFactory.createComponentType()); + impl.getComponentType().getServices().add(s); + sc.setName(name); + sc.setImplementation(impl); + return sc; + } + + /** + * Creates an composite component with the given name + */ + public static ModuleComponent createSystemCompositeComponent(String name) throws ConfigurationLoadException { + ModuleComponent sc = systemFactory.createModuleComponent(); + SystemModule impl = systemFactory.createSystemModule(); + impl.setName(name); + impl.setImplementationClass(SystemCompositeContextImpl.class); + impl.setComponentType(getComponentType()); + sc.setImplementation(impl); + Service s = systemFactory.createService(); + JavaServiceContract ji = systemFactory.createJavaServiceContract(); + s.setServiceContract(ji); + ji.setScope(Scope.AGGREGATE); + //impl.setComponentType(systemFactory.createComponentType()); + impl.getComponentType().getServices().add(s); + sc.setName(name); + sc.setImplementation(impl); + return sc; + } + + /** + * Creates a basic entry point with no configured reference using the system binding + * + * @param name the name of the entry point + * @param interfaz the inteface exposed by the entry point + * @param refName the name of the entry point reference + */ + public static EntryPoint createEPSystemBinding(String name, Class interfaz, String refName) { + return createEPSystemBinding(name, interfaz, refName, null); + } + + /** + * Creates an entry point wired to the given target (e.g. component, external service) using the system + * binding + * + * @param name the name of the entry point + * @param interfaz the inteface exposed by the entry point + * @param refName the name of the entry point reference + * @param target the target the entry point is wired to + */ + public static EntryPoint createEPSystemBinding(String name, Class interfaz, String refName, Part target) { + JavaServiceContract contract = systemFactory.createJavaServiceContract(); + contract.setInterface(interfaz); + + EntryPoint ep = systemFactory.createEntryPoint(); + ep.setName(name); + + Reference ref = systemFactory.createReference(); + ref.setName(refName); + ref.setServiceContract(contract); + ConfiguredReference configuredReference = systemFactory.createConfiguredReference(); + configuredReference.setPort(ref); + Service service = systemFactory.createService(); + service.setServiceContract(contract); + + ConfiguredService cService = systemFactory.createConfiguredService(); + cService.setPort(service); + cService.initialize(assemblyContext); + + configuredReference.getTargetConfiguredServices().add(cService); + ep.setConfiguredReference(configuredReference); + + Service epService = systemFactory.createService(); + epService.setServiceContract(contract); + + ConfiguredService epCService = systemFactory.createConfiguredService(); + epCService.initialize(assemblyContext); + epCService.setPort(epService); + + ep.setConfiguredService(epCService); + SystemBinding binding = systemFactory.createSystemBinding(); + ep.getBindings().add(binding); + if (target != null) { + if (target instanceof Component) { + ((Component) target).getConfiguredServices().add(cService); + // cService. + } else if (target instanceof ExternalService) { + ((ExternalService) target).setConfiguredService(cService); + } + target.initialize(assemblyContext); + } + ep.initialize(null); + return ep; + } + + /** + * Creates an entry point that should be wired to the given target (e.g. component, external service) + * using the system binding. The system assembly process should resolve the target name to an actual + * target configuration. + * + * @param name the name of the entry point + * @param interfaz the inteface exposed by the entry point + * @param refName the name of the entry point reference + * @param componentName the name of the target to resolve + */ + public static EntryPoint createEntryPointWithStringRef(String name, Class interfaz, String refName, String componentName) { + EntryPoint ep = createEPSystemBinding(name, interfaz, refName, null); + ConfiguredReference cRef = systemFactory.createConfiguredReference(); + Reference ref = systemFactory.createReference(); + cRef.setPort(ref); + Service service = systemFactory.createService(); + service.setName(componentName); + ConfiguredService cService = systemFactory.createConfiguredService(); + cService.setPort(service); + cRef.getTargetConfiguredServices().add(cService); + cRef.initialize(assemblyContext); + cService.initialize(assemblyContext); + JavaServiceContract contract = systemFactory.createJavaServiceContract(); + contract.setInterface(interfaz); + ref.setServiceContract(contract); + ep.setConfiguredReference(cRef); + ep.initialize(assemblyContext); + return ep; + } + + /** + * Creates an external service configured with a {@link SystemBinding} + */ + public static ExternalService createESSystemBinding(String name, String refName) { + ExternalService es = systemFactory.createExternalService(); + es.setName(name); + ConfiguredService configuredService = systemFactory.createConfiguredService(); + es.setConfiguredService(configuredService); + SystemBinding binding = systemFactory.createSystemBinding(); + binding.setTargetName(refName); + es.getBindings().add(binding); + es.initialize(null); + return es; + } + + /** + * Creates an external service that specifies an autowire of the given type + */ + public static ExternalService createAutowirableExternalService(String name, Class type) { + ExternalService es = systemFactory.createExternalService(); + es.setName(name); + JavaServiceContract inter = systemFactory.createJavaServiceContract(); + inter.setInterface(type); + Service service = systemFactory.createService(); + service.setServiceContract(inter); + ConfiguredService cService = systemFactory.createConfiguredService(); + cService.setPort(service); + cService.initialize(assemblyContext); + es.setConfiguredService(cService); + es.getBindings().add(systemFactory.createSystemBinding()); + es.initialize(null); + return es; + } + + /** + * Creates a test system module with a module-scoped component and entry point + */ + public static Module createSystemModule() throws ConfigurationLoadException { + Module module = systemFactory.createSystemModule(); + module.setName("system.module"); + + // create test component + Component component = systemFactory.createSystemComponent("TestService1", ModuleScopeSystemComponent.class, + ModuleScopeSystemComponentImpl.class, Scope.MODULE); + component.getImplementation().setComponentType(getIntrospector().introspect(ModuleScopeSystemComponent.class)); + module.getComponents().add(component); + + // create the entry point + EntryPoint ep = createEPSystemBinding("TestService1EP", ModuleScopeSystemComponent.class, "target", component); + module.getEntryPoints().add(ep); + + module.initialize(assemblyContext); + module.setImplementationClass(SystemCompositeContextImpl.class); + module.setComponentType(getComponentType()); + return module; + } + + public static Component createSystemComponent(String name, Class service, Class impl, Scope scope) throws ConfigurationLoadException { + Component c = systemFactory.createSystemComponent(name, service, impl, scope); + c.getImplementation().setComponentType(getIntrospector().introspect(impl)); + for (Service s : c.getImplementation().getComponentType().getServices()) { + s.getServiceContract().setScope(scope); //hack + } + + return c; + } + + /** + * Creates a test system module with source and target components wired together. + * + * @see org.apache.tuscany.core.mock.component.Source + * @see org.apache.tuscany.core.mock.component.Target + */ + public static Module createSystemModuleWithWiredComponents(String moduleName, Scope sourceScope, Scope targetScope) throws ConfigurationLoadException { + + // create the target component + Component target = systemFactory.createSystemComponent("target", Target.class, TargetImpl.class, targetScope); + target.initialize(assemblyContext); + + // create the source componentType + Component source = systemFactory.createSystemComponent("source", Source.class, SourceImpl.class, sourceScope); + ComponentType sourceComponentType = source.getImplementation().getComponentType(); + List references = sourceComponentType.getReferences(); + List configuredReferences = source.getConfiguredReferences(); + + // wire source to target + references.add(systemFactory.createReference("setTarget", Target.class)); + ConfiguredReference configuredReference = systemFactory.createConfiguredReference("setTarget", "target"); + configuredReferences.add(configuredReference); + + // wire multiplicity using a setter + references.add(systemFactory.createReference("setTargets", Target.class, Multiplicity.ONE_N)); + configuredReference = systemFactory.createConfiguredReference("setTargets", "target"); + configuredReferences.add(configuredReference); + + // wire multiplicity using a field + references.add(systemFactory.createReference("targetsThroughField", Target.class, Multiplicity.ONE_N)); + configuredReference = systemFactory.createConfiguredReference("targetsThroughField", "target"); + configuredReferences.add(configuredReference); + + // wire multiplicity using a setter + references.add(systemFactory.createReference("setArrayOfTargets", Target.class, Multiplicity.ONE_N)); + configuredReference = systemFactory.createConfiguredReference("setArrayOfTargets", "target"); + configuredReferences.add(configuredReference); + + source.initialize(assemblyContext); + + Module module = systemFactory.createSystemModule(); + module.setImplementationClass(SystemCompositeContextImpl.class); + module.setComponentType(getComponentType()); + module.setName(moduleName); + module.getComponents().add(source); + module.getComponents().add(target); + module.initialize(assemblyContext); + return module; + } + + /** + * Creates a test system module component with source and target components wired together. + * + * @see org.apache.tuscany.core.mock.component.Source + * @see org.apache.tuscany.core.mock.component.Target + */ + public static ModuleComponent createSystemModuleComponentWithWiredComponents(String moduleComponentName, Scope sourceScope, + Scope targetScope) throws ConfigurationLoadException { + ModuleComponent mc = systemFactory.createModuleComponent(); + mc.setName(moduleComponentName); + mc.setImplementation(createSystemModuleWithWiredComponents(moduleComponentName + ".module", sourceScope, targetScope)); + return mc; + } + + /** + * Creates a test system module component with a module-scoped component and entry point + */ + public static Module createSystemChildModule() throws ConfigurationLoadException { + Module module = systemFactory.createSystemModule(); + module.setName("system.test.module"); + module.setImplementationClass(SystemCompositeContextImpl.class); + module.setComponentType(getComponentType()); + + // create test component + Component component = systemFactory.createSystemComponent("TestService2", ModuleScopeSystemComponent.class, + ModuleScopeSystemComponentImpl.class, Scope.MODULE); + module.getComponents().add(component); + + // create the entry point + EntryPoint ep = createEPSystemBinding("TestService2EP", ModuleScopeSystemComponent.class, "target", component); + module.getEntryPoints().add(ep); + + module.initialize(assemblyContext); + return module; + } + + /** + * Returns a collection of bootstrap configuration builders + */ + public static List createSystemBuilders() { + List builders = new ArrayList(); + builders.add((new SystemContextFactoryBuilder(null))); + builders.add(new SystemEntryPointBuilder()); + builders.add(new SystemExternalServiceBuilder()); + return builders; + } + + /** + * Creates a default {@link RuntimeContext} configured with support for Java component implementations + */ + public static RuntimeContext createCoreRuntime() { + NullMonitorFactory monitorFactory = new NullMonitorFactory(); + RuntimeContext runtime = new RuntimeContextImpl(monitorFactory, BootstrapHelper.bootstrapContextFactoryBuilders(monitorFactory), null); + runtime.start(); + return runtime; + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/AutowireSourceImpl.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/AutowireSourceImpl.java new file mode 100644 index 0000000000..fb1cb86873 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/AutowireSourceImpl.java @@ -0,0 +1,64 @@ +/** + * + * 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.mock.component; + +import org.apache.tuscany.core.system.annotation.Autowire; + +import java.util.List; + +/** + * Mock system component implementation used in autowire tests + * + * @version $Rev$ $Date$ + */ +public class AutowireSourceImpl implements Source { + + @Autowire + protected Target target; + + private List targets; + + private List targetsThroughField; + + public void setTarget(Target target) { + this.target = target; + } + + public Target getTarget() { + return target; + } + + public List getTargets() { + return targets; + } + + public void setTargets(List targets) { + this.targets = targets; + } + + public List getTargetsThroughField() { + return targetsThroughField; + } + + private Target[] targetsArray; + + public Target[] getArrayOfTargets() { + return targetsArray; + } + + public void setArrayOfTargets(Target[] targets) { + targetsArray = targets; + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/GenericSystemComponent.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/GenericSystemComponent.java new file mode 100644 index 0000000000..1fd02de992 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/GenericSystemComponent.java @@ -0,0 +1,22 @@ +/** + * + * 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.mock.component; + +public interface GenericSystemComponent { + +} + diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/ModuleScopeSystemComponent.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/ModuleScopeSystemComponent.java new file mode 100644 index 0000000000..dabbd9e4ef --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/ModuleScopeSystemComponent.java @@ -0,0 +1,28 @@ +/** + * + * 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.mock.component; + +import org.osoa.sca.annotations.Scope; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public interface ModuleScopeSystemComponent extends GenericSystemComponent { + +} + diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/ModuleScopeSystemComponentImpl.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/ModuleScopeSystemComponentImpl.java new file mode 100644 index 0000000000..58afde9354 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/ModuleScopeSystemComponentImpl.java @@ -0,0 +1,25 @@ +/** + * + * 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.mock.component; + +/** + * @version $Rev$ $Date$ + */ +public class ModuleScopeSystemComponentImpl implements ModuleScopeSystemComponent { + + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/Source.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/Source.java new file mode 100644 index 0000000000..6ce1059db1 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/Source.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.mock.component; + +import java.util.List; + +/** + * Implementations are used in wiring tests + * + * @version $Rev$ $Date$ + */ +public interface Source { + + public Target getTarget(); + + public List getTargets(); + + public List getTargetsThroughField(); + + public Target[] getArrayOfTargets(); + +} + diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/SourceImpl.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/SourceImpl.java new file mode 100644 index 0000000000..075e70699e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/SourceImpl.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.mock.component; + +import java.util.List; + +import org.osoa.sca.annotations.Destroy; + +/** + * Mock system component implementation used in wiring tests + * + * @version $Rev$ $Date$ + */ +public class SourceImpl implements Source { + + private Target target; + + private List targets; + + private List targetsThroughField; + + @Destroy + public void foo(){ + } + + public void setTarget(Target target) { + this.target = target; + } + + public Target getTarget() { + return target; + } + + public List getTargets() { + return targets; + } + + public void setTargets(List targets) { + this.targets = targets; + } + + public List getTargetsThroughField() { + return targetsThroughField; + } + + private Target[] targetsArray; + + public Target[] getArrayOfTargets() { + return targetsArray; + } + + public void setArrayOfTargets(Target[] targets) { + targetsArray = targets; + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/Target.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/Target.java new file mode 100644 index 0000000000..fb3642a495 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/Target.java @@ -0,0 +1,27 @@ +/** + * + * 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.mock.component; + +/** + * Implementations are used in wiring tests + * + * @version $Rev$ $Date$ + */ +public interface Target { + + public String getString(); + + public void setString(String val); +} + diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/TargetImpl.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/TargetImpl.java new file mode 100644 index 0000000000..323bee0713 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/mock/component/TargetImpl.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.mock.component; + +/** + * Mock system component implementation used in wiring tests + * + * @version $Rev$ $Date$ + */ +public class TargetImpl implements Target { + + private String theString; + + public String getString() { + return theString; + } + + public void setString(String val) { + theString = val; + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/runtime/RuntimeBootTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/runtime/RuntimeBootTestCase.java new file mode 100644 index 0000000000..c4e1ea9962 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/runtime/RuntimeBootTestCase.java @@ -0,0 +1,99 @@ +/** + * + * 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 junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.tuscany.common.monitor.impl.NullMonitorFactory; +import org.apache.tuscany.core.builder.ContextFactoryBuilderRegistry; +import org.apache.tuscany.core.builder.impl.DefaultWireBuilder; +import org.apache.tuscany.core.client.BootstrapHelper; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.Lifecycle; +import org.apache.tuscany.core.context.event.ModuleStart; +import org.apache.tuscany.core.context.event.ModuleStop; +import org.apache.tuscany.core.mock.MockFactory; + +/** + * Tests runtime boot scenarios + * + * @version $Rev$ $Date$ + */ +public class RuntimeBootTestCase extends TestCase { + private RuntimeContext runtime; + private NullMonitorFactory monitorFactory; + private ContextFactoryBuilderRegistry builderRegistry; + private DefaultWireBuilder wireBuilder; + + public void testContextParents() { + CompositeContext rootContext = runtime.getRootContext(); + assertNotNull(rootContext); + assertEquals("tuscany.root", rootContext.getName()); + assertSame(runtime, rootContext.getParent()); + assertSame(rootContext, runtime.getContext("tuscany.root")); + + CompositeContext systemContext = runtime.getSystemContext(); + assertNotNull(systemContext); + assertEquals("tuscany.system", systemContext.getName()); + assertSame(runtime, systemContext.getParent()); + assertSame(systemContext, runtime.getContext("tuscany.system")); + } + + public void testRuntimeLifecycle() { + assertEquals(Lifecycle.RUNNING, runtime.getLifecycleState()); + runtime.stop(); + + assertEquals(Lifecycle.STOPPED, runtime.getLifecycleState()); + } + + public void testIncrementalBoot() throws Exception{ + + // start the runtime context + RuntimeContext runtimeContext = new RuntimeContextImpl(monitorFactory, builderRegistry, wireBuilder); + runtimeContext.start(); + + CompositeContext system = runtimeContext.getSystemContext(); + Assert.assertNotNull(system); + // register system components + system.registerModelObject(MockFactory.createSystemModule()); + // start the module scope + system.publish(new ModuleStart(this)); + // register the first module + + // register the second module + + // start the modules + + system.publish(new ModuleStop(this)); + runtimeContext.stop(); + Assert.assertEquals(Lifecycle.STOPPED,system.getLifecycleState()); + } + + protected void setUp() throws Exception { + super.setUp(); + + monitorFactory = new NullMonitorFactory(); + builderRegistry = BootstrapHelper.bootstrapContextFactoryBuilders(monitorFactory); + wireBuilder = new DefaultWireBuilder(); + runtime = new RuntimeContextImpl(monitorFactory, builderRegistry, wireBuilder); + runtime.start(); + } + + protected void tearDown() throws Exception { + runtime.stop(); + super.tearDown(); + } +} + diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/runtime/RuntimeContextImplTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/runtime/RuntimeContextImplTestCase.java new file mode 100644 index 0000000000..d9596239fa --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/runtime/RuntimeContextImplTestCase.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 junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.tuscany.common.monitor.MonitorFactory; +import org.apache.tuscany.common.monitor.impl.NullMonitorFactory; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.core.builder.ContextFactoryBuilderRegistry; +import org.apache.tuscany.core.client.BootstrapHelper; +import org.apache.tuscany.core.config.ConfigurationException; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.Lifecycle; +import org.apache.tuscany.core.context.ServiceNotFoundException; +import org.apache.tuscany.core.context.event.ModuleStart; +import org.apache.tuscany.core.context.event.ModuleStop; +import org.apache.tuscany.core.context.impl.CompositeContextImpl; +import org.apache.tuscany.core.mock.MockFactory; +import org.apache.tuscany.core.mock.component.ModuleScopeSystemComponent; +import org.apache.tuscany.core.mock.component.ModuleScopeSystemComponentImpl; +import org.apache.tuscany.core.system.assembly.SystemAssemblyFactory; +import org.apache.tuscany.core.system.assembly.impl.SystemAssemblyFactoryImpl; +import org.apache.tuscany.core.system.context.TestBuilder; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.EntryPoint; +import org.apache.tuscany.model.assembly.ExternalService; +import org.apache.tuscany.model.assembly.Scope; +import org.apache.tuscany.model.assembly.Service; +import org.apache.tuscany.model.types.java.JavaServiceContract; + +/** + * Performs basic tests on the runtime context + * + * @version $Rev$ $Date$ + */ +public class RuntimeContextImplTestCase extends TestCase { + + private SystemAssemblyFactory systemFactory = new SystemAssemblyFactoryImpl(); + + private ContextFactoryBuilderRegistry builderRegistry; + + private SystemAssemblyFactory factory; + private MonitorFactory monitorFactory; + private RuntimeContext runtime; + + /** + * Tests explicit wiring of an external service to a system entry point that is wired to a child system + * module entry point + */ + public void testSystemExplicitWiring() throws Exception { + CompositeContext root = runtime.getRootContext(); + Assert.assertNotNull(root); + Assert.assertTrue(root.getLifecycleState() == Lifecycle.RUNNING); + + CompositeContext system = runtime.getSystemContext(); + Assert.assertNotNull(system); + system.registerModelObject(MockFactory.createSystemModule()); + + // register a child system context + system.registerModelObject(MockFactory.createSystemCompositeComponent("system.child")); + CompositeContext systemChild = (CompositeContext) system.getContext("system.child"); + systemChild.registerModelObject(MockFactory.createSystemChildModule()); + + // register a top-level system entry point that exposes the child entry point + EntryPoint ep = MockFactory.createEPSystemBinding("TestService2EP", ModuleScopeSystemComponent.class, "ref"); + ep.getBindings().add(systemFactory.createSystemBinding()); + Service service = systemFactory.createService(); + service.setName("system.child/TestService2EP"); + ep.getConfiguredReference().getTargetConfiguredServices().get(0).setPort(service); + JavaServiceContract inter = systemFactory.createJavaServiceContract(); + inter.setInterface(ModuleScopeSystemComponentImpl.class); + service.setServiceContract(inter); + system.registerModelObject(ep); + system.publish(new ModuleStart(this)); + Assert.assertNotNull(system.getContext("TestService1").getInstance(null)); + Assert.assertNotNull(system.getContext("TestService2EP").getInstance(null)); + + // create a test module and wire an external service to the system entry point + Component moduleComponent = MockFactory.createCompositeComponent("test.module"); + runtime.registerModelObject(moduleComponent); + CompositeContextImpl moduleContext = (CompositeContextImpl) runtime.getContext("test.module"); + Assert.assertNotNull(moduleContext); + ExternalService es = MockFactory.createESSystemBinding("TestService2ES", "tuscany.system/TestService2EP"); + moduleContext.registerModelObject(es); + moduleContext.publish(new ModuleStart(this)); + Assert.assertNotNull(moduleContext.getContext("TestService2ES").getInstance(null)); + + moduleContext.publish(new ModuleStop(this)); + system.publish(new ModuleStop(this)); + } + + /** + * Tests autowiring an external service to a system entry point + */ + public void testSystemAutoWiring() throws Exception { + CompositeContext root = runtime.getRootContext(); + Assert.assertNotNull(root); + Assert.assertTrue(root.getLifecycleState() == Lifecycle.RUNNING); + + CompositeContext system = runtime.getSystemContext(); + Assert.assertNotNull(system); + system.registerModelObject(MockFactory.createSystemModule()); + + // create a test module and wire an external service to the system entry point + Component moduleComponent = MockFactory.createCompositeComponent("test.module"); + runtime.registerModelObject(moduleComponent); + CompositeContextImpl moduleContext = (CompositeContextImpl) runtime.getContext("test.module"); + Assert.assertNotNull(moduleContext); + ExternalService es = MockFactory.createAutowirableExternalService("TestService2ES", ModuleScopeSystemComponent.class); + moduleContext.registerModelObject(es); + + system.publish(new ModuleStart(this)); + moduleContext.publish(new ModuleStart(this)); + // test that the autowire was resolved + Assert.assertNotNull(moduleContext.getContext("TestService2ES").getInstance(null)); + + moduleContext.publish(new ModuleStop(this)); + system.publish(new ModuleStop(this)); + } + + public void testServiceNotFound() throws Exception { + // create a test module + Component moduleComponent = MockFactory.createCompositeComponent("module"); + runtime.registerModelObject(moduleComponent); + CompositeContextImpl moduleContext = (CompositeContextImpl) runtime.getContext("module"); + moduleContext.publish(new ModuleStart(this)); + try { + moduleContext.locateService("TestService"); + fail("Expected " + ServiceNotFoundException.class.getName()); + } catch (ServiceNotFoundException e) { + // expected + } + moduleContext.publish(new ModuleStop(this)); + } + + public void testExternalServiceReferenceNotFound() throws Exception { + CompositeContext system = runtime.getSystemContext(); + + // create a test module + Component moduleComponent = MockFactory.createCompositeComponent("module"); + runtime.registerModelObject(moduleComponent); + CompositeContextImpl moduleContext = (CompositeContextImpl) runtime.getContext("module"); + ExternalService es = MockFactory.createESSystemBinding("TestServiceES", "tuscany.system/TestService1xEP"); + moduleContext.registerModelObject(es); + + // start the modules and test inter-module system wires + system.publish(new ModuleStart(this)); + moduleContext.publish(new ModuleStart(this)); + try { + moduleContext.locateService("TestServiceES"); + fail("Expected " + ServiceNotFoundException.class.getName()); + } catch (ServiceNotFoundException e) { + // expected + } + moduleContext.publish(new ModuleStop(this)); + system.publish(new ModuleStop(this)); + } + + public void testEntryPointReferenceNotFound() throws Exception { + // create a test module + Component moduleComponent = MockFactory.createCompositeComponent("module"); + runtime.registerModelObject(moduleComponent); + + Component component = factory.createSystemComponent("NoService", ModuleScopeSystemComponent.class, ModuleScopeSystemComponentImpl.class, Scope.MODULE); + // do not register the above component! + + CompositeContextImpl moduleContext = (CompositeContextImpl) runtime.getContext("module"); + EntryPoint epSystemBinding = MockFactory.createEPSystemBinding("TestServiceEP", ModuleScopeSystemComponent.class, "NoReference", component); + moduleContext.registerModelObject(epSystemBinding); + + moduleContext.publish(new ModuleStart(this)); + try { + moduleContext.locateService("TestServiceEP"); + fail("Expected " + ServiceNotFoundException.class.getName()); + } catch (ServiceNotFoundException e) { + // expected + } + moduleContext.publish(new ModuleStop(this)); + } + + /** + * Test two module components that have external services wired to entry points contained in each + */ + public void testCircularWires() throws Exception { + // create a test modules + Component module1 = MockFactory.createCompositeComponent("module1"); + runtime.registerModelObject(module1); + Component module2 = MockFactory.createCompositeComponent("module2"); + runtime.registerModelObject(module2); + + CompositeContextImpl moduleContext1 = (CompositeContextImpl) runtime.getContext("module1"); + CompositeContextImpl moduleContext2 = (CompositeContextImpl) runtime.getContext("module2"); + + Component component1 = factory.createSystemComponent("Component1", ModuleScopeSystemComponent.class, ModuleScopeSystemComponentImpl.class, Scope.MODULE); + EntryPoint entryPoint1 = MockFactory.createEPSystemBinding("EntryPoint1", ModuleScopeSystemComponent.class, "Component1", component1); + ExternalService externalService1 = MockFactory.createESSystemBinding("ExternalService1", "module2/EntryPoint2"); + moduleContext1.registerModelObject(component1); + moduleContext1.registerModelObject(entryPoint1); + moduleContext1.registerModelObject(externalService1); + + Component component2 = factory.createSystemComponent("Component2", ModuleScopeSystemComponent.class, ModuleScopeSystemComponentImpl.class, Scope.MODULE); + EntryPoint entryPoint2 = MockFactory.createEPSystemBinding("EntryPoint2", ModuleScopeSystemComponent.class, "Component2", component2); + ExternalService externalService2 = MockFactory.createESSystemBinding("ExternalService2", "module1/EntryPoint1"); + moduleContext2.registerModelObject(component2); + moduleContext2.registerModelObject(entryPoint2); + moduleContext2.registerModelObject(externalService2); + + moduleContext1.publish(new ModuleStart(this)); + moduleContext2.publish(new ModuleStart(this)); + Assert.assertNotNull(moduleContext2.getContext("ExternalService2").getInstance(null)); + Assert.assertNotNull(moduleContext1.getContext("ExternalService1").getInstance(null)); + } + + /** + * Tests that a circular reference between an external service in one module and an entry point in another + * is caught as an error condition FIXME this must be implemented + */ + public void testInterModuleCircularReference() throws Exception { + // create a test modules + Component module1 = MockFactory.createCompositeComponent("module1"); + runtime.registerModelObject(module1); + Component module2 = MockFactory.createCompositeComponent("module2"); + runtime.registerModelObject(module2); + + CompositeContextImpl moduleContext1 = (CompositeContextImpl) runtime.getContext("module1"); + CompositeContextImpl moduleContext2 = (CompositeContextImpl) runtime.getContext("module2"); + ExternalService externalService1 = MockFactory.createESSystemBinding("ExternalService1", "module2/EntryPoint2"); + EntryPoint entryPoint1 = MockFactory.createEPSystemBinding("EntryPoint1", ModuleScopeSystemComponent.class, + "ExternalService1", externalService1); + ExternalService externalService2 = MockFactory.createESSystemBinding("ExternalService2", "module1/EntryPoint1"); + EntryPoint entryPoint2 = MockFactory.createEPSystemBinding("EntryPoint2", ModuleScopeSystemComponent.class, + "ExternalService2", externalService2); + try { + // FIXME this should throw a circular reference exception + moduleContext1.registerModelObject(externalService1); + moduleContext1.registerModelObject(entryPoint1); + moduleContext2.registerModelObject(externalService2); + moduleContext2.registerModelObject(entryPoint2); + // FIXME implement fail("Expected " + ConfigurationException.class.getName()); + } catch (ConfigurationException e) { + // expected + } + } + + public void testRuntimeBuilderAutowire() throws Exception { + + + CompositeContext system = runtime.getSystemContext(); + Component builder = factory.createSystemComponent("TestBuilder", ContextFactoryBuilder.class, TestBuilder.class, Scope.MODULE); + builder.getImplementation().setComponentType(MockFactory.getIntrospector().introspect(TestBuilder.class)); + system.registerModelObject(builder); + system.publish(new ModuleStart(this)); + Component module1 = MockFactory.createCompositeComponent("module1"); + runtime.registerModelObject(module1); + runtime.getContext("module1"); + Assert.assertTrue(((TestBuilder) system.getContext("TestBuilder").getInstance(null)).invoked()); + system.publish(new ModuleStop(this)); + } + + protected void setUp() throws Exception { + super.setUp(); + monitorFactory = new NullMonitorFactory(); + builderRegistry = BootstrapHelper.bootstrapContextFactoryBuilders(monitorFactory); + factory = new SystemAssemblyFactoryImpl(); + + runtime = new RuntimeContextImpl(monitorFactory, builderRegistry, null); + runtime.start(); + } + + protected void tearDown() throws Exception { + runtime.stop(); + super.tearDown(); + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/runtime/SystemBootstrapTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/runtime/SystemBootstrapTestCase.java new file mode 100644 index 0000000000..45af495239 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/runtime/SystemBootstrapTestCase.java @@ -0,0 +1,127 @@ +/** + * + * 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 junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.tuscany.common.monitor.impl.NullMonitorFactory; +import org.apache.tuscany.core.builder.ContextFactoryBuilderRegistry; +import org.apache.tuscany.core.client.BootstrapHelper; +import org.apache.tuscany.core.context.AutowireContext; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.event.ModuleStart; +import org.apache.tuscany.core.context.event.ModuleStop; +import org.apache.tuscany.core.context.impl.CompositeContextImpl; +import org.apache.tuscany.core.mock.MockFactory; +import org.apache.tuscany.core.mock.component.GenericSystemComponent; +import org.apache.tuscany.core.mock.component.ModuleScopeSystemComponent; +import org.apache.tuscany.core.mock.component.ModuleScopeSystemComponentImpl; +import org.apache.tuscany.core.system.assembly.SystemAssemblyFactory; +import org.apache.tuscany.core.system.assembly.impl.SystemAssemblyFactoryImpl; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.EntryPoint; +import org.apache.tuscany.model.assembly.ExternalService; +import org.apache.tuscany.model.assembly.Module; +import org.apache.tuscany.model.assembly.Service; +import org.apache.tuscany.model.types.java.JavaServiceContract; + +/** + * Tests bootstrapping a system module + * + * @version $Rev: 385834 $ $Date: 2006-03-14 08:57:08 -0800 (Tue, 14 Mar 2006) $ + */ +public class SystemBootstrapTestCase extends TestCase { + private ContextFactoryBuilderRegistry builderRegistry; + + private SystemAssemblyFactory factory = new SystemAssemblyFactoryImpl(); + + /** + * Simulates booting a runtime process + */ + public void testBoot() throws Exception { + RuntimeContext runtimeContext = new RuntimeContextImpl(new NullMonitorFactory(), builderRegistry,null); + runtimeContext.start(); + + CompositeContext systemContext = runtimeContext.getSystemContext(); + Assert.assertNotNull(systemContext); + Module systemModule = MockFactory.createSystemModule(); + // MockSystemAssemblyFactory.buildModule(systemModule, systemContext); + systemContext.registerModelObject(systemModule); + + // create a test module + Component moduleComponent = MockFactory.createCompositeComponent("module"); + runtimeContext.registerModelObject(moduleComponent); + CompositeContextImpl moduleContext = (CompositeContextImpl) runtimeContext.getContext("module"); + Assert.assertNotNull(moduleContext); + ExternalService es = MockFactory.createESSystemBinding("TestServiceES", "tuscany.system/TestService1EP"); + moduleContext.registerModelObject(es); + + // start the modules and test inter-module system wires + systemContext.publish(new ModuleStart(this)); + moduleContext.publish(new ModuleStart(this)); + + Assert.assertNotNull(systemContext.getContext("TestService1EP").getInstance(null)); + GenericSystemComponent testService = (GenericSystemComponent) systemContext.getContext("TestService1").getInstance(null); + Assert.assertNotNull(testService); + GenericSystemComponent testES = (GenericSystemComponent) moduleContext.getContext("TestServiceES").getInstance(null); + Assert.assertNotNull(testES); + Assert.assertSame(testService, testES); + } + + public void testRuntimeBoot() throws Exception { + RuntimeContext runtime = new RuntimeContextImpl(new NullMonitorFactory(), builderRegistry,null); + runtime.start(); + runtime.getRootContext(); + + CompositeContext system = runtime.getSystemContext(); + system.registerModelObject(MockFactory.createSystemModule()); + system.registerModelObject(MockFactory.createSystemCompositeComponent("module2")); + CompositeContext systemModule2 = (CompositeContext) system.getContext("module2"); + systemModule2.registerModelObject(MockFactory.createSystemChildModule()); + + EntryPoint ep = MockFactory.createEPSystemBinding("TestService2EP", ModuleScopeSystemComponent.class, "ref"); + ep.getBindings().add(factory.createSystemBinding()); + Service service = factory.createService(); + service.setName("module2/TestService2EP"); + JavaServiceContract inter = factory.createJavaServiceContract(); + inter.setInterface(ModuleScopeSystemComponentImpl.class); + service.setServiceContract(inter); + ep.getConfiguredReference().getTargetConfiguredServices().get(0).setPort(service); + system.registerModelObject(ep); + system.publish(new ModuleStart(this)); + Assert.assertNotNull(system.getContext("TestService1").getInstance(null)); + Assert.assertNotNull(system.getContext("TestService2EP").getInstance(null)); + + Assert.assertNotNull(((AutowireContext) system).resolveInstance(ModuleScopeSystemComponent.class)); + // create a test module + Component moduleComponent = MockFactory.createCompositeComponent("test.module"); + runtime.registerModelObject(moduleComponent); + CompositeContextImpl moduleContext = (CompositeContextImpl) runtime.getContext("test.module"); + Assert.assertNotNull(moduleContext); + ExternalService es = MockFactory.createESSystemBinding("TestService2ES", "tuscany.system/TestService2EP"); + moduleContext.registerModelObject(es); + moduleContext.publish(new ModuleStart(this)); + Assert.assertNotNull(moduleContext.getContext("TestService2ES").getInstance(null)); + + moduleContext.publish(new ModuleStop(this)); + system.publish(new ModuleStop(this)); + runtime.stop(); + } + + protected void setUp() throws Exception { + super.setUp(); + builderRegistry = BootstrapHelper.bootstrapContextFactoryBuilders(null); + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/builder/MonitorInjectionTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/builder/MonitorInjectionTestCase.java new file mode 100644 index 0000000000..fe6bff635a --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/builder/MonitorInjectionTestCase.java @@ -0,0 +1,106 @@ +/** + * + * Copyright 2006 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.system.builder; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.tuscany.common.monitor.MonitorFactory; +import org.apache.tuscany.core.builder.ContextFactory; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.Context; +import org.apache.tuscany.core.context.impl.CompositeContextImpl; +import org.apache.tuscany.core.context.impl.EventContextImpl; +import org.apache.tuscany.core.context.scope.DefaultScopeStrategy; +import org.apache.tuscany.core.mock.MockConfigContext; +import org.apache.tuscany.core.mock.MockFactory; +import org.apache.tuscany.core.system.annotation.Monitor; +import org.apache.tuscany.core.system.assembly.SystemAssemblyFactory; +import org.apache.tuscany.core.system.assembly.impl.SystemAssemblyFactoryImpl; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.Scope; + +/** + * @version $Rev$ $Date$ + */ +public class MonitorInjectionTestCase extends TestCase { + private SystemContextFactoryBuilder builder; + private Component component; + + public static interface TestService { + } + + public static class TestComponent implements TestService { + @Monitor + protected Monitor1 monitor1; + Monitor2 monitor2; + + @Monitor + public void setMonitor2(Monitor2 monitor2) { + this.monitor2 = monitor2; + } + } + + public static interface Monitor1 { + } + + public static interface Monitor2 { + } + + public void testMonitorInjection() { + builder.build(component); + ContextFactory contextFactory = (ContextFactory) component.getContextFactory(); + Assert.assertNotNull(contextFactory); + contextFactory.prepare(createContext()); + Context ctx = contextFactory.createContext(); + + ctx.start(); + TestComponent instance = (TestComponent) ctx.getInstance(null); + assertSame(MONITOR1, instance.monitor1); + assertSame(MONITOR2, instance.monitor2); + } + + protected void setUp() throws Exception { + super.setUp(); + SystemAssemblyFactory factory = new SystemAssemblyFactoryImpl(); + MockMonitorFactory monitorFactory = new MockMonitorFactory(); + builder = new SystemContextFactoryBuilder(monitorFactory); + component = factory.createSystemComponent("test", TestService.class, TestComponent.class, Scope.MODULE); + component.getImplementation().setComponentType(MockFactory.getIntrospector().introspect(TestComponent.class)); + } + + private static final Monitor1 MONITOR1 = new Monitor1() { + }; + private static final Monitor2 MONITOR2 = new Monitor2() { + }; + + public static class MockMonitorFactory implements MonitorFactory { + public T getMonitor(Class monitorInterface) { + if (Monitor1.class.equals(monitorInterface)) { + return monitorInterface.cast(MONITOR1); + } else if (Monitor2.class.equals(monitorInterface)) { + return monitorInterface.cast(MONITOR2); + } else { + throw new AssertionError(); + } + } + } + + private static CompositeContext createContext() { + return new CompositeContextImpl("test.parent", null, new DefaultScopeStrategy(), new EventContextImpl(), new MockConfigContext(null)); + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/builder/SystemComponentImpl.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/builder/SystemComponentImpl.java new file mode 100644 index 0000000000..3398a010e9 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/builder/SystemComponentImpl.java @@ -0,0 +1,167 @@ +/** + * + * 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.context.CompositeContext; +import org.apache.tuscany.core.context.AutowireContext; +import org.apache.tuscany.core.context.ConfigurationContext; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.core.system.annotation.ParentContext; +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Scope; + +/** + * A system component used for unit testing + * + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class SystemComponentImpl { + + @Autowire + protected ConfigurationContext ctx; + + @ParentContext + protected CompositeContext parent; + + @Autowire + protected AutowireContext autowireCtx; + + private ConfigurationContext ctxSetter; + + private CompositeContext parentSetter; + + private AutowireContext autowireCtxSetter; + + public ConfigurationContext getConfigContext() { + return ctx; + } + + public CompositeContext getParentContext() { + return parent; + } + + public AutowireContext getAutowireContext() { + return autowireCtx; + } + + @Autowire + public void setConfigContext(ConfigurationContext configCtx) { + ctxSetter = configCtx; + } + + public ConfigurationContext getConfigContextSetter() { + return ctxSetter; + } + + @ParentContext + public void setParentContex(CompositeContext ctx) { + parentSetter = ctx; + } + + public CompositeContext getParentContextSetter() { + return parentSetter; + } + + @Autowire + public void setAutowireContext(AutowireContext ctx) { + autowireCtxSetter = ctx; + } + + public AutowireContext getAutowireContextSetter() { + return autowireCtx; + } + + private boolean inited; + + @Init + public void init(){ + inited=true; + } + + public boolean initialized(){ + return (inited); + } + + private boolean destroyed; + + @Destroy + public void destroy(){ + destroyed=true; + } + + public boolean destroyed(){ + return (destroyed); + } + + @Property + protected int testInt; + + public int getTestInt(){ + return testInt; + } + + @Property + protected double testDouble; + + public double getTestDouble(){ + return testDouble; + } + + @Property + protected float testFloat; + + public float getTestFloat(){ + return testFloat; + } + + @Property + protected short testShort; + + public short getTestShort(){ + return testShort; + } + + @Property + protected boolean testBoolean; + + public boolean getTestBoolean(){ + return testBoolean; + } + + @Property + protected byte testByte; + + public byte getTestByte(){ + return testByte; + } + + @Property + protected char testChar; + + public char getTestChar(){ + return testChar; + } + + @Property + protected String testString; + + public String getTestString(){ + return testString; + } + + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/builder/SystemContextFactoryBuilderTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/builder/SystemContextFactoryBuilderTestCase.java new file mode 100644 index 0000000000..f7543911a6 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/builder/SystemContextFactoryBuilderTestCase.java @@ -0,0 +1,173 @@ +/** + * + * 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 junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.tuscany.core.builder.ContextFactory; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.Context; +import org.apache.tuscany.core.context.AtomicContext; +import org.apache.tuscany.core.context.impl.CompositeContextImpl; +import org.apache.tuscany.core.context.impl.EventContextImpl; +import org.apache.tuscany.core.context.scope.DefaultScopeStrategy; +import org.apache.tuscany.core.mock.MockConfigContext; +import org.apache.tuscany.core.mock.MockFactory; +import org.apache.tuscany.core.system.assembly.SystemAssemblyFactory; +import org.apache.tuscany.core.system.assembly.SystemImplementation; +import org.apache.tuscany.core.system.assembly.impl.SystemAssemblyFactoryImpl; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.ConfiguredProperty; +import org.apache.tuscany.model.assembly.Property; +import org.apache.tuscany.model.assembly.Scope; +import org.apache.tuscany.model.assembly.Service; +import org.apache.tuscany.model.assembly.ComponentType; +import org.apache.tuscany.model.types.java.JavaServiceContract; + +/** + * Tests to system components are built properly + * + * @version $Rev$ $Date$ + */ +public class SystemContextFactoryBuilderTestCase extends TestCase { + + private SystemAssemblyFactory factory = new SystemAssemblyFactoryImpl(); + + public void testComponentContextBuilder() throws Exception { + SystemContextFactoryBuilder builder = new SystemContextFactoryBuilder(null); + Component component = factory.createSystemComponent("test", null, SystemComponentImpl.class, Scope.AGGREGATE); + component.getImplementation().setComponentType(MockFactory.getIntrospector().introspect(SystemComponentImpl.class)); + ConfiguredProperty cProp = factory.createConfiguredProperty(); + Property prop = factory.createProperty(); + prop.setName("testInt"); + cProp.setValue(1); + cProp.setProperty(prop); + component.getConfiguredProperties().add(cProp); + + cProp = factory.createConfiguredProperty(); + prop = factory.createProperty(); + prop.setName("testString"); + cProp.setValue("test"); + cProp.setProperty(prop); + component.getConfiguredProperties().add(cProp); + + cProp = factory.createConfiguredProperty(); + prop = factory.createProperty(); + prop.setName("testDouble"); + cProp.setValue(1d); + cProp.setProperty(prop); + component.getConfiguredProperties().add(cProp); + + cProp = factory.createConfiguredProperty(); + prop = factory.createProperty(); + prop.setName("testFloat"); + cProp.setValue(1f); + cProp.setProperty(prop); + component.getConfiguredProperties().add(cProp); + + cProp = factory.createConfiguredProperty(); + prop = factory.createProperty(); + prop.setName("testShort"); + cProp.setValue((short) 1); + cProp.setProperty(prop); + component.getConfiguredProperties().add(cProp); + + cProp = factory.createConfiguredProperty(); + prop = factory.createProperty(); + prop.setName("testByte"); + cProp.setValue((byte) 1); + cProp.setProperty(prop); + component.getConfiguredProperties().add(cProp); + + cProp = factory.createConfiguredProperty(); + prop = factory.createProperty(); + prop.setName("testBoolean"); + cProp.setValue(Boolean.TRUE); + cProp.setProperty(prop); + component.getConfiguredProperties().add(cProp); + + cProp = factory.createConfiguredProperty(); + prop = factory.createProperty(); + prop.setName("testChar"); + cProp.setValue('1'); + cProp.setProperty(prop); + component.getConfiguredProperties().add(cProp); + + builder.build(component); + ContextFactory contextFactory = (ContextFactory) component.getContextFactory(); + Assert.assertNotNull(contextFactory); + contextFactory.prepare(createContext()); + AtomicContext ctx = contextFactory.createContext(); + + ctx.start(); + SystemComponentImpl instance = (SystemComponentImpl) ctx.getInstance(null); + Assert.assertNotNull(instance.getConfigContext()); + Assert.assertNotNull(instance.getParentContext()); + Assert.assertNotNull(instance.getAutowireContext()); + Assert.assertNotNull(instance.getConfigContextSetter()); + Assert.assertNotNull(instance.getParentContextSetter()); + Assert.assertNotNull(instance.getAutowireContextSetter()); + Assert.assertEquals(1, instance.getTestInt()); + Assert.assertEquals(1d, instance.getTestDouble()); + Assert.assertEquals(1f, instance.getTestFloat()); + Assert.assertEquals((short) 1, instance.getTestShort()); + Assert.assertTrue(instance.getTestBoolean()); + Assert.assertEquals('1', instance.getTestChar()); + Assert.assertEquals((byte) 1, instance.getTestByte()); + Assert.assertEquals("test", instance.getTestString()); + + Assert.assertTrue(instance.initialized()); + ctx.destroy(); + ctx.stop(); + Assert.assertTrue(instance.destroyed()); + } + + + public void testDefaultScopeIsModuleScope() throws Exception { + SystemContextFactoryBuilder builder = new SystemContextFactoryBuilder(null); + Component component = createSystemComponentWithNoScope("test", null, SystemComponentImpl.class); + builder.build(component); + ContextFactory contextFactory = (ContextFactory) component.getContextFactory(); + Assert.assertEquals(Scope.MODULE, contextFactory.getScope()); + } + + + + + private static CompositeContext createContext() { + return new CompositeContextImpl("test.parent", null, new DefaultScopeStrategy(), new EventContextImpl(), + new MockConfigContext(null)); + } + + private Component createSystemComponentWithNoScope(String name, Class service, Class impl) { + JavaServiceContract jsc = factory.createJavaServiceContract(); + jsc.setInterface(service); + Service s = factory.createService(); + s.setServiceContract(jsc); + + ComponentType componentType = factory.createComponentType(); + componentType.getServices().add(s); + + SystemImplementation sysImpl = factory.createSystemImplementation(); + sysImpl.setImplementationClass(impl); + sysImpl.setComponentType(componentType); + + Component sc = factory.createSimpleComponent(); + sc.setName(name); + sc.setImplementation(sysImpl); + return sc; + } + + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/builder/impl/AssemblyVisitorTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/builder/impl/AssemblyVisitorTestCase.java new file mode 100644 index 0000000000..3d63664848 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/builder/impl/AssemblyVisitorTestCase.java @@ -0,0 +1,136 @@ +/** + * + * 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.impl; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.tuscany.core.builder.BuilderException; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.core.builder.impl.AssemblyVisitorImpl; +import org.apache.tuscany.core.mock.component.ModuleScopeSystemComponent; +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.core.system.assembly.impl.SystemAssemblyFactoryImpl; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.model.assembly.AssemblyObject; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.ComponentType; +import org.apache.tuscany.model.assembly.ConfiguredPort; +import org.apache.tuscany.model.assembly.ConfiguredReference; +import org.apache.tuscany.model.assembly.ConfiguredService; +import org.apache.tuscany.model.assembly.ContextFactoryHolder; +import org.apache.tuscany.model.assembly.EntryPoint; +import org.apache.tuscany.model.assembly.Module; +import org.apache.tuscany.model.assembly.Reference; +import org.apache.tuscany.model.assembly.Service; +import org.apache.tuscany.model.assembly.impl.AssemblyContextImpl; +import org.apache.tuscany.model.types.java.JavaServiceContract; + +/** + * Tests decorating a logical configuration model + * + * @version $Rev$ $Date$ + */ +public class AssemblyVisitorTestCase extends TestCase { + + private static final Object MARKER = new Object(); + + private SystemAssemblyFactory factory = new SystemAssemblyFactoryImpl(); + private AssemblyContext assemblyContext = new AssemblyContextImpl(factory, null, null); + + public void testModelVisit() throws Exception { + ComponentType componentType; + Service service; + SystemImplementation impl; + Component component; + + Module module = factory.createModule(); + + // create target component + componentType = factory.createComponentType(); + service = factory.createService(); + service.setName("target"); + componentType.getServices().add(service); + impl = factory.createSystemImplementation(); + impl.setComponentType(componentType); + component = factory.createSimpleComponent(); + component.setName("target"); + component.setImplementation(impl); + component.initialize(assemblyContext); + module.getComponents().add(component); + + // create source component + componentType = factory.createComponentType(); + Reference ref = factory.createReference(); + ref.setName("ref"); + componentType.getReferences().add(ref); + impl = factory.createSystemImplementation(); + impl.setComponentType(componentType); + component = factory.createSimpleComponent(); + component.setName("source"); + component.setImplementation(impl); + ConfiguredReference cRef = factory.createConfiguredReference("ref", "target"); + component.getConfiguredReferences().add(cRef); + component.initialize(assemblyContext); + module.getComponents().add(component); + + EntryPoint ep = factory.createEntryPoint(); + JavaServiceContract contract = factory.createJavaServiceContract(); + contract.setInterface(ModuleScopeSystemComponent.class); + service = factory.createService(); + service.setServiceContract(contract); + ConfiguredService cService = factory.createConfiguredService(); + cService.setPort(service); + cService.initialize(assemblyContext); + ep.setConfiguredService(cService); + SystemBinding binding = factory.createSystemBinding(); + ep.getBindings().add(binding); + ConfiguredReference cEpRef = factory.createConfiguredReference(); + Reference epRef = factory.createReference(); + cEpRef.setPort(epRef); + ep.setConfiguredReference(cEpRef); + ep.initialize(assemblyContext); + module.getEntryPoints().add(ep); + + List builders = new ArrayList(); + builders.add(new TestBuilder()); + AssemblyVisitorImpl visitor = new AssemblyVisitorImpl(builders); + module.initialize(assemblyContext); + visitor.start(module); + + Assert.assertSame(MARKER, component.getContextFactory()); + Assert.assertSame(MARKER, cRef.getProxyFactory()); + Assert.assertSame(MARKER, ep.getContextFactory()); + Assert.assertSame(MARKER, cEpRef.getProxyFactory()); + + } + + private static class TestBuilder implements ContextFactoryBuilder { + public void build(AssemblyObject model) throws BuilderException { + if (model instanceof ConfiguredPort) { + ((ConfiguredPort) model).setProxyFactory(MARKER); + } + if (model instanceof ContextFactoryHolder) { + ((ContextFactoryHolder) model).setContextFactory(MARKER); + } + } + + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/AutowireTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/AutowireTestCase.java new file mode 100644 index 0000000000..6316fe3a67 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/AutowireTestCase.java @@ -0,0 +1,310 @@ +/** + * + * 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 junit.framework.TestCase; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.SystemCompositeContext; +import org.apache.tuscany.core.context.impl.CompositeContextImpl; +import org.apache.tuscany.core.context.event.ModuleStop; +import org.apache.tuscany.core.context.event.ModuleStart; +import org.apache.tuscany.core.mock.MockFactory; +import org.apache.tuscany.core.mock.component.AutowireSourceImpl; +import org.apache.tuscany.core.mock.component.Source; +import org.apache.tuscany.core.mock.component.Target; +import org.apache.tuscany.core.mock.component.TargetImpl; +import org.apache.tuscany.core.runtime.RuntimeContext; +import org.apache.tuscany.core.system.assembly.SystemAssemblyFactory; +import org.apache.tuscany.core.system.assembly.impl.SystemAssemblyFactoryImpl; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.EntryPoint; +import org.apache.tuscany.model.assembly.Module; +import org.apache.tuscany.model.assembly.ModuleComponent; +import org.apache.tuscany.model.assembly.Scope; +import org.apache.tuscany.model.assembly.Service; +import org.apache.tuscany.model.assembly.impl.AssemblyContextImpl; + +/** + * Tests autowiring for serveral scenarios according to the following runtime scheme: + * + * + * tuscany.runtime + * | + * + tuscany.system + * | | + * | + system1 + * | | | + * | | + system1a + * | | + * | + system2 + * | + * + tuscany.root + * | + * + app1 + * | + * + app1a + * | + * + app1b + * + * + * @version $Rev$ $Date$ + */ +public class AutowireTestCase extends TestCase { + + private static SystemAssemblyFactory systemFactory = new SystemAssemblyFactoryImpl(); + + /** + * Covers the case where a component in app1a requests autowire, which is resolved by the runtime to a service + * exposed on an entry point in tuscany.system. The entry point is wired to an entry point on system1, which itself + * is wired to a component in system1 + */ + public void testScenario1() throws Exception { + RuntimeContext runtime = createScenario1Runtime(); + CompositeContext root = runtime.getRootContext(); + SystemCompositeContext system = runtime.getSystemContext(); + CompositeContext system1 = (CompositeContext) system.getContext("system1"); + system1.publish(new ModuleStart(this)); + Target target = (Target) system.getContext("target.system.ep").getInstance(null); + assertNotNull(target); + CompositeContext app1 = (CompositeContext) root.getContext("app1"); + app1.publish(new ModuleStart(this)); + CompositeContext app1a = (CompositeContext) app1.getContext("app1a"); + app1a.publish(new ModuleStart(this)); + app1a.publish(new ModuleStop(this)); + app1.publish(new ModuleStop(this)); + Source source = (Source) app1a.getContext("source").getInstance(null); + assertEquals(target, source.getTarget()); + source.getTarget().getString(); + runtime.stop(); + } + + /** + * Covers the case where a component in app1a requests autowire, which is resolved to service exposed as an entry + * point on app1b. The entry point is wired to a component in app1b. + */ + public void testScenario2() throws Exception { + RuntimeContext runtime = createScenario2Runtime(); + CompositeContext root = runtime.getRootContext(); + CompositeContext app1 = (CompositeContext) root.getContext("app1"); + app1.publish(new ModuleStart(this)); + CompositeContext app1b = (CompositeContext) app1.getContext("app1b"); + app1b.publish(new ModuleStart(this)); + CompositeContext app1a = (CompositeContext) app1.getContext("app1a"); + app1a.publish(new ModuleStart(this)); + Target target = (Target) app1b.getContext("target.ep").getInstance(null); + assertNotNull(target); + Source source = (Source) app1a.getContext("source").getInstance(null); + assertEquals(target, source.getTarget()); + source.getTarget().getString(); + runtime.stop(); + } + + /** + * Covers the case where a component in system1a requests autowire, which is resolved to an entry point exposed on + * system2. The entry point is wired to a component in system2. + */ + public void testScenario3() throws Exception { + RuntimeContext runtime = createScenario3Runtime(); + SystemCompositeContext system = runtime.getSystemContext(); + + CompositeContext system2 = (CompositeContext) system.getContext("system2"); + system2.publish(new ModuleStart(this)); + Target target = (Target) system2.getContext("target.ep").getInstance(null); + assertNotNull(target); + + CompositeContext system1 = (CompositeContext) system.getContext("system1"); + system1.publish(new ModuleStart(this)); + CompositeContext system1a = (CompositeContext) system1.getContext("system1a"); + system1a.publish(new ModuleStart(this)); + + Source source = (Source) system1a.getContext("source").getInstance(null); + assertEquals(target, source.getTarget()); + source.getTarget().getString(); + runtime.stop(); + } + + /** + * Covers the case where a component in system1a requests autowire, which is resolved to component in its parent, + * system1. + */ + public void testScenario4() throws Exception { + RuntimeContext runtime = createScenario4Runtime(); + SystemCompositeContext system = runtime.getSystemContext(); + CompositeContext system1 = (CompositeContext) system.getContext("system1"); + system1.publish(new ModuleStart(this)); + Target target = (Target) system1.getContext("target").getInstance(null); + assertNotNull(target); + CompositeContext system1a = (CompositeContext) system1.getContext("system1a"); + system1a.publish(new ModuleStart(this)); + + Source source = (Source) system1a.getContext("source").getInstance(null); + assertEquals(target, source.getTarget()); + source.getTarget().getString(); + runtime.stop(); + } + + /** + * Covers the case where a component in system1a requests autowire, which is resolved to component in the parent of + * its parent (grandparent), system. + */ + public void testScenario5() throws Exception { + RuntimeContext runtime = createScenario5Runtime(); + SystemCompositeContext system = runtime.getSystemContext(); + CompositeContext system1 = (CompositeContext) system.getContext("system1"); + system1.publish(new ModuleStart(this)); + Target target = (Target) system.getContext("target").getInstance(null); + assertNotNull(target); + CompositeContext system1a = (CompositeContext) system1.getContext("system1a"); + system1a.publish(new ModuleStart(this)); + + Source source = (Source) system1a.getContext("source").getInstance(null); + assertEquals(target, source.getTarget()); + source.getTarget().getString(); + runtime.stop(); + } + + private RuntimeContext createScenario1Runtime() throws Exception { + RuntimeContext runtime = MockFactory.createCoreRuntime(); + runtime.start(); + SystemCompositeContext system = runtime.getSystemContext(); + ModuleComponent system1Component = MockFactory.createSystemCompositeComponent("system1"); + ModuleComponent system1aComponent = MockFactory.createSystemCompositeComponent("system1a"); + system1Component.getImplementation().getComponents().add(system1aComponent); + Component target = MockFactory.createSystemComponent("target", Target.class, TargetImpl.class, Scope.MODULE); + system1Component.getImplementation().getComponents().add(target); + + EntryPoint ep = MockFactory.createEPSystemBinding("target.ep", Target.class, "target", target); + system1Component.getImplementation().getEntryPoints().add(ep); + system.registerModelObject(system1Component); + EntryPoint systemEp = MockFactory.createEPSystemBinding("target.system.ep", Target.class, "ref"); + + systemEp.getBindings().add(systemFactory.createSystemBinding()); + Service service = systemFactory.createService(); + service.setName("system1/target.ep"); + (systemEp.getConfiguredReference().getTargetConfiguredServices().get(0)).setPort(service); + + system.registerModelObject(systemEp); + ModuleComponent app1Component = createAppModuleComponent("app1"); + ModuleComponent app1aComponent = createAppModuleComponent("app1a"); + Component source = MockFactory.createSystemComponent("source", Source.class, AutowireSourceImpl.class, Scope.MODULE); + app1aComponent.getImplementation().getComponents().add(source); + app1Component.getImplementation().getComponents().add(app1aComponent); + CompositeContext root = runtime.getRootContext(); + root.registerModelObject(app1Component); + system.publish(new ModuleStart(this)); + return runtime; + } + + private RuntimeContext createScenario2Runtime() throws Exception { + RuntimeContext runtime = MockFactory.createCoreRuntime(); + runtime.start(); + + ModuleComponent app1Component = createAppModuleComponent("app1"); + ModuleComponent app1aComponent = createAppModuleComponent("app1a"); + ModuleComponent app1bComponent = createAppModuleComponent("app1b"); + Component source = MockFactory.createSystemComponent("source", Source.class, AutowireSourceImpl.class, Scope.MODULE); + app1aComponent.getImplementation().getComponents().add(source); + app1Component.getImplementation().getComponents().add(app1aComponent); + app1Component.getImplementation().getComponents().add(app1bComponent); + + Component target = MockFactory.createSystemComponent("target", Target.class, TargetImpl.class, Scope.MODULE); + app1bComponent.getImplementation().getComponents().add(target); + + EntryPoint ep = MockFactory.createEPSystemBinding("target.ep", Target.class, "target", target); + ep.getBindings().add(systemFactory.createSystemBinding()); + Service service = systemFactory.createService(); + service.setName("target.ep"); + ep.getConfiguredReference().getTargetConfiguredServices().get(0).setPort(service); + app1bComponent.getImplementation().getEntryPoints().add(ep); + + CompositeContext root = runtime.getRootContext(); + root.registerModelObject(app1Component); + return runtime; + } + + private RuntimeContext createScenario3Runtime() throws Exception { + RuntimeContext runtime = MockFactory.createCoreRuntime(); + runtime.start(); + SystemCompositeContext system = runtime.getSystemContext(); + ModuleComponent system1Component = MockFactory.createSystemCompositeComponent("system1"); + ModuleComponent system2Component = MockFactory.createSystemCompositeComponent("system2"); + ModuleComponent system1aComponent = MockFactory.createSystemCompositeComponent("system1a"); + system1Component.getImplementation().getComponents().add(system1aComponent); + + Component target = MockFactory.createSystemComponent("target", Target.class, TargetImpl.class, Scope.MODULE); + system2Component.getImplementation().getComponents().add(target); + EntryPoint ep = MockFactory.createEPSystemBinding("target.ep", Target.class, "target", target); + system2Component.getImplementation().getEntryPoints().add(ep); + system.registerModelObject(system2Component); + + Component source = MockFactory.createSystemComponent("source", Source.class, AutowireSourceImpl.class, Scope.MODULE); + system1aComponent.getImplementation().getComponents().add(source); + system.registerModelObject(system1Component); + system.publish(new ModuleStart(this)); + return runtime; + } + + private RuntimeContext createScenario4Runtime() throws Exception { + RuntimeContext runtime = MockFactory.createCoreRuntime(); + runtime.start(); + SystemCompositeContext system = runtime.getSystemContext(); + ModuleComponent system1Component = MockFactory.createSystemCompositeComponent("system1"); + ModuleComponent system1aComponent = MockFactory.createSystemCompositeComponent("system1a"); + system1Component.getImplementation().getComponents().add(system1aComponent); + + Component target = MockFactory.createSystemComponent("target", Target.class, TargetImpl.class, Scope.MODULE); + system1Component.getImplementation().getComponents().add(target); + + Component source = MockFactory.createSystemComponent("source", Source.class, AutowireSourceImpl.class, Scope.MODULE); + system1aComponent.getImplementation().getComponents().add(source); + system.registerModelObject(system1Component); + system.publish(new ModuleStart(this)); + return runtime; + } + + private RuntimeContext createScenario5Runtime() throws Exception { + RuntimeContext runtime = MockFactory.createCoreRuntime(); + runtime.start(); + SystemCompositeContext system = runtime.getSystemContext(); + ModuleComponent system1Component = MockFactory.createSystemCompositeComponent("system1"); + ModuleComponent system1aComponent = MockFactory.createSystemCompositeComponent("system1a"); + system1Component.getImplementation().getComponents().add(system1aComponent); + + Component target = MockFactory.createSystemComponent("target", Target.class, TargetImpl.class, Scope.MODULE); + system.registerModelObject(target); + + Component source = MockFactory.createSystemComponent("source", Source.class, AutowireSourceImpl.class, Scope.MODULE); + system1aComponent.getImplementation().getComponents().add(source); + system.registerModelObject(system1Component); + system.publish(new ModuleStart(this)); + return runtime; + } + + private ModuleComponent createAppModuleComponent(String name) throws ConfigurationLoadException { + AssemblyContext assemblyContext = new AssemblyContextImpl(systemFactory, null, null); + ModuleComponent mc = systemFactory.createModuleComponent(); + mc.setName(name); + Module module = systemFactory.createModule(); + module.setImplementationClass(CompositeContextImpl.class); + module.setComponentType(MockFactory.getComponentType()); + module.setName(name); + module.initialize(assemblyContext); + mc.setImplementation(module); + return mc; + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/CompositeNestingTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/CompositeNestingTestCase.java new file mode 100644 index 0000000000..27ffc5794e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/CompositeNestingTestCase.java @@ -0,0 +1,98 @@ +/** + * + * 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 junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.event.ModuleStart; +import org.apache.tuscany.core.context.event.ModuleStop; +import org.apache.tuscany.core.mock.MockFactory; +import org.apache.tuscany.core.mock.component.Source; +import org.apache.tuscany.core.mock.component.Target; +import org.apache.tuscany.core.runtime.RuntimeContext; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.model.assembly.ModuleComponent; +import org.apache.tuscany.model.assembly.Scope; + +/** + * Tests registering arbirarily deep child composite contexts + * + * @version $Rev$ $Date$ + */ +public class CompositeNestingTestCase extends TestCase { + + /** + * Tests registration of a 3-level deep hierarchy under the top-level system composite context + */ + public void testSystemContext() throws Exception { + RuntimeContext runtime = MockFactory.createCoreRuntime(); + ModuleComponent child1 = createHierarchy(); + runtime.getSystemContext().registerModelObject(child1); + CompositeContext child1Ctx = (CompositeContext) runtime.getSystemContext().getContext("child1"); + Assert.assertNotNull(child1Ctx); + child1Ctx.publish(new ModuleStart(this)); + analyzeLeafComponents(child1Ctx); + CompositeContext child2Ctx = (CompositeContext) child1Ctx.getContext("child2"); + Assert.assertNotNull(child2Ctx); + child2Ctx.publish(new ModuleStart(this)); + analyzeLeafComponents(child2Ctx); + CompositeContext child3Ctx = (CompositeContext) child2Ctx.getContext("child3"); + Assert.assertNotNull(child3Ctx); + child3Ctx.publish(new ModuleStart(this)); + analyzeLeafComponents(child3Ctx); + + Assert.assertNull(child1Ctx.getContext("child3")); // sanity check + } + + /** + * Tests registration of a 3-level deep hierarchy under the root application composite context + */ + public void testRootContext() throws Exception { + RuntimeContext runtime = MockFactory.createCoreRuntime(); + ModuleComponent child1 = createHierarchy(); + runtime.getRootContext().registerModelObject(child1); + CompositeContext child1Ctx = (CompositeContext) runtime.getRootContext().getContext("child1"); + Assert.assertNotNull(child1Ctx); + child1Ctx.publish(new ModuleStart(this)); + analyzeLeafComponents(child1Ctx); + CompositeContext child2Ctx = (CompositeContext) child1Ctx.getContext("child2"); + Assert.assertNotNull(child2Ctx); + child2Ctx.publish(new ModuleStart(this)); + analyzeLeafComponents(child2Ctx); + CompositeContext child3Ctx = (CompositeContext) child2Ctx.getContext("child3"); + Assert.assertNotNull(child3Ctx); + child3Ctx.publish(new ModuleStart(this)); + analyzeLeafComponents(child3Ctx); + + Assert.assertNull(child1Ctx.getContext("child3")); // sanity check + child1Ctx.publish(new ModuleStop(this)); + } + + private ModuleComponent createHierarchy() throws ConfigurationLoadException { + ModuleComponent child3 = MockFactory.createSystemModuleComponentWithWiredComponents("child3", Scope.MODULE, Scope.MODULE); + ModuleComponent child2 = MockFactory.createSystemModuleComponentWithWiredComponents("child2", Scope.MODULE, Scope.MODULE); + child2.getImplementation().getComponents().add(child3); + ModuleComponent child1 = MockFactory.createSystemModuleComponentWithWiredComponents("child1", Scope.MODULE, Scope.MODULE); + child1.getImplementation().getComponents().add(child2); + return child1; + } + + private void analyzeLeafComponents(CompositeContext ctx) throws Exception { + Source source = (Source) ctx.getContext("source").getInstance(null); + Assert.assertNotNull(source); + Target target = source.getTarget(); + Assert.assertNotNull(target); + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/IntraCompositeWireTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/IntraCompositeWireTestCase.java new file mode 100644 index 0000000000..a956263cc8 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/IntraCompositeWireTestCase.java @@ -0,0 +1,125 @@ +/** + * + * 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 junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.tuscany.core.context.AtomicContext; +import org.apache.tuscany.core.context.SystemCompositeContext; +import org.apache.tuscany.core.context.event.ModuleStart; +import org.apache.tuscany.core.context.event.ModuleStop; +import org.apache.tuscany.core.mock.MockConfigContext; +import org.apache.tuscany.core.mock.MockFactory; +import org.apache.tuscany.core.mock.component.Source; +import org.apache.tuscany.core.mock.component.Target; +import org.apache.tuscany.model.assembly.Scope; + +import java.util.List; + +/** + * Tests intra-composite system component wiring scenarios + * + * @version $Rev$ $Date$ + */ +public class IntraCompositeWireTestCase extends TestCase { + + public void testModuleToModuleScope() throws Exception { + SystemCompositeContext context = createContext(); + context.start(); + context.registerModelObject(MockFactory.createSystemModuleWithWiredComponents("system.module",Scope.MODULE, Scope.MODULE)); + context.publish(new ModuleStart(this)); + Source source = (Source) ((AtomicContext) context.getContext("source")).getTargetInstance(); + Assert.assertNotNull(source); + Target targetRef = source.getTarget(); + Assert.assertNotNull(targetRef); + Target target = (Target) ((AtomicContext) context.getContext("target")).getTargetInstance(); + Assert.assertSame(target, targetRef); + Assert.assertSame(target, source.getTarget()); + context.publish(new ModuleStop(this)); + context.stop(); + } + + public void testStatelessToModuleScope() throws Exception { + SystemCompositeContext context = createContext(); + context.start(); + context.registerModelObject(MockFactory.createSystemModuleWithWiredComponents("system.module",Scope.INSTANCE, Scope.MODULE)); + context.publish(new ModuleStart(this)); + Source source = (Source) ((AtomicContext) context.getContext("source")).getTargetInstance(); + Assert.assertNotNull(source); + Target targetRef = source.getTarget(); + Assert.assertNotNull(targetRef); + source = (Source) ((AtomicContext) context.getContext("source")).getTargetInstance(); + Target target = (Target) ((AtomicContext) context.getContext("target")).getTargetInstance(); + Assert.assertSame(target, targetRef); + Assert.assertSame(target, source.getTarget()); + context.publish(new ModuleStop(this)); + context.stop(); + } + + public void testModuleToStatelessScope() throws Exception { + SystemCompositeContext context = createContext(); + context.start(); + context.registerModelObject(MockFactory.createSystemModuleWithWiredComponents("system.module",Scope.MODULE, Scope.INSTANCE)); + context.publish(new ModuleStart(this)); + Source source = (Source) ((AtomicContext) context.getContext("source")).getTargetInstance(); + Assert.assertNotNull(source); + Target targetRef = source.getTarget(); + Assert.assertNotNull(targetRef); + Target target = (Target) ((AtomicContext) context.getContext("target")).getTargetInstance(); + Assert.assertNotSame(target, targetRef); + Source source2 = (Source) ((AtomicContext) context.getContext("source")).getTargetInstance(); + // should be the same since the module scope component was alreadyy created and the stateless + // component will be "attached" to it + Assert.assertSame(source.getTarget(), source2.getTarget()); + context.publish(new ModuleStop(this)); + context.stop(); + } + + public void testMultiplicity() throws Exception { + SystemCompositeContext context = createContext(); + context.start(); + context.registerModelObject(MockFactory.createSystemModuleWithWiredComponents("system.module",Scope.MODULE, Scope.MODULE)); + context.publish(new ModuleStart(this)); + Source source = (Source) ((AtomicContext) context.getContext("source")).getTargetInstance(); + Assert.assertNotNull(source); + Target target = (Target) ((AtomicContext) context.getContext("target")).getTargetInstance(); + Assert.assertNotNull(target); + // test setter injection + List targets = source.getTargets(); + Assert.assertEquals(1,targets.size()); + assertSame(target,targets.get(0)); + + // test field injection + targets = source.getTargetsThroughField(); + Assert.assertEquals(1,targets.size()); + assertSame(target,targets.get(0)); + + // test array injection + Target[] targetArray = source.getArrayOfTargets(); + Assert.assertEquals(1,targetArray.length); + assertSame(target,targetArray[0]); + + + } + + private SystemCompositeContext createContext() { + SystemCompositeContextImpl context = new SystemCompositeContextImpl(); + context.setName("system.context"); + context.setConfigurationContext(new MockConfigContext(MockFactory.createSystemBuilders())); + return context; + } + + + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/SystemCompositeComponentContextTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/SystemCompositeComponentContextTestCase.java new file mode 100644 index 0000000000..75208f47b6 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/SystemCompositeComponentContextTestCase.java @@ -0,0 +1,108 @@ +/** + * + * 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 junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.core.context.event.ModuleStart; +import org.apache.tuscany.core.context.event.ModuleStop; +import org.apache.tuscany.core.context.impl.EventContextImpl; +import org.apache.tuscany.core.mock.MockConfigContext; +import org.apache.tuscany.core.mock.MockFactory; +import org.apache.tuscany.core.mock.component.ModuleScopeSystemComponent; +import org.apache.tuscany.core.mock.component.ModuleScopeSystemComponentImpl; +import org.apache.tuscany.core.system.assembly.SystemAssemblyFactory; +import org.apache.tuscany.core.system.assembly.impl.SystemAssemblyFactoryImpl; +import org.apache.tuscany.model.assembly.Component; +import org.apache.tuscany.model.assembly.EntryPoint; +import org.apache.tuscany.model.assembly.Scope; + +import java.util.List; + +/** + * Tests the system composite context + * + * @version $Rev$ $Date$ + */ +public class SystemCompositeComponentContextTestCase extends TestCase { + private SystemAssemblyFactory factory; + private SystemCompositeContextImpl system; + + public void testChildLocate() throws Exception { + system.start(); + Component compositeComponent = MockFactory.createCompositeComponent("system.child"); + system.registerModelObject(compositeComponent); + CompositeContext childContext = (CompositeContext) system.getContext("system.child"); + Assert.assertNotNull(childContext); + + Component component = factory.createSystemComponent("TestService1", ModuleScopeSystemComponent.class, ModuleScopeSystemComponentImpl.class, Scope.MODULE); + EntryPoint ep = MockFactory.createEPSystemBinding("TestService1EP", ModuleScopeSystemComponent.class, "TestService1", component); + childContext.registerModelObject(component); + childContext.registerModelObject(ep); + childContext.publish(new ModuleStart(this)); + Assert.assertNotNull(system.getContext("system.child").getInstance(new QualifiedName("./TestService1EP"))); + childContext.publish(new ModuleStop(this)); + } + + public void testAutowireRegisterBeforeStart() throws Exception { + Component component = factory.createSystemComponent("TestService1", ModuleScopeSystemComponent.class, ModuleScopeSystemComponentImpl.class, Scope.MODULE); + EntryPoint ep = MockFactory.createEPSystemBinding("TestService1EP", ModuleScopeSystemComponent.class, "TestService1", component); + system.registerModelObject(component); + system.registerModelObject(ep); + system.start(); + system.publish(new ModuleStart(this)); + Assert.assertSame(system.getContext("TestService1EP").getInstance(null), system.resolveInstance(ModuleScopeSystemComponent.class)); + } + + public void testAutowireRegisterAfterStart() throws Exception { + Component component = factory.createSystemComponent("TestService1", ModuleScopeSystemComponent.class, ModuleScopeSystemComponentImpl.class, Scope.MODULE); + system.registerModelObject(component); + system.start(); + system.publish(new ModuleStart(this)); + EntryPoint ep = MockFactory.createEPSystemBinding("TestService1EP", ModuleScopeSystemComponent.class, "TestService1", component); + system.registerModelObject(ep); + Assert.assertSame(system.getContext("TestService1EP").getInstance(null), system.resolveInstance(ModuleScopeSystemComponent.class)); + } + + public void testAutowireModuleRegisterBeforeStart() throws Exception { + system.registerModelObject(MockFactory.createSystemModule()); + system.start(); + system.publish(new ModuleStart(this)); + Assert.assertSame(system.getContext("TestService1EP").getInstance(null), system.resolveInstance(ModuleScopeSystemComponent.class)); + } + + public void testAutowireModuleRegisterAfterStart() throws Exception { + system.start(); + system.publish(new ModuleStart(this)); + system.registerModelObject(MockFactory.createSystemModule()); + Assert.assertSame(system.getContext("TestService1EP").getInstance(null), system.resolveInstance(ModuleScopeSystemComponent.class)); + } + + protected void setUp() throws Exception { + super.setUp(); + factory = new SystemAssemblyFactoryImpl(); + List builders = MockFactory.createSystemBuilders(); + + system = new SystemCompositeContextImpl("system", null, null, new SystemScopeStrategy(), new EventContextImpl(), new MockConfigContext(builders)); + } + + protected void tearDown() throws Exception { + system.publish(new ModuleStop(this)); + system.stop(); + super.tearDown(); + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/SystemCompositeContextRegisterTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/SystemCompositeContextRegisterTestCase.java new file mode 100644 index 0000000000..4397e39bec --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/SystemCompositeContextRegisterTestCase.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.context; + +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.core.context.CompositeContextRegisterTestCase; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.impl.EventContextImpl; +import org.apache.tuscany.core.context.scope.DefaultScopeStrategy; +import org.apache.tuscany.core.mock.MockConfigContext; +import org.apache.tuscany.core.mock.MockFactory; + +import java.util.List; + +/** + * Tests registration of model objects for an system composite context + * + * @version $Rev$ $Date$ + */ +public class SystemCompositeContextRegisterTestCase extends CompositeContextRegisterTestCase { + + protected CompositeContext createContext() { + List builders = MockFactory.createSystemBuilders(); + return new SystemCompositeContextImpl("test.context", null, null, new DefaultScopeStrategy(), new EventContextImpl(), new MockConfigContext(builders)); + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/SystemCompositeHierarchyTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/SystemCompositeHierarchyTestCase.java new file mode 100644 index 0000000000..ba7a3ba5da --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/SystemCompositeHierarchyTestCase.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.system.context; + +import junit.framework.Assert; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.core.context.AbstractCompositeHierarchyTests; +import org.apache.tuscany.core.context.CompositeContext; +import org.apache.tuscany.core.context.impl.EventContextImpl; +import org.apache.tuscany.core.context.scope.DefaultScopeStrategy; +import org.apache.tuscany.core.mock.MockConfigContext; +import org.apache.tuscany.core.mock.MockFactory; + +import java.util.List; + +/** + * Performs testing of various hierarchical scenarios + * + * @version $Rev$ $Date$ + */ +public class SystemCompositeHierarchyTestCase extends AbstractCompositeHierarchyTests { + + + + protected CompositeContext createContextHierachy() throws Exception { + List mockBuilders = MockFactory.createSystemBuilders(); + CompositeContext parent = new SystemCompositeContextImpl("test.parent", null, null, new DefaultScopeStrategy(), new EventContextImpl(), new MockConfigContext(mockBuilders)); + parent.registerModelObject(MockFactory.createCompositeComponent("test.child")); + parent.start(); + CompositeContext child = (CompositeContext) parent.getContext("test.child"); + Assert.assertNotNull(child); + return parent; + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/SystemObjectRegistrationTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/SystemObjectRegistrationTestCase.java new file mode 100644 index 0000000000..241346e24f --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/SystemObjectRegistrationTestCase.java @@ -0,0 +1,84 @@ +/** + * + * 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.system.context; + +import junit.framework.TestCase; +import org.apache.tuscany.core.config.ConfigurationException; +import org.apache.tuscany.core.context.SystemCompositeContext; +import org.apache.tuscany.core.context.DuplicateNameException; +import org.apache.tuscany.core.context.event.ModuleStart; +import org.apache.tuscany.core.runtime.RuntimeContext; +import org.apache.tuscany.core.runtime.RuntimeContextImpl; +import org.apache.tuscany.core.builder.ContextFactoryBuilderRegistry; +import org.apache.tuscany.core.builder.impl.DefaultWireBuilder; +import org.apache.tuscany.core.client.BootstrapHelper; +import org.apache.tuscany.common.monitor.MonitorFactory; +import org.apache.tuscany.common.monitor.impl.NullMonitorFactory; + +/** + * @version $Rev$ $Date$ + */ +public class SystemObjectRegistrationTestCase extends TestCase { + private RuntimeContext runtime; + private SystemCompositeContext systemContext; + + public void testRegistration() throws ConfigurationException { + MockComponent instance = new MockComponent(); + systemContext.registerJavaObject("foo", MockComponent.class, instance); + assertSame(instance, systemContext.getContext("foo").getInstance(null)); + } + + public void testDuplicateRegistration() throws ConfigurationException { + MockComponent instance = new MockComponent(); + systemContext.registerJavaObject("foo", MockComponent.class, instance); + try { + systemContext.registerJavaObject("foo", MockComponent.class, instance); + fail(); + } catch (DuplicateNameException e) { + // ok + } + } + + public void testAutowireToObject() throws ConfigurationException { + MockComponent instance = new MockComponent(); + systemContext.registerJavaObject("foo", MockComponent.class, instance); + assertSame(instance, systemContext.resolveInstance(MockComponent.class)); + assertNull(systemContext.resolveExternalInstance(MockComponent.class)); + } + + protected void setUp() throws Exception { + super.setUp(); + MonitorFactory monitorFactory = new NullMonitorFactory(); + ContextFactoryBuilderRegistry builderRegistry = BootstrapHelper.bootstrapContextFactoryBuilders(monitorFactory); + DefaultWireBuilder wireBuilder = new DefaultWireBuilder(); + runtime = new RuntimeContextImpl(monitorFactory, builderRegistry, wireBuilder); + runtime.start(); + systemContext = runtime.getSystemContext(); + systemContext.publish(new ModuleStart(this)); + } + + protected void tearDown() throws Exception { + runtime.stop(); + super.tearDown(); + } + + private static class MockComponent { + public String hello(String message) { + return message; + } + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/TestBuilder.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/TestBuilder.java new file mode 100644 index 0000000000..c531c8f7f9 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/system/context/TestBuilder.java @@ -0,0 +1,55 @@ +/** + * + * 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.system.context; + +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Scope; + +import org.apache.tuscany.core.builder.BuilderException; +import org.apache.tuscany.core.builder.ContextFactoryBuilder; +import org.apache.tuscany.core.builder.ContextFactoryBuilderRegistry; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.model.assembly.AssemblyObject; + +@Scope("MODULE") +public class TestBuilder implements ContextFactoryBuilder { + private ContextFactoryBuilderRegistry builderRegistry; + + private boolean invoked = false; + + public TestBuilder() { + super(); + } + + @Init(eager = true) + public void init() { + builderRegistry.register(this); + } + + @Autowire + public void setBuilderRegistry(ContextFactoryBuilderRegistry builderRegistry) { + this.builderRegistry = builderRegistry; + } + + public void build(AssemblyObject object) throws BuilderException { + invoked = true; + } + + public boolean invoked() { + return invoked; + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationErrorTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationErrorTestCase.java new file mode 100644 index 0000000000..5e4b3e2f9e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationErrorTestCase.java @@ -0,0 +1,155 @@ +/** + * + * 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.wire; + +import junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.tuscany.core.wire.impl.InvokerInterceptor; +import org.apache.tuscany.core.wire.impl.MessageChannelImpl; +import org.apache.tuscany.core.wire.mock.MockHandler; +import org.apache.tuscany.core.wire.mock.SimpleTarget; +import org.apache.tuscany.core.wire.mock.MockSyncInterceptor; +import org.apache.tuscany.core.wire.mock.SimpleTargetImpl; +import org.apache.tuscany.core.wire.mock.MockStaticInvoker; +import org.apache.tuscany.core.message.Message; +import org.apache.tuscany.core.message.MessageFactory; +import org.apache.tuscany.core.message.impl.MessageFactoryImpl; + +import java.lang.reflect.Method; + +/** + * Tests error propagation through an innvocation + * + * @version $Rev$ $Date$ + */ +public class InvocationConfigurationErrorTestCase extends TestCase { + + + private Method hello; + + private MessageFactory factory = new MessageFactoryImpl(); + + public InvocationConfigurationErrorTestCase() { + super(); + } + + public InvocationConfigurationErrorTestCase(String arg0) { + super(arg0); + } + + public void setUp() throws Exception { + hello = SimpleTarget.class.getMethod("hello", String.class); + } + + public void testInvokeWithHandlers() throws Exception{ + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + MockHandler sourceRequestHandler = new MockHandler(); + MockHandler sourceResponseHandler = new MockHandler(); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addRequestHandler(sourceRequestHandler); + source.addResponseHandler(sourceResponseHandler); + source.addInterceptor(sourceInterceptor); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + MockHandler targetRequestHandler = new MockHandler(); + MockHandler targetResponseHandler = new MockHandler(); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addRequestHandler(targetRequestHandler); + target.addResponseHandler(targetResponseHandler); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + // connect the source to the target + source.setTargetRequestChannel(new MessageChannelImpl(target.getRequestHandlers())); + source.setTargetResponseChannel(new MessageChannelImpl(target.getResponseHandlers())); + source.build(); + target.build(); + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Message msg = factory.createMessage(); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + Assert.assertTrue(response.getBody() instanceof IllegalArgumentException); + Assert.assertEquals(1,sourceRequestHandler.getCount()); + Assert.assertEquals(1,sourceResponseHandler.getCount()); + Assert.assertEquals(1,sourceInterceptor.getCount()); + Assert.assertEquals(1,targetRequestHandler.getCount()); + Assert.assertEquals(1,targetResponseHandler.getCount()); + Assert.assertEquals(1,targetInterceptor.getCount()); + } + + public void testInvokeWithRequestHandlers() throws Exception{ + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + MockHandler sourceRequestHandler = new MockHandler(); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addRequestHandler(sourceRequestHandler); + source.addInterceptor(sourceInterceptor); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + MockHandler targetRequestHandler = new MockHandler(); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addRequestHandler(targetRequestHandler); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + // connect the source to the target + source.setTargetRequestChannel(new MessageChannelImpl(target.getRequestHandlers())); + source.setTargetResponseChannel(new MessageChannelImpl(target.getResponseHandlers())); + source.build(); + target.build(); + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Message msg = factory.createMessage(); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + Assert.assertTrue(response.getBody() instanceof IllegalArgumentException); + Assert.assertEquals(1,sourceRequestHandler.getCount()); + Assert.assertEquals(1,sourceInterceptor.getCount()); + Assert.assertEquals(1,targetRequestHandler.getCount()); + Assert.assertEquals(1,targetInterceptor.getCount()); + } + + /** + * Tests basic wiring of a source to a target, including handlers and interceptors + */ + public void testInvokeWithInterceptorsOnly() throws Exception{ + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addInterceptor(sourceInterceptor); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + // connect the source to the target + source.setTargetInterceptor(target.getHeadInterceptor()); + source.build(); + target.build(); + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Message msg = factory.createMessage(); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + Assert.assertTrue(response.getBody() instanceof IllegalArgumentException); + Assert.assertEquals(1,sourceInterceptor.getCount()); + Assert.assertEquals(1,targetInterceptor.getCount()); + + } + +} + diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationTestCase.java new file mode 100644 index 0000000000..0519573439 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/InvocationConfigurationTestCase.java @@ -0,0 +1,153 @@ +/** + * + * 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.wire; + +import junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.tuscany.core.wire.impl.InvokerInterceptor; +import org.apache.tuscany.core.wire.impl.MessageChannelImpl; +import org.apache.tuscany.core.wire.mock.SimpleTarget; +import org.apache.tuscany.core.wire.mock.MockHandler; +import org.apache.tuscany.core.wire.mock.MockSyncInterceptor; +import org.apache.tuscany.core.wire.mock.MockStaticInvoker; +import org.apache.tuscany.core.wire.mock.SimpleTargetImpl; +import org.apache.tuscany.core.message.Message; +import org.apache.tuscany.core.message.MessageFactory; +import org.apache.tuscany.core.message.impl.MessageFactoryImpl; + +import java.lang.reflect.Method; + +public class InvocationConfigurationTestCase extends TestCase { + + private Method hello; + + + private MessageFactory factory = new MessageFactoryImpl(); + + public InvocationConfigurationTestCase() { + super(); + } + + public InvocationConfigurationTestCase(String arg0) { + super(arg0); + } + + public void setUp() throws Exception { + hello = SimpleTarget.class.getMethod("hello", String.class); + } + + /** + * Tests basic wiring of a source to a target, including handlers and interceptors + */ + public void testInvokeWithHandlers() throws Exception { + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + MockHandler sourceRequestHandler = new MockHandler(); + MockHandler sourceResponseHandler = new MockHandler(); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addRequestHandler(sourceRequestHandler); + source.addResponseHandler(sourceResponseHandler); + source.addInterceptor(sourceInterceptor); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + MockHandler targetRequestHandler = new MockHandler(); + MockHandler targetResponseHandler = new MockHandler(); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addRequestHandler(targetRequestHandler); + target.addResponseHandler(targetResponseHandler); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + // connect the source to the target + source.setTargetRequestChannel(new MessageChannelImpl(target.getRequestHandlers())); + source.setTargetResponseChannel(new MessageChannelImpl(target.getResponseHandlers())); + source.build(); + target.build(); + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Message msg = factory.createMessage(); + msg.setBody("foo"); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + Assert.assertEquals("foo", response.getBody()); + Assert.assertEquals(1, sourceRequestHandler.getCount()); + Assert.assertEquals(1, sourceResponseHandler.getCount()); + Assert.assertEquals(1, sourceInterceptor.getCount()); + Assert.assertEquals(1, targetRequestHandler.getCount()); + Assert.assertEquals(1, targetResponseHandler.getCount()); + Assert.assertEquals(1, targetInterceptor.getCount()); + } + + public void testInvokeWithRequestHandlers() throws Exception { + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + MockHandler sourceRequestHandler = new MockHandler(); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addRequestHandler(sourceRequestHandler); + source.addInterceptor(sourceInterceptor); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + MockHandler targetRequestHandler = new MockHandler(); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addRequestHandler(targetRequestHandler); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + // connect the source to the target + source.setTargetRequestChannel(new MessageChannelImpl(target.getRequestHandlers())); + source.setTargetResponseChannel(new MessageChannelImpl(target.getResponseHandlers())); + source.build(); + target.build(); + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Message msg = factory.createMessage(); + msg.setBody("foo"); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + Assert.assertEquals("foo", response.getBody()); + Assert.assertEquals(1, sourceRequestHandler.getCount()); + Assert.assertEquals(1, sourceInterceptor.getCount()); + Assert.assertEquals(1, targetRequestHandler.getCount()); + Assert.assertEquals(1, targetInterceptor.getCount()); + } + + /** + * Tests basic wiring of a source to a target, including handlers and interceptors + */ + public void testInvokeWithInterceptorsOnly() throws Exception { + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addInterceptor(sourceInterceptor); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(hello); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + // connect the source to the target + source.setTargetInterceptor(target.getHeadInterceptor()); + source.build(); + target.build(); + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Message msg = factory.createMessage(); + msg.setBody("foo"); + msg.setTargetInvoker(invoker); + Message response = source.getHeadInterceptor().invoke(msg); + Assert.assertEquals("foo", response.getBody()); + Assert.assertEquals(1, sourceInterceptor.getCount()); + Assert.assertEquals(1, targetInterceptor.getCount()); + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/InvocationErrorTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/InvocationErrorTestCase.java new file mode 100644 index 0000000000..1d04e18757 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/InvocationErrorTestCase.java @@ -0,0 +1,122 @@ +/** + * + * 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.wire; + +import junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.tuscany.core.wire.impl.InvokerInterceptor; +import org.apache.tuscany.core.wire.jdk.JDKInvocationHandler; +import org.apache.tuscany.core.wire.mock.MockHandler; +import org.apache.tuscany.core.wire.mock.MockStaticInvoker; +import org.apache.tuscany.core.wire.mock.MockSyncInterceptor; +import org.apache.tuscany.core.message.impl.MessageFactoryImpl; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Map; + +/** + * Tests handling of exceptions thrown during an wire + * + * @version $Rev: 377006 $ $Date: 2006-02-11 09:41:59 -0800 (Sat, 11 Feb 2006) $ + */ +public class InvocationErrorTestCase extends TestCase { + + private Method checkedMethod; + private Method runtimeMethod; + + public InvocationErrorTestCase() { + super(); + } + + public InvocationErrorTestCase(String arg0) { + super(arg0); + } + + public void setUp() throws Exception { + checkedMethod = TestBean.class.getDeclaredMethod("checkedException", (Class[]) null); + runtimeMethod = TestBean.class.getDeclaredMethod("runtimeException", (Class[]) null); + Assert.assertNotNull(checkedMethod); + Assert.assertNotNull(runtimeMethod); + } + + public void testCheckedException() throws Exception { + Map config = new MethodHashMap(); + config.put(checkedMethod, getConfiguration(checkedMethod)); + InvocationHandler handler = new JDKInvocationHandler(new MessageFactoryImpl(), config); + try { + TestBean proxy = (TestBean) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), + new Class[]{TestBean.class}, handler); + proxy.checkedException(); + } catch (TestException e) { + return; + } + Assert.fail(TestException.class.getName() + " should have been thrown"); + } + + public void testRuntimeException() throws Exception { + Map config = new MethodHashMap(); + config.put(runtimeMethod, getConfiguration(runtimeMethod)); + InvocationHandler handler = new JDKInvocationHandler(new MessageFactoryImpl(), config); + try { + TestBean proxy = (TestBean) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), + new Class[]{TestBean.class}, handler); + proxy.runtimeException(); + } catch (TestRuntimeException e) { + return; + } + Assert.fail(TestException.class.getName() + " should have been thrown"); + } + + private InvocationConfiguration getConfiguration(Method m) { + MockStaticInvoker invoker = new MockStaticInvoker(m, new TestBeanImpl()); + SourceInvocationConfiguration invocationConfiguration=new SourceInvocationConfiguration(m); + invocationConfiguration.addInterceptor(new MockSyncInterceptor()); + invocationConfiguration.addRequestHandler(new MockHandler()); + invocationConfiguration.setTargetInvoker(invoker); + invocationConfiguration.setTargetInterceptor(new InvokerInterceptor()); + invocationConfiguration.build(); + return invocationConfiguration; + } + + public interface TestBean { + + public void checkedException() throws TestException; + + public void runtimeException() throws TestRuntimeException; + + } + + public class TestBeanImpl implements TestBean { + + public void checkedException() throws TestException { + throw new TestException(); + } + + public void runtimeException() throws TestRuntimeException { + throw new TestRuntimeException(); + } + } + + public class TestException extends Exception { + } + + public class TestRuntimeException extends RuntimeException { + } + +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandlerTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandlerTestCase.java new file mode 100644 index 0000000000..28a2da23b5 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKInvocationHandlerTestCase.java @@ -0,0 +1,126 @@ +/** + * + * 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.wire.jdk; + +import junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.tuscany.core.wire.InvocationConfiguration; +import org.apache.tuscany.core.wire.MethodHashMap; +import org.apache.tuscany.core.wire.SourceInvocationConfiguration; +import org.apache.tuscany.core.wire.TargetInvocationConfiguration; +import org.apache.tuscany.core.wire.mock.SimpleTarget; +import org.apache.tuscany.core.wire.mock.SimpleTargetImpl; +import org.apache.tuscany.core.wire.mock.MockStaticInvoker; +import org.apache.tuscany.core.wire.mock.MockHandler; +import org.apache.tuscany.core.wire.mock.MockSyncInterceptor; +import org.apache.tuscany.core.wire.impl.InvokerInterceptor; +import org.apache.tuscany.core.wire.impl.MessageChannelImpl; +import org.apache.tuscany.core.message.impl.MessageFactoryImpl; + +import java.lang.reflect.Method; +import java.util.Map; + +public class JDKInvocationHandlerTestCase extends TestCase { + + private Method hello; + + public JDKInvocationHandlerTestCase() { + super(); + } + + public JDKInvocationHandlerTestCase(String arg0) { + super(arg0); + } + + public void setUp() throws Exception { + hello = SimpleTarget.class.getMethod("hello", String.class); + } + + public void testBasicInvoke() throws Throwable { + Map configs = new MethodHashMap(); + configs.put(hello, getInvocationHandler(hello)); + JDKInvocationHandler handler = new JDKInvocationHandler(new MessageFactoryImpl(), configs); + Assert.assertEquals("foo", handler.invoke(null, hello, new Object[] { "foo" })); + } + + public void testErrorInvoke() throws Throwable { + Map configs = new MethodHashMap(); + configs.put(hello, getInvocationHandler(hello)); + JDKInvocationHandler handler = new JDKInvocationHandler(new MessageFactoryImpl(), configs); + try { + Assert.assertEquals("foo", handler.invoke(null, hello, new Object[] {})); + fail("Expected " + IllegalArgumentException.class.getName()); + } catch (IllegalArgumentException e) { + // should throw + } + } + + public void testDirectErrorInvoke() throws Throwable { + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Map configs = new MethodHashMap(); + configs.put(hello, source); + JDKInvocationHandler handler = new JDKInvocationHandler(new MessageFactoryImpl(), configs); + try { + Assert.assertEquals("foo", handler.invoke(null, hello, new Object[] {})); + fail("Expected " + IllegalArgumentException.class.getName()); + } catch (IllegalArgumentException e) { + // should throw + } + } + + public void testDirectInvoke() throws Throwable { + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + MockStaticInvoker invoker = new MockStaticInvoker(hello, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + + Map configs = new MethodHashMap(); + configs.put(hello, source); + JDKInvocationHandler handler = new JDKInvocationHandler(new MessageFactoryImpl(), configs); + Assert.assertEquals("foo", handler.invoke(null, hello, new Object[] { "foo" })); + } + + private InvocationConfiguration getInvocationHandler(Method m) { + SourceInvocationConfiguration source = new SourceInvocationConfiguration(m); + MockHandler sourceRequestHandler = new MockHandler(); + MockHandler sourceResponseHandler = new MockHandler(); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addRequestHandler(sourceRequestHandler); + source.addResponseHandler(sourceResponseHandler); + source.addInterceptor(sourceInterceptor); + + TargetInvocationConfiguration target = new TargetInvocationConfiguration(m); + MockHandler targetRequestHandler = new MockHandler(); + MockHandler targetResponseHandler = new MockHandler(); + MockSyncInterceptor targetInterceptor = new MockSyncInterceptor(); + target.addRequestHandler(targetRequestHandler); + target.addResponseHandler(targetResponseHandler); + target.addInterceptor(targetInterceptor); + target.addInterceptor(new InvokerInterceptor()); + + // connect the source to the target + source.setTargetRequestChannel(new MessageChannelImpl(target.getRequestHandlers())); + source.setTargetResponseChannel(new MessageChannelImpl(target.getResponseHandlers())); + source.build(); + target.build(); + MockStaticInvoker invoker = new MockStaticInvoker(m, new SimpleTargetImpl()); + source.setTargetInvoker(invoker); + return source; + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKWireFactoryFactoryTestCase.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKWireFactoryFactoryTestCase.java new file mode 100644 index 0000000000..60f8cf837d --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/jdk/JDKWireFactoryFactoryTestCase.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.wire.jdk; + +import junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.core.wire.MethodHashMap; +import org.apache.tuscany.core.wire.WireSourceConfiguration; +import org.apache.tuscany.core.wire.SourceInvocationConfiguration; +import org.apache.tuscany.core.wire.TargetInvocationConfiguration; +import org.apache.tuscany.core.wire.WireTargetConfiguration; +import org.apache.tuscany.core.wire.impl.InvokerInterceptor; +import org.apache.tuscany.core.wire.mock.MockStaticInvoker; +import org.apache.tuscany.core.wire.mock.MockSyncInterceptor; +import org.apache.tuscany.core.wire.mock.SimpleTarget; +import org.apache.tuscany.core.wire.mock.SimpleTargetImpl; +import org.apache.tuscany.core.message.impl.MessageFactoryImpl; + +import java.lang.reflect.Method; +import java.util.Map; + +public class JDKWireFactoryFactoryTestCase extends TestCase { + + private Method hello; + + public JDKWireFactoryFactoryTestCase(String arg0) { + super(arg0); + } + + public void setUp() throws Exception { + hello = SimpleTarget.class.getMethod("hello", String.class); + } + + public void testSourceWireFactory() throws Exception { + SourceInvocationConfiguration source = new SourceInvocationConfiguration(hello); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addInterceptor(sourceInterceptor); + source.setTargetInterceptor(new InvokerInterceptor()); + source.setTargetInvoker(new MockStaticInvoker(hello, new SimpleTargetImpl())); + source.build(); + Map configs = new MethodHashMap(); + configs.put(hello, source); + WireSourceConfiguration config = new WireSourceConfiguration("foo",new QualifiedName("foo"), configs, Thread.currentThread() + .getContextClassLoader(), new MessageFactoryImpl()); + JDKSourceWireFactory factory = new JDKSourceWireFactory(); + factory.setConfiguration(config); + factory.setBusinessInterface(SimpleTarget.class); + factory.initialize(); + SimpleTarget instance = (SimpleTarget) factory.createProxy(); + Assert.assertEquals("foo",instance.hello("foo")); + } + + public void testTargetWireFactory() throws Exception { + TargetInvocationConfiguration source = new TargetInvocationConfiguration(hello); + MockSyncInterceptor sourceInterceptor = new MockSyncInterceptor(); + source.addInterceptor(sourceInterceptor); + source.addInterceptor(new InvokerInterceptor()); + source.setTargetInvoker(new MockStaticInvoker(hello, new SimpleTargetImpl())); + source.build(); + Map configs = new MethodHashMap(); + configs.put(hello, source); + WireTargetConfiguration config = new WireTargetConfiguration(new QualifiedName("foo"), configs, Thread.currentThread() + .getContextClassLoader(), new MessageFactoryImpl()); + JDKTargetWireFactory factory = new JDKTargetWireFactory(); + factory.setConfiguration(config); + factory.setBusinessInterface(SimpleTarget.class); + factory.initialize(); + SimpleTarget instance = (SimpleTarget) factory.createProxy(); + Assert.assertEquals("foo",instance.hello("foo")); + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/MockHandler.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/MockHandler.java new file mode 100644 index 0000000000..9def6b5b0e --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/MockHandler.java @@ -0,0 +1,38 @@ +/** + * + * 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.wire.mock; + +import org.apache.tuscany.core.wire.MessageHandler; +import org.apache.tuscany.core.message.Message; + +/** + * + */ +public class MockHandler implements MessageHandler { + + private int count =0; + + public boolean processMessage(Message message) { + //System.out.println("Invoking handler"); + count++; + return true; + } + + public int getCount(){ + return count; + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/MockScopeContext.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/MockScopeContext.java new file mode 100644 index 0000000000..915885549a --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/MockScopeContext.java @@ -0,0 +1,131 @@ +/** + * + * 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.wire.mock; + +import org.apache.tuscany.core.builder.ContextFactory; +import org.apache.tuscany.core.context.ScopeContext; +import org.apache.tuscany.core.context.RuntimeEventListener; +import org.apache.tuscany.core.context.ContextRuntimeException; +import org.apache.tuscany.core.context.AtomicContext; +import org.apache.tuscany.core.context.ScopeRuntimeException; +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.core.context.Context; +import org.apache.tuscany.core.context.EventFilter; +import org.apache.tuscany.core.context.event.Event; +import org.apache.tuscany.model.assembly.AtomicComponent; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class MockScopeContext implements ScopeContext { + + Map components; + + public MockScopeContext() { + components = new HashMap(); + components.put("foo", new SimpleTargetImpl()); + components.put("bar", new SimpleTargetImpl()); + } + + public MockScopeContext(Map instances) { + components = instances; + } + + + public void start() { + } + + public void stop() { + } + + public void publish(Event object) { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void addListener(RuntimeEventListener listener) throws ContextRuntimeException { + } + + public void addListener(EventFilter filter, RuntimeEventListener listener) { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void removeListener(RuntimeEventListener listener) throws ContextRuntimeException { + } + + public String getName() { + return "Mock Scope Container"; + } + + public boolean isCacheable() { + return false; + } + + public int[] getEventTypes() { + return null; + } + + public AtomicContext getContext(String name) { + return null; + } + + public Object getInstance(QualifiedName name) throws ScopeRuntimeException { + return components.get(name.getPartName()); + } + + public AtomicContext getContextByKey(String name, Object key) { + return null; + } + + public void setComponent(AtomicComponent component) throws ScopeRuntimeException { + } + + public void removeContext(String name) throws ScopeRuntimeException { + } + + public void removeContextByKey(String name, Object key) throws ScopeRuntimeException { + } + + public AtomicComponent[] getComponents() { + return null; + } + + + public void registerFactories(List> configurations) { + } + + public void registerFactory(ContextFactory configuration) { + } + + public int getLifecycleState(){ + return RUNNING; + } + + + public void setLifecycleState(int state) { + } + + + public void setName(String name) { + } + + + public void onEvent(Event event) { + //To change body of implemented methods use File | Settings | File Templates. + } +} + diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/MockStaticInvoker.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/MockStaticInvoker.java new file mode 100644 index 0000000000..66e8579cb4 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/MockStaticInvoker.java @@ -0,0 +1,86 @@ +/** + * + * 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.wire.mock; + +import org.apache.tuscany.core.wire.Interceptor; +import org.apache.tuscany.core.wire.InvocationRuntimeException; +import org.apache.tuscany.core.wire.TargetInvoker; +import org.apache.tuscany.core.message.Message; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Caches component instances that do not need to be resolved for every wire, e.g. an wire originating from + * a lesser scope intended for a target with a wider scope + * + * @version $Rev: 377006 $ $Date: 2006-02-11 09:41:59 -0800 (Sat, 11 Feb 2006) $ + */ +public class MockStaticInvoker implements TargetInvoker { + + private Object instance; + + private Method operation; + + public MockStaticInvoker(Method operation, Object instance) { + this.operation = operation; + this.instance = instance; + } + + public boolean isCacheable() { + return true; + } + + public Object invokeTarget(Object payload) throws InvocationTargetException { + try { + if (payload != null && !payload.getClass().isArray()) { + return operation.invoke(instance, payload); + } else { + return operation.invoke(instance, (Object[]) payload); + } + } catch (IllegalAccessException e) { + throw new InvocationRuntimeException(e); + } + } + + public Message invoke(Message msg) { + try { + Object resp = invokeTarget(msg.getBody()); + msg.setBody(resp); + } catch (InvocationTargetException e) { + msg.setBody(e.getCause()); + } catch (Throwable e) { + msg.setBody(e); + } + return msg; + } + + public void setNext(Interceptor next) { + throw new IllegalStateException("This interceptor must be the last interceptor in an interceptor chain"); + } + + public Object clone() throws CloneNotSupportedException { + try { + MockStaticInvoker invoker = (MockStaticInvoker) super.clone(); + invoker.instance = this.instance; + invoker.operation = this.operation; + return invoker; + } catch (CloneNotSupportedException e) { + return null; // will not happen + } + } +} diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/MockSyncInterceptor.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/MockSyncInterceptor.java new file mode 100644 index 0000000000..a64caed8eb --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/MockSyncInterceptor.java @@ -0,0 +1,45 @@ +/** + * + * 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.wire.mock; + +import org.apache.tuscany.core.wire.Interceptor; +import org.apache.tuscany.core.message.Message; + +public class MockSyncInterceptor implements Interceptor { + + private int count; + + private Interceptor next; + + public MockSyncInterceptor() { + } + + public Message invoke(Message msg) { + ++count; + //System.out.println("Invoking interceptor"); + return next.invoke(msg); + } + + public int getCount() { + return count; + } + + public void setNext(Interceptor next) { + this.next=next; + } +} + diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/SimpleSource.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/SimpleSource.java new file mode 100644 index 0000000000..8e8af9ec18 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/SimpleSource.java @@ -0,0 +1,25 @@ +/** + * + * 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.wire.mock; + +public interface SimpleSource { + + public void invokeHello() throws Exception; + + public void invokeGoodbye() throws Exception; +} + diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/SimpleSourceImpl.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/SimpleSourceImpl.java new file mode 100644 index 0000000000..900fa9c324 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/SimpleSourceImpl.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.wire.mock; + +public class SimpleSourceImpl implements SimpleSource { + + private SimpleTarget proxy; + + public SimpleSourceImpl(SimpleTarget proxy) { + this.proxy = proxy; + } + + public void invokeHello() throws Exception { + proxy.hello("hello"); + } + + public void invokeGoodbye() throws Exception { + proxy.goodbye("hello"); + } + +} + diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/SimpleTarget.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/SimpleTarget.java new file mode 100644 index 0000000000..d63d3a0565 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/SimpleTarget.java @@ -0,0 +1,28 @@ +/** + * + * 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.wire.mock; + +public interface SimpleTarget { + + public String hello(String message) throws Exception; + + public String goodbye(String message) throws Exception; + + public String echo(String message) throws Exception; + +} + diff --git a/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/SimpleTargetImpl.java b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/SimpleTargetImpl.java new file mode 100644 index 0000000000..1b6fe93ac8 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/java/org/apache/tuscany/core/wire/mock/SimpleTargetImpl.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.wire.mock; + +public class SimpleTargetImpl implements SimpleTarget { + + public SimpleTargetImpl() { + super(); + } + + public String hello(String message) throws Exception { + return message; + } + + public String goodbye(String message) throws Exception { + return message; + } + + public String echo(String message) throws Exception { + return message; + } + + +} + diff --git a/branches/java-post-M1/sca/core/src/test/resources/org/apache/tuscany/core/config/ModuleComponentLoaderTest1.module b/branches/java-post-M1/sca/core/src/test/resources/org/apache/tuscany/core/config/ModuleComponentLoaderTest1.module new file mode 100644 index 0000000000..b261cbe6c0 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/resources/org/apache/tuscany/core/config/ModuleComponentLoaderTest1.module @@ -0,0 +1,24 @@ + + + + + + + + diff --git a/branches/java-post-M1/sca/core/src/test/resources/org/apache/tuscany/core/loader/assembly/example.wsdl b/branches/java-post-M1/sca/core/src/test/resources/org/apache/tuscany/core/loader/assembly/example.wsdl new file mode 100644 index 0000000000..3a23e7b717 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/resources/org/apache/tuscany/core/loader/assembly/example.wsdl @@ -0,0 +1,23 @@ + + + + + + + diff --git a/branches/java-post-M1/sca/core/src/test/resources/org/apache/tuscany/core/loader/assembly/example.xsd b/branches/java-post-M1/sca/core/src/test/resources/org/apache/tuscany/core/loader/assembly/example.xsd new file mode 100644 index 0000000000..e34b6e92e0 --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/resources/org/apache/tuscany/core/loader/assembly/example.xsd @@ -0,0 +1,23 @@ + + + + + + diff --git a/branches/java-post-M1/sca/core/src/test/resources/org/apache/tuscany/core/loader/assembly/interfacestyles.wsdl b/branches/java-post-M1/sca/core/src/test/resources/org/apache/tuscany/core/loader/assembly/interfacestyles.wsdl new file mode 100644 index 0000000000..eeab33193d --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/resources/org/apache/tuscany/core/loader/assembly/interfacestyles.wsdl @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/branches/java-post-M1/sca/core/src/test/resources/system.fragment b/branches/java-post-M1/sca/core/src/test/resources/system.fragment new file mode 100644 index 0000000000..74d04561cd --- /dev/null +++ b/branches/java-post-M1/sca/core/src/test/resources/system.fragment @@ -0,0 +1,21 @@ + + + + + -- cgit v1.2.3