diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c507849
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+target
+.idea
diff --git a/pom.xml b/pom.xml
index 01b0d39..2317e7d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,8 +20,15 @@ See the Apache License Version 2.0 for the specific language governing permissio
org.sonatype.plexus
plexus-build-api
- 0.0.8-SNAPSHOT
-
+ 0.0.9-SNAPSHOT
+
+
+ scm:git:https://github.com/codehaus-plexus/plexus-build-api.git
+ ${project.scm.connection}
+ https://github.com/codehaus-plexus/plexus-build-api
+ 0.x
+
+
org.codehaus.plexus
@@ -36,6 +43,10 @@ See the Apache License Version 2.0 for the specific language governing permissio
+
+ UTF-8
+
+
@@ -47,7 +58,7 @@ See the Apache License Version 2.0 for the specific language governing permissio
org.codehaus.plexus
plexus-maven-plugin
- 1.3.4
+ 1.3.8
@@ -56,18 +67,23 @@ See the Apache License Version 2.0 for the specific language governing permissio
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ 3.3.1
+
org.apache.maven.plugins
maven-compiler-plugin
+ 3.11.0
- 1.4
- 1.4
+ 8
org.apache.maven.plugins
maven-surefire-plugin
- 2.4.2
+ 3.1.0
true
@@ -75,6 +91,7 @@ See the Apache License Version 2.0 for the specific language governing permissio
org.apache.maven.plugins
maven-jar-plugin
+ 3.3.0
@@ -83,6 +100,34 @@ See the Apache License Version 2.0 for the specific language governing permissio
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.5.0
+
+ none
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 3.1.0
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+ 3.0.0
+
+
+ org.apache.maven.plugins
+ maven-install-plugin
+ 3.1.1
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ 3.1.1
+
diff --git a/src/main/java/org/sonatype/plexus/build/incremental/CachingOutputStream.java b/src/main/java/org/sonatype/plexus/build/incremental/CachingOutputStream.java
new file mode 100644
index 0000000..03cdf5e
--- /dev/null
+++ b/src/main/java/org/sonatype/plexus/build/incremental/CachingOutputStream.java
@@ -0,0 +1,151 @@
+package org.sonatype.plexus.build.incremental;
+
+/*
+ * Copyright The Codehaus Foundation.
+ *
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+
+/**
+ * Caching OutputStream to avoid overwriting a file with
+ * the same content.
+ */
+class CachingOutputStream extends OutputStream {
+ private final Path path;
+ private FileChannel channel;
+ private ByteBuffer readBuffer;
+ private ByteBuffer writeBuffer;
+ private boolean modified;
+
+ public CachingOutputStream(File path) throws IOException {
+ this(requireNonNull(path).toPath());
+ }
+
+ public CachingOutputStream(Path path) throws IOException {
+ this(path, 32 * 1024);
+ }
+
+ public CachingOutputStream(Path path, int bufferSize) throws IOException {
+ this.path = requireNonNull(path);
+ this.channel =
+ FileChannel.open(path, StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
+ this.readBuffer = ByteBuffer.allocate(bufferSize);
+ this.writeBuffer = ByteBuffer.allocate(bufferSize);
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ if (writeBuffer.remaining() < 1) {
+ ((Buffer) writeBuffer).flip();
+ flushBuffer(writeBuffer);
+ ((Buffer) writeBuffer).clear();
+ }
+ writeBuffer.put((byte) b);
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ write(b, 0, b.length);
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ if (writeBuffer.remaining() < len) {
+ ((Buffer) writeBuffer).flip();
+ flushBuffer(writeBuffer);
+ ((Buffer) writeBuffer).clear();
+ }
+ int capacity = writeBuffer.capacity();
+ while (len >= capacity) {
+ flushBuffer(ByteBuffer.wrap(b, off, capacity));
+ off += capacity;
+ len -= capacity;
+ }
+ if (len > 0) {
+ writeBuffer.put(b, off, len);
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ ((Buffer) writeBuffer).flip();
+ flushBuffer(writeBuffer);
+ ((Buffer) writeBuffer).clear();
+ super.flush();
+ }
+
+ private void flushBuffer(ByteBuffer writeBuffer) throws IOException {
+ if (modified) {
+ channel.write(writeBuffer);
+ } else {
+ int len = writeBuffer.remaining();
+ ByteBuffer readBuffer;
+ if (this.readBuffer.capacity() >= len) {
+ readBuffer = this.readBuffer;
+ ((Buffer) readBuffer).clear();
+ readBuffer.limit(len);
+ } else {
+ readBuffer = ByteBuffer.allocate(len);
+ }
+ while (len > 0) {
+ int read = channel.read(readBuffer);
+ if (read <= 0) {
+ modified = true;
+ channel.position(channel.position() - readBuffer.position());
+ channel.write(writeBuffer);
+ return;
+ }
+ len -= read;
+ }
+ ((Buffer) readBuffer).flip();
+ if (readBuffer.compareTo(writeBuffer) != 0) {
+ modified = true;
+ channel.position(channel.position() - readBuffer.remaining());
+ channel.write(writeBuffer);
+ }
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (channel.isOpen()) {
+ flush();
+ long position = channel.position();
+ if (position != channel.size()) {
+ modified = true;
+ channel.truncate(position);
+ }
+ channel.close();
+ }
+ }
+
+ public boolean isModified() {
+ return modified;
+ }
+
+ private static T requireNonNull(T t) {
+ if (t == null) {
+ throw new NullPointerException();
+ }
+ return t;
+ }
+}
diff --git a/src/main/java/org/sonatype/plexus/build/incremental/DefaultBuildContext.java b/src/main/java/org/sonatype/plexus/build/incremental/DefaultBuildContext.java
index f82cfd9..7173227 100644
--- a/src/main/java/org/sonatype/plexus/build/incremental/DefaultBuildContext.java
+++ b/src/main/java/org/sonatype/plexus/build/incremental/DefaultBuildContext.java
@@ -51,7 +51,7 @@ public boolean hasDelta(List relpaths) {
}
public OutputStream newFileOutputStream(File file) throws IOException {
- return new FileOutputStream(file);
+ return new CachingOutputStream(file);
}
public Scanner newScanner(File basedir) {