From d725546a99257c1fe6b03a7321142e6d564665d7 Mon Sep 17 00:00:00 2001
From: "Chris West (Faux)" <git@goeswhere.com>
Date: Fri, 9 Jan 2015 21:19:43 +0000
Subject: [PATCH] honour BUILD_DATE when generating pom.properties

---
 .../apache/maven/archiver/PomPropertiesUtil.java   | 88 +++++++++++++++++++++-
 .../maven/archiver/PomPropertiesUtilTest.java      | 34 +++++++++
 2 files changed, 121 insertions(+), 1 deletion(-)
 create mode 100644 src/test/java/org/apache/maven/archiver/PomPropertiesUtilTest.java

diff --git a/src/main/java/org/apache/maven/archiver/PomPropertiesUtil.java b/src/main/java/org/apache/maven/archiver/PomPropertiesUtil.java
index 5e0a41b..605a2f1 100644
--- a/src/main/java/org/apache/maven/archiver/PomPropertiesUtil.java
+++ b/src/main/java/org/apache/maven/archiver/PomPropertiesUtil.java
@@ -25,6 +25,17 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.io.BufferedWriter;
+import java.text.SimpleDateFormat;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 
 import org.apache.maven.project.MavenProject;
@@ -85,7 +96,7 @@ public class PomPropertiesUtil
         OutputStream os = new FileOutputStream( outputFile );
         try
         {
-            properties.store( os, GENERATED_BY_MAVEN );
+            storeWithCustomTimestamp(properties, os);
             os.close(); // stream is flushed but not closed by Properties.store()
             os = null;
         }
@@ -117,4 +128,79 @@ public class PomPropertiesUtil
 
         archiver.addFile( pomPropertiesFile, "META-INF/maven/" + groupId + "/" + artifactId + "/pom.properties" );
     }
+
+    /**
+     * Java always writes the date in a comment.  We have to reimplement the method to change the date.
+     */
+    static void storeWithCustomTimestamp(Properties properties, OutputStream os) throws IOException {
+        final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "8859_1"));
+        try {
+            writer.append("#" + GENERATED_BY_MAVEN);
+            writer.newLine();
+            writer.append("#" + computeBuildDate().toString());
+            writer.newLine();
+            final List<Map.Entry<Object, Object>> entries =
+                new ArrayList<Map.Entry<Object, Object>>(properties.entrySet());
+            Collections.sort(entries, new Comparator<Map.Entry<Object, Object>>() {
+                public int compare(Map.Entry<Object, Object> left, Map.Entry<Object, Object> right) {
+                    return String.valueOf(left.getKey()).compareTo(String.valueOf(right.getKey()));
+                }
+            });
+            for (Map.Entry<Object, Object> property : entries) {
+                writer.write(property.getKey() + "=" + escapeForProperties(String.valueOf(property.getValue())));
+                writer.newLine();
+            }
+        } finally {
+            writer.flush();
+            writer.close();
+        }
+    }
+
+    private static Date computeBuildDate() {
+        final String envVariable = System.getenv("BUILD_DATE");
+        if (null != envVariable) {
+            try {
+                return new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz").parse(envVariable);
+            } catch (ParseException e) {
+                System.err.println("maven-archiver: BUILD_DATE not in recognised format");
+                e.printStackTrace();
+                // fall through
+            }
+        }
+        return new Date();
+    }
+
+    static String escapeForProperties(String input) {
+        final StringBuilder output = new StringBuilder(input.length());
+
+        for (char c : input.toCharArray()) {
+            switch (c) {
+                case '\t':
+                    output.append('\\');
+                    output.append('t');
+                    break;
+                case '\n':
+                    output.append('\\');
+                    output.append('n');
+                    break;
+                case '=':
+                case ':':
+                case '#':
+                case '!':
+                case '\\':
+                    output.append('\\');
+                    output.append(c);
+                    break;
+                default:
+                    if (c < ' ' || c > 127) {
+                        output.append("\\u");
+                        output.append(String.format("%04x", (int) c));
+                    } else {
+                        output.append(c);
+                    }
+            }
+        }
+
+        return output.toString();
+    }
 }
diff --git a/src/test/java/org/apache/maven/archiver/PomPropertiesUtilTest.java b/src/test/java/org/apache/maven/archiver/PomPropertiesUtilTest.java
new file mode 100644
index 0000000..b69321d
--- /dev/null
+++ b/src/test/java/org/apache/maven/archiver/PomPropertiesUtilTest.java
@@ -0,0 +1,34 @@
+package org.apache.maven.archiver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 junit.framework.TestCase;
+
+import static org.apache.maven.archiver.PomPropertiesUtil.escapeForProperties;
+
+public class PomPropertiesUtilTest extends TestCase {
+    public void testEscape() {
+        assertEquals("hello world", escapeForProperties("hello world"));
+        assertEquals("a \\u001f b", escapeForProperties("a \u001f b"));
+        assertEquals("hello\\nworld", escapeForProperties("hello\nworld"));
+        assertEquals("hello \\# \\! \\\\ \\: \\t \\u0100 \\u000c world",
+                escapeForProperties("hello # ! \\ : \t \u0100 \f world"));
+    }
+}
\ No newline at end of file
-- 
2.1.0

