Java tutorial
/** * * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php * * 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 eu.dnetlib.maven.plugin.properties; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; /** * Writes project properties for the keys listed in specified properties files. * Based on: * http://site.kuali.org/maven/plugins/properties-maven-plugin/1.3.2/write-project-properties-mojo.html * @author mhorst * @goal write-project-properties */ public class WritePredefinedProjectProperties extends AbstractMojo { private static final String CR = "\r"; private static final String LF = "\n"; private static final String TAB = "\t"; private static final String[] ANT_ESCAPE_CHARS = { CR, LF, TAB, ":", "#", "=" }; /** * @parameter expression="${properties.includePropertyKeysFromFiles}" */ private String[] includePropertyKeysFromFiles; /** * @parameter default-value="${project}" * @required * @readonly */ private MavenProject project; /** * The file that properties will be written to * * @parameter expression="${properties.outputFile}" * default-value="${project.build.directory}/properties/project.properties"; * @required */ private File outputFile; /** * If true, the plugin will silently ignore any non-existent properties files, and the build will continue * * @parameter expression="${properties.quiet}" default-value="true" */ private boolean quiet; /** * Comma separated list of characters to escape when writing property values. cr=carriage return, lf=linefeed, * tab=tab. Any other values are taken literally. * * @parameter default-value="cr,lf,tab" expression="${properties.escapeChars}" */ private String escapeChars; /** * If true, the plugin will create the properties file formatted the same way Ant formats properties files using the * <code>echoproperties</code> task. This mode adds 3 custom properties at the top of the file, DSTAMP, TODAY, and * TSTAMP. In this mode <code>escapeChars</code> is ignored and the 6 characters Ant escapes are used instead * <code>CR</code>,<code>LF</code>,<code>TAB</code>,<code>:</code>,<code>#</code>,<code>=</code> * * @parameter default-value="false" expression="${properties.antEchoPropertiesMode}" */ private boolean antEchoPropertiesMode; /** * If true, the plugin will include system properties when writing the properties file. System properties override * both environment variables and project properties. * * @parameter default-value="false" expression="${properties.includeSystemProperties}" */ private boolean includeSystemProperties; /** * If true, the plugin will include environment variables when writing the properties file. Environment variables * are prefixed with "env". Environment variables override project properties. * * @parameter default-value="false" expression="${properties.includeEnvironmentVariables}" */ private boolean includeEnvironmentVariables; /** * Comma separated set of properties to exclude when writing the properties file * * @parameter expression="${properties.exclude}" */ private String exclude; /** * Comma separated set of properties to write to the properties file. If provided, only the properties matching * those supplied here will be written to the properties file. * * @parameter expression="${properties.include}" */ private String include; /* (non-Javadoc) * @see org.apache.maven.plugin.AbstractMojo#execute() */ @Override public void execute() throws MojoExecutionException, MojoFailureException { Properties properties = new Properties(); // Add project properties properties.putAll(project.getProperties()); if (includeEnvironmentVariables) { // Add environment variables, overriding any existing properties with the same key properties.putAll(getEnvironmentVariables()); } if (includeSystemProperties) { // Add system properties, overriding any existing properties with the same key properties.putAll(System.getProperties()); } // Remove properties as appropriate trim(properties, exclude, include); String comment = "# " + new Date() + "\n"; List<String> escapeTokens = getEscapeChars(escapeChars); if (antEchoPropertiesMode) { escapeTokens = Arrays.asList(ANT_ESCAPE_CHARS); comment = getAntHeader(); properties.remove("DSTAMP"); properties.remove("TODAY"); properties.remove("TSTAMP"); } getLog().info("Creating " + outputFile); writeProperties(outputFile, comment, properties, escapeTokens); } /** * Provides environment variables. * @return environment variables */ protected static Properties getEnvironmentVariables() { String prefix = "env"; Map<String, String> map = System.getenv(); Properties props = new Properties(); for (String key : map.keySet()) { String newKey = prefix + "." + key; String value = map.get(key); props.setProperty(newKey, value); } return props; } /** * Removes properties which should not be written. * @param properties * @param omitCSV * @param includeCSV * @throws MojoExecutionException */ protected void trim(Properties properties, String omitCSV, String includeCSV) throws MojoExecutionException { List<String> omitKeys = getListFromCSV(omitCSV); for (String key : omitKeys) { properties.remove(key); } List<String> includeKeys = getListFromCSV(includeCSV); // mh: including keys from predefined properties if (includePropertyKeysFromFiles != null && includePropertyKeysFromFiles.length > 0) { for (String currentIncludeLoc : includePropertyKeysFromFiles) { if (validate(currentIncludeLoc)) { Properties p = getProperties(currentIncludeLoc); for (String key : p.stringPropertyNames()) { includeKeys.add(key); } } } } if (includeKeys != null && !includeKeys.isEmpty()) { // removing only when include keys provided Set<String> keys = properties.stringPropertyNames(); for (String key : keys) { if (!includeKeys.contains(key)) { properties.remove(key); } } } } protected String toEmpty(String s) { if (StringUtils.isBlank(s)) { return ""; } else { return s; } } /** * Checks whether file exists. * @param location * @return true when exists, false otherwise. */ protected boolean exists(String location) { if (StringUtils.isBlank(location)) { return false; } File file = new File(location); if (file.exists()) { return true; } ResourceLoader loader = new DefaultResourceLoader(); Resource resource = loader.getResource(location); return resource.exists(); } /** * Validates resource location. * @param location * @return true when valid, false otherwise * @throws MojoExecutionException */ protected boolean validate(String location) throws MojoExecutionException { boolean exists = exists(location); if (exists) { return true; } if (quiet) { getLog().info("Ignoring non-existent properties file '" + toEmpty(location) + "'"); return false; } else { throw new MojoExecutionException("Non-existent properties file '" + location + "'"); } } /** * Provides input stream. * @param location * @return input stream * @throws IOException */ protected InputStream getInputStream(String location) throws IOException { File file = new File(location); if (file.exists()) { return new FileInputStream(location); } ResourceLoader loader = new DefaultResourceLoader(); Resource resource = loader.getResource(location); return resource.getInputStream(); } /** * Creates properties for given location. * @param location * @return properties for given location * @throws MojoExecutionException */ protected Properties getProperties(String location) throws MojoExecutionException { InputStream in = null; try { Properties properties = new Properties(); in = getInputStream(location); if (location.toLowerCase().endsWith(".xml")) { properties.loadFromXML(in); } else { properties.load(in); } return properties; } catch (IOException e) { throw new MojoExecutionException("Error reading properties file " + location, e); } finally { IOUtils.closeQuietly(in); } } /** * Provides ant header. * @return ant header */ protected String getAntHeader() { SimpleDateFormat dstamp = new SimpleDateFormat("yyyyMMdd"); SimpleDateFormat today = new SimpleDateFormat("MMMM d yyyy"); SimpleDateFormat tstamp = new SimpleDateFormat("HHmm"); Date now = new Date(); StringBuilder sb = new StringBuilder(); sb.append("# Ant properties\n"); sb.append("# " + now + "\n"); sb.append("DSTAMP=" + dstamp.format(now) + "\n"); sb.append("TODAY=" + today.format(now) + "\n"); sb.append("TSTAMP=" + tstamp.format(now) + "\n"); return sb.toString(); } /** * Provides escape characters. * @param escapeChars * @return escape characters */ protected List<String> getEscapeChars(String escapeChars) { List<String> tokens = getListFromCSV(escapeChars); List<String> realTokens = new ArrayList<String>(); for (String token : tokens) { String realToken = getRealToken(token); realTokens.add(realToken); } return realTokens; } /** * Provides real token. * @param token * @return real token */ protected String getRealToken(String token) { if (token.equalsIgnoreCase("CR")) { return CR; } else if (token.equalsIgnoreCase("LF")) { return LF; } else if (token.equalsIgnoreCase("TAB")) { return TAB; } else { return token; } } /** * Returns content. * @param comment * @param properties * @param escapeTokens * @return content */ protected String getContent(String comment, Properties properties, List<String> escapeTokens) { List<String> names = new ArrayList<String>(properties.stringPropertyNames()); Collections.sort(names); StringBuilder sb = new StringBuilder(); if (!StringUtils.isBlank(comment)) { sb.append(comment); } for (String name : names) { String value = properties.getProperty(name); String escapedValue = escape(value, escapeTokens); sb.append(name + "=" + escapedValue + "\n"); } return sb.toString(); } /** * Writes properties to given file. * @param file * @param comment * @param properties * @param escapeTokens * @throws MojoExecutionException */ protected void writeProperties(File file, String comment, Properties properties, List<String> escapeTokens) throws MojoExecutionException { try { String content = getContent(comment, properties, escapeTokens); FileUtils.writeStringToFile(file, content); } catch (IOException e) { throw new MojoExecutionException("Error creating properties file", e); } } /** * Writes properties. * @param properties * @param file * @throws MojoExecutionException */ protected void writeProperties(Properties properties, File file) throws MojoExecutionException { OutputStream out = null; try { out = FileUtils.openOutputStream(outputFile); properties.store(out, "Properties"); } catch (IOException e) { throw new MojoExecutionException("Error creating properties file", e); } finally { IOUtils.closeQuietly(out); } } /** * Escapes characters. * @param s * @param escapeChars * @return */ protected String escape(String s, List<String> escapeChars) { String result = s; for (String escapeChar : escapeChars) { result = result.replace(escapeChar, getReplacementToken(escapeChar)); } return result; } /** * Provides replacement token. * @param escapeChar * @return replacement token */ protected String getReplacementToken(String escapeChar) { if (escapeChar.equals(CR)) { return "\\r"; } else if (escapeChar.equals(LF)) { return "\\n"; } else if (escapeChar.equals(TAB)) { return "\\t"; } else { return "\\" + escapeChar; } } /** * Returns list from csv. * @param csv * @return list of values generated from CSV */ protected static final List<String> getListFromCSV(String csv) { if (StringUtils.isBlank(csv)) { return new ArrayList<String>(); } List<String> list = new ArrayList<String>(); String[] tokens = StringUtils.split(csv, ","); for (String token : tokens) { list.add(token.trim()); } return list; } public boolean isAntEchoPropertiesMode() { return antEchoPropertiesMode; } public void setAntEchoPropertiesMode(boolean antEchoPropertiesMode) { this.antEchoPropertiesMode = antEchoPropertiesMode; } public boolean isIncludeSystemProperties() { return includeSystemProperties; } public void setIncludeSystemProperties(boolean includeSystemProperties) { this.includeSystemProperties = includeSystemProperties; } public String getEscapeChars() { return escapeChars; } public void setEscapeChars(String escapeChars) { this.escapeChars = escapeChars; } public boolean isIncludeEnvironmentVariables() { return includeEnvironmentVariables; } public void setIncludeEnvironmentVariables(boolean includeEnvironmentVariables) { this.includeEnvironmentVariables = includeEnvironmentVariables; } public String getExclude() { return exclude; } public void setExclude(String exclude) { this.exclude = exclude; } public String getInclude() { return include; } public void setInclude(String include) { this.include = include; } public boolean isQuiet() { return quiet; } public void setQuiet(boolean quiet) { this.quiet = quiet; } /** * Sets property files for which keys properties should be included. * @param includePropertyKeysFromFiles */ public void setIncludePropertyKeysFromFiles(String[] includePropertyKeysFromFiles) { if (includePropertyKeysFromFiles != null) { this.includePropertyKeysFromFiles = Arrays.copyOf(includePropertyKeysFromFiles, includePropertyKeysFromFiles.length); } } }