001 package org.codehaus.mojo.properties; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE 005 * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the 007 * License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 012 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 013 * specific language governing permissions and limitations under the License. 014 */ 015 016 import java.io.File; 017 import java.io.FileInputStream; 018 import java.io.IOException; 019 import java.util.Enumeration; 020 import java.util.Properties; 021 022 import org.apache.maven.plugin.AbstractMojo; 023 import org.apache.maven.plugin.MojoExecutionException; 024 import org.apache.maven.project.MavenProject; 025 import org.codehaus.plexus.util.cli.CommandLineUtils; 026 027 /** 028 * The read-project-properties goal reads property files and stores the properties as project properties. It serves as 029 * an alternate to specifying properties in pom.xml. 030 * 031 * @author <a href="mailto:zarars@gmail.com">Zarar Siddiqi</a> 032 * @author <a href="mailto:Krystian.Nowak@gmail.com">Krystian Nowak</a> 033 * @version $Id: ReadPropertiesMojo.java 8861 2009-01-21 15:35:38Z pgier $ 034 * @goal read-project-properties 035 */ 036 public class ReadPropertiesMojo extends AbstractMojo { 037 /** 038 * @parameter default-value="${project}" 039 * @required 040 * @readonly 041 */ 042 private MavenProject project; 043 044 /** 045 * The properties files that will be used when reading properties. Can use both .properties and .xml files 046 * 047 * @parameter 048 * @required 049 */ 050 private File[] files; 051 052 /** 053 * If the plugin should be quiet if any of the files was not found 054 * 055 * @parameter default-value="false" 056 */ 057 private boolean quiet; 058 059 public void execute() throws MojoExecutionException { 060 Properties projectProperties = new Properties(); 061 for (int i = 0; i < files.length; i++) { 062 File file = files[i]; 063 064 if (file.exists()) { 065 try { 066 getLog().debug("Loading property file: " + file); 067 068 FileInputStream stream = new FileInputStream(file); 069 projectProperties = project.getProperties(); 070 071 try { 072 String filename = file.getName().toLowerCase(); 073 if (filename.endsWith(".xml")) { 074 projectProperties.loadFromXML(stream); 075 } else { 076 projectProperties.load(stream); 077 } 078 } finally { 079 if (stream != null) { 080 stream.close(); 081 } 082 } 083 } catch (IOException e) { 084 throw new MojoExecutionException("Error reading properties file " + file.getAbsolutePath(), e); 085 } 086 } else { 087 if (quiet) { 088 getLog().warn("Ignoring missing properties file: " + file.getAbsolutePath()); 089 } else { 090 throw new MojoExecutionException("Properties file not found: " + file.getAbsolutePath()); 091 } 092 } 093 } 094 095 boolean useEnvVariables = false; 096 for (Enumeration n = projectProperties.propertyNames(); n.hasMoreElements();) { 097 String k = (String) n.nextElement(); 098 String p = (String) projectProperties.get(k); 099 if (p.indexOf("${env.") != -1) { 100 useEnvVariables = true; 101 break; 102 } 103 } 104 Properties environment = null; 105 if (useEnvVariables) { 106 try { 107 environment = CommandLineUtils.getSystemEnvVars(); 108 } catch (IOException e) { 109 throw new MojoExecutionException("Error getting system envorinment variables: ", e); 110 } 111 } 112 for (Enumeration n = projectProperties.propertyNames(); n.hasMoreElements();) { 113 String k = (String) n.nextElement(); 114 projectProperties.setProperty(k, getPropertyValue(k, projectProperties, environment)); 115 } 116 } 117 118 /** 119 * Retrieves a property value, replacing values like ${token} using the Properties to look them up. Shamelessly 120 * adapted from: 121 * http://maven.apache.org/plugins/maven-war-plugin/xref/org/apache/maven/plugin/war/PropertyUtils.html 122 * 123 * It will leave unresolved properties alone, trying for System properties, and environment variables and implements 124 * reparsing (in the case that the value of a property contains a key), and will not loop endlessly on a pair like 125 * test = ${test} 126 * 127 * @param k 128 * property key 129 * @param p 130 * project properties 131 * @param environment 132 * environment variables 133 * @return resolved property value 134 */ 135 private String getPropertyValue(String k, Properties p, Properties environment) { 136 String v = p.getProperty(k); 137 String ret = ""; 138 int idx, idx2; 139 140 while ((idx = v.indexOf("${")) >= 0) { 141 // append prefix to result 142 ret += v.substring(0, idx); 143 144 // strip prefix from original 145 v = v.substring(idx + 2); 146 147 idx2 = v.indexOf("}"); 148 149 // if no matching } then bail 150 if (idx2 < 0) { 151 break; 152 } 153 154 // strip out the key and resolve it 155 // resolve the key/value for the ${statement} 156 String nk = v.substring(0, idx2); 157 v = v.substring(idx2 + 1); 158 String nv = p.getProperty(nk); 159 160 // try global environment 161 if (nv == null) { 162 nv = System.getProperty(nk); 163 } 164 165 // try environment variable 166 if (nv == null && nk.startsWith("env.") && environment != null) { 167 nv = environment.getProperty(nk.substring(4)); 168 } 169 170 // if the key cannot be resolved, 171 // leave it alone ( and don't parse again ) 172 // else prefix the original string with the 173 // resolved property ( so it can be parsed further ) 174 // taking recursion into account. 175 if (nv == null || nv.equals(nk)) { 176 ret += "${" + nk + "}"; 177 } else { 178 v = nv + v; 179 } 180 } 181 return ret + v; 182 } 183 }