Skip to content

Commit

Permalink
Merge pull request #61 from avpinchuk/fix-last-modified-detection
Browse files Browse the repository at this point in the history
Improve file last modified time detection
  • Loading branch information
arjantijms authored Oct 4, 2023
2 parents 1ed2425 + d37cdd3 commit 1f9bff7
Showing 1 changed file with 56 additions and 6 deletions.
62 changes: 56 additions & 6 deletions src/main/java/org/glassfish/wasp/compiler/Compiler.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, 2022 Contributors to the Eclipse Foundation.
* Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation.
* Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright 2004 The Apache Software Foundation
* Copyright (c) 2022 Contributors to the Eclipse Foundation
Expand All @@ -20,14 +20,20 @@
package org.glassfish.wasp.compiler;

import static java.util.logging.Level.FINE;
import static java.util.logging.Level.SEVERE;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -461,9 +467,9 @@ public boolean isOutDated(boolean checkClass) {
targetFile = new File(pagesCompilationContext.getServletJavaFileName());
}

// Get the target file's last modified time. File.lastModified()
// returns 0 if the file does not exist.
long targetLastModified = targetFile.lastModified();
// Get the target file's last modified time.
// getLastModifiedTime() returns 0 if the file does not exist.
long targetLastModified = getLastModifiedTime(targetFile);

// Check cached class file
if (checkClass) {
Expand All @@ -484,7 +490,7 @@ public boolean isOutDated(boolean checkClass) {
}

// Check if the Pages file exists in the filesystem (instead of a jar
// or a remote location). If yes, then do a File.lastModified()
// or a remote location). If yes, then do a getLastModifiedTime()
// to determine its last modified time. This is more performant
// (fewer stat calls) than the ctxt.getResource() followed by
// openConnection(). However, it only works for file system jsps.
Expand All @@ -493,7 +499,7 @@ public boolean isOutDated(boolean checkClass) {
if (pagesServletWrapper != null) {
File jspFile = pagesServletWrapper.getJspFile();
if (jspFile != null) {
jspRealLastModified = jspFile.lastModified();
jspRealLastModified = getLastModifiedTime(jspFile);
}
}

Expand Down Expand Up @@ -577,6 +583,50 @@ public boolean isOutDated(boolean checkClass) {

}

/**
* Returns a file's last modified time.
*
* <p>The {@code 0L} time stamp may be returned when:
* <ul>
* <li>Basic attribute view is not available for {@code file}.</li>
* <li>Creation time stamp and last modified time stamp not implemented for {@code file}.</li>
* <li>An I/O error occurred.</li>
* </ul>
*
* <p>If numeric overflow occurs, returns Long.MIN_VALUE if negative and Long.MAX_VALUE if positive.
*
* @param file file to read attributes from
* @return a time stamp representing the time the file was last modified
*/
private long getLastModifiedTime(File file) {
BasicFileAttributeView attributeView = Files.getFileAttributeView(file.toPath(), BasicFileAttributeView.class);
if (attributeView == null) {
log.log(SEVERE, "Basic attribute view is not available for " + file.getAbsolutePath());
return 0L;
}

BasicFileAttributes attributes;
try {
attributes = attributeView.readAttributes();
} catch (IOException e) {
log.log(SEVERE, "Failed to read attributes for file " + file.getAbsolutePath(), e);
return 0L;
}

FileTime creationTime = attributes.creationTime();
FileTime lastModifiedTime = attributes.lastModifiedTime();

if (creationTime == null) {
return lastModifiedTime != null ? lastModifiedTime.toMillis() : 0L;
}

if (lastModifiedTime == null) {
return creationTime.toMillis();
}

return creationTime.compareTo(lastModifiedTime) <= 0 ? lastModifiedTime.toMillis() : creationTime.toMillis();
}

/**
* Gets the error dispatcher.
*/
Expand Down

0 comments on commit 1f9bff7

Please sign in to comment.