net.hasor.cobble.loader.providers.ExportResourceLoader Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2008-2009 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
*
* http://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 net.hasor.cobble.loader.providers;
import net.hasor.cobble.loader.AbstractResourceLoader;
import net.hasor.cobble.loader.MatchType;
import net.hasor.cobble.loader.ResourceLoader;
import net.hasor.cobble.loader.Scanner;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.util.*;
import java.util.function.Predicate;
/**
* 仅允许将 ResourceLoader 的中的一部分资源设置为 '可见'
*
* -- 与 ImportResourceLoader 不同的是 ExportResourceLoader 是对某个特定 ResourceLoader 的增强。
* -- 可以通过 setExportAll 方法开放所有资源被访问。
* @version : 2021-10-10
* @author 赵永春 ([email protected])
*/
public class ExportResourceLoader extends AbstractResourceLoader {
private boolean exportAll = false;
private final Set exportPathSet = new HashSet<>();
private final ResourceLoader resourceLoader;
public ExportResourceLoader(ResourceLoader resourceLoader) {
this(null, resourceLoader);
}
public ExportResourceLoader(ClassLoader parent, ResourceLoader resourceLoader) {
super(parent);
this.resourceLoader = resourceLoader;
}
public Class> getClass(String className) throws ClassNotFoundException {
String resource = className.replace(".", "/") + ".class";
if (this.exist(resource)) {
return resourceLoader.getClass(className);
} else {
throw new ClassNotFoundException(className);
}
}
public boolean isExportAll() {
return this.exportAll;
}
public void setExportAll(boolean exportAll) {
this.exportAll = exportAll;
}
public void addExport(String exportResources) {
if (exportResources != null && exportResources.length() > 0) {
if (exportResources.charAt(exportResources.length() - 1) != '/') {
exportResources = exportResources + '/';
}
this.exportPathSet.add(fmtDirPath(exportResources));
}
}
public Set getExportSet() {
return this.exportPathSet;
}
private static String fmtDirPath(String dirPath) {
if (dirPath.startsWith("/")) {
dirPath = dirPath.substring(1);
}
// Looking for org/codehaus/werkflow/personality/basic/../common/core-idioms.xml
// | i |
// +-------+ remove
int i = dirPath.indexOf("/..");
// Can't be at the beginning because we have no root to refer to so we start at 1.
if (i > 0) {
int j = dirPath.lastIndexOf("/", i - 1);
if (j >= 0) {
dirPath = dirPath.substring(0, j) + dirPath.substring(i + 3);
}
}
int j = dirPath.lastIndexOf("/");
if (j > 0) {
dirPath = dirPath.substring(0, j);
}
dirPath = dirPath.replace("\\", "/");
if (!dirPath.isEmpty() && dirPath.charAt(0) == '/') {
dirPath = dirPath.substring(1);
}
return dirPath;
}
protected boolean testPath(String dirPath) {
if (this.exportAll) {
return true;
} else if (this.exportPathSet.isEmpty()) {
return false;
}
dirPath = fmtDirPath(dirPath);
if (this.exportPathSet.contains(dirPath)) {
return true;
}
int index = dirPath.length();
while (true) {
index = dirPath.lastIndexOf("/", index);
if (index == -1) {
break;
}
dirPath = dirPath.substring(0, index);
if (this.exportPathSet.contains(dirPath)) {
return true;
}
}
return false;
}
@Override
public List scanResources(MatchType matchType, Predicate matcher, Scanner scanner, String[] scanPaths) throws IOException {
if (scanPaths.length == 0) {
scanPaths = this.exportPathSet.toArray(new String[0]);
} else {
scanPaths = Arrays.stream(scanPaths).filter(this::testPath).toArray(String[]::new);
}
if (scanPaths.length == 0) {
return Collections.emptyList();
}
return this.resourceLoader.scanResources(matchType, matcher, scanner, scanPaths);
}
@Override
public T scanOneResource(MatchType matchType, Predicate matcher, Scanner scanner, String[] scanPaths) throws IOException {
if (scanPaths.length == 0) {
scanPaths = this.exportPathSet.toArray(new String[0]);
} else {
scanPaths = Arrays.stream(scanPaths).filter(this::testPath).toArray(String[]::new);
}
if (scanPaths.length == 0) {
return null;
}
return this.resourceLoader.scanOneResource(matchType, matcher, scanner, scanPaths);
}
@Override
public URL getResource(String resource) throws IOException {
if (!testPath(resource)) {
return null;
}
return this.resourceLoader.getResource(resource);
}
@Override
public InputStream getResourceAsStream(String resource) throws IOException {
if (!testPath(resource)) {
return null;
}
return this.resourceLoader.getResourceAsStream(resource);
}
@Override
public long getResourceSize(String resource) throws IOException {
if (!testPath(resource)) {
return -1;
}
return this.resourceLoader.getResourceSize(resource);
}
@Override
public List getResources(String resource) throws IOException {
if (!testPath(resource)) {
return Collections.emptyList();
}
return this.resourceLoader.getResources(resource);
}
@Override
public List getResourcesAsStream(String resource) throws IOException {
if (!testPath(resource)) {
return Collections.emptyList();
}
return this.resourceLoader.getResourcesAsStream(resource);
}
@Override
public boolean exist(String resource) {
if (!testPath(resource)) {
return false;
}
return this.resourceLoader.exist(resource);
}
}