View Javadoc
1   /**
2    * Copyright (C) 2008-2010 Matt Gumbley, DevZendo.org <http://devzendo.org>;
3    *
4    * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
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  
17  /**
18   * 
19   */
20  package org.devzendo.xplp;
21  
22  import java.util.Properties;
23  import java.util.regex.Matcher;
24  import java.util.regex.Pattern;
25  
26  /**
27   * Interpolation of name=value pairs from a
28   * Properties object into a String, using Ant-style references
29   * to names - e.g ${name}.
30   * @author matt
31   *
32   */
33  public final class PropertiesInterpolator {
34      private final Properties mProps;
35      private final Matcher variableReferenceMatcher = 
36          Pattern.compile("^(.*?)\\$\\{([^}]+?)\\}(.*?)$", Pattern.DOTALL).matcher("");
37  
38      /**
39       * Create an interpolator, given a set of properties to
40       * interpolate inside incoming string data.
41       * @param props the name=value pairs.
42       * 
43       */
44      public PropertiesInterpolator(final Properties props) {
45          mProps = props;
46      }
47  
48      /**
49       * Replace any ${names} with their ${values}, except in # lines
50       * @param input the input string, can be null
51       * @return the output, null iff input == null
52       */
53      public String interpolate(final String input) {
54          //System.out.println("Interpolating '" + input + "'");
55          if (input == null || input.length() == 0) {
56              return input;
57          }
58          if (input.matches("^\\s*#.*$")) {
59              return input;
60          }
61          String s = input;
62          while (true) {
63              //System.out.println("Finding variables in '" + s + "'");
64              variableReferenceMatcher.reset(s);
65              if (variableReferenceMatcher.find()) {
66                  //System.out.println("Found variable");
67                  final String before = variableReferenceMatcher.group(1);
68                  final String variableName = variableReferenceMatcher.group(2);
69                  final String after = variableReferenceMatcher.group(3);
70                  //System.out.println("Variable '" + variableName + "'");
71                  if (mProps.containsKey(variableName)) {
72                      final String variableValue = mProps.getProperty(variableName);
73                      //System.out.println("Replacement is '" + variableValue + "'");
74                      s = before + variableValue + after;
75                  } else {
76                      //System.out.println("Got no value for variable");
77                      throw new IllegalStateException("The name '" + variableName + "' is not defined");
78                  }
79              } else {
80                  //System.out.println("No more variables");
81                  break;
82              }
83          }
84          //System.out.println("Output is '" + s + "'");
85          return s;
86      }
87  }