All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.batch.core.jsr.launch.support.BatchPropertyBeanPostProcessor Maven / Gradle / Ivy

/*
 * Copyright 2013-2014 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
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR 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.jsr.launch.support;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

import javax.batch.api.BatchProperty;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext;
import org.springframework.batch.core.jsr.configuration.support.JsrExpressionParser;
import org.springframework.batch.core.scope.StepScope;
import org.springframework.batch.core.scope.context.StepContext;
import org.springframework.batch.core.scope.context.StepSynchronizationManager;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanExpressionContext;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.expression.StandardBeanExpressionResolver;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

/**
 * 

* {@link BeanPostProcessor} implementation used to inject JSR-352 String properties into batch artifact fields * that are marked with the {@link BatchProperty} annotation. *

* * @author Chris Schaefer * @author Michael Minella * @since 3.0 */ @SuppressWarnings("unchecked") public class BatchPropertyBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware { private static final String SCOPED_TARGET_BEAN_PREFIX = "scopedTarget."; private static final Log LOGGER = LogFactory.getLog(BatchPropertyBeanPostProcessor.class); private static final Set> REQUIRED_ANNOTATIONS = new HashSet<>(); private JsrExpressionParser jsrExpressionParser; private BatchPropertyContext batchPropertyContext; static { ClassLoader cl = BatchPropertyBeanPostProcessor.class.getClassLoader(); try { REQUIRED_ANNOTATIONS.add((Class) cl.loadClass("javax.inject.Inject")); } catch (ClassNotFoundException ex) { LOGGER.warn("javax.inject.Inject not found - @BatchProperty marked fields will not be processed."); } REQUIRED_ANNOTATIONS.add(BatchProperty.class); } @Override public Object postProcessBeforeInitialization(final Object artifact, String artifactName) throws BeansException { Properties artifactProperties = getArtifactProperties(artifactName); if (artifactProperties.isEmpty()) { return artifact; } injectBatchProperties(artifact, artifactProperties); return artifact; } @Override public Object postProcessAfterInitialization(Object artifact, String artifactName) throws BeansException { return artifact; } private Properties getArtifactProperties(String artifactName) { String originalArtifactName = artifactName; if(originalArtifactName.startsWith(SCOPED_TARGET_BEAN_PREFIX)) { originalArtifactName = artifactName.substring(SCOPED_TARGET_BEAN_PREFIX.length()); } StepContext stepContext = StepSynchronizationManager.getContext(); if (stepContext != null) { return batchPropertyContext.getStepArtifactProperties(stepContext.getStepName(), originalArtifactName); } return batchPropertyContext.getArtifactProperties(originalArtifactName); } private void injectBatchProperties(final Object artifact, final Properties artifactProperties) { ReflectionUtils.doWithFields(artifact.getClass(), new ReflectionUtils.FieldCallback() { @Override public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException { if (isValidFieldModifier(field) && isAnnotated(field)) { boolean isAccessible = field.isAccessible(); field.setAccessible(true); String batchProperty = getBatchPropertyFieldValue(field, artifactProperties); if (StringUtils.hasText(batchProperty)) { field.set(artifact, batchProperty); } field.setAccessible(isAccessible); } } }); } private String getBatchPropertyFieldValue(Field field, Properties batchArtifactProperties) { BatchProperty batchProperty = field.getAnnotation(BatchProperty.class); if (!"".equals(batchProperty.name())) { return getBatchProperty(batchProperty.name(), batchArtifactProperties); } return getBatchProperty(field.getName(), batchArtifactProperties); } private String getBatchProperty(String propertyKey, Properties batchArtifactProperties) { if (batchArtifactProperties.containsKey(propertyKey)) { String propertyValue = (String) batchArtifactProperties.get(propertyKey); return jsrExpressionParser.parseExpression(propertyValue); } return null; } private boolean isAnnotated(Field field) { for (Class annotation : REQUIRED_ANNOTATIONS) { if (!field.isAnnotationPresent(annotation)) { return false; } } return true; } private boolean isValidFieldModifier(Field field) { return !Modifier.isStatic(field.getModifiers()) && !Modifier.isFinal(field.getModifiers()); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { if (!(beanFactory instanceof ConfigurableListableBeanFactory)) { throw new IllegalArgumentException( "BatchPropertyBeanPostProcessor requires a ConfigurableListableBeanFactory"); } ConfigurableListableBeanFactory configurableListableBeanFactory = (ConfigurableListableBeanFactory) beanFactory; BeanExpressionContext beanExpressionContext = new BeanExpressionContext(configurableListableBeanFactory, configurableListableBeanFactory.getBean(StepScope.class)); this.jsrExpressionParser = new JsrExpressionParser(new StandardBeanExpressionResolver(), beanExpressionContext); } @Autowired public void setBatchPropertyContext(BatchPropertyContext batchPropertyContext) { this.batchPropertyContext = batchPropertyContext; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy