GenericResourceRepository.java
/*
* Copyright 2013-2020 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.cloud.config.server.resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import org.springframework.cloud.config.server.config.ConfigServerProperties;
import org.springframework.cloud.config.server.environment.SearchPathLocator;
import org.springframework.cloud.config.server.support.PathUtils;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* An {@link ResourceRepository} backed by a {@link SearchPathLocator}.
*
* @author Dave Syer
*/
public class GenericResourceRepository implements ResourceRepository, ResourceLoaderAware {
private ResourceLoader resourceLoader;
private SearchPathLocator service;
private ConfigServerProperties properties;
public GenericResourceRepository(SearchPathLocator service) {
this.service = service;
}
public GenericResourceRepository(SearchPathLocator service, ConfigServerProperties properties) {
this(service);
this.properties = properties;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Override
public synchronized Resource findOne(String application, String profile, String label, String path) {
if (StringUtils.hasText(path)) {
String[] locations = this.service.getLocations(application, profile, label).getLocations();
if (!ObjectUtils.isEmpty(properties) && properties.isReverseLocationOrder()) {
Collections.reverse(Arrays.asList(locations));
}
ArrayList<Resource> locationResources = new ArrayList<>();
for (String location : locations) {
if (!PathUtils.isInvalidEncodedLocation(location)) {
locationResources.add(this.resourceLoader.getResource(location.replaceFirst("optional:", "")));
}
}
try {
for (Resource location : locationResources) {
for (String local : getProfilePaths(profile, path)) {
if (!PathUtils.isInvalidPath(local) && !PathUtils.isInvalidEncodedPath(local)) {
Resource file = location.createRelative(local);
if (file.exists() && file.isReadable()
&& PathUtils.checkResource(file, location, locationResources)) {
return file;
}
}
}
}
}
catch (IOException e) {
throw new NoSuchResourceException("Error : " + path + ". (" + e.getMessage() + ")");
}
}
throw new NoSuchResourceException("Not found: " + path);
}
private Collection<String> getProfilePaths(String profiles, String path) {
Set<String> paths = new LinkedHashSet<>();
for (String profile : StringUtils.commaDelimitedListToSet(profiles)) {
if (!StringUtils.hasText(profile) || "default".equals(profile)) {
paths.add(path);
}
else {
String ext = StringUtils.getFilenameExtension(path);
String file = path;
if (ext != null) {
ext = "." + ext;
file = StringUtils.stripFilenameExtension(path);
}
else {
ext = "";
}
paths.add(file + "-" + profile + ext);
}
}
paths.add(path);
return paths;
}
}