KEYCLOAK-4148 StringUtils property replacer optimization
StringUtils.getSystemPropertyAsString is used in SAML attribute retrieval and uses StringBuffer and suboptimal regex. This optimization gains another ~ 3 %.
This commit is contained in:
parent
2b57b8371b
commit
862502f3ed
2 changed files with 64 additions and 26 deletions
|
@ -59,6 +59,9 @@ public class StringUtil {
|
|||
return str == null || str.isEmpty();
|
||||
}
|
||||
|
||||
private static final Pattern PROPERTY_REPLACEMENT = Pattern.compile("(.*?)" + "\\$\\{(.*?)" + "(?:::(.*?))?\\}");
|
||||
// 1: PREFIX | START 2: NAME | 3: OPTIONAL DEFAULT VALUE
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Get the system property value if the string is of the format ${sysproperty}
|
||||
|
@ -84,37 +87,25 @@ public class StringUtil {
|
|||
public static String getSystemPropertyAsString(String str) {
|
||||
if (str == null)
|
||||
throw logger.nullArgumentError("str");
|
||||
if (str.contains("${")) {
|
||||
Pattern pattern = Pattern.compile("\\$\\{([^}]+)}");
|
||||
Matcher matcher = pattern.matcher(str);
|
||||
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
String sysPropertyValue = null;
|
||||
Matcher m = PROPERTY_REPLACEMENT.matcher(str);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int lastPosition = 0;
|
||||
while (m.find()) {
|
||||
String propertyName = m.group(2);
|
||||
String defaultValue = m.group(3);
|
||||
|
||||
while (matcher.find()) {
|
||||
String subString = matcher.group(1);
|
||||
String defaultValue = "";
|
||||
|
||||
// Look for default value
|
||||
if (subString.contains("::")) {
|
||||
int index = subString.indexOf("::");
|
||||
defaultValue = subString.substring(index + 2);
|
||||
subString = subString.substring(0, index);
|
||||
}
|
||||
sysPropertyValue = SecurityActions.getSystemProperty(subString, defaultValue);
|
||||
String sysPropertyValue = SecurityActions.getSystemProperty(propertyName, defaultValue);
|
||||
if (sysPropertyValue.isEmpty()) {
|
||||
throw logger.systemPropertyMissingError(matcher.group(1));
|
||||
}else{
|
||||
// sanitize the value before we use append-and-replace
|
||||
sysPropertyValue = Matcher.quoteReplacement(sysPropertyValue);
|
||||
}
|
||||
matcher.appendReplacement(buffer, sysPropertyValue);
|
||||
throw logger.systemPropertyMissingError(propertyName);
|
||||
}
|
||||
|
||||
matcher.appendTail(buffer);
|
||||
str = buffer.toString();
|
||||
sb.append(m.group(1)).append(sysPropertyValue);
|
||||
|
||||
lastPosition = m.end();
|
||||
}
|
||||
return str;
|
||||
|
||||
return sb.append(str.substring(lastPosition)).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.keycloak.saml.common.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public class StringUtilTest {
|
||||
|
||||
public StringUtilTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSystemPropertyAsString() {
|
||||
System.setProperty("StringUtilTest.prop1", "value1");
|
||||
System.setProperty("StringUtilTest.prop2", "value2");
|
||||
|
||||
assertThat(StringUtil.getSystemPropertyAsString("a"), is("a"));
|
||||
assertThat(StringUtil.getSystemPropertyAsString("a ${StringUtilTest.prop1}"), is("a value1"));
|
||||
assertThat(
|
||||
StringUtil.getSystemPropertyAsString("a" + "${StringUtilTest.prop1}" + "StringUtilTest.prop1"),
|
||||
is("a" + "value1" + "StringUtilTest.prop1")
|
||||
);
|
||||
assertThat(
|
||||
StringUtil.getSystemPropertyAsString("a" + "${StringUtilTest.prop1}" + "StringUtilTest.prop1" + "${StringUtilTest.prop2}"),
|
||||
is("a" + "value1" + "StringUtilTest.prop1" + "value2")
|
||||
);
|
||||
assertThat(
|
||||
StringUtil.getSystemPropertyAsString("a" + "${StringUtilTest.prop1}" + "StringUtilTest.prop1" + "${StringUtilTest.prop2}" + "${StringUtilTest.prop3::abc}"),
|
||||
is("a" + "value1" + "StringUtilTest.prop1" + "value2" + "abc")
|
||||
);
|
||||
assertThat(
|
||||
StringUtil.getSystemPropertyAsString("a" + "${StringUtilTest.prop1}" + "StringUtilTest.prop1" + "${StringUtilTest.prop2}" + "${StringUtilTest.prop3::abc}" + "end"),
|
||||
is("a" + "value1" + "StringUtilTest.prop1" + "value2" + "abc" + "end")
|
||||
);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue