1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.codehaus.mojo.properties;
17  
18  import java.io.File;
19  import java.io.IOException;
20  import java.text.SimpleDateFormat;
21  import java.util.ArrayList;
22  import java.util.Arrays;
23  import java.util.Collections;
24  import java.util.Date;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Properties;
28  import java.util.Set;
29  
30  import org.apache.commons.io.FileUtils;
31  import org.apache.maven.plugin.MojoExecutionException;
32  import org.apache.maven.plugin.MojoFailureException;
33  import org.codehaus.plexus.util.StringUtils;
34  
35  
36  
37  
38  
39  
40  
41  
42  public class WriteProjectProperties extends AbstractWritePropertiesMojo {
43      private static final String CR = "\r";
44      private static final String LF = "\n";
45      private static final String TAB = "\t";
46      private static final String[] ANT_ESCAPE_CHARS = { CR, LF, TAB, ":", "#", "=" };
47  
48      
49  
50  
51  
52  
53  
54      private String escapeChars;
55  
56      
57  
58  
59  
60  
61  
62  
63  
64      private boolean antEchoPropertiesMode;
65  
66      
67  
68  
69  
70  
71  
72      private boolean includeSystemProperties;
73  
74      
75  
76  
77  
78  
79  
80      private boolean includeEnvironmentVariables;
81  
82      
83  
84  
85  
86  
87      private String exclude;
88  
89      
90  
91  
92  
93  
94  
95      private String include;
96  
97      @Override
98      public void execute() throws MojoExecutionException, MojoFailureException {
99          Properties properties = new Properties();
100         
101         properties.putAll(project.getProperties());
102         if (includeEnvironmentVariables) {
103             
104             properties.putAll(getEnvironmentVariables());
105         }
106         if (includeSystemProperties) {
107             
108             properties.putAll(System.getProperties());
109         }
110 
111         
112         trim(properties, exclude, include);
113 
114         String comment = "# " + new Date() + "\n";
115         List<String> escapeTokens = getEscapeChars(escapeChars);
116         if (antEchoPropertiesMode) {
117             escapeTokens = Arrays.asList(ANT_ESCAPE_CHARS);
118             comment = getAntHeader();
119             properties.remove("DSTAMP");
120             properties.remove("TODAY");
121             properties.remove("TSTAMP");
122         }
123 
124         getLog().info("Creating " + outputFile);
125         writeProperties(outputFile, comment, properties, escapeTokens);
126     }
127 
128     protected static Properties getEnvironmentVariables() {
129         String prefix = "env";
130         Map<String, String> map = System.getenv();
131         Properties props = new Properties();
132         for (String key : map.keySet()) {
133             String newKey = prefix + "." + key;
134             String value = map.get(key);
135             props.setProperty(newKey, value);
136         }
137         return props;
138     }
139 
140     protected void trim(Properties properties, String omitCSV, String includeCSV) {
141         List<String> omitKeys = ReadPropertiesMojo.getListFromCSV(omitCSV);
142         for (String key : omitKeys) {
143             properties.remove(key);
144         }
145         if (StringUtils.isBlank(includeCSV)) {
146             return;
147         }
148         List<String> includeKeys = ReadPropertiesMojo.getListFromCSV(includeCSV);
149         Set<String> keys = properties.stringPropertyNames();
150         for (String key : keys) {
151             if (!includeKeys.contains(key)) {
152                 properties.remove(key);
153             }
154         }
155     }
156 
157     protected String getAntHeader() {
158         SimpleDateFormat dstamp = new SimpleDateFormat("yyyyMMdd");
159         SimpleDateFormat today = new SimpleDateFormat("MMMM d yyyy");
160         SimpleDateFormat tstamp = new SimpleDateFormat("HHmm");
161         Date now = new Date();
162         StringBuilder sb = new StringBuilder();
163         sb.append("# Ant properties\n");
164         sb.append("# " + now + "\n");
165         sb.append("DSTAMP=" + dstamp.format(now) + "\n");
166         sb.append("TODAY=" + today.format(now) + "\n");
167         sb.append("TSTAMP=" + tstamp.format(now) + "\n");
168         return sb.toString();
169     }
170 
171     protected List<String> getEscapeChars(String escapeChars) {
172         List<String> tokens = ReadPropertiesMojo.getListFromCSV(escapeChars);
173         List<String> realTokens = new ArrayList<String>();
174         for (String token : tokens) {
175             String realToken = getRealToken(token);
176             realTokens.add(realToken);
177         }
178         return realTokens;
179     }
180 
181     protected String getRealToken(String token) {
182         if (token.equalsIgnoreCase("CR")) {
183             return CR;
184         } else if (token.equalsIgnoreCase("LF")) {
185             return LF;
186         } else if (token.equalsIgnoreCase("TAB")) {
187             return TAB;
188         } else {
189             return token;
190         }
191     }
192 
193     protected String getContent(String comment, Properties properties, List<String> escapeTokens) {
194         List<String> names = new ArrayList<String>(properties.stringPropertyNames());
195         Collections.sort(names);
196         StringBuilder sb = new StringBuilder();
197         if (!StringUtils.isBlank(comment)) {
198             sb.append(comment);
199         }
200         for (String name : names) {
201             String value = properties.getProperty(name);
202             String escapedValue = escape(value, escapeTokens);
203             sb.append(name + "=" + escapedValue + "\n");
204         }
205         return sb.toString();
206     }
207 
208     protected void writeProperties(File file, String comment, Properties properties, List<String> escapeTokens)
209             throws MojoExecutionException {
210         try {
211             String content = getContent(comment, properties, escapeTokens);
212             FileUtils.writeStringToFile(file, content);
213         } catch (IOException e) {
214             throw new MojoExecutionException("Error creating properties file", e);
215         }
216     }
217 
218     protected String escape(String s, List<String> escapeChars) {
219         for (String escapeChar : escapeChars) {
220             s = s.replace(escapeChar, getReplacementToken(escapeChar));
221         }
222         return s;
223     }
224 
225     protected String getReplacementToken(String escapeChar) {
226         if (escapeChar.equals(CR)) {
227             return "\\r";
228         } else if (escapeChar.equals(LF)) {
229             return "\\n";
230         } else if (escapeChar.equals(TAB)) {
231             return "\\t";
232         } else
233             return "\\" + escapeChar;
234     }
235 
236     public boolean isAntEchoPropertiesMode() {
237         return antEchoPropertiesMode;
238     }
239 
240     public void setAntEchoPropertiesMode(boolean antEchoPropertiesMode) {
241         this.antEchoPropertiesMode = antEchoPropertiesMode;
242     }
243 
244     public boolean isIncludeSystemProperties() {
245         return includeSystemProperties;
246     }
247 
248     public void setIncludeSystemProperties(boolean includeSystemProperties) {
249         this.includeSystemProperties = includeSystemProperties;
250     }
251 
252     public String getEscapeChars() {
253         return escapeChars;
254     }
255 
256     public void setEscapeChars(String escapeChars) {
257         this.escapeChars = escapeChars;
258     }
259 
260     public boolean isIncludeEnvironmentVariables() {
261         return includeEnvironmentVariables;
262     }
263 
264     public void setIncludeEnvironmentVariables(boolean includeEnvironmentVariables) {
265         this.includeEnvironmentVariables = includeEnvironmentVariables;
266     }
267 
268     public String getExclude() {
269         return exclude;
270     }
271 
272     public void setExclude(String exclude) {
273         this.exclude = exclude;
274     }
275 
276     public String getInclude() {
277         return include;
278     }
279 
280     public void setInclude(String include) {
281         this.include = include;
282     }
283 }