001/*
002 * Copyright 2006-2014 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.batch.sample.launch;
018
019import java.util.HashMap;
020import java.util.Map;
021
022import org.springframework.batch.core.Job;
023import org.springframework.batch.core.configuration.ListableJobLocator;
024import org.springframework.batch.core.launch.NoSuchJobException;
025import org.springframework.beans.BeanWrapperImpl;
026import org.springframework.beans.BeansException;
027import org.springframework.beans.PropertyAccessorUtils;
028import org.springframework.context.ApplicationContext;
029import org.springframework.context.ApplicationContextAware;
030import org.springframework.context.support.ClassPathXmlApplicationContext;
031import org.springframework.util.Assert;
032
033public class DefaultJobLoader implements JobLoader, ApplicationContextAware {
034
035        private ListableJobLocator registry;
036
037        private ApplicationContext applicationContext;
038
039        private Map<String, String> configurations = new HashMap<String, String>();
040
041        @Override
042        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
043                this.applicationContext = applicationContext;
044        }
045
046        public void setRegistry(ListableJobLocator registry) {
047                this.registry = registry;
048        }
049
050        @Override
051        public Map<String, String> getConfigurations() {
052                Map<String, String> result = new HashMap<String, String>(configurations);
053                for (String jobName : registry.getJobNames()) {
054                        try {
055                                Job configuration = registry.getJob(jobName);
056                                String name = configuration.getName();
057                                if (!configurations.containsKey(name)) {
058                                        result.put(name, "<unknown path>: " + configuration);
059                                }
060                        }
061                        catch (NoSuchJobException e) {
062                                throw new IllegalStateException("Registry could not locate its own job (NoSuchJobException).", e);
063                        }
064                }
065                return result;
066        }
067
068        @Override
069        @SuppressWarnings("resource")
070        public void loadResource(String path) {
071                ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { path },
072                                applicationContext);
073                String[] names = context.getBeanNamesForType(Job.class);
074                for (String name : names) {
075                        configurations.put(name, path);
076                }
077        }
078
079        @Override
080        public Object getJobConfiguration(String name) {
081                try {
082                        return registry.getJob(name);
083                }
084                catch (NoSuchJobException e) {
085                        return null;
086                }
087        }
088
089        @Override
090        public Object getProperty(String path) {
091                int index = PropertyAccessorUtils.getFirstNestedPropertySeparatorIndex(path);
092                BeanWrapperImpl wrapper = createBeanWrapper(path, index);
093                String key = path.substring(index + 1);
094                return wrapper.getPropertyValue(key);
095        }
096
097        @Override
098        public void setProperty(String path, String value) {
099                int index = PropertyAccessorUtils.getFirstNestedPropertySeparatorIndex(path);
100                BeanWrapperImpl wrapper = createBeanWrapper(path, index);
101                String key = path.substring(index + 1);
102                wrapper.setPropertyValue(key, value);
103        }
104
105        private BeanWrapperImpl createBeanWrapper(String path, int index) {
106                Assert.state(index > 0, "Path must be nested, e.g. bean.value");
107                String name = path.substring(0, index);
108                Object bean = getJobConfiguration(name);
109                Assert.notNull(bean, "No JobConfiguration exists with name=" + name);
110                return new BeanWrapperImpl(bean);
111        }
112
113}