1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package net.sf.hermesftp.utils;
26
27 import java.util.Properties;
28 import java.util.regex.Matcher;
29 import java.util.regex.Pattern;
30
31 /***
32 * Replaces all placeholders in a given text document with the values of a properties-Object.
33 * Example: The text "Hello ${name}" becomes "Hello world" provided that passed properties object
34 * contains the entry name=world.
35 * <p>
36 * <code>
37 * VarMerger vm = new VarMerger("The ${dog} chases the ${cat}");
38 * Properties p = new Properties();
39 * p.put("dog", "fox");
40 * p.put("cat", "mouse");
41 * vm.merge(p);
42 * String neuerSatz = vm.getText();
43 * </code>
44 *
45 * @author Lars Behnke
46 */
47 public class VarMerger {
48
49 private static final String VAR_PATTERN = "(//$//{)([//w//.]*)(//})";
50
51 private String text;
52
53 /***
54 * @param text Der Text containing placeholders.
55 */
56 public VarMerger(String text) {
57 setText(text);
58 }
59
60 /***
61 * Replaces the placeholders with the passed values.
62 *
63 * @param props The values.
64 */
65 public void merge(Properties props) {
66 StringBuffer sb = new StringBuffer();
67 Pattern pattern = Pattern.compile(VAR_PATTERN);
68 Matcher m = pattern.matcher(getText());
69 boolean hasNext = m.find();
70 while (hasNext) {
71 String key = m.group(2);
72 String val = props.getProperty(key);
73 if (val != null) {
74 val = quoteReplacement(val);
75 m.appendReplacement(sb, val);
76 }
77 hasNext = m.find();
78 }
79 m.appendTail(sb);
80 text = sb.toString();
81 }
82
83 /***
84 * Returns a literal replacement <code>String</code> for the specified <code>String</code>.
85 * This method produces a <code>String</code> that will work use as a literal replacement
86 * <code>s</code> in the <code>appendReplacement</code> method of the {@link Matcher} class.
87 * The <code>String</code> produced will match the sequence of characters in <code>s</code>
88 * treated as a literal sequence. Slashes ('\') and dollar signs ('$') will be given no special
89 * meaning.
90 *
91 * @param s The string to be literalized
92 * @return A literal string replacement
93 */
94 private static String quoteReplacement(String s) {
95 if ((s.indexOf('//') == -1) && (s.indexOf('$') == -1)) {
96 return s;
97 }
98 StringBuffer sb = new StringBuffer();
99 for (int i = 0; i < s.length(); i++) {
100 char c = s.charAt(i);
101 if (c == '//') {
102 sb.append('//');
103 sb.append('//');
104 } else if (c == '$') {
105 sb.append('//');
106 sb.append('$');
107 } else {
108 sb.append(c);
109 }
110 }
111 return sb.toString();
112 }
113
114 /***
115 * Sets the text containing placeholders.
116 *
117 * @param text The text.
118 */
119 public void setText(String text) {
120 if (text == null) {
121 throw new IllegalArgumentException("NULL-Werte k�nnen nicht verarbeitet werden.");
122 }
123 this.text = text;
124 }
125
126 /***
127 * @return Der Text mit den ersetzten Platzhaltern.
128 */
129 public String getText() {
130 return text;
131 }
132
133 /***
134 * Pr�ft, ob der Text noch Platzhalter enth�lt, die noch nicht ersetzt wurden.
135 *
136 * @return True, falls der Text keine Platzhalter mehr enth�lt.
137 */
138 public boolean isReplacementComplete() {
139 Pattern pattern = Pattern.compile(VAR_PATTERN);
140 boolean found = pattern.matcher(getText()).find();
141 return !found;
142 }
143
144 }