Commit c84b5ec0 authored by Jeroen Hoffman's avatar Jeroen Hoffman

HIPPLUG-1104: forward porting from 7.9: support prefix in parsing of...

HIPPLUG-1104: forward porting from 7.9: support prefix in parsing of property=condition. Also move code to MatcherUtils with unit tests
parent 85c8261d
/*
* Copyright 2012-2013 Hippo B.V. (http://www.onehippo.com)
* Copyright 2012-2015 Hippo B.V. (http://www.onehippo.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -23,8 +23,6 @@ import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.hippoecm.hst.component.support.bean.BaseHstComponent;
......@@ -41,6 +39,7 @@ import org.hippoecm.hst.core.parameters.ParametersInfo;
import org.hippoecm.hst.core.request.HstRequestContext;
import org.onehippo.forge.sitemap.components.model.news.NewsUrlset;
import org.onehippo.forge.sitemap.components.model.news.info.Publication;
import org.onehippo.forge.sitemap.components.util.MatcherUtils;
import org.onehippo.forge.sitemap.generator.DefaultNewsInformationProvider;
import org.onehippo.forge.sitemap.generator.NewsSitemapGenerator;
......@@ -193,28 +192,27 @@ public class NewsSitemapFeed extends BaseHstComponent {
}
/**
* Takes an input string with comma seperated property criteria (in the format prop1=condition1,prop2=condiion2...)
* Takes an input string with comma separated property criteria (in the format prop1=condition1,prop2=condiion2...)
* and returns a map with key = property and value = criterion
*
* @param propertyCriteria comma seperated list of property criteria
* @param propertyCriteria comma separated list of property criteria
* @return {@link Map} containing the property criteria
*/
private static Map<String, String> parsePropertyCriteria(final String propertyCriteria) {
if (StringUtils.isEmpty(propertyCriteria)) {
return Collections.emptyMap();
}
String[] criteria = propertyCriteria.trim().split("[\\s]*,[\\s]*");
Pattern propertyCriterionPattern = Pattern.compile("([\\w]+)[\\s]*=[\\s]*([\\w]+)");
Map<String, String> propertiesWithCriteria = new HashMap<String, String>();
final String[] criteria = MatcherUtils.getCommaSeparatedValues(propertyCriteria);
final Map<String, String> propertiesWithCriteria = new HashMap<>();
for (final String criterion : criteria) {
Matcher propertyCriterionMatcher = propertyCriterionPattern.matcher(criterion);
if (!propertyCriterionMatcher.matches()) {
throw new HstComponentException("Criterion does not match pattern \"property=condition\"");
final String[] propertyValuePair = MatcherUtils.parsePropertyValue(criterion);
if (propertyValuePair == null) {
throw new HstComponentException("Criterion '" + criterion + "' doet not have format 'property=value'");
}
String property = propertyCriterionMatcher.group(1);
String condition = propertyCriterionMatcher.group(2);
propertiesWithCriteria.put(property, condition);
propertiesWithCriteria.put(propertyValuePair[0], propertyValuePair[1]);
}
return propertiesWithCriteria;
}
}
......@@ -30,6 +30,11 @@ public final class MatcherUtils {
private static final Pattern ANY_OR_DEFAULT = Pattern.compile("(_default_|_any_)");
private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("(\\$\\{\\d\\})");
// RegExp matching (optional-prefix:)property(optional-spaces)=(optional-spaces)value
private static final Pattern PROPERTY_VALUE_PATTERN = Pattern.compile("([\\w]+:?[\\w]+)[\\s]*=[\\s]*([\\w]+)");
private static final String COMMA_SEPARATING_REG_EXP = "[\\s]*,[\\s]*";
private MatcherUtils() {} // Hide constructor of utility class
/**
......@@ -117,7 +122,7 @@ public final class MatcherUtils {
*/
public static Map<Integer, String> extractPlaceholderValues(final String stringWithPlaceholders,
final String stringToParse) {
Map<Integer, String> result = new HashMap<Integer, String>();
Map<Integer, String> result = new HashMap<>();
Pattern matcherPattern = buildPatternWithCaptureGroupsFromStringWithPlaceholders(stringWithPlaceholders);
Matcher matcher = matcherPattern.matcher(stringToParse);
......@@ -136,6 +141,42 @@ public final class MatcherUtils {
return result;
}
public static String replaceDefaultAndAnyMatchersWithMatchedNodes(final String path,
final List<String> matchedNodes) {
String newPath = path;
for (String matchedNode : matchedNodes) {
Matcher matcher = ANY_OR_DEFAULT.matcher(newPath);
if (matcher.find()) {
newPath = matcher.replaceFirst(matchedNode);
}
}
return newPath;
}
/**
* Get the comma separated values from a string.
*/
public static String[] getCommaSeparatedValues(final String values) {
if (values == null) {
return new String[]{};
}
return values.trim().split(COMMA_SEPARATING_REG_EXP);
}
/**
* Get a property/value pair for a string of format 'property=value'.
*
* @return null if the argument is not a 'property=value' string, else the property and value in a 2-string array
*/
public static String[] parsePropertyValue(final String propertyAndValue) {
Matcher matcher = PROPERTY_VALUE_PATTERN.matcher(propertyAndValue);
if (!matcher.matches()) {
return null;
}
return new String[] {matcher.group(1), matcher.group(2)};
}
/**
* Parses a String with placeholders and returns a list of placeholder numbers in the order that they appear in
* the String.
......@@ -143,7 +184,7 @@ public final class MatcherUtils {
* @return {@link Integer[]} with the order in which placeholder appear in the String
*/
private static Integer[] resolveOrderOfPlaceholders(final String stringWithPlaceholders) {
List<Integer> placeholderList = new ArrayList<Integer>();
List<Integer> placeholderList = new ArrayList<>();
Matcher placeholderMatcher = Pattern.compile("(\\$\\{(\\d)\\})").matcher(stringWithPlaceholders);
while (placeholderMatcher.find()) {
......@@ -164,17 +205,4 @@ public final class MatcherUtils {
String resultingPattern = matcher.replaceAll("(.*)");
return Pattern.compile(resultingPattern);
}
public static String replaceDefaultAndAnyMatchersWithMatchedNodes(final String path,
final List<String> matchedNodes) {
String newPath = path;
for (String matchedNode : matchedNodes) {
Matcher matcher = ANY_OR_DEFAULT.matcher(newPath);
if (matcher.find()) {
newPath = matcher.replaceFirst(matchedNode);
}
}
return newPath;
}
}
......@@ -21,8 +21,6 @@ import java.util.Map;
import org.junit.Test;
import junit.framework.Assert;
import static org.onehippo.forge.sitemap.components.util.MatcherUtils.extractPlaceholderValues;
import static org.onehippo.forge.sitemap.components.util.MatcherUtils.replacePlaceholdersWithMatchedNodes;
/**
*
......@@ -44,7 +42,7 @@ public class MatcherUtilsTest {
String input = "dada --- ${1}/${2}/${3} dumtidum";
String expected = "dada --- a/g/l dumtidum";
String[] matchedNodes = {"a", "g", "l"};
Assert.assertEquals(expected, replacePlaceholdersWithMatchedNodes(input, Arrays.asList(matchedNodes)));
Assert.assertEquals(expected, MatcherUtils.replacePlaceholdersWithMatchedNodes(input, Arrays.asList(matchedNodes)));
}
@Test
......@@ -57,9 +55,56 @@ public class MatcherUtilsTest {
@Test
public void testExtractPlaceholderValues() throws Exception {
Map<Integer, String> result = extractPlaceholderValues("${3}://${1}/lfaskdjflkas/${2}", "a://b/lfaskdjflkas/c");
Map<Integer, String> result = MatcherUtils.extractPlaceholderValues("${3}://${1}/lfaskdjflkas/${2}", "a://b/lfaskdjflkas/c");
Assert.assertEquals(result.get(1), "b");
Assert.assertEquals(result.get(2), "c");
Assert.assertEquals(result.get(3), "a");
}
@Test
public void testGetCommaSeparatedValues() throws Exception {
final String input = " value1, \n\t value2 ,value3 , value4,value5";
final String[] expected = new String[]{"value1","value2","value3","value4","value5"};
final String[] actual = MatcherUtils.getCommaSeparatedValues(input);
Assert.assertEquals("Lengths of resulting arrays don't match", 5, actual.length);
Assert.assertEquals(expected[0], actual[0]);
Assert.assertEquals(expected[1], actual[1]);
Assert.assertEquals(expected[2], actual[2]);
Assert.assertEquals(expected[3], actual[3]);
Assert.assertEquals(expected[4], actual[4]);
}
@Test
public void testParsePropertyValueOK() throws Exception {
final String input1 = "property=value";
final String input2 = "property = value";
final String input3 = "property \t\n = \t\n value";
final String[] expectedA = new String[]{"property","value"};
assertPropertyValue(input1, expectedA);
assertPropertyValue(input2, expectedA);
assertPropertyValue(input3, expectedA);
final String input4 = "namespace:property=value";
final String input5 = "namespace:property = value";
final String input6 = "namespace:property \t\n = \t\n value";
final String[] expectedB = new String[]{"namespace:property","value"};
assertPropertyValue(input4, expectedB);
assertPropertyValue(input5, expectedB);
assertPropertyValue(input6, expectedB);
}
private void assertPropertyValue(final String input, final String[] expected) {
final String[] actual = MatcherUtils.parsePropertyValue(input);
Assert.assertEquals(2, actual.length);
Assert.assertEquals(expected[0], actual[0]);
Assert.assertEquals(expected[1], actual[1]);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment