001 /** 002 * Copyright 2009-2012 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.codehaus.mojo.properties; 017 018 import java.io.File; 019 import java.io.IOException; 020 import java.text.SimpleDateFormat; 021 import java.util.ArrayList; 022 import java.util.Collections; 023 import java.util.Date; 024 import java.util.List; 025 import java.util.Map; 026 import java.util.Properties; 027 import java.util.Set; 028 029 import org.apache.commons.io.FileUtils; 030 import org.apache.maven.plugin.MojoExecutionException; 031 import org.apache.maven.plugin.MojoFailureException; 032 import org.codehaus.plexus.util.StringUtils; 033 034 /** 035 * Writes project properties to a file. 036 * 037 * @author <a href="mailto:zarars@gmail.com">Zarar Siddiqi</a> 038 * @version $Id: WriteProjectProperties.java 9747 2009-05-20 13:27:44Z mark $ 039 * @goal write-project-properties 040 */ 041 public class WriteProjectProperties extends AbstractWritePropertiesMojo { 042 private static final String[] ESCAPE_CHARS = { "\n", "\r", "\t", ":", "#", "=" }; 043 044 /** 045 * If true, the plugin will create the properties file formatted the same way Ant formats properties files using the 046 * <code>echoproperties</code> task. This mode adds 3 custom properties at the top of the file, DSTAMP, TODAY, and 047 * TSTAMP 048 * 049 * @parameter default-value="false" expression="${properties.antEchoPropertiesMode}" 050 */ 051 private boolean antEchoPropertiesMode; 052 053 /** 054 * If true, the plugin will include system properties when writing the properties file. System properties override 055 * both environment variables and project properties. 056 * 057 * @parameter default-value="false" expression="${properties.includeSystemProperties}" 058 */ 059 private boolean includeSystemProperties; 060 061 /** 062 * If true, the plugin will include environment variables when writing the properties file. Environment variables 063 * are prefixed with "env". Environment variables override project properties. 064 * 065 * @parameter default-value="false" expression="${properties.includeEnvironmentVariables}" 066 */ 067 private boolean includeEnvironmentVariables; 068 069 /** 070 * Comma separated set of properties to exclude when writing the properties file 071 * 072 * @parameter expression="${properties.exclude}" 073 */ 074 private String exclude; 075 076 /** 077 * Comma separated set of properties to write to the properties file. If provided, only the properties matching 078 * those supplied here will be written to the properties file. 079 * 080 * @parameter expression="${properties.include}" 081 */ 082 private String include; 083 084 @Override 085 public void execute() throws MojoExecutionException, MojoFailureException { 086 Properties properties = new Properties(); 087 // Add project properties 088 properties.putAll(project.getProperties()); 089 if (includeEnvironmentVariables) { 090 // Add environment variables, overriding any properties with the same key 091 properties.putAll(getEnvironmentVariables()); 092 } 093 if (includeSystemProperties) { 094 // Add system properties, overriding any properties with the same key 095 properties.putAll(System.getProperties()); 096 } 097 098 // Remove properties as appropriate 099 trim(properties, exclude, include); 100 101 String comment = "# " + new Date() + "\n"; 102 if (antEchoPropertiesMode) { 103 comment = getAntHeader(); 104 properties.remove("DSTAMP"); 105 properties.remove("TODAY"); 106 properties.remove("TSTAMP"); 107 } 108 109 getLog().info("Creating " + outputFile); 110 writeProperties(outputFile, comment, properties); 111 } 112 113 protected Properties getEnvironmentVariables() { 114 String prefix = "env"; 115 Map<String, String> map = System.getenv(); 116 Properties props = new Properties(); 117 for (String key : map.keySet()) { 118 String newKey = prefix + "." + key; 119 String value = map.get(key); 120 props.setProperty(newKey, value); 121 } 122 return props; 123 } 124 125 protected void trim(Properties properties, String omitCSV, String includeCSV) { 126 List<String> omitKeys = ReadPropertiesMojo.getListFromCSV(omitCSV); 127 for (String key : omitKeys) { 128 properties.remove(key); 129 } 130 if (StringUtils.isBlank(includeCSV)) { 131 return; 132 } 133 List<String> includeKeys = ReadPropertiesMojo.getListFromCSV(includeCSV); 134 Set<String> keys = properties.stringPropertyNames(); 135 for (String key : keys) { 136 if (!includeKeys.contains(key)) { 137 properties.remove(key); 138 } 139 } 140 } 141 142 protected String getAntHeader() throws MojoExecutionException { 143 SimpleDateFormat dstamp = new SimpleDateFormat("yyyyMMdd"); 144 SimpleDateFormat today = new SimpleDateFormat("MMMM d yyyy"); 145 SimpleDateFormat tstamp = new SimpleDateFormat("HHmm"); 146 Date now = new Date(); 147 StringBuilder sb = new StringBuilder(); 148 sb.append("# Ant properties\n"); 149 sb.append("# " + now + "\n"); 150 sb.append("DSTAMP=" + dstamp.format(now) + "\n"); 151 sb.append("TODAY=" + today.format(now) + "\n"); 152 sb.append("TSTAMP=" + tstamp.format(now) + "\n"); 153 return sb.toString(); 154 } 155 156 protected void writeProperties(File file, String comment, Properties properties) throws MojoExecutionException { 157 List<String> names = new ArrayList<String>(properties.stringPropertyNames()); 158 Collections.sort(names); 159 StringBuilder sb = new StringBuilder(); 160 if (!StringUtils.isBlank(comment)) { 161 sb.append(comment); 162 } 163 for (String name : names) { 164 String value = properties.getProperty(name); 165 String escapedValue = escape(value, ESCAPE_CHARS); 166 sb.append(name + "=" + escapedValue + "\n"); 167 } 168 try { 169 FileUtils.writeStringToFile(file, sb.toString()); 170 } catch (IOException e) { 171 throw new MojoExecutionException("Error creating properties file", e); 172 } 173 } 174 175 protected String escape(String s, String[] escapeChars) { 176 for (String escapeChar : escapeChars) { 177 s = s.replace(escapeChar, "\\" + escapeChar); 178 } 179 return s; 180 181 } 182 183 public boolean isAntEchoPropertiesMode() { 184 return antEchoPropertiesMode; 185 } 186 187 public void setAntEchoPropertiesMode(boolean antEchoPropertiesMode) { 188 this.antEchoPropertiesMode = antEchoPropertiesMode; 189 } 190 191 public boolean isIncludeSystemProperties() { 192 return includeSystemProperties; 193 } 194 195 public void setIncludeSystemProperties(boolean includeSystemProperties) { 196 this.includeSystemProperties = includeSystemProperties; 197 } 198 }