diff --git a/tools/core/src/main/java/org/teavm/tooling/sources/DirectorySourceFileProvider.java b/tools/core/src/main/java/org/teavm/tooling/sources/DirectorySourceFileProvider.java index aaf0e2abc..1d19ce942 100644 --- a/tools/core/src/main/java/org/teavm/tooling/sources/DirectorySourceFileProvider.java +++ b/tools/core/src/main/java/org/teavm/tooling/sources/DirectorySourceFileProvider.java @@ -20,10 +20,6 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -/** - * - * @author Alexey Andreev - */ public class DirectorySourceFileProvider implements SourceFileProvider { private File baseDirectory; @@ -40,8 +36,26 @@ public class DirectorySourceFileProvider implements SourceFileProvider { } @Override - public InputStream openSourceFile(String fullPath) throws IOException { + public SourceFileInfo getSourceFile(String fullPath) throws IOException { File file = new File(baseDirectory, fullPath); - return file.exists() ? new FileInputStream(file) : null; + return file.exists() ? new DirectorySourceFile(file) : null; + } + + static class DirectorySourceFile implements SourceFileInfo { + private File file; + + DirectorySourceFile(File file) { + this.file = file; + } + + @Override + public long lastModified() { + return file.lastModified(); + } + + @Override + public InputStream open() throws IOException { + return new FileInputStream(file); + } } } diff --git a/tools/core/src/main/java/org/teavm/tooling/sources/JarSourceFileProvider.java b/tools/core/src/main/java/org/teavm/tooling/sources/JarSourceFileProvider.java index 07269d76f..7d474f10e 100644 --- a/tools/core/src/main/java/org/teavm/tooling/sources/JarSourceFileProvider.java +++ b/tools/core/src/main/java/org/teavm/tooling/sources/JarSourceFileProvider.java @@ -24,10 +24,6 @@ import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -/** - * - * @author Alexey Andreev - */ public class JarSourceFileProvider implements SourceFileProvider { private File file; private ZipFile zipFile; @@ -58,11 +54,31 @@ public class JarSourceFileProvider implements SourceFileProvider { } @Override - public InputStream openSourceFile(String fullPath) throws IOException { + public SourceFileInfo getSourceFile(String fullPath) throws IOException { if (zipFile == null || !sourceFiles.contains(fullPath)) { return null; } ZipEntry entry = zipFile.getEntry(fullPath); - return entry != null ? zipFile.getInputStream(entry) : null; + return entry != null ? new JarSourceFile(zipFile, entry) : null; + } + + static class JarSourceFile implements SourceFileInfo { + private ZipFile file; + private ZipEntry entry; + + JarSourceFile(ZipFile file, ZipEntry entry) { + this.file = file; + this.entry = entry; + } + + @Override + public long lastModified() { + return entry.getTime(); + } + + @Override + public InputStream open() throws IOException { + return file.getInputStream(entry); + } } } diff --git a/tools/core/src/main/java/org/teavm/tooling/sources/SourceFileInfo.java b/tools/core/src/main/java/org/teavm/tooling/sources/SourceFileInfo.java new file mode 100644 index 000000000..e71c453b5 --- /dev/null +++ b/tools/core/src/main/java/org/teavm/tooling/sources/SourceFileInfo.java @@ -0,0 +1,25 @@ +/* + * Copyright 2017 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.tooling.sources; + +import java.io.IOException; +import java.io.InputStream; + +public interface SourceFileInfo { + long lastModified(); + + InputStream open() throws IOException; +} diff --git a/tools/core/src/main/java/org/teavm/tooling/sources/SourceFileProvider.java b/tools/core/src/main/java/org/teavm/tooling/sources/SourceFileProvider.java index c1dbebd9b..278606430 100644 --- a/tools/core/src/main/java/org/teavm/tooling/sources/SourceFileProvider.java +++ b/tools/core/src/main/java/org/teavm/tooling/sources/SourceFileProvider.java @@ -16,16 +16,11 @@ package org.teavm.tooling.sources; import java.io.IOException; -import java.io.InputStream; -/** - * - * @author Alexey Andreev - */ public interface SourceFileProvider { void open() throws IOException; void close() throws IOException; - InputStream openSourceFile(String fullPath) throws IOException; + SourceFileInfo getSourceFile(String fullPath) throws IOException; } diff --git a/tools/core/src/main/java/org/teavm/tooling/sources/SourceFilesCopier.java b/tools/core/src/main/java/org/teavm/tooling/sources/SourceFilesCopier.java index 746f38bdf..54255392b 100644 --- a/tools/core/src/main/java/org/teavm/tooling/sources/SourceFilesCopier.java +++ b/tools/core/src/main/java/org/teavm/tooling/sources/SourceFilesCopier.java @@ -26,10 +26,6 @@ import org.teavm.model.MethodReader; import org.teavm.tooling.EmptyTeaVMToolLog; import org.teavm.tooling.TeaVMToolLog; -/** - * - * @author Alexey Andreev - */ public class SourceFilesCopier { private TeaVMToolLog log = new EmptyTeaVMToolLog(); private List sourceFileProviders; @@ -66,15 +62,22 @@ public class SourceFilesCopier { } targetDirectory.mkdirs(); for (String fileName : sourceFiles) { - try (InputStream input = findSourceFile(fileName)) { - if (input != null) { - File outputFile = new File(targetDirectory, fileName); - outputFile.getParentFile().mkdirs(); - try (OutputStream output = new FileOutputStream(outputFile)) { - IOUtils.copy(input, output); + try { + SourceFileInfo sourceFile = findSourceFile(fileName); + File outputFile = new File(targetDirectory, fileName); + if (outputFile.exists() && outputFile.lastModified() > sourceFile.lastModified() + && sourceFile.lastModified() > 0) { + continue; + } + try (InputStream input = sourceFile.open()) { + if (input != null) { + outputFile.getParentFile().mkdirs(); + try (OutputStream output = new FileOutputStream(outputFile)) { + IOUtils.copy(input, output); + } + } else { + log.info("Missing source file: " + fileName); } - } else { - log.info("Missing source file: " + fileName); } } catch (IOException e) { log.warning("Could not copy source file " + fileName, e); @@ -89,11 +92,11 @@ public class SourceFilesCopier { } } - private InputStream findSourceFile(String fileName) throws IOException { + private SourceFileInfo findSourceFile(String fileName) throws IOException { for (SourceFileProvider provider : sourceFileProviders) { - InputStream input = provider.openSourceFile(fileName); - if (input != null) { - return input; + SourceFileInfo sourceFile = provider.getSourceFile(fileName); + if (sourceFile != null) { + return sourceFile; } } return null;