001/*
002 * Copyright 2002-2019 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.scheduling.quartz;
018
019import java.io.IOException;
020import java.io.InputStream;
021import java.net.URL;
022
023import org.apache.commons.logging.Log;
024import org.apache.commons.logging.LogFactory;
025import org.quartz.spi.ClassLoadHelper;
026
027import org.springframework.core.io.DefaultResourceLoader;
028import org.springframework.core.io.Resource;
029import org.springframework.core.io.ResourceLoader;
030import org.springframework.lang.Nullable;
031import org.springframework.util.Assert;
032import org.springframework.util.ClassUtils;
033
034/**
035 * Wrapper that adapts from the Quartz {@link ClassLoadHelper} interface
036 * onto Spring's {@link ResourceLoader} interface. Used by default when
037 * the SchedulerFactoryBean runs in a Spring ApplicationContext.
038 *
039 * @author Juergen Hoeller
040 * @since 2.5.5
041 * @see SchedulerFactoryBean#setApplicationContext
042 */
043public class ResourceLoaderClassLoadHelper implements ClassLoadHelper {
044
045        protected static final Log logger = LogFactory.getLog(ResourceLoaderClassLoadHelper.class);
046
047        @Nullable
048        private ResourceLoader resourceLoader;
049
050
051        /**
052         * Create a new ResourceLoaderClassLoadHelper for the default
053         * ResourceLoader.
054         * @see SchedulerFactoryBean#getConfigTimeResourceLoader()
055         */
056        public ResourceLoaderClassLoadHelper() {
057        }
058
059        /**
060         * Create a new ResourceLoaderClassLoadHelper for the given ResourceLoader.
061         * @param resourceLoader the ResourceLoader to delegate to
062         */
063        public ResourceLoaderClassLoadHelper(@Nullable ResourceLoader resourceLoader) {
064                this.resourceLoader = resourceLoader;
065        }
066
067
068        @Override
069        public void initialize() {
070                if (this.resourceLoader == null) {
071                        this.resourceLoader = SchedulerFactoryBean.getConfigTimeResourceLoader();
072                        if (this.resourceLoader == null) {
073                                this.resourceLoader = new DefaultResourceLoader();
074                        }
075                }
076        }
077
078        @Override
079        public Class<?> loadClass(String name) throws ClassNotFoundException {
080                Assert.state(this.resourceLoader != null, "ResourceLoaderClassLoadHelper not initialized");
081                return ClassUtils.forName(name, this.resourceLoader.getClassLoader());
082        }
083
084        @SuppressWarnings("unchecked")
085        @Override
086        public <T> Class<? extends T> loadClass(String name, Class<T> clazz) throws ClassNotFoundException {
087                return (Class<? extends T>) loadClass(name);
088        }
089
090        @Override
091        @Nullable
092        public URL getResource(String name) {
093                Assert.state(this.resourceLoader != null, "ResourceLoaderClassLoadHelper not initialized");
094                Resource resource = this.resourceLoader.getResource(name);
095                if (resource.exists()) {
096                        try {
097                                return resource.getURL();
098                        }
099                        catch (IOException ex) {
100                                if (logger.isWarnEnabled()) {
101                                        logger.warn("Could not load " + resource);
102                                }
103                                return null;
104                        }
105                }
106                else {
107                        return getClassLoader().getResource(name);
108                }
109        }
110
111        @Override
112        @Nullable
113        public InputStream getResourceAsStream(String name) {
114                Assert.state(this.resourceLoader != null, "ResourceLoaderClassLoadHelper not initialized");
115                Resource resource = this.resourceLoader.getResource(name);
116                if (resource.exists()) {
117                        try {
118                                return resource.getInputStream();
119                        }
120                        catch (IOException ex) {
121                                if (logger.isWarnEnabled()) {
122                                        logger.warn("Could not load " + resource);
123                                }
124                                return null;
125                        }
126                }
127                else {
128                        return getClassLoader().getResourceAsStream(name);
129                }
130        }
131
132        @Override
133        public ClassLoader getClassLoader() {
134                Assert.state(this.resourceLoader != null, "ResourceLoaderClassLoadHelper not initialized");
135                ClassLoader classLoader = this.resourceLoader.getClassLoader();
136                Assert.state(classLoader != null, "No ClassLoader");
137                return classLoader;
138        }
139
140}