001/*
002 * Copyright 2002-2012 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.core.io;
018
019import org.springframework.util.Assert;
020import org.springframework.util.StringUtils;
021
022/**
023 * {@link ResourceLoader} implementation that interprets plain resource paths
024 * as relative to a given {@code java.lang.Class}.
025 *
026 * @author Juergen Hoeller
027 * @since 3.0
028 * @see Class#getResource(String)
029 * @see ClassPathResource#ClassPathResource(String, Class)
030 */
031public class ClassRelativeResourceLoader extends DefaultResourceLoader {
032
033        private final Class<?> clazz;
034
035
036        /**
037         * Create a new ClassRelativeResourceLoader for the given class.
038         * @param clazz the class to load resources through
039         */
040        public ClassRelativeResourceLoader(Class<?> clazz) {
041                Assert.notNull(clazz, "Class must not be null");
042                this.clazz = clazz;
043                setClassLoader(clazz.getClassLoader());
044        }
045
046        @Override
047        protected Resource getResourceByPath(String path) {
048                return new ClassRelativeContextResource(path, this.clazz);
049        }
050
051
052        /**
053         * ClassPathResource that explicitly expresses a context-relative path
054         * through implementing the ContextResource interface.
055         */
056        private static class ClassRelativeContextResource extends ClassPathResource implements ContextResource {
057
058                private final Class<?> clazz;
059
060                public ClassRelativeContextResource(String path, Class<?> clazz) {
061                        super(path, clazz);
062                        this.clazz = clazz;
063                }
064
065                @Override
066                public String getPathWithinContext() {
067                        return getPath();
068                }
069
070                @Override
071                public Resource createRelative(String relativePath) {
072                        String pathToUse = StringUtils.applyRelativePath(getPath(), relativePath);
073                        return new ClassRelativeContextResource(pathToUse, this.clazz);
074                }
075        }
076
077}