Skip to content

Commit

Permalink
Fixed image-loader, recreating images when file changes (#50)
Browse files Browse the repository at this point in the history
* Fixed image-loader, recreating images when file changes

* fixing test and adding comments

* testing fix for windows modified date
  • Loading branch information
FlorianKirmaier authored Dec 9, 2024
1 parent ddcd43b commit 34a1af3
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,10 @@ public ImageEncoder getEncoder() {

/**
* Computes and returns a hash string representation for this instance.
* Note: This method currently returns the default hashCode as a string, which might not guarantee uniqueness.
*
* @return A string representing the hash of this instance.
*/
String getHashString() {
return Integer.toString(hashCode());
return ImageManager.computeImageDefinitionHash(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ CompletableFuture<Image> loadFXImageFuture(ImageSource source, ImageTransformer
* @param imageDefinition the image definition
* @return the computed MD5 hash as a string
*/
private String computeImageDefinitionHash(ImageDefinition imageDefinition) {
public static String computeImageDefinitionHash(ImageDefinition imageDefinition) {
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] hashBytes = digest.digest(imageDefinition.toJSON().toString().getBytes(StandardCharsets.UTF_8));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public JSONObject toJSON() {
JSONObject json = new JSONObject();
json.put("type", getClass().getSimpleName());
json.put("path", ImageUtils.escapeJson(file.getAbsolutePath()));
json.put("modified", file.lastModified());
return json;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,19 @@ public long identityHashValue() {
public JSONObject toJSON() {
JSONObject json = new JSONObject();
json.put("type", getClass().getSimpleName());
// Escaping might be necessary depending on the structure of resourcePath.
json.put("resourcePath", ImageUtils.escapeJson(resourcePath));
// get last modified date
// It's important, so the images get recreated, when the files in the jar are updated
try {
URL resourceUrl = getClass().getResource(resourcePath);
if (resourceUrl != null) {
// we don't access any stream here, so we don't need to close it
URLConnection conn = resourceUrl.openConnection();
json.put("modified", conn.getLastModified());
}
} catch (Exception ex) {
throw new RuntimeException("Error obtaining modification date for resource: " + resourcePath, ex);
}
return json;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,14 @@
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import java.io.IOException;
import java.nio.file.Files;

import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.FileTime;
import java.time.Instant;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;

Expand All @@ -26,6 +32,9 @@ class ImageManagerTest {

ImageManager manager;
ImageDefinition def;
File imageDef2File;
ImageDefinition imageDef2;



@BeforeEach
Expand All @@ -44,6 +53,12 @@ void setUp() throws InterruptedException {
ImageTransformer transformer = new ImageTransformerFitWidth(200);
ImageEncoder encoder = new ImageEncoderPNG();
def = new ImageDefinition(source, transformer, encoder);

imageDef2File = new File("testImage.png");
ImageSource source2 = new ImageSourceFile(imageDef2File);
ImageTransformer transformer2 = new ImageTransformerFitWidth(200);
ImageEncoder encoder2 = new ImageEncoderPNG();
imageDef2 = new ImageDefinition(source2, transformer2, encoder2);
}

@Test
Expand All @@ -68,6 +83,45 @@ void testImageNotCreatedTwice() {
assertEquals(imageFileBefore.lastModified(), imageFileAfter.lastModified(), "Image was created again.");
}

@Test
void testImageRecreateOnChange() throws IOException {
// Copy file1 to imageDef2File
File file1 = new File(getClass().getResource("/testImage.png").getFile());
File file2 = new File(getClass().getResource("/logo.png").getFile());
assertTrue(file1.exists());
assertTrue(file2.exists());

Files.copy(file1.toPath(), imageDef2File.toPath(), StandardCopyOption.REPLACE_EXISTING);

var image1 = manager.loadImage(imageDef2);
String hash1 = imageDef2.getHashString();
System.out.println("ModifiedDate1: " + imageDef2File.lastModified());

Files.copy(file2.toPath(), imageDef2File.toPath(), StandardCopyOption.REPLACE_EXISTING);
System.out.println("ModifiedDate2: " + imageDef2File.lastModified());
Files.setLastModifiedTime(imageDef2File.toPath(), FileTime.from(Instant.now()));
System.out.println("ModifiedDate3: " + imageDef2File.lastModified());

var image2 = manager.loadImage(imageDef2);
String hash2 = imageDef2.getHashString();

System.out.println("hash1: " + hash1);
System.out.println("hash2: " + hash2);
assertNotEquals(hash1, hash2, "changed image file should have different hash");

File imageFile1 = image1.getFile();
File imageFile2 = image2.getFile();

assertTrue(imageFile1.exists());
assertTrue(imageFile2.exists());

System.out.println("imageFile1: " + imageFile1.lastModified());
System.out.println("imageFile2: " + imageFile2.lastModified());

assertNotEquals(imageFile1.lastModified(), imageFile2.lastModified(),
"Image was not created again.");
}

@Test
void testLoadImageFuture() {
CompletableFuture<ImageResult> future = manager.loadImageFuture(def);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public void testToJson() {
JSONObject json = new JSONObject();
json.put("type", "ImageSourceFile");
json.put("path", ImageUtils.escapeJson(testImageFile.getAbsolutePath()));
json.put("modified", testImageFile.lastModified());

assertTrue(imageSource.toJSON().similar(json));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import org.junit.jupiter.api.Test;

import java.awt.image.BufferedImage;
import java.net.URL;
import java.net.URLConnection;

import static org.junit.jupiter.api.Assertions.*;

Expand All @@ -30,12 +32,18 @@ void testIdentityHashValue_validResourcePath_returnsHash() {
}

@Test
void testToJson_returnsExpectedJson() {
void testToJson_returnsExpectedJson() throws Exception {
ImageSourceResource resource = new ImageSourceResource("/testImage.png");

JSONObject json = new JSONObject();
json.put("type", "ImageSourceResource");
json.put("resourcePath", "/testImage.png");
URL resourceUrl = getClass().getResource("/testImage.png");
if (resourceUrl != null) {
// we don't access any stream here, so we don't need to close it
URLConnection conn = resourceUrl.openConnection();
json.put("modified", conn.getLastModified());
}
assertTrue(resource.toJSON().similar(json));
}
}

0 comments on commit 34a1af3

Please sign in to comment.