View Javadoc

1   /**
2    * Copyright 2009-2012 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.codehaus.mojo.properties;
17  
18  /*
19   * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
20   * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
21   * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
22   * License. You may obtain a copy of the License at
23   *
24   * http://www.apache.org/licenses/LICENSE-2.0
25   *
26   * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
27   * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
28   * specific language governing permissions and limitations under the License.
29   */
30  
31  import java.io.File;
32  import java.io.FileInputStream;
33  import java.io.IOException;
34  import java.util.Enumeration;
35  import java.util.Properties;
36  
37  import org.apache.maven.plugin.AbstractMojo;
38  import org.apache.maven.plugin.MojoExecutionException;
39  import org.apache.maven.project.MavenProject;
40  import org.codehaus.plexus.util.cli.CommandLineUtils;
41  
42  /**
43   * The read-project-properties goal reads property files and stores the properties as project properties. It serves as
44   * an alternate to specifying properties in pom.xml.
45   *
46   * @author <a href="mailto:zarars@gmail.com">Zarar Siddiqi</a>
47   * @author <a href="mailto:Krystian.Nowak@gmail.com">Krystian Nowak</a>
48   * @version $Id: ReadPropertiesMojo.java 8861 2009-01-21 15:35:38Z pgier $
49   * @goal read-project-properties
50   */
51  public class ReadPropertiesMojo extends AbstractMojo {
52      /**
53       * @parameter default-value="${project}"
54       * @required
55       * @readonly
56       */
57      private MavenProject project;
58  
59      /**
60       * The properties files that will be used when reading properties. Can use both .properties and .xml files
61       *
62       * @parameter
63       * @required
64       */
65      private File[] files;
66  
67      /**
68       * If the plugin should be quiet if any of the files was not found
69       *
70       * @parameter default-value="false"
71       */
72      private boolean quiet;
73  
74      public void execute() throws MojoExecutionException {
75          Properties projectProperties = new Properties();
76          for (int i = 0; i < files.length; i++) {
77              File file = files[i];
78  
79              if (file == null) {
80                  if (quiet) {
81                      getLog().info("Ignoring null properties file parameter");
82                      continue;
83                  } else {
84                      throw new MojoExecutionException("null properties file parameter");
85                  }
86              }
87  
88              if (file.exists()) {
89                  try {
90                      getLog().debug("Loading property file: " + file);
91  
92                      FileInputStream stream = new FileInputStream(file);
93                      projectProperties = project.getProperties();
94  
95                      try {
96                          String filename = file.getName().toLowerCase();
97                          if (filename.endsWith(".xml")) {
98                              projectProperties.loadFromXML(stream);
99                          } else {
100                             projectProperties.load(stream);
101                         }
102                     } finally {
103                         if (stream != null) {
104                             stream.close();
105                         }
106                     }
107                 } catch (IOException e) {
108                     throw new MojoExecutionException("Error reading properties file " + file.getAbsolutePath(), e);
109                 }
110             } else {
111                 if (quiet) {
112                     getLog().info("Ignoring missing properties file: " + file.getAbsolutePath());
113                 } else {
114                     throw new MojoExecutionException("Properties file not found: " + file.getAbsolutePath());
115                 }
116             }
117         }
118 
119         boolean useEnvVariables = false;
120         for (Enumeration n = projectProperties.propertyNames(); n.hasMoreElements();) {
121             String k = (String) n.nextElement();
122             String p = (String) projectProperties.get(k);
123             if (p.indexOf("${env.") != -1) {
124                 useEnvVariables = true;
125                 break;
126             }
127         }
128         Properties environment = null;
129         if (useEnvVariables) {
130             try {
131                 environment = CommandLineUtils.getSystemEnvVars();
132             } catch (IOException e) {
133                 throw new MojoExecutionException("Error getting system envorinment variables: ", e);
134             }
135         }
136         for (Enumeration n = projectProperties.propertyNames(); n.hasMoreElements();) {
137             String k = (String) n.nextElement();
138             projectProperties.setProperty(k, getPropertyValue(k, projectProperties, environment));
139         }
140     }
141 
142     /**
143      * Retrieves a property value, replacing values like ${token} using the Properties to look them up. Shamelessly
144      * adapted from:
145      * http://maven.apache.org/plugins/maven-war-plugin/xref/org/apache/maven/plugin/war/PropertyUtils.html
146      *
147      * It will leave unresolved properties alone, trying for System properties, and environment variables and implements
148      * reparsing (in the case that the value of a property contains a key), and will not loop endlessly on a pair like
149      * test = ${test}
150      *
151      * @param k
152      *            property key
153      * @param p
154      *            project properties
155      * @param environment
156      *            environment variables
157      * @return resolved property value
158      */
159     private String getPropertyValue(String k, Properties p, Properties environment) {
160         String v = p.getProperty(k);
161         String ret = "";
162         int idx, idx2;
163 
164         while ((idx = v.indexOf("${")) >= 0) {
165             // append prefix to result
166             ret += v.substring(0, idx);
167 
168             // strip prefix from original
169             v = v.substring(idx + 2);
170 
171             idx2 = v.indexOf("}");
172 
173             // if no matching } then bail
174             if (idx2 < 0) {
175                 break;
176             }
177 
178             // strip out the key and resolve it
179             // resolve the key/value for the ${statement}
180             String nk = v.substring(0, idx2);
181             v = v.substring(idx2 + 1);
182             String nv = p.getProperty(nk);
183 
184             // try global environment
185             if (nv == null) {
186                 nv = System.getProperty(nk);
187             }
188 
189             // try environment variable
190             if (nv == null && nk.startsWith("env.") && environment != null) {
191                 nv = environment.getProperty(nk.substring(4));
192             }
193 
194             // if the key cannot be resolved,
195             // leave it alone ( and don't parse again )
196             // else prefix the original string with the
197             // resolved property ( so it can be parsed further )
198             // taking recursion into account.
199             if (nv == null || nv.equals(nk)) {
200                 ret += "${" + nk + "}";
201             } else {
202                 v = nv + v;
203             }
204         }
205         return ret + v;
206     }
207 }