Add support for getting last modified date to Resource

- Use AssetVersions.yml for jar files
- Use File#lastModified for regular files
This commit is contained in:
Aurora Lahtela 2023-01-21 15:03:29 +02:00
parent b26678b3dc
commit 0bce7880cd
9 changed files with 59 additions and 14 deletions

View File

@ -20,6 +20,7 @@ import com.djrapitops.plan.settings.config.Config;
import com.djrapitops.plan.settings.config.ConfigNode;
import com.djrapitops.plan.settings.config.ConfigReader;
import com.djrapitops.plan.storage.file.PlanFiles;
import com.djrapitops.plan.utilities.dev.Untrusted;
import javax.inject.Inject;
import javax.inject.Singleton;
@ -46,7 +47,7 @@ public class AssetVersions {
}
}
public Optional<Long> getAssetVersion(String resource) {
public Optional<Long> getAssetVersion(@Untrusted String resource) {
if (webAssetConfig == null) return Optional.empty();
return webAssetConfig.getNode(resource.replace('.', ',')).map(ConfigNode::getLong);

View File

@ -62,6 +62,11 @@ public class FileResource implements Resource {
return resourceName;
}
@Override
public long getLastModifiedDate() {
return file.lastModified();
}
@Override
public InputStream asInputStream() throws IOException {
return new FileInputStream(file);

View File

@ -26,6 +26,7 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.function.LongSupplier;
/**
* {@link Resource} implementation for something that is read via InputStream.
@ -36,14 +37,21 @@ public class JarResource implements Resource {
private final String resourceName;
private final StreamSupplier streamSupplier;
private final LongSupplier lastModifiedSupplier;
public JarResource(String resourceName, StreamSupplier streamSupplier) {
public JarResource(String resourceName, StreamSupplier streamSupplier, LongSupplier lastModifiedSupplier) {
this.resourceName = resourceName;
this.streamSupplier = streamSupplier;
this.lastModifiedSupplier = lastModifiedSupplier;
}
public JarResource(String resourceName, StreamFunction streamFunction) {
this(resourceName, () -> streamFunction.get(resourceName));
public JarResource(String resourceName, StreamFunction streamFunction, LongSupplier lastModifiedSupplier) {
this(resourceName, () -> streamFunction.get(resourceName), lastModifiedSupplier);
}
@Override
public long getLastModifiedDate() {
return lastModifiedSupplier.getAsLong();
}
@Override

View File

@ -17,11 +17,14 @@
package com.djrapitops.plan.storage.file;
import com.djrapitops.plan.SubSystem;
import com.djrapitops.plan.delivery.web.AssetVersions;
import com.djrapitops.plan.exceptions.EnableException;
import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.settings.config.paths.CustomizedFileSettings;
import com.djrapitops.plan.utilities.dev.Untrusted;
import dagger.Lazy;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import javax.inject.Inject;
import javax.inject.Named;
@ -46,16 +49,19 @@ public class PlanFiles implements SubSystem {
private final File dataFolder;
private final File configFile;
private final Lazy<AssetVersions> assetVersions;
private final Lazy<PlanConfig> config;
@Inject
public PlanFiles(
@Named("dataFolder") File dataFolder,
JarResource.StreamFunction getResourceStream,
Lazy<AssetVersions> assetVersions,
Lazy<PlanConfig> config
) {
this.dataFolder = dataFolder;
this.getResourceStream = getResourceStream;
this.assetVersions = assetVersions;
this.config = config;
this.configFile = getFileFromPluginFolder("config.yml");
}
@ -120,7 +126,18 @@ public class PlanFiles implements SubSystem {
* @return a {@link Resource} for accessing the resource.
*/
public Resource getResourceFromJar(@Untrusted String resourceName) {
return new JarResource("assets/plan/" + resourceName, getResourceStream);
return new JarResource(
"assets/plan/" + resourceName,
getResourceStream,
() -> getLastModifiedForJarResource(resourceName)
);
}
@NotNull
protected Long getLastModifiedForJarResource(@Untrusted String resourceName) {
String webResourceName = StringUtils.remove(resourceName, "web/");
return assetVersions.get().getAssetVersion(webResourceName)
.orElseGet(System::currentTimeMillis);
}
/**

View File

@ -42,6 +42,8 @@ public interface Resource {
@Untrusted
String getResourceName();
long getLastModifiedDate();
byte[] asBytes() throws IOException;
/**

View File

@ -33,7 +33,7 @@ import java.util.function.Supplier;
*/
public class ResourceCache {
private static final Cache<String, String> cache = Caffeine.newBuilder()
private static final Cache<String, Resource> cache = Caffeine.newBuilder()
.expireAfterAccess(1, TimeUnit.MINUTES)
.build();
@ -42,17 +42,17 @@ public class ResourceCache {
}
public static Resource getOrCache(@Untrusted String resourceName, Supplier<Resource> resourceSupplier) {
String found = cache.getIfPresent(resourceName);
Resource found = cache.getIfPresent(resourceName);
if (found == null) {
Resource created = resourceSupplier.get();
if (created == null) return null;
return new StringCachingResource(created);
}
return new StringResource(resourceName, found);
return found;
}
public static void cache(String resourceName, String got) {
cache.put(resourceName, got);
public static void cache(@Untrusted String resourceName, String contents, long lastModifiedDate) {
cache.put(resourceName, new StringResource(resourceName, contents, lastModifiedDate));
}
public static void invalidateAll() {

View File

@ -38,6 +38,9 @@ public class StringCachingResource implements Resource {
return implementation.getResourceName();
}
@Override
public long getLastModifiedDate() {return implementation.getLastModifiedDate();}
@Override
public InputStream asInputStream() throws IOException {
return implementation.asInputStream();
@ -51,7 +54,7 @@ public class StringCachingResource implements Resource {
@Override
public String asString() throws IOException {
String got = implementation.asString();
ResourceCache.cache(implementation.getResourceName(), got);
ResourceCache.cache(implementation.getResourceName(), got, implementation.getLastModifiedDate());
return got;
}

View File

@ -33,10 +33,12 @@ public class StringResource implements Resource {
private final String resourceName;
private final String resource;
private final long lastModified;
StringResource(String resourceName, String resource) {
StringResource(String resourceName, String resource, long lastModified) {
this.resourceName = resourceName;
this.resource = resource;
this.lastModified = lastModified;
}
@Override
@ -44,6 +46,11 @@ public class StringResource implements Resource {
return resourceName;
}
@Override
public long getLastModifiedDate() {
return lastModified;
}
@Override
public InputStream asInputStream() {
return new ByteArrayInputStream(resource.getBytes(StandardCharsets.UTF_8));

View File

@ -18,6 +18,7 @@ package com.djrapitops.plan.storage.file;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.PlanSponge;
import com.djrapitops.plan.delivery.web.AssetVersions;
import com.djrapitops.plan.settings.config.PlanConfig;
import dagger.Lazy;
import org.spongepowered.api.Sponge;
@ -45,9 +46,10 @@ public class SpongePlanFiles extends PlanFiles {
@Named("dataFolder") File dataFolder,
JarResource.StreamFunction getResourceStream,
PlanPlugin plugin,
Lazy<AssetVersions> assetVersions,
Lazy<PlanConfig> config
) {
super(dataFolder, getResourceStream, config);
super(dataFolder, getResourceStream, assetVersions, config);
this.plugin = plugin;
}
@ -73,7 +75,7 @@ public class SpongePlanFiles extends PlanFiles {
StringWriter writer = new StringWriter()
) {
reader.transferTo(writer);
return new StringResource(resourceName, writer.toString());
return new StringResource(resourceName, writer.toString(), getLastModifiedForJarResource(resourceName));
}
}
}