|
@@ -3,6 +3,7 @@ package org.ssssssss.magicapi.adapter;
|
|
|
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
|
|
import org.springframework.util.ResourceUtils;
|
|
|
import org.ssssssss.magicapi.utils.IoUtils;
|
|
|
+import org.ssssssss.magicapi.utils.PathUtils;
|
|
|
|
|
|
import java.io.File;
|
|
|
import java.io.FileNotFoundException;
|
|
@@ -21,6 +22,8 @@ public abstract class ResourceAdapter {
|
|
|
|
|
|
private static PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
|
|
|
|
|
|
+ private static final String SPRING_BOOT_CLASS_PATH = "BOOT-INF/classes/";
|
|
|
+
|
|
|
public static Resource getResource(String location) throws IOException {
|
|
|
if (location == null) {
|
|
|
return null;
|
|
@@ -30,7 +33,7 @@ public abstract class ResourceAdapter {
|
|
|
resource = resolver.getResource(location);
|
|
|
if (resource.exists()) {
|
|
|
return resolveResource(resource, true);
|
|
|
- }else {
|
|
|
+ } else {
|
|
|
throw new FileNotFoundException(String.format("%s not found", resource.getDescription()));
|
|
|
}
|
|
|
} else {
|
|
@@ -43,20 +46,19 @@ public abstract class ResourceAdapter {
|
|
|
}
|
|
|
|
|
|
private static Resource resolveResource(org.springframework.core.io.Resource resource, boolean readonly) throws IOException {
|
|
|
- URL url = resource.getURL();
|
|
|
+ URL url = resource.getURI().toURL();
|
|
|
if (url.getProtocol().equals(ResourceUtils.URL_PROTOCOL_JAR)) {
|
|
|
JarURLConnection connection = (JarURLConnection) url.openConnection();
|
|
|
- String entryName = connection.getEntryName();
|
|
|
+ boolean springBootClassPath = connection.getClass().getName().equals("org.springframework.boot.loader.jar.JarURLConnection");
|
|
|
+ String entryName = (springBootClassPath ? SPRING_BOOT_CLASS_PATH : "") + connection.getEntryName();
|
|
|
JarFile jarFile = connection.getJarFile();
|
|
|
- return new JarResource(jarFile, entryName, jarFile.getEntry(entryName), jarFile.stream()
|
|
|
- .filter(it -> it.getName().startsWith(entryName))
|
|
|
- .collect(Collectors.toList()));
|
|
|
+ List<JarEntry> entries = jarFile.stream().filter(it -> it.getName().startsWith(entryName)).collect(Collectors.toList());
|
|
|
+ return new JarResource(jarFile, entryName, entries, springBootClassPath);
|
|
|
} else {
|
|
|
return new FileResource(resource.getFile(), readonly);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
private static class FileResource implements Resource {
|
|
|
|
|
|
private File file;
|
|
@@ -80,7 +82,7 @@ public abstract class ResourceAdapter {
|
|
|
|
|
|
@Override
|
|
|
public boolean delete() {
|
|
|
- return IoUtils.delete(this.file);
|
|
|
+ return !readonly() && IoUtils.delete(this.file);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -90,7 +92,7 @@ public abstract class ResourceAdapter {
|
|
|
|
|
|
@Override
|
|
|
public boolean mkdir() {
|
|
|
- return this.file.mkdirs();
|
|
|
+ return !readonly() && this.file.mkdirs();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -100,10 +102,12 @@ public abstract class ResourceAdapter {
|
|
|
|
|
|
@Override
|
|
|
public boolean renameTo(Resource resource) {
|
|
|
- File target = ((FileResource) resource).file;
|
|
|
- if (this.file.renameTo(target)) {
|
|
|
- this.file = target;
|
|
|
- return true;
|
|
|
+ if (!this.readonly()) {
|
|
|
+ File target = ((FileResource) resource).file;
|
|
|
+ if (this.file.renameTo(target)) {
|
|
|
+ this.file = target;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
@@ -136,21 +140,21 @@ public abstract class ResourceAdapter {
|
|
|
|
|
|
@Override
|
|
|
public boolean write(byte[] bytes) {
|
|
|
- return IoUtils.write(this.file, bytes);
|
|
|
+ return !readonly() && IoUtils.write(this.file, bytes);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public boolean write(String content) {
|
|
|
- return IoUtils.write(this.file, content);
|
|
|
+ return !readonly() && IoUtils.write(this.file, content);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public List<Resource> files(String suffix) {
|
|
|
- return IoUtils.files(this.file, suffix).stream().map(it -> new FileResource(it,this.readonly)).collect(Collectors.toList());
|
|
|
+ return IoUtils.files(this.file, suffix).stream().map(it -> new FileResource(it, this.readonly)).collect(Collectors.toList());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public String getAbsolutePath(){
|
|
|
+ public String getAbsolutePath() {
|
|
|
return this.file.getAbsolutePath();
|
|
|
}
|
|
|
|
|
@@ -172,15 +176,18 @@ public abstract class ResourceAdapter {
|
|
|
|
|
|
private JarResource parent = this;
|
|
|
|
|
|
- public JarResource(JarFile jarFile, String entryName, ZipEntry entry, List<JarEntry> entries) {
|
|
|
+ private boolean inSpringBoot;
|
|
|
+
|
|
|
+ public JarResource(JarFile jarFile, String entryName, List<JarEntry> entries, boolean inSpringBoot) {
|
|
|
this.jarFile = jarFile;
|
|
|
this.entryName = entryName;
|
|
|
- this.entry = entry;
|
|
|
+ this.inSpringBoot = inSpringBoot;
|
|
|
+ this.entry = getEntry(this.entryName);
|
|
|
this.entries = entries;
|
|
|
}
|
|
|
|
|
|
- public JarResource(JarFile jarFile, String entryName, ZipEntry entry, List<JarEntry> entries, JarResource parent) {
|
|
|
- this(jarFile, entryName, entry, entries);
|
|
|
+ public JarResource(JarFile jarFile, String entryName, List<JarEntry> entries, JarResource parent, boolean inSpringBoot) {
|
|
|
+ this(jarFile, entryName, entries, inSpringBoot);
|
|
|
this.parent = parent;
|
|
|
}
|
|
|
|
|
@@ -208,11 +215,20 @@ public abstract class ResourceAdapter {
|
|
|
return this.entry != null;
|
|
|
}
|
|
|
|
|
|
+ protected ZipEntry getEntry(String name) {
|
|
|
+ if (inSpringBoot && name.startsWith(SPRING_BOOT_CLASS_PATH)) {
|
|
|
+ name = name.substring(SPRING_BOOT_CLASS_PATH.length());
|
|
|
+ }
|
|
|
+ return this.jarFile.getEntry(name);
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public Resource getResource(String name) {
|
|
|
- String entryName = this.entryName + "/" + name;
|
|
|
- String prefix = this.entryName + "/";
|
|
|
- return new JarResource(this.jarFile, entryName, this.jarFile.getEntry(entryName), entries.stream().filter(it -> it.getName().startsWith(prefix)).collect(Collectors.toList()),this);
|
|
|
+ String entryName = PathUtils.replaceSlash(this.entryName + "/" + name);
|
|
|
+ String prefix = PathUtils.replaceSlash(entryName + "/");
|
|
|
+ return new JarResource(this.jarFile, entryName, entries.stream()
|
|
|
+ .filter(it -> it.getName().startsWith(prefix))
|
|
|
+ .collect(Collectors.toList()), this, this.inSpringBoot);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -228,26 +244,24 @@ public abstract class ResourceAdapter {
|
|
|
|
|
|
@Override
|
|
|
public List<Resource> dirs() {
|
|
|
- List<Resource> resources = resources();
|
|
|
- resources.stream().filter(Resource::isDirectory).map(Resource::dirs).forEach(resources::addAll);
|
|
|
- return resources;
|
|
|
+ return resources().stream().filter(Resource::isDirectory).collect(Collectors.toList());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public List<Resource> files(String suffix) {
|
|
|
return this.entries.stream().filter(it -> it.getName().endsWith(suffix))
|
|
|
- .map(entry -> new JarResource(jarFile, entry.getName(), entry, Collections.emptyList()))
|
|
|
+ .map(entry -> new JarResource(jarFile, entry.getName(), Collections.emptyList(), this.inSpringBoot))
|
|
|
.collect(Collectors.toList());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public List<Resource> resources() {
|
|
|
- String prefix = this.entryName + "/";
|
|
|
+ String prefix = PathUtils.replaceSlash(this.entryName + "/");
|
|
|
return entries.stream()
|
|
|
.filter(it -> it.getName().startsWith(prefix))
|
|
|
- .map(entry -> new JarResource(jarFile, entry.getName(), entry, entries.stream()
|
|
|
- .filter(item -> item.getName().startsWith(entry.getName() + "/"))
|
|
|
- .collect(Collectors.toList()))
|
|
|
+ .map(entry -> new JarResource(jarFile, entry.getName(), entries.stream()
|
|
|
+ .filter(item -> item.getName().startsWith(PathUtils.replaceSlash(entry.getName() + "/")))
|
|
|
+ .collect(Collectors.toList()), this.inSpringBoot)
|
|
|
)
|
|
|
.collect(Collectors.toList());
|
|
|
}
|