Skip to content

Commit d402274

Browse files
yardusjbachorik
authored andcommitted
Use lazy inited regex expression for template extraction (btraceio#363)
Fixes btraceio#345
1 parent 527d86f commit d402274

2 files changed

Lines changed: 71 additions & 54 deletions

File tree

src/share/classes/com/sun/btrace/ArgsMap.java

Lines changed: 16 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,18 @@
2424
import java.util.Iterator;
2525
import java.util.LinkedHashMap;
2626
import java.util.Map;
27+
import java.util.regex.Matcher;
28+
import java.util.regex.Pattern;
2729

2830
/**
2931
* A simple argument map wrapper allowing indexed access
3032
*/
31-
public final class ArgsMap implements Iterable<Map.Entry<String, String>>{
33+
public final class ArgsMap implements Iterable<Map.Entry<String, String>> {
34+
private static final class PatternSingleton {
35+
// lazy initialization trick
36+
// do not compile the pattern until it is actually requested
37+
private static final Pattern INSTANCE = Pattern.compile("\\$\\{(.*?)\\}");
38+
}
3239
private final LinkedHashMap<String, String> map;
3340
private final DebugSupport debug;
3441

@@ -138,60 +145,15 @@ public String template(String value) {
138145
return value;
139146
}
140147

141-
StringBuilder sb = new StringBuilder();
142-
StringBuilder keySb = new StringBuilder();
143-
int state = 0;
144-
145-
for (char c : value.toCharArray()) {
146-
switch (c) {
147-
case '$': {
148-
if (state == 0) {
149-
state = 1;
150-
}
151-
break;
152-
}
153-
case '{': {
154-
if (state == 1) {
155-
state = 2;
156-
keySb.setLength(0);
157-
}
158-
break;
159-
}
160-
case '}': {
161-
if (state == 2) {
162-
String key = keySb.toString();
163-
String val = get(key);
164-
if (val != null) {
165-
sb.append(val);
166-
} else {
167-
sb.append("${").append(key).append("}");
168-
}
169-
state = 0;
170-
}
171-
break;
172-
}
173-
default: {
174-
switch (state) {
175-
case 0: {
176-
sb.append(c);
177-
break;
178-
}
179-
case 2: {
180-
keySb.append(c);
181-
break;
182-
}
183-
default: {
184-
// other states are invalid; ignore input
185-
}
186-
}
187-
}
188-
}
189-
}
148+
Matcher matcher = PatternSingleton.INSTANCE.matcher(value);
149+
StringBuffer buffer = new StringBuffer(value.length());
190150

191-
String expanded = sb.toString();
192-
if (debug.isDebug()) {
193-
debug.debug("Template: " + value + " -> " + expanded);
151+
while (matcher.find()) {
152+
String val = get(matcher.group(1));
153+
matcher.appendReplacement(buffer, val != null ? val : "$0");
194154
}
195-
return expanded;
155+
matcher.appendTail(buffer);
156+
157+
return buffer.toString();
196158
}
197159
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.sun.btrace;
2+
3+
import org.junit.Before;
4+
import org.junit.Test;
5+
import static org.junit.Assert.*;
6+
7+
public class ArgsMapTest {
8+
private static final String KEY1 = "key1";
9+
private static final String KEY2 = "key2";
10+
private static final String VALUE1 = "value1";
11+
private static final String VALUE2 = "value2";
12+
13+
private ArgsMap instance;
14+
15+
@Before
16+
public void setUp() {
17+
instance = new ArgsMap();
18+
instance.put(KEY1, VALUE1);
19+
instance.put(KEY2, VALUE2);
20+
}
21+
22+
@Test
23+
public void templateExisting() {
24+
String value = instance.template(KEY1 + "=${" + KEY1 + "}");
25+
assertEquals(KEY1 + "=" + VALUE1, value);
26+
}
27+
28+
@Test
29+
public void templateNonExisting() {
30+
String orig = KEY1 + "=${key3}";
31+
String value = instance.template(orig);
32+
assertEquals(orig, value);
33+
}
34+
35+
@Test
36+
public void templateTrailing$() {
37+
String orig = KEY1 + "$";
38+
String value = instance.template(orig);
39+
assertEquals(orig, value);
40+
}
41+
42+
@Test
43+
public void templateUnclosedPlaceholder() {
44+
String orig = KEY1 + "${";
45+
String value = instance.template(orig);
46+
assertEquals(orig, value);
47+
}
48+
49+
@Test
50+
public void templateSingle$() {
51+
String orig = KEY1 + "$" + KEY2;
52+
String value = instance.template(orig);
53+
assertEquals(orig, value);
54+
}
55+
}

0 commit comments

Comments
 (0)