KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > util > StringPropertyReplacer


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.util;
23
24 import java.util.Properties JavaDoc;
25 import java.io.File JavaDoc;
26
27 /**
28  * A utility class for replacing properties in strings.
29  *
30  * @author <a HREF="mailto:jason@planet57.com">Jason Dillon</a>
31  * @author <a HREF="Scott.Stark@jboss.org">Scott Stark</a>
32  * @author <a HREF="claudio.vesco@previnet.it">Claudio Vesco</a>
33  * @author <a HREF="mailto:adrian@jboss.com">Adrian Brock</a>
34  * @author <a HREF="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
35  * @version <tt>$Revision: 1958 $</tt>
36  */

37 public final class StringPropertyReplacer
38 {
39    /** New line string constant */
40    public static final String JavaDoc NEWLINE = SysPropertyActions.getProperty("line.separator", "\n");
41
42    /** File separator value */
43    private static final String JavaDoc FILE_SEPARATOR = File.separator;
44
45    /** Path separator value */
46    private static final String JavaDoc PATH_SEPARATOR = File.pathSeparator;
47
48    /** File separator alias */
49    private static final String JavaDoc FILE_SEPARATOR_ALIAS = "/";
50
51    /** Path separator alias */
52    private static final String JavaDoc PATH_SEPARATOR_ALIAS = ":";
53
54    // States used in property parsing
55
private static final int NORMAL = 0;
56    private static final int SEEN_DOLLAR = 1;
57    private static final int IN_BRACKET = 2;
58
59    /**
60     * Go through the input string and replace any occurance of ${p} with
61     * the System.getProperty(p) value. If there is no such property p defined,
62     * then the ${p} reference will remain unchanged.
63     *
64     * If the property reference is of the form ${p:v} and there is no such property p,
65     * then the default value v will be returned.
66     *
67     * If the property reference is of the form ${p1,p2} or ${p1,p2:v} then
68     * the primary and the secondary properties will be tried in turn, before
69     * returning either the unchanged input, or the default value.
70     *
71     * The property ${/} is replaced with System.getProperty("file.separator")
72     * value and the property ${:} is replaced with System.getProperty("path.separator").
73     *
74     * @param string - the string with possible ${} references
75     * @return the input string with all property references replaced if any.
76     * If there are no valid references the input string will be returned.
77     */

78    public static String JavaDoc replaceProperties(final String JavaDoc string)
79    {
80       return replaceProperties(string, null);
81    }
82
83    /**
84     * Go through the input string and replace any occurance of ${p} with
85     * the props.getProperty(p) value. If there is no such property p defined,
86     * then the ${p} reference will remain unchanged.
87     *
88     * If the property reference is of the form ${p:v} and there is no such property p,
89     * then the default value v will be returned.
90     *
91     * If the property reference is of the form ${p1,p2} or ${p1,p2:v} then
92     * the primary and the secondary properties will be tried in turn, before
93     * returning either the unchanged input, or the default value.
94     *
95     * The property ${/} is replaced with System.getProperty("file.separator")
96     * value and the property ${:} is replaced with System.getProperty("path.separator").
97     *
98     * @param string - the string with possible ${} references
99     * @param props - the source for ${x} property ref values, null means use System.getProperty()
100     * @return the input string with all property references replaced if any.
101     * If there are no valid references the input string will be returned.
102     * @throws java.lang.AccessControlException when not authorised to retrieved system properties
103     */

104    public static String JavaDoc replaceProperties(final String JavaDoc string, final Properties JavaDoc props)
105    {
106       final char[] chars = string.toCharArray();
107       StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
108       boolean properties = false;
109       int state = NORMAL;
110       int start = 0;
111       for (int i = 0; i < chars.length; ++i)
112       {
113          char c = chars[i];
114
115          // Dollar sign outside brackets
116
if (c == '$' && state != IN_BRACKET)
117             state = SEEN_DOLLAR;
118
119          // Open bracket immediatley after dollar
120
else if (c == '{' && state == SEEN_DOLLAR)
121          {
122             buffer.append(string.substring(start, i - 1));
123             state = IN_BRACKET;
124             start = i - 1;
125          }
126
127          // No open bracket after dollar
128
else if (state == SEEN_DOLLAR)
129             state = NORMAL;
130
131          // Closed bracket after open bracket
132
else if (c == '}' && state == IN_BRACKET)
133          {
134             // No content
135
if (start + 2 == i)
136             {
137                buffer.append("${}"); // REVIEW: Correct?
138
}
139             else // Collect the system property
140
{
141                String JavaDoc value = null;
142
143                String JavaDoc key = string.substring(start + 2, i);
144                
145                // check for alias
146
if (FILE_SEPARATOR_ALIAS.equals(key))
147                {
148                   value = FILE_SEPARATOR;
149                }
150                else if (PATH_SEPARATOR_ALIAS.equals(key))
151                {
152                   value = PATH_SEPARATOR;
153                }
154                else
155                {
156                   // check from the properties
157
if (props != null)
158                      value = props.getProperty(key);
159                   else
160                      value = System.getProperty(key);
161                   
162                   if (value == null)
163                   {
164                      // Check for a default value ${key:default}
165
int colon = key.indexOf(':');
166                      if (colon > 0)
167                      {
168                         String JavaDoc realKey = key.substring(0, colon);
169                         if (props != null)
170                            value = props.getProperty(realKey);
171                         else
172                            value = System.getProperty(realKey);
173
174                         if (value == null)
175                         {
176                            // Check for a composite key, "key1,key2"
177
value = resolveCompositeKey(realKey, props);
178                         
179                            // Not a composite key either, use the specified default
180
if (value == null)
181                               value = key.substring(colon+1);
182                         }
183                      }
184                      else
185                      {
186                         // No default, check for a composite key, "key1,key2"
187
value = resolveCompositeKey(key, props);
188                      }
189                   }
190                }
191
192                if (value != null)
193                {
194                   properties = true;
195                   buffer.append(value);
196                }
197             }
198             start = i + 1;
199             state = NORMAL;
200          }
201       }
202
203       // No properties
204
if (properties == false)
205          return string;
206
207       // Collect the trailing characters
208
if (start != chars.length)
209          buffer.append(string.substring(start, chars.length));
210
211       // Done
212
return buffer.toString();
213    }
214    
215    /**
216     * Try to resolve a "key" from the provided properties by
217     * checking if it is actually a "key1,key2", in which case
218     * try first "key1", then "key2". If all fails, return null.
219     *
220     * It also accepts "key1," and ",key2".
221     *
222     * @param key the key to resolve
223     * @param props the properties to use
224     * @return the resolved key or null
225     */

226    private static String JavaDoc resolveCompositeKey(String JavaDoc key, Properties JavaDoc props)
227    {
228       String JavaDoc value = null;
229       
230       // Look for the comma
231
int comma = key.indexOf(',');
232       if (comma > -1)
233       {
234          // If we have a first part, try resolve it
235
if (comma > 0)
236          {
237             // Check the first part
238
String JavaDoc key1 = key.substring(0, comma);
239             if (props != null)
240                value = props.getProperty(key1);
241             else
242                value = System.getProperty(key1);
243          }
244          // Check the second part, if there is one and first lookup failed
245
if (value == null && comma < key.length() - 1)
246          {
247             String JavaDoc key2 = key.substring(comma + 1);
248             if (props != null)
249                value = props.getProperty(key2);
250             else
251                value = System.getProperty(key2);
252          }
253       }
254       // Return whatever we've found or null
255
return value;
256    }
257 }
Popular Tags