From aadc5ee39ee27cf2ad59b8f4f1b6c2b424a0a010 Mon Sep 17 00:00:00 2001 From: Michael Minella Date: Fri, 11 Jan 2013 15:01:51 -0600 Subject: [PATCH] BATCH-1949: Updated for autoproxy check --- .../batch/core/scope/StepScope.java | 16 + .../batch/core/scope/util/ContextFactory.java | 38 -- .../util/PlaceholderProxyFactoryBean.java | 190 ------- .../scope/util/PlaceholderTargetSource.java | 494 ------------------ .../core/scope/util/StepContextFactory.java | 42 -- .../AsyncPlaceholderTargetSourceTests.java | 147 ------ .../scope/util/ContextFactorySupport.java | 27 - ...leContextPlaceholderTargetSourceTests.java | 228 -------- ...ceholderTargetSourceCustomEditorTests.java | 63 --- .../PlaceholderTargetSourceErrorTests.java | 205 -------- .../util/PlaceholderTargetSourceTests.java | 298 ----------- .../SimplePlaceholderTargetSourceTests.java | 72 --- .../scope/util/StepContextFactoryTests.java | 39 -- 13 files changed, 16 insertions(+), 1843 deletions(-) delete mode 100644 spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/ContextFactory.java delete mode 100644 spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderProxyFactoryBean.java delete mode 100644 spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderTargetSource.java delete mode 100644 spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/StepContextFactory.java delete mode 100644 spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/AsyncPlaceholderTargetSourceTests.java delete mode 100644 spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/ContextFactorySupport.java delete mode 100644 spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/MultipleContextPlaceholderTargetSourceTests.java delete mode 100644 spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/PlaceholderTargetSourceCustomEditorTests.java delete mode 100644 spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/PlaceholderTargetSourceErrorTests.java delete mode 100644 spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/PlaceholderTargetSourceTests.java delete mode 100644 spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/SimplePlaceholderTargetSourceTests.java delete mode 100644 spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/StepContextFactoryTests.java diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/StepScope.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/StepScope.java index 161275284..8cedf3b84 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/StepScope.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/StepScope.java @@ -80,6 +80,8 @@ public class StepScope implements Scope, BeanFactoryPostProcessor, Ordered { private int order = Ordered.LOWEST_PRECEDENCE; + private boolean autoProxy = true; + private final Object mutex = new Object(); /** @@ -115,6 +117,16 @@ public class StepScope implements Scope, BeanFactoryPostProcessor, Ordered { this.proxyTargetClass = proxyTargetClass; } + /** + * Flag to indicate that bean definitions need not be auto proxied. This gives control back to the declarer of the + * bean definition (e.g. in an @Configuration class). + * + * @param autoProxy the flag value to set (default true) + */ + public void setAutoProxy(boolean autoProxy) { + this.autoProxy = autoProxy; + } + /** * This will be used to resolve expressions in step-scoped beans. */ @@ -212,6 +224,10 @@ public class StepScope implements Scope, BeanFactoryPostProcessor, Ordered { beanFactory.registerScope(name, this); + if(!autoProxy) { + return; + } + Assert.state(beanFactory instanceof BeanDefinitionRegistry, "BeanFactory was not a BeanDefinitionRegistry, so StepScope cannot be used."); BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/ContextFactory.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/ContextFactory.java deleted file mode 100644 index 4f89d47e0..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/ContextFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2006-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.springframework.batch.core.scope.util; - -/** - * Interface to allow the context root for placeholder resolution to be switched - * at runtime. Useful for testing. - * - * @author Dave Syer - * - */ -public interface ContextFactory { - - /** - * @return a root object to which placeholders resolve relatively - */ - Object getContext(); - - /** - * @return a unique identifier for this context - */ - String getContextId(); - -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderProxyFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderProxyFactoryBean.java deleted file mode 100644 index 515469274..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderProxyFactoryBean.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2006-2013 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.springframework.batch.core.scope.util; - -import java.lang.reflect.Modifier; - -import org.springframework.aop.framework.AopInfrastructureBean; -import org.springframework.aop.framework.ProxyConfig; -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.aop.framework.autoproxy.AutoProxyUtils; -import org.springframework.aop.scope.DefaultScopedObject; -import org.springframework.aop.scope.ScopedObject; -import org.springframework.aop.scope.ScopedProxyFactoryBean; -import org.springframework.aop.support.DelegatingIntroductionInterceptor; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.FactoryBeanNotInitializedException; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.BeanDefinitionHolder; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.util.ClassUtils; - -/** - * Factory bean for proxies that can replace placeholders in their target. Just - * a specialisation of {@link ScopedProxyFactoryBean}, with a different target - * source type. - * - * @author Dave Syer - * - */ -@SuppressWarnings({ "serial", "rawtypes" }) -public class PlaceholderProxyFactoryBean extends ProxyConfig implements FactoryBean, BeanFactoryAware { - - /** The TargetSource that manages scoping */ - private final PlaceholderTargetSource scopedTargetSource = new PlaceholderTargetSource(); - - /** The name of the target bean */ - private String targetBeanName; - - /** The cached singleton proxy */ - private Object proxy; - - private final ContextFactory contextFactory; - - /** - * Create a new FactoryBean instance. - */ - public PlaceholderProxyFactoryBean(ContextFactory contextFactory) { - this.contextFactory = contextFactory; - // setProxyTargetClass(false); - } - - /** - * Set the name of the bean that is to be scoped. - */ - public void setTargetBeanName(String targetBeanName) { - this.targetBeanName = targetBeanName; - this.scopedTargetSource.setTargetBeanName(targetBeanName); - } - - @Override - public void setBeanFactory(BeanFactory beanFactory) { - if (!(beanFactory instanceof ConfigurableBeanFactory)) { - throw new IllegalStateException("Not running in a ConfigurableBeanFactory: " + beanFactory); - } - ConfigurableBeanFactory cbf = (ConfigurableBeanFactory) beanFactory; - - this.scopedTargetSource.setBeanFactory(beanFactory); - this.scopedTargetSource.setContextFactory(contextFactory); - - ProxyFactory pf = new ProxyFactory(); - pf.copyFrom(this); - pf.setTargetSource(this.scopedTargetSource); - - Class beanType = beanFactory.getType(this.targetBeanName); - if (beanType == null) { - throw new IllegalStateException("Cannot create scoped proxy for bean '" + this.targetBeanName - + "': Target type could not be determined at the time of proxy creation."); - } - if (!isProxyTargetClass() || beanType.isInterface() || Modifier.isPrivate(beanType.getModifiers())) { - pf.setInterfaces(ClassUtils.getAllInterfacesForClass(beanType, cbf.getBeanClassLoader())); - } - - // Add an introduction that implements only the methods on ScopedObject. - ScopedObject scopedObject = new DefaultScopedObject(cbf, this.scopedTargetSource.getTargetBeanName()); - pf.addAdvice(new DelegatingIntroductionInterceptor(scopedObject)); - - // Add the AopInfrastructureBean marker to indicate that the scoped - // proxy itself is not subject to auto-proxying! Only its target bean - // is. - pf.addInterface(AopInfrastructureBean.class); - - this.scopedTargetSource.afterPropertiesSet(); - - this.proxy = pf.getProxy(cbf.getBeanClassLoader()); - } - - @Override - public Object getObject() { - if (this.proxy == null) { - throw new FactoryBeanNotInitializedException(); - } - return this.proxy; - } - - @Override - public Class getObjectType() { - if (this.proxy != null) { - return this.proxy.getClass(); - } - if (this.scopedTargetSource != null) { - return this.scopedTargetSource.getTargetClass(); - } - return null; - } - - @Override - public boolean isSingleton() { - return true; - } - - /** - * Convenience method to create a {@link BeanDefinition} for a target - * wrapped in a placeholder tarrget source, able to defer binding of - * placeholders until the bean is used. - * - * @param definition a target bean definition - * @param registry a {@link BeanDefinitionRegistry} - * @param proxyTargetClass true if we need to use CGlib to create the - * proxies - * @return a {@link BeanDefinitionHolder} for a - * {@link PlaceholderProxyFactoryBean} - */ - public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder definition, - BeanDefinitionRegistry registry, boolean proxyTargetClass) { - - String originalBeanName = definition.getBeanName(); - BeanDefinition targetDefinition = definition.getBeanDefinition(); - - // Create a proxy definition for the original bean name, - // "hiding" the target bean in an internal target definition. - RootBeanDefinition proxyDefinition = new RootBeanDefinition(PlaceholderProxyFactoryBean.class); - proxyDefinition.getConstructorArgumentValues().addGenericArgumentValue(new StepContextFactory()); - proxyDefinition.setOriginatingBeanDefinition(definition.getBeanDefinition()); - proxyDefinition.setSource(definition.getSource()); - proxyDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - - String targetBeanName = "lazyBindingProxy." + originalBeanName; - proxyDefinition.getPropertyValues().addPropertyValue("targetBeanName", targetBeanName); - - if (proxyTargetClass) { - targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE); - // ProxyFactoryBean's "proxyTargetClass" default is FALSE, so we - // need to set it explicitly here. - proxyDefinition.getPropertyValues().addPropertyValue("proxyTargetClass", Boolean.TRUE); - } - else { - proxyDefinition.getPropertyValues().addPropertyValue("proxyTargetClass", Boolean.FALSE); - } - - proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate()); - // The target bean should be ignored in favor of the proxy. - targetDefinition.setAutowireCandidate(false); - - // Register the target bean as separate bean in the factory. - registry.registerBeanDefinition(targetBeanName, targetDefinition); - - // Return the scoped proxy definition as primary bean definition - // (potentially an inner bean). - return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases()); - } - -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderTargetSource.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderTargetSource.java deleted file mode 100644 index c2f5b3887..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderTargetSource.java +++ /dev/null @@ -1,494 +0,0 @@ -/* - * Copyright 2006-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.springframework.batch.core.scope.util; - -import java.beans.PropertyEditor; -import java.lang.reflect.Field; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.springframework.aop.TargetSource; -import org.springframework.aop.target.SimpleBeanTargetSource; -import org.springframework.beans.BeanWrapper; -import org.springframework.beans.BeanWrapperImpl; -import org.springframework.beans.BeansException; -import org.springframework.beans.PropertyEditorRegistrySupport; -import org.springframework.beans.TypeConverter; -import org.springframework.beans.TypeMismatchException; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.BeanDefinitionHolder; -import org.springframework.beans.factory.config.BeanDefinitionVisitor; -import org.springframework.beans.factory.config.TypedStringValue; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.beans.factory.support.GenericBeanDefinition; -import org.springframework.beans.factory.support.ManagedList; -import org.springframework.beans.factory.support.ManagedMap; -import org.springframework.beans.factory.support.ManagedSet; -import org.springframework.core.AttributeAccessor; -import org.springframework.core.MethodParameter; -import org.springframework.util.Assert; -import org.springframework.util.StringValueResolver; - -/** - * A {@link TargetSource} that lazily initializes its target, replacing bean - * definition properties dynamically if they are marked as placeholders. String - * values with embedded %{key} patterns will be replaced with the - * corresponding value from the injected context (which must also be a String). - * This includes dynamically locating a bean reference (e.g. - * ref="%{foo}"), and partial replacement of patterns (e.g. - * value="%{foo}-bar-%{spam}"). These replacements work for context - * values that are primitive (String, Long, Integer). You can also replace - * non-primitive values directly by making the whole bean property value into a - * placeholder (e.g. value="%{foo}" where foo is a - * property in the context). - * - * @author Dave Syer - * - */ -public class PlaceholderTargetSource extends SimpleBeanTargetSource implements InitializingBean { - - /** - * Key for placeholders to be replaced from the properties provided. - */ - private static final String PLACEHOLDER_PREFIX = "%{"; - - private static final String PLACEHOLDER_SUFFIX = "}"; - - private ContextFactory contextFactory; - - private String beanName; - - /** - * Public setter for the context factory. Used to construct the context root - * whenever placeholders are replaced in a bean definition. - * - * @param contextFactory the {@link ContextFactory} - */ - public void setContextFactory(ContextFactory contextFactory) { - this.contextFactory = contextFactory; - } - - /* - * (non-Javadoc) - * - * @see - * org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() { - Assert.notNull(contextFactory, "The ContextFactory must be set."); - beanName = getTargetBeanName() + "#" + contextFactory.getContextId(); - } - - /* - * (non-Javadoc) - * - * @see org.springframework.aop.target.LazyInitTargetSource#getTarget() - */ - @Override - public synchronized Object getTarget() throws BeansException { - - // Object target; - Object target = getTargetFromContext(); - if (target != null) { - return target; - } - - DefaultListableBeanFactory listableBeanFactory = (DefaultListableBeanFactory) getBeanFactory(); - - final TypeConverter typeConverter = listableBeanFactory.getTypeConverter(); - - DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(listableBeanFactory); - beanFactory.copyConfigurationFrom(listableBeanFactory); - - final TypeConverter contextTypeConverter = new TypeConverter() { - @Override - @SuppressWarnings({ "unchecked", "rawtypes" }) - public Object convertIfNecessary(Object value, Class requiredType, MethodParameter methodParam) - throws TypeMismatchException { - return doConvertIfNecessary(value, requiredType, - methodParam); - } - - private Object doConvertIfNecessary(Object value, - Class requiredType, Object param) { - Object result = null; - if (value instanceof String) { - String key = (String) value; - if (key.startsWith(PLACEHOLDER_PREFIX) && key.endsWith(PLACEHOLDER_SUFFIX)) { - key = extractKey(key); - result = convertFromContext(key, requiredType); - if (result == null) { - Object property = getPropertyFromContext(key); - // Give the normal type converter a chance by - // reversing to a String - if (property != null) { - property = convertToString(property, typeConverter); - if (property != null) { - value = property; - } - logger.debug(String.format("Bound %%{%s} to String value [%s]", key, result)); - } - else { - throw new IllegalStateException("Cannot bind to placeholder: " + key); - } - } - else { - logger.debug(String.format("Bound %%{%s} to [%s]", key, result)); - } - } - } - else if (requiredType.isAssignableFrom(value.getClass())) { - result = value; - } - else if (requiredType.isAssignableFrom(String.class)) { - result = convertToString(value, typeConverter); - if (result == null) { - logger.debug("Falling back on toString for conversion of : [" + value.getClass() + "]"); - result = value.toString(); - } - } - - if(result != null) { - return result; - } - else if(param instanceof Field) { - return typeConverter.convertIfNecessary(value, requiredType, (Field) param); - } - else { - return typeConverter.convertIfNecessary(value, requiredType, (MethodParameter) param); - } - } - - @Override - @SuppressWarnings("rawtypes") - public Object convertIfNecessary(Object value, Class requiredType) throws TypeMismatchException { - return doConvertIfNecessary(value, requiredType, null); - } - - @Override - public Object convertIfNecessary(Object value, - Class requiredType, Field field) - throws TypeMismatchException { - return doConvertIfNecessary(value, requiredType, - field); - } - }; - beanFactory.setTypeConverter(contextTypeConverter); - - try { - - /* - * Need to use the merged bean definition here, otherwise it gets - * cached and "frozen" in and the "regular" bean definition does not - * come back when getBean() is called later on - */ - String targetBeanName = getTargetBeanName(); - GenericBeanDefinition beanDefinition = new GenericBeanDefinition(listableBeanFactory - .getMergedBeanDefinition(targetBeanName)); - logger.debug("Rehydrating scoped target: [" + targetBeanName + "]"); - - BeanDefinitionVisitor visitor = new PlaceholderBeanDefinitionVisitor(contextTypeConverter); - - beanFactory.registerBeanDefinition(beanName, beanDefinition); - // Make the replacements before the target is hydrated - visitor.visitBeanDefinition(beanDefinition); - target = beanFactory.getBean(beanName); - putTargetInContext(target); - return target; - - } - finally { - beanFactory.removeBeanDefinition(beanName); - beanFactory = null; - // Anything else we can do to clean it up? - } - - } - - private void putTargetInContext(Object target) { - Object context = contextFactory.getContext(); - if (context instanceof AttributeAccessor) { - ((AttributeAccessor) context).setAttribute(beanName, target); - } - } - - private Object getTargetFromContext() { - Object context = contextFactory.getContext(); - if (context instanceof AttributeAccessor) { - return ((AttributeAccessor) context).getAttribute(beanName); - } - return null; - } - - /** - * @param value - * @param typeConverter - * @return a String representation of the input if possible - */ - protected String convertToString(Object value, TypeConverter typeConverter) { - String result = null; - try { - // Give it one chance to convert - this forces the default editors - // to be registered - result = typeConverter.convertIfNecessary(value, String.class); - } - catch (TypeMismatchException e) { - // ignore - } - if (result == null && typeConverter instanceof PropertyEditorRegistrySupport) { - /* - * PropertyEditorRegistrySupport is de rigeur with TypeConverter - * instances used internally by Spring. If we have one of those then - * we can convert to String but the TypeConverter doesn't know how - * to. - */ - PropertyEditorRegistrySupport registry = (PropertyEditorRegistrySupport) typeConverter; - PropertyEditor editor = registry.findCustomEditor(value.getClass(), null); - if (editor != null) { - if (registry.isSharedEditor(editor)) { - // Synchronized access to shared editor - // instance. - synchronized (editor) { - editor.setValue(value); - result = editor.getAsText(); - } - } - else { - editor.setValue(value); - result = editor.getAsText(); - } - } - } - return result; - } - - /** - * @param value - * @param requiredType - * @return - */ - private Object convertFromContext(String key, Class requiredType) { - Object result = null; - Object property = getPropertyFromContext(key); - if (property == null || requiredType.isAssignableFrom(property.getClass())) { - result = property; - } - return result; - } - - private Object getPropertyFromContext(String key) { - Object context = contextFactory.getContext(); - if (context == null) { - throw new IllegalStateException("No context available while replacing placeholders."); - } - BeanWrapper wrapper = new BeanWrapperImpl(context); - if (wrapper.isReadableProperty(key)) { - return wrapper.getPropertyValue(key); - } - return null; - } - - private String extractKey(String value) { - return value.substring(value.indexOf(PLACEHOLDER_PREFIX) + PLACEHOLDER_PREFIX.length(), value - .indexOf(PLACEHOLDER_SUFFIX)); - } - - /** - * Determine whether the input is a whole key in the form - * %{...}, i.e. starting with the correct prefix, ending with - * the correct suffix and containing only one of each. - * - * @param value a String with placeholder patterns - * @return true if the value is a key - */ - private boolean isKey(String value) { - return value.indexOf(PLACEHOLDER_PREFIX) == value.lastIndexOf(PLACEHOLDER_PREFIX) - && value.startsWith(PLACEHOLDER_PREFIX) && value.endsWith(PLACEHOLDER_SUFFIX); - } - - /** - * A {@link BeanDefinitionVisitor} that will replace embedded placeholders - * with values from the provided context. - * - * @author Dave Syer - * - */ - private final class PlaceholderBeanDefinitionVisitor extends BeanDefinitionVisitor { - - public PlaceholderBeanDefinitionVisitor(final TypeConverter typeConverter) { - super(new PlaceholderStringValueResolver(typeConverter)); - } - - @Override - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected Object resolveValue(Object value) { - - if (value instanceof TypedStringValue) { - - TypedStringValue typedStringValue = (TypedStringValue) value; - String stringValue = typedStringValue.getValue(); - if (stringValue != null) { - - // If the value is a whole key, try to simply replace it - // from context. - if (isKey(stringValue)) { - String key = extractKey(stringValue); - Object result = getPropertyFromContext(key); - if (result != null) { - value = result; - logger.debug(String.format("Resolved %%{%s} to obtain [%s]", key, result)); - } - } - else { - // Otherwise it might contain embedded keys so we try to - // replace those - String visitedString = resolveStringValue(stringValue); - value = new TypedStringValue(visitedString); - } - } - - } - else if (value instanceof Map) { - - Map map = (Map) value; - Map newValue = new ManagedMap(map.size()); - newValue.putAll(map); - super.visitMap(newValue); - value = newValue; - - } - else if (value instanceof List) { - - List list = (List) value; - List newValue = new ManagedList(list.size()); - newValue.addAll(list); - super.visitList(newValue); - value = newValue; - - } - else if (value instanceof Set) { - - Set list = (Set) value; - Set newValue = new ManagedSet(list.size()); - newValue.addAll(list); - super.visitSet(newValue); - value = newValue; - - } - else if (value instanceof BeanDefinition) { - - BeanDefinition newValue = new GenericBeanDefinition((BeanDefinition) value); - visitBeanDefinition(newValue); - value = newValue; - - } - else if (value instanceof BeanDefinitionHolder) { - - BeanDefinition newValue = new GenericBeanDefinition(((BeanDefinitionHolder) value).getBeanDefinition()); - visitBeanDefinition(newValue); - value = newValue; - - } - else { - - value = super.resolveValue(value); - - } - - return value; - - } - - } - - private final class PlaceholderStringValueResolver implements StringValueResolver { - - private final TypeConverter typeConverter; - - private PlaceholderStringValueResolver(TypeConverter typeConverter) { - this.typeConverter = typeConverter; - } - - @Override - public String resolveStringValue(String strVal) { - if (!strVal.contains(PLACEHOLDER_PREFIX)) { - return strVal; - } - return replacePlaceholders(strVal, typeConverter); - } - - /** - * Convenience method to replace all the placeholders in the input. - * - * @param typeConverter a {@link TypeConverter} that can be used to - * convert placeholder keys to context values - * @param value the value to replace placeholders in - * @return the input with placeholders replaced - */ - private String replacePlaceholders(String value, TypeConverter typeConverter) { - - StringBuilder result = new StringBuilder(value); - - int first = result.indexOf(PLACEHOLDER_PREFIX); - int next = result.indexOf(PLACEHOLDER_SUFFIX, first + 1); - - while (first >= 0) { - - Assert.state(next > 0, String.format("Placeholder key incorrectly specified: use %skey%s (in %s)", - PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, value)); - - String key = result.substring(first + PLACEHOLDER_PREFIX.length(), next); - - boolean replaced = replaceIfTypeMatches(result, first, next, key, String.class, typeConverter); - replaced |= replaceIfTypeMatches(result, first, next, key, Long.class, typeConverter); - replaced |= replaceIfTypeMatches(result, first, next, key, Integer.class, typeConverter); - replaced |= replaceIfTypeMatches(result, first, next, key, Date.class, typeConverter); - if (!replaced) { - if (!value.startsWith(PLACEHOLDER_PREFIX) || !value.endsWith(PLACEHOLDER_SUFFIX)) { - throw new IllegalStateException(String.format("Cannot bind to partial key %%{%s} in %s", key, - value)); - } - logger.debug(String.format("Deferring binding of placeholder: %%{%s}", key)); - } - else { - logger.debug(String.format("Bound %%{%s} to obtain [%s]", key, result)); - } - first = result.indexOf(PLACEHOLDER_PREFIX, first + 1); - next = result.indexOf(PLACEHOLDER_SUFFIX, first + 1); - - } - - return result.toString(); - - } - - private boolean replaceIfTypeMatches(StringBuilder result, int first, int next, String key, - Class requiredType, TypeConverter typeConverter) { - Object property = convertFromContext(key, requiredType); - if (property != null) { - result.replace(first, next + 1, typeConverter.convertIfNecessary(property, String.class)); - return true; - } - return false; - } - - } - -} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/StepContextFactory.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/StepContextFactory.java deleted file mode 100644 index 19f1cc560..000000000 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/StepContextFactory.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2006-2013 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.springframework.batch.core.scope.util; - -import org.springframework.batch.core.scope.context.StepContext; -import org.springframework.batch.core.scope.context.StepSynchronizationManager; - -/** - * Implementation of {@link ContextFactory} that provides the current - * {@link StepContext} as a context object. - * - * @author Dave Syer - * - */ -public class StepContextFactory implements ContextFactory { - - @Override - public Object getContext() { - return StepSynchronizationManager.getContext(); - } - - @Override - public String getContextId() { - StepContext context = StepSynchronizationManager.getContext(); - return context!=null ? (String) context.getId() : "sysinit"; - } - -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/AsyncPlaceholderTargetSourceTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/AsyncPlaceholderTargetSourceTests.java deleted file mode 100644 index 7ec92fa59..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/AsyncPlaceholderTargetSourceTests.java +++ /dev/null @@ -1,147 +0,0 @@ -package org.springframework.batch.core.scope.util; - -import static org.junit.Assert.assertEquals; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.FutureTask; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.task.SimpleAsyncTaskExecutor; -import org.springframework.core.task.TaskExecutor; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@ContextConfiguration -@RunWith(SpringJUnit4ClassRunner.class) -public class AsyncPlaceholderTargetSourceTests implements BeanFactoryAware { - - private ThreadLocal> attributes = new ThreadLocal>(); - - public Map getAttributes() { - return attributes.get(); - } - - @Autowired - private Node simple; - - @Autowired - private SimpleContextFactory contextFactory; - - private TaskExecutor taskExecutor = new SimpleAsyncTaskExecutor(); - - private ListableBeanFactory beanFactory; - - private int beanCount; - - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - this.beanFactory = (ListableBeanFactory) beanFactory; - } - - @After - public void removeContext() { - contextFactory.clearContext(); - attributes.set(null); - // Check that all temporary bean definitions are cleaned up - assertEquals(beanCount, beanFactory.getBeanDefinitionCount()); - } - - @Before - public void setUpContext() { - contextFactory.setContext(this); - beanCount = beanFactory.getBeanDefinitionCount(); - } - - @Test - public void testGetSimple() { - attributes.set(Collections.singletonMap("foo", "bar")); - assertEquals("bar", simple.getName()); - } - - @Test - public void testGetMultiple() throws Exception { - - List> tasks = new ArrayList>(); - - for (int i = 0; i < 12; i++) { - final String value = "foo" + i; - FutureTask task = new FutureTask(new Callable() { - @Override - public String call() throws Exception { - attributes.set(Collections.singletonMap("foo", value)); - try { - return simple.getName(); - } - finally { - attributes.set(null); - } - } - }); - tasks.add(task); - taskExecutor.execute(task); - } - - int i = 0; - for (FutureTask task : tasks) { - assertEquals("foo" + i, task.get()); - i++; - } - - } - - public static class SimpleContextFactory extends ContextFactorySupport { - - private Object root; - - @Override - public Object getContext() { - return root; - } - - public void setContext(Object root) { - this.root = root; - } - - public void clearContext() { - root = null; - } - - } - - public static interface Node { - String getName(); - } - - public static class Foo implements Node { - - private String name; - - private Log logger = LogFactory.getLog(getClass()); - - @Override - public String getName() { - return name; - } - - public void setName(String name) { - logger.debug("Setting name: " + name); - this.name = name; - } - - } - -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/ContextFactorySupport.java b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/ContextFactorySupport.java deleted file mode 100644 index d50da3cc0..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/ContextFactorySupport.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.springframework.batch.core.scope.util; - -public class ContextFactorySupport implements ContextFactory { - - private int count = 0; - - /** - * Returns this. Override for more sensible behaviour. - * - * @see org.springframework.batch.core.scope.util.ContextFactory#getContext() - */ - @Override - public Object getContext() { - return this; - } - - /** - * Returns the context plus a counter, so each call is unique. - * - * @see org.springframework.batch.core.scope.util.ContextFactory#getContextId() - */ - @Override - public String getContextId() { - return getContext()+"#"+(count ++); - } - -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/MultipleContextPlaceholderTargetSourceTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/MultipleContextPlaceholderTargetSourceTests.java deleted file mode 100644 index 47fd03bd0..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/MultipleContextPlaceholderTargetSourceTests.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2006-2013 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.springframework.batch.core.scope.util; - -import static org.junit.Assert.assertEquals; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author Dave Syer - * - */ -@ContextConfiguration -@RunWith(SpringJUnit4ClassRunner.class) -public class MultipleContextPlaceholderTargetSourceTests { - - private Map attributes; - - public Map getAttributes() { - return attributes; - } - - @Autowired - private SimpleContextFactory contextFactory; - - @Autowired - @Qualifier("simple") - private TestBean simple; - - @Autowired - @Qualifier("nested") - private TestBean nested; - - @Autowired - @Qualifier("list") - private TestBean list; - - @Autowired - @Qualifier("nestedList") - private TestBean nestedList; - - @Autowired - @Qualifier("map") - private TestBean map; - - @After - public void removeContext() { - contextFactory.clearContext(); - } - - @Before - public void setUpContext() { - contextFactory.setContext(this); - } - - @Test - public void testValueFromProperties() throws Exception { - attributes = Collections.singletonMap("foo", "bar"); - assertEquals("bar", simple.getName()); - } - - @Test - public void testMultipleValueFromProperties() throws Exception { - - for (int i = 0; i < 4; i++) { - final String value = "foo" + i; - attributes = Collections.singletonMap("foo", value); - assertEquals("foo" + i, simple.getName()); - } - - } - - @Test - public void testMultipleNestedValueFromProperties() throws Exception { - - for (int i = 0; i < 4; i++) { - final String value = "bar" + i; - attributes = Collections.singletonMap("foo", value); - assertEquals("foo-bar" + i, nested.getName()); - } - - } - - @Test - public void testMultipleValueInList() throws Exception { - - for (int i = 0; i < 4; i++) { - final String value = "foo" + i; - contextFactory.setContext(this); - attributes = Collections.singletonMap("foo", value); - try { - assertEquals("foo" + i, list.getNames().get(0)); - } - finally { - contextFactory.clearContext(); - } - } - - } - - @Test - public void testMultipleValueInNestedList() throws Exception { - - for (int i = 0; i < 4; i++) { - final String value = "foo" + i; - contextFactory.setContext(this); - attributes = Collections.singletonMap("foo", value); - try { - assertEquals("foo" + i, nestedList.getParent().getNames().get(0)); - } - finally { - contextFactory.clearContext(); - } - } - - } - - @Test - public void testMultipleValueInMap() throws Exception { - - for (int i = 0; i < 4; i++) { - final String value = "foo" + i; - contextFactory.setContext(this); - attributes = Collections.singletonMap("foo", value); - try { - assertEquals("foo" + i, map.getMap().get("foo")); - } - finally { - contextFactory.clearContext(); - } - } - - } - - @Override - public String toString() { - return "Test context: attributes=" + attributes; - } - - public static class TestBean { - private String name; - - private TestBean parent; - - private List names = new ArrayList(); - - private Map map = new HashMap(); - - public TestBean getParent() { - return parent; - } - - public void setParent(TestBean parent) { - this.parent = parent; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public List getNames() { - return new ArrayList(names); - } - - public void setNames(List names) { - this.names.addAll(names); - } - - public Map getMap() { - return new HashMap(map); - } - - public void setMap(Map map) { - this.map.putAll(map); - } - - } - - public static class SimpleContextFactory extends ContextFactorySupport { - - private Object root; - - @Override - public Object getContext() { - return root; - } - - public void setContext(Object root) { - this.root = root; - } - - public void clearContext() { - root = null; - } - - } - -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/PlaceholderTargetSourceCustomEditorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/PlaceholderTargetSourceCustomEditorTests.java deleted file mode 100644 index 3a8c0dd1f..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/PlaceholderTargetSourceCustomEditorTests.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.springframework.batch.core.scope.util; - -import static org.junit.Assert.assertEquals; - -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@ContextConfiguration -@RunWith(SpringJUnit4ClassRunner.class) -public class PlaceholderTargetSourceCustomEditorTests extends ContextFactorySupport { - - @Autowired - @Qualifier("withEmbeddedDate") - private PlaceholderTargetSource withEmbeddedDate; - - private Date date = new Date(1L); - - @Override - public Object getContext() { - return this; - } - - public Date getDate() { - return date; - } - - @Test - public void testGetEmbeddedDate() { - Node target = (Node) withEmbeddedDate.getTarget(); - String date = new SimpleDateFormat("yyyy/MM/dd").format(new Date(1L)); - assertEquals("bar-"+date, target.getName()); - } - - public static interface Node { - String getName(); - } - - public static class Foo implements Node { - - private String name; - - public Foo() { - } - - @Override - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - } - -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/PlaceholderTargetSourceErrorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/PlaceholderTargetSourceErrorTests.java deleted file mode 100644 index 2a9718c5f..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/PlaceholderTargetSourceErrorTests.java +++ /dev/null @@ -1,205 +0,0 @@ -package org.springframework.batch.core.scope.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.Collections; -import java.util.Date; -import java.util.Map; - -import org.apache.commons.io.IOUtils; -import org.junit.Test; -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.core.io.ByteArrayResource; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; - -public class PlaceholderTargetSourceErrorTests extends ContextFactorySupport { - - private Map map = Collections.singletonMap("foo.foo", (Object) "bar"); - - private Date date = new Date(1L); - - @Override - public Object getContext() { - return this; - } - - public String getFoo() { - return "bar"; - } - - public Map getMap() { - return map; - } - - public Node getParent() { - return new Foo("spam"); - } - - public Long getLong() { - return 12345678912345L; - } - - public Integer getInteger() { - return 4321; - } - - public Date getDate() { - return date; - } - - public String getGarbage() { - return null; - } - - private PlaceholderTargetSource createValue(String name, String value) throws Exception { - String input = IOUtils.toString(new ClassPathResource(getClass().getSimpleName() + "-context.xml", getClass()) - .getInputStream()); - input = input.replace("", String.format("", name, value)); - Resource resource = new ByteArrayResource(input.getBytes()); - GenericApplicationContext context = new GenericApplicationContext(); - new XmlBeanDefinitionReader(context).loadBeanDefinitions(resource); - context.refresh(); - // XmlBeanFactory context = new XmlBeanFactory(resource); - return (PlaceholderTargetSource) context.getBean("value"); - } - - @Test - public void testPartialReplaceSunnyDay() throws Exception { - Node target = (Node) createValue("name", "%{foo}-bar").getTarget(); - assertEquals("bar-bar", target.getName()); - } - - @Test - public void testPartialReplaceMissingProperty() throws Exception { - try { - Node target = (Node) createValue("name", "%{garbage}-bar").getTarget(); - assertEquals("%{garbage}-bar", target.getName()); - fail("Expected IllegalStateException"); - } - catch (IllegalStateException e) { - String message = e.getMessage(); - assertTrue("Wrong message: " + message, message.toLowerCase().contains("cannot bind")); - } - } - - @Test - public void testFullReplaceSunnyDay() throws Exception { - Node target = (Node) createValue("name", "%{foo}").getTarget(); - assertEquals("bar", target.getName()); - } - - @Test - public void testFullReplaceMissingProperty() throws Exception { - try { - Node target = (Node) createValue("name", "%{garbage}").getTarget(); - assertEquals("bar", target.getName()); - fail("Expected IllegalStateException"); - } - catch (BeanCreationException e) { - String message = e.getMessage(); - assertTrue("Wrong message: " + message, message.toLowerCase().contains("cannot bind")); - } - } - - @Test - public void testPartialReplaceIntegerToString() throws Exception { - Node target = (Node) createValue("name", "foo-%{integer}").getTarget(); - assertEquals("foo-4321", target.getName()); - } - - @Test - public void testFullReplaceIntegerToString() throws Exception { - Node target = (Node) createValue("name", "%{integer}").getTarget(); - assertEquals("4321", target.getName()); - } - - @Test - public void testFullReplaceIntegerToLong() throws Exception { - Node target = (Node) createValue("value", "%{integer}").getTarget(); - assertEquals(4321L, target.getValue()); - } - - @Test - public void testFullReplaceIntegerToNode() throws Exception { - try { - Node target = (Node) createValue("parent", "%{integer}").getTarget(); - assertEquals("4321", target.getParent()); - fail("Expected IllegalArgumentException"); - } - catch (Exception e) { - String message = e.getMessage(); - assertTrue("Wrong message: " + message, message.toLowerCase().contains("cannot convert")); - } - } - - public static interface Node { - String getName(); - - Date getDate(); - - Node getParent(); - - long getValue(); - } - - public static class Foo implements Node { - - private String name; - - private Date date; - - private Node parent; - - private long value; - - public Foo() { - } - - @Override - public long getValue() { - return value; - } - - public void setValue(long value) { - this.value = value; - } - - public Foo(String name) { - this.name = name; - } - - @Override - public String getName() { - return name; - } - - @Override - public Date getDate() { - return date; - } - - public void setDate(Date date) { - this.date = date; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public Node getParent() { - return parent; - } - - public void setParent(Node parent) { - this.parent = parent; - } - - } - -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/PlaceholderTargetSourceTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/PlaceholderTargetSourceTests.java deleted file mode 100644 index a34f7519c..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/PlaceholderTargetSourceTests.java +++ /dev/null @@ -1,298 +0,0 @@ -package org.springframework.batch.core.scope.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@ContextConfiguration -@RunWith(SpringJUnit4ClassRunner.class) -public class PlaceholderTargetSourceTests extends ContextFactorySupport { - - @Autowired - @Qualifier("vanilla") - private PlaceholderTargetSource vanilla; - - @Autowired - @Qualifier("simple") - private PlaceholderTargetSource simple; - - @Autowired - @Qualifier("withLong") - private PlaceholderTargetSource withLong; - - @Autowired - @Qualifier("withInteger") - private PlaceholderTargetSource withInteger; - - @Autowired - @Qualifier("withList") - private PlaceholderTargetSource withList; - - @Autowired - @Qualifier("withLiteralList") - private PlaceholderTargetSource withLiteralList; - - @Autowired - @Qualifier("withMap") - private PlaceholderTargetSource withMap; - - @Autowired - @Qualifier("withMultiple") - private PlaceholderTargetSource withMultiple; - - @Autowired - @Qualifier("withMultipleStartAndEnd") - private PlaceholderTargetSource withMultipleStartAndEnd; - - @Autowired - @Qualifier("withEmbeddedDate") - private PlaceholderTargetSource withEmbeddedDate; - - @Autowired - @Qualifier("withDate") - private PlaceholderTargetSource withDate; - - @Autowired - @Qualifier("compound") - private PlaceholderTargetSource compound; - - @Autowired - @Qualifier("ref") - private PlaceholderTargetSource ref; - - @Autowired - @Qualifier("value") - private PlaceholderTargetSource value; - - private Map map = Collections.singletonMap("foo.foo", (Object) "bar"); - - private Date date = new Date(1L); - - @Override - public Object getContext() { - return this; - } - - public String getFoo() { - return "bar"; - } - - public Map getMap() { - return map; - } - - public List getList() { - return Arrays.asList("bar", "spam"); - } - - public Node getParent() { - return new Foo("spam"); - } - - public Long getLong() { - return 12345678912345L; - } - - public Integer getInteger() { - return 4321; - } - - public Date getDate() { - return date; - } - - public String getGarbage() { - return null; - } - - @Test - public void testAfterPropertiesSet() throws Exception { - PlaceholderTargetSource targetSource = new PlaceholderTargetSource(); - try { - targetSource.afterPropertiesSet(); - fail("Axpected IllegalArgumentException"); - } - catch (IllegalArgumentException e) { - // expected - } - } - - @Test - public void testGetVanilla() { - Node target = (Node) vanilla.getTarget(); - assertEquals("foo", target.getName()); - } - - @Test - public void testGetSimple() { - Node target = (Node) simple.getTarget(); - assertEquals("bar", target.getName()); - } - - @Test - public void testGetCompound() { - Node target = (Node) compound.getTarget(); - assertEquals("bar-bar", target.getName()); - } - - @Test - public void testGetRef() { - Node target = (Node) ref.getTarget(); - assertEquals("foo", target.getParent().getName()); - } - - @Test - public void testGetValue() { - Node target = (Node) value.getTarget(); - assertEquals("spam", target.getParent().getName()); - } - - @Test - public void testGetLong() { - Node target = (Node) withLong.getTarget(); - assertEquals("bar-12345678912345", target.getName()); - } - - @Test - public void testGetInteger() { - Node target = (Node) withInteger.getTarget(); - assertEquals("bar-4321", target.getName()); - } - - @Test - public void testGetList() { - Node target = (Node) withList.getTarget(); - assertEquals(3, target.getList().size()); - assertEquals("[bar, foo-4321, bar-4321]", target.getList().toString()); - } - - @Test - public void testGetLiteralList() { - Node target = (Node) withLiteralList.getTarget(); - assertEquals(2, target.getList().size()); - assertEquals("[bar, spam]", target.getList().toString()); - } - - @Test - public void testGetMap() { - Node target = (Node) withMap.getTarget(); - assertEquals(3, target.getMap().size()); - assertEquals("{foo=bar, bar=foo-4321, spam=[bar, spam]}", target.getMap().toString()); - } - - @Test - public void testGetMultiple() { - Node target = (Node) withMultiple.getTarget(); - assertEquals("bar-4321-4321", target.getName()); - } - - @Test - public void testGetMultipleStartAndEnd() { - Node target = (Node) withMultipleStartAndEnd.getTarget(); - assertEquals("4321-4321", target.getName()); - } - - @Test - public void testGetEmbeddedDate() { - Node target = (Node) withEmbeddedDate.getTarget(); - String date = new Date(1L).toString(); - assertEquals("bar-"+date, target.getName()); - } - - @Test - public void testGetDate() { - Node target = (Node) withDate.getTarget(); - assertEquals(new Date(1L), target.getDate()); - } - - public static interface Node { - String getName(); - - Date getDate(); - - Node getParent(); - - List getList(); - - Map getMap(); - } - - public static class Foo implements Node { - - private String name; - - private Date date; - - private Node parent; - - private List list; - - private Map map; - - public Foo() { - } - - public Foo(String name) { - this.name = name; - } - - @Override - public String getName() { - return name; - } - - @Override - public Date getDate() { - return date; - } - - public void setDate(Date date) { - this.date = date; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public Node getParent() { - return parent; - } - - public void setParent(Node parent) { - this.parent = parent; - } - - public void setList(List list) { - this.list = list; - } - - @Override - public List getList() { - return list; - } - - @Override - public Map getMap() { - return map; - } - - public void setMap(Map map) { - this.map = map; - } - - } - -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/SimplePlaceholderTargetSourceTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/SimplePlaceholderTargetSourceTests.java deleted file mode 100644 index 720bd7eaa..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/SimplePlaceholderTargetSourceTests.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.springframework.batch.core.scope.util; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@ContextConfiguration -@RunWith(SpringJUnit4ClassRunner.class) -public class SimplePlaceholderTargetSourceTests { - - @Autowired - @Qualifier("simple") - private Node simple; - - @Autowired - private SimpleContextFactory contextFactory; - - @Test - public void testGetSimple() { - contextFactory.set("bar"); - assertEquals("bar", simple.getName()); - contextFactory.clear(); - } - - public static class SimpleContextFactory extends ContextFactorySupport { - - private ThreadLocal fooHolder = new ThreadLocal(); - - @Override - public Object getContext() { - return this; - } - - public void set(String value) { - fooHolder.set(value); - } - - public void clear() { - fooHolder.set(null); - } - - public String getFoo() { - return fooHolder.get(); - } - - } - - public static interface Node { - String getName(); - } - - public static class Foo implements Node { - - private String name; - - @Override - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - } - -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/StepContextFactoryTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/StepContextFactoryTests.java deleted file mode 100644 index dc1a9942e..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/StepContextFactoryTests.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.springframework.batch.core.scope.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import org.junit.After; -import org.junit.Test; -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.scope.context.StepContext; -import org.springframework.batch.core.scope.context.StepSynchronizationManager; - -public class StepContextFactoryTests { - - private StepContextFactory factory = new StepContextFactory(); - - @After - public void cleanUp() { - StepSynchronizationManager.close(); - StepSynchronizationManager.close(); - } - - @Test - public void testGetContext() { - StepExecution stepExecution = new StepExecution("foo", new JobExecution(11L)); - StepContext context = StepSynchronizationManager.register(stepExecution); - assertEquals(context, factory.getContext()); - } - - @Test - public void testGetContextId() { - StepSynchronizationManager.register(new StepExecution("foo", new JobExecution(11L), 0L)); - Object id1 = factory.getContextId(); - StepSynchronizationManager.register(new StepExecution("foo", new JobExecution(12L), 1L)); - Object id2 = factory.getContextId(); - assertFalse(id2.equals(id1)); - } - -}