Skip to content

Commit

Permalink
fix isModified comparison.
Browse files Browse the repository at this point in the history
While also:
1. Upgrade reflection library due to ronmamo/reflections#273
2. Memoized list of classloaders as it's getting called on each processed file.
3. Added tests for SimpleCache
4. Added tests CodeGenerator fix
5. Minor adjustments
  • Loading branch information
afathonih committed Aug 9, 2022
1 parent dd8daca commit 1655a20
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 20 deletions.
Expand Up @@ -29,7 +29,6 @@
import org.apache.commons.io.FilenameUtils;
import org.graphwalker.core.generator.PathGeneratorBase;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.slf4j.Logger;
Expand All @@ -47,10 +46,6 @@ private GeneratorFactoryScanner() {

private static final Logger logger = LoggerFactory.getLogger(GeneratorFactoryScanner.class);

static {
Reflections.log = null;
}

private static boolean valid(URL url) {
String extension = FilenameUtils.getExtension(url.getPath());
return "".equals(extension) || "jar".equals(extension);
Expand Down
Expand Up @@ -33,9 +33,12 @@
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import org.apache.commons.io.FilenameUtils;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.Scanners;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.slf4j.Logger;
Expand All @@ -56,10 +59,6 @@ private ContextFactoryScanner() {

private static final Logger logger = LoggerFactory.getLogger(ContextFactoryScanner.class);

static {
Reflections.log = null;
}

private static Map<Class<? extends ContextFactory>, ContextFactory> factories = new HashMap<>();

private static boolean valid(URL url) {
Expand All @@ -80,8 +79,15 @@ private static Collection<URL> getUrls() {
return filteredUrls;
}

private static Reflections getReflections(Collection<URL> urls) {
return new Reflections(new ConfigurationBuilder().addUrls(urls).setScanners(Scanners.SubTypes));
}

public static ContextFactory get(Path path) {
return get(new Reflections(new ConfigurationBuilder().addUrls(getUrls()).addScanners(new SubTypesScanner())), path);
Supplier<Collection<URL>> memoizedUrls;
memoizedUrls = Suppliers.memoize(ContextFactoryScanner::getUrls);

return get(getReflections(memoizedUrls.get()), path);
}

public static ContextFactory get(Reflections reflections, Path path) {
Expand Down
4 changes: 4 additions & 0 deletions graphwalker-java/pom.xml
Expand Up @@ -81,6 +81,10 @@
<artifactId>classgraph</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Expand Up @@ -49,8 +49,10 @@
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -91,7 +93,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) thro
}

private boolean isModified(Path file) throws IOException {
return !Files.getLastModifiedTime(file).equals(cache.get(file).getLastModifiedTime());
return Files.getLastModifiedTime(file).toMillis() != cache.get(file).getLastModifiedTime().toMillis();
}

@Override
Expand All @@ -111,7 +113,7 @@ private static void write(Context context, SourceFile file) throws IOException {
RuntimeModel model = context.getModel();
String source = generator.generate(file, model);
Files.createDirectories(file.getOutputPath().getParent());
Files.write(file.getOutputPath(), source.getBytes(Charset.forName("UTF-8"))
Files.write(file.getOutputPath(), source.getBytes(StandardCharsets.UTF_8)
, StandardOpenOption.CREATE
, StandardOpenOption.TRUNCATE_EXISTING);
} catch (Throwable t) {
Expand Down
Expand Up @@ -32,6 +32,7 @@
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Expand Down Expand Up @@ -60,7 +61,7 @@ public SimpleCache(Path path) {
private void read() {
if (Files.exists(path)) {
try {
String json = new String(Files.readAllBytes(path), Charset.forName("UTF-8"));
String json = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
Map<String, CacheEntry> data = gson.fromJson(json, type);
storage.putAll(data);
} catch (IOException e) {
Expand All @@ -74,7 +75,7 @@ private void save() {
try {
String json = gson.toJson(storage);
Files.createDirectories(path.getParent());
Files.write(path, json.getBytes(Charset.forName("UTF-8")));
Files.write(path, json.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
logger.error(e.getMessage());
throw new CacheException(e);
Expand Down
Expand Up @@ -40,8 +40,7 @@
import org.graphwalker.java.factory.PathGeneratorFactory;
import org.graphwalker.java.report.XMLReportGenerator;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.reflections.scanners.Scanners;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.slf4j.Logger;
Expand Down Expand Up @@ -70,10 +69,9 @@ public final class TestExecutor implements Executor, Observer {

private static final Reflections reflections = new Reflections(new ConfigurationBuilder()
.addUrls(filter(ClasspathHelper.forJavaClassPath(), ClasspathHelper.forClassLoader()))
.addScanners(new SubTypesScanner(), new TypeAnnotationsScanner()));
.setScanners(Scanners.SubTypes, Scanners.TypesAnnotated));

private static Collection<URL> filter(Collection<URL> classPath, Collection<URL> classLoader) {
Reflections.log = null;
List<URL> urls = new ArrayList<>(), filteredUrls = new ArrayList<>();
urls.addAll(classPath);
urls.addAll(classLoader);
Expand Down
@@ -0,0 +1,70 @@
package org.graphwalker.java.source;

import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.*;
import java.nio.file.attribute.FileTime;
import java.util.Arrays;

import static org.junit.Assert.*;

public class CodeGeneratorTest {

@Test
public void testOnlyRegenerateWhenSourceIsModified() throws IOException, URISyntaxException {
String tmpdir = System.getProperty("java.io.tmpdir");
Path inputDir = Files.createTempDirectory(Paths.get(tmpdir), "input").toAbsolutePath();
Path outputDir = Files.createTempDirectory(Paths.get(tmpdir), "output").toAbsolutePath();

// sample file
URL resource = getClass().getClassLoader().getResource("org/graphwalker/java/path with space/MyModel.graphml");
File testFile = new File(resource.toURI());

Files.copy(testFile.toPath(), inputDir.resolve(testFile.getName()), StandardCopyOption.REPLACE_EXISTING);
FileTime sourceLastModified = Files.getLastModifiedTime(inputDir.resolve(testFile.getName()));

File[] inputFiles = Arrays.stream(inputDir.toFile().listFiles())
.toArray(File[]::new);

assertEquals(1, inputFiles.length);

// run codegenerator for each input files in inputDir
CodeGenerator.generate(inputDir, outputDir);

// source modified time should not be altered
FileTime sourceLastModifiedDelta = Files.getLastModifiedTime(inputDir.resolve(testFile.getName()));
assertEquals(sourceLastModified.toMillis(), sourceLastModifiedDelta.toMillis());

// glob the output files, find the one with the same name as the input file
File[] outputFiles = Arrays.stream(outputDir.toFile().listFiles())
.filter(f -> f.getName().equals(testFile.getName().replace(".graphml", ".java")))
.toArray(File[]::new);

assertEquals(1, outputFiles.length);
assertEquals("MyModel.java", outputFiles[0].getName());

// note lst modified time is in milliseconds
long lastModified = outputFiles[0].lastModified();

// sleep 5 seconds to make sure the last modified time is different
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}

// regenerate the file
CodeGenerator.generate(inputDir, outputDir);

// check that the file was not regenerated
outputFiles = Arrays.stream(outputDir.toFile().listFiles())
.filter(f -> f.getName().equals(testFile.getName().replace(".graphml", ".java")))
.toArray(File[]::new);
assertEquals(1, outputFiles.length);
assertEquals(lastModified, outputFiles[0].lastModified());
}
}
@@ -0,0 +1,30 @@
package org.graphwalker.java.source.cache;

import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;

import static org.junit.Assert.*;

public class SimpleCacheTest {

@Test
public void get() throws IOException {
SimpleCache cache = new SimpleCache(Paths.get("./"));
// create temporary file
File foo = File.createTempFile("prefix", "suffix");
foo.deleteOnExit();
Path key = foo.toPath();
long lastModified = foo.lastModified();
cache.add(key, new CacheEntry(lastModified, true));
CacheEntry cached = cache.get(key);
assertEquals(lastModified, cached.getLastModifiedTime().toMillis());
assertEquals(true, cached.isGenerated());

assertTrue(cache.contains(key));
}
}
2 changes: 1 addition & 1 deletion pom.xml
Expand Up @@ -206,7 +206,7 @@
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.12</version>
<version>0.10.2</version>
</dependency>
<dependency>
<groupId>com.google.code.javaparser</groupId>
Expand Down

0 comments on commit 1655a20

Please sign in to comment.