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();
|
return str == null || str.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Pattern PROPERTY_REPLACEMENT = Pattern.compile("(.*?)" + "\\$\\{(.*?)" + "(?:::(.*?))?\\}");
|
||||||
|
// 1: PREFIX | START 2: NAME | 3: OPTIONAL DEFAULT VALUE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Get the system property value if the string is of the format ${sysproperty}
|
* 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) {
|
public static String getSystemPropertyAsString(String str) {
|
||||||
if (str == null)
|
if (str == null)
|
||||||
throw logger.nullArgumentError("str");
|
throw logger.nullArgumentError("str");
|
||||||
if (str.contains("${")) {
|
|
||||||
Pattern pattern = Pattern.compile("\\$\\{([^}]+)}");
|
|
||||||
Matcher matcher = pattern.matcher(str);
|
|
||||||
|
|
||||||
StringBuffer buffer = new StringBuffer();
|
Matcher m = PROPERTY_REPLACEMENT.matcher(str);
|
||||||
String sysPropertyValue = null;
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int lastPosition = 0;
|
||||||
|
while (m.find()) {
|
||||||
|
String propertyName = m.group(2);
|
||||||
|
String defaultValue = m.group(3);
|
||||||
|
|
||||||
while (matcher.find()) {
|
String sysPropertyValue = SecurityActions.getSystemProperty(propertyName, defaultValue);
|
||||||
String subString = matcher.group(1);
|
if (sysPropertyValue.isEmpty()) {
|
||||||
String defaultValue = "";
|
throw logger.systemPropertyMissingError(propertyName);
|
||||||
|
|
||||||
// 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);
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
matcher.appendTail(buffer);
|
sb.append(m.group(1)).append(sysPropertyValue);
|
||||||
str = buffer.toString();
|
|
||||||
|
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