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