fixes #9427 regex pattern is now pre-compiled
This commit is contained in:
parent
9d5355b7ad
commit
9b18688ce2
2 changed files with 52 additions and 5 deletions
|
@ -26,6 +26,7 @@ import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -35,10 +36,10 @@ import java.util.stream.Stream;
|
||||||
* <p/>
|
* <p/>
|
||||||
* For example,
|
* For example,
|
||||||
* <p/>
|
* <p/>
|
||||||
* for operator {@link ModelCriteriaBuilder.Operator.EQ} we concatenate left operand and right operand with equal sign:
|
* for operator {@link ModelCriteriaBuilder.Operator#EQ} we concatenate left operand and right operand with equal sign:
|
||||||
* {@code fieldName = :parameterName}
|
* {@code fieldName = :parameterName}
|
||||||
* <p/>
|
* <p/>
|
||||||
* however, for operator {@link ModelCriteriaBuilder.Operator.EXISTS} we add following:
|
* however, for operator {@link ModelCriteriaBuilder.Operator#EXISTS} we add following:
|
||||||
* <p/>
|
* <p/>
|
||||||
* {@code fieldName IS NOT NULL AND fieldName IS NOT EMPTY"}.
|
* {@code fieldName IS NOT NULL AND fieldName IS NOT EMPTY"}.
|
||||||
*
|
*
|
||||||
|
@ -46,7 +47,7 @@ import java.util.stream.Stream;
|
||||||
* corresponding value is then saved into {@code Map<String, Object>} that is passed to each {@link ExpressionCombinator}.
|
* corresponding value is then saved into {@code Map<String, Object>} that is passed to each {@link ExpressionCombinator}.
|
||||||
*/
|
*/
|
||||||
public class IckleQueryOperators {
|
public class IckleQueryOperators {
|
||||||
private static final String UNWANTED_CHARACTERS_REGEX = "[^a-zA-Z\\d]";
|
private static final Pattern UNWANTED_CHARACTERS_REGEX = Pattern.compile("[^a-zA-Z\\d]");
|
||||||
public static final String C = "c";
|
public static final String C = "c";
|
||||||
private static final Map<ModelCriteriaBuilder.Operator, String> OPERATOR_TO_STRING = new HashMap<>();
|
private static final Map<ModelCriteriaBuilder.Operator, String> OPERATOR_TO_STRING = new HashMap<>();
|
||||||
private static final Map<ModelCriteriaBuilder.Operator, ExpressionCombinator> OPERATOR_TO_EXPRESSION_COMBINATORS = new HashMap<>();
|
private static final Map<ModelCriteriaBuilder.Operator, ExpressionCombinator> OPERATOR_TO_EXPRESSION_COMBINATORS = new HashMap<>();
|
||||||
|
@ -123,14 +124,18 @@ public class IckleQueryOperators {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String removeForbiddenCharactersFromNamedParameter(String name) {
|
private static String removeForbiddenCharactersFromNamedParameter(String name) {
|
||||||
return name.replaceAll(UNWANTED_CHARACTERS_REGEX, "");
|
return UNWANTED_CHARACTERS_REGEX.matcher(name).replaceAll( "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps {@code namePrefix} to next available parameter name. For example, if {@code namePrefix == "id"}
|
* Maps {@code namePrefix} to next available parameter name. For example, if {@code namePrefix == "id"}
|
||||||
* and {@code existingNames} set already contains {@code id0} and {@code id1} it returns {@code id2}.
|
* and {@code existingNames} set already contains {@code id0} and {@code id1} it returns {@code id2}.
|
||||||
|
* Any character that is not an alphanumeric will be stripped, so that it works for prefixes like
|
||||||
|
* {@code "attributes.name"} as well.
|
||||||
*
|
*
|
||||||
* This method is used for computing available names for name query parameters
|
* This method is used for computing available names for name query parameters.
|
||||||
|
* Instead of creating generic named parameters that would be hard to debug and read by humans, it creates readable
|
||||||
|
* named parameters from the prefix.
|
||||||
*
|
*
|
||||||
* @param existingNames set of parameter names that are already used in this Ickle query
|
* @param existingNames set of parameter names that are already used in this Ickle query
|
||||||
* @param namePrefix name of the parameter
|
* @param namePrefix name of the parameter
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package org.keycloak.models.map.storage.hotRod;
|
||||||
|
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
public class IckleQueryOperatorsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindAvailableNamedParamSimple() {
|
||||||
|
Set<String> existingNames = new HashSet<>();
|
||||||
|
|
||||||
|
String param = IckleQueryOperators.findAvailableNamedParam(existingNames, "clientId");
|
||||||
|
|
||||||
|
assertThat("should create the first ID", param, Matchers.equalTo("clientId0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindAvailableNamedParamAlreadyExists() {
|
||||||
|
Set<String> existingNames = new HashSet<>();
|
||||||
|
existingNames.add("clientId0");
|
||||||
|
|
||||||
|
String param = IckleQueryOperators.findAvailableNamedParam(existingNames, "clientId");
|
||||||
|
|
||||||
|
assertThat("should create the next ID as clientId0 is already taken", param, Matchers.equalTo("clientId1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindAvailableNamedParamIllegalCharacterInPrefix() {
|
||||||
|
Set<String> existingNames = new HashSet<>();
|
||||||
|
existingNames.add("clientid0");
|
||||||
|
|
||||||
|
String param = IckleQueryOperators.findAvailableNamedParam(existingNames, "client.id");
|
||||||
|
|
||||||
|
assertThat("should remove non-characters and non-numbers from the ID", param, Matchers.equalTo("clientid1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue