X-Git-Url: http://wamblee.org/gitweb/?a=blobdiff_plain;f=system%2Fspring%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fsystem%2Fspring%2FSpringComponent.java;h=d0abbcd173b8f20152744cac6b4b35df1cd94f53;hb=d67dfdb9198fbe3bb9034cd1d9f4a9870618d2b6;hp=a5dd685d4d6074be65811bac4dd3f1197956edfb;hpb=cc58fc5b498c82163904e8ccdc5eed7b96406a65;p=utils diff --git a/system/spring/src/main/java/org/wamblee/system/spring/SpringComponent.java b/system/spring/src/main/java/org/wamblee/system/spring/SpringComponent.java index a5dd685d..d0abbcd1 100644 --- a/system/spring/src/main/java/org/wamblee/system/spring/SpringComponent.java +++ b/system/spring/src/main/java/org/wamblee/system/spring/SpringComponent.java @@ -1,5 +1,21 @@ +/* + * Copyright 2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.wamblee.system.spring; +import java.util.HashMap; import java.util.Map; import java.util.Properties; @@ -10,41 +26,31 @@ import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.GenericApplicationContext; -import org.wamblee.system.AbstractComponent; -import org.wamblee.system.ProvidedInterfaceDescriptor; -import org.wamblee.system.RequiredInterfaceDescriptor; -import org.wamblee.system.Service; -import org.wamblee.system.ServiceRegistry; -import org.wamblee.system.SystemAssembler; -import org.wamblee.system.SystemAssemblyException; +import org.wamblee.system.core.AbstractComponent; +import org.wamblee.system.core.DefaultScope; +import org.wamblee.system.core.ProvidedInterface; +import org.wamblee.system.core.RequiredInterface; +import org.wamblee.system.core.Scope; +import org.wamblee.system.core.SystemAssemblyException; /** - * Represents a system configured based on spring. - * The spring config files that are configured should not contain any PropertyPlaceholderConfigurer - * objects. - * + * Represents a system configured based on spring. The spring config files that + * are configured should not contain any PropertyPlaceholderConfigurer objects. + * * @author Erik Brakkee */ -public class SpringComponent extends AbstractComponent { +public class SpringComponent extends AbstractComponent { - /** - * Singleton access to the service registry. Required while starting up. - */ - static ThreadLocal REGISTRY = new ThreadLocal(); + private static final String CONTEXT_KEY = "context"; - private Properties _properties; - private String[] _configFiles; - private Map _provided; - private Map _required; - /** - * Parent application context containing required services. - */ - private GenericApplicationContext _parentContext; + static final ThreadLocal THIS = new ThreadLocal(); + static final ThreadLocal SCOPE = new ThreadLocal(); - /** - * Application context containing parsed objects. - */ - private AbstractApplicationContext _context; + private Properties _properties; + private String[] _configFiles; + private Map _provided; + private Map _required; + private Map _propertyObjects; /** * Constructs a spring system. @@ -62,101 +68,131 @@ public class SpringComponent extends AbstractComponent { * names that the spring config files use for each required * service. */ - public SpringComponent(String aName, ServiceRegistry aRegistry, String[] aConfigFiles, - Map aProvided, - Map aRequired) { - super(aName, aRegistry, aProvided.values().toArray(new ProvidedInterfaceDescriptor[0]), - aRequired.keySet().toArray(new RequiredInterfaceDescriptor[0])); - _properties = new Properties(); + public SpringComponent(String aName, String[] aConfigFiles, + Map aProvided, + Map aRequired) { + super(aName, aProvided.values().toArray(new ProvidedInterface[0]), + aRequired.keySet().toArray(new RequiredInterface[0])); + _properties = new Properties(); _configFiles = aConfigFiles; _provided = aProvided; _required = aRequired; + _propertyObjects = new HashMap(); + } - + /** - * Must be called to make a property available in the application context. - * @param aKey Property key. - * @param aValue Property value. + * Must be called to make a property available in the application context. + * + * @param aKey + * Property key. + * @param aValue + * Property value. */ - public void setProperty(String aKey, String aValue) { + public void setProperty(String aKey, String aValue) { _properties.put(aKey, aValue); } - - public void addProperties(Properties aProperties) { - for (Object key: aProperties.keySet()) { - setProperty((String)key, aProperties.getProperty((String)key)); + + public void addProperties(Properties aProperties) { + for (Object key : aProperties.keySet()) { + setProperty((String) key, aProperties.getProperty((String) key)); } } + + public void addProperties(String aBeanname, Properties aProperties) { + _propertyObjects.put(aBeanname, aProperties); + } + + public Properties getProperties(String aBeanname) { + return _propertyObjects.get(aBeanname); + } @Override - protected void doStart(String aContext, - Service[] aRequiredServices) { - ServiceRegistry oldRegistry = REGISTRY.get(); - try { - REGISTRY.set(getRegistry()); - try { - _parentContext = new GenericApplicationContext(); - - registerRequiredServices(aRequiredServices); - - _parentContext.refresh(); - - parseConfigFiles(); - - _context.addBeanFactoryPostProcessor(new PropertySetter(_properties)); - _context.refresh(); - - exposeProvidedServices(aContext); - } catch (Exception e) { - throw new SystemAssemblyException( - "Failed to assemble spring system", e); - } + protected Scope doStart(Scope aExternalScope) { + + SpringComponent old = THIS.get(); + Scope oldScope = SCOPE.get(); + THIS.set(this); + Scope scope = new DefaultScope(getProvidedInterfaces(), aExternalScope); + SCOPE.set(scope); + try { + GenericApplicationContext parentContext = new GenericApplicationContext(); + + registerRequiredServices(parentContext); + registerPropertyObjects(parentContext); + + parentContext.refresh(); + + System.out.println("Parent context " + parentContext); + + AbstractApplicationContext context = parseConfigFiles(parentContext); + + context + .addBeanFactoryPostProcessor(new PropertySetter(_properties)); + context.refresh(); + + exposeProvidedServices(context, aExternalScope); + + scope.put(CONTEXT_KEY, context); + return scope; + } catch (Exception e) { + throw new SystemAssemblyException( + "Failed to assemble spring system " + getName(), e); } finally { - REGISTRY.set(oldRegistry); + THIS.set(old); + SCOPE.set(oldScope); } } - private void exposeProvidedServices(String aContext) { + private void exposeProvidedServices(AbstractApplicationContext aContext, Scope aScope) { // Call addService for each provided service. for (String name : _provided.keySet()) { - Object svc = _context.getBean(name); + Object svc = aContext.getBean(name); if (svc == null) { - throw new IllegalArgumentException(aContext + ": service '" + throw new IllegalArgumentException(getQualifiedName() + ": service '" + name + "' is null"); } - addService(aContext, _provided.get(name), svc); + addInterface(_provided.get(name), svc, aScope); + System.out.println("addService " + _provided.get(name) + " " + svc); } } - private void parseConfigFiles() { + private AbstractApplicationContext parseConfigFiles(GenericApplicationContext aParentContext) { // Parse spring config files - _context = new ClassPathXmlApplicationContext((String[]) _configFiles, - _parentContext); + return new ClassPathXmlApplicationContext((String[]) _configFiles, + false, aParentContext); } - private void registerRequiredServices(Service[] aRequiredServices) { + private void registerRequiredServices(GenericApplicationContext aParentContext) { // Register required services in a parent context - - for (Service svc: aRequiredServices) { - String id = svc.getId(); - ProvidedInterfaceDescriptor descriptor = svc.getDescriptor(); - RequiredInterfaceDescriptor[] requiredServices = SystemAssembler.filterRequiredServices(descriptor, - _required.keySet()); - for (RequiredInterfaceDescriptor required: requiredServices) { - String beanName = _required.get(required); - ConstructorArgumentValues cargs = new ConstructorArgumentValues(); - cargs.addGenericArgumentValue(id); - BeanDefinition definition = new RootBeanDefinition(RequiredServiceBean.class, cargs, - new MutablePropertyValues()); - _parentContext.registerBeanDefinition(beanName, definition); - } + for (RequiredInterface required: getRequiredInterfaces()) { + String beanName = _required.get(required); + ConstructorArgumentValues cargs = new ConstructorArgumentValues(); + cargs.addGenericArgumentValue(required.getName()); + BeanDefinition definition = new RootBeanDefinition( + RequiredServiceBean.class, cargs, + new MutablePropertyValues()); + aParentContext.registerBeanDefinition(beanName, definition); } } + + private void registerPropertyObjects(GenericApplicationContext aParentContext) { + for (String beanName: _propertyObjects.keySet()) { + ConstructorArgumentValues cargs = new ConstructorArgumentValues(); + cargs.addGenericArgumentValue(PropertySetter.createPropertyFile(_propertyObjects.get(beanName))); + BeanDefinition definition = new RootBeanDefinition( + ConfiguredProperties.class, cargs, + new MutablePropertyValues()); + aParentContext.registerBeanDefinition(beanName, definition); + } + } + @Override - protected void doStop() { - _context.close(); + protected void doStop(Scope aRuntime) { + AbstractApplicationContext context = (AbstractApplicationContext)aRuntime.get(CONTEXT_KEY); + context.close(); } }