diff --git a/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java b/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java index 28ed7e2562e..ce5a22a406b 100644 --- a/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java +++ b/wicket-core/src/main/java/org/apache/wicket/resource/ResourceUtil.java @@ -19,8 +19,8 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; +import java.util.ArrayList; import java.util.Locale; -import java.util.regex.Pattern; import org.apache.wicket.WicketRuntimeException; import org.apache.wicket.request.Url; @@ -39,7 +39,10 @@ public class ResourceUtil { - private static final Pattern ESCAPED_ATTRIBUTE_PATTERN = Pattern.compile("(\\w)~(\\w)"); + /** + * Used to denote {@code null} in encoded strings. + */ + private static final String NULL_VALUE = "null"; /** * Reads resource reference attributes (style, locale, variation) encoded in the given string. @@ -52,24 +55,12 @@ public class ResourceUtil */ public static ResourceReference.UrlAttributes decodeResourceReferenceAttributes(String encodedAttributes) { - Locale locale = null; - String style = null; - String variation = null; + String[] decodeAttributes = decodeStringParts(encodedAttributes); + + Locale locale = decodeAttributes.length > 0 ? parseLocale(decodeAttributes[0]) : null; + String style = decodeAttributes.length > 1 ? decodeAttributes[1] : null; + String variation = decodeAttributes.length > 2 ? decodeAttributes[2] : null; - if (Strings.isEmpty(encodedAttributes) == false) - { - String split[] = Strings.split(encodedAttributes, '-'); - locale = parseLocale(split[0]); - if (split.length == 2) - { - style = Strings.defaultIfEmpty(unescapeAttributesSeparator(split[1]), null); - } - else if (split.length == 3) - { - style = Strings.defaultIfEmpty(unescapeAttributesSeparator(split[1]), null); - variation = Strings.defaultIfEmpty(unescapeAttributesSeparator(split[2]), null); - } - } return new ResourceReference.UrlAttributes(locale, style, variation); } @@ -109,37 +100,18 @@ public static ResourceReference.UrlAttributes decodeResourceReferenceAttributes( public static String encodeResourceReferenceAttributes(ResourceReference.UrlAttributes attributes) { if (attributes == null || - (attributes.getLocale() == null && attributes.getStyle() == null && attributes.getVariation() == null)) - { - return null; - } - else - { - StringBuilder res = new StringBuilder(32); - if (attributes.getLocale() != null) + (attributes.getLocale() == null && attributes.getStyle() == null && attributes.getVariation() == null)) { - res.append(attributes.getLocale()); + return null; } - boolean styleEmpty = Strings.isEmpty(attributes.getStyle()); - if (!styleEmpty) + else { - res.append('-'); - res.append(escapeAttributesSeparator(attributes.getStyle())); + StringBuilder buffer = new StringBuilder(32); + encodeStringPart(attributes.getLocale() == null ? null : attributes.getLocale().toString(), buffer); + encodeStringPart(attributes.getStyle(), buffer); + encodeStringPart(attributes.getVariation(), buffer); + return buffer.toString(); } - if (!Strings.isEmpty(attributes.getVariation())) - { - if (styleEmpty) - { - res.append("--"); - } - else - { - res.append('-'); - } - res.append(escapeAttributesSeparator(attributes.getVariation())); - } - return res.toString(); - } } /** @@ -164,20 +136,6 @@ public static void encodeResourceReferenceAttributes(Url url, ResourceReference } } - /** - * Escapes any occurrences of - character in the style and variation - * attributes with ~. Any occurrence of ~ is encoded as ~~. - * - * @param attribute - * the attribute to escape - * @return the attribute with escaped separator character - */ - public static CharSequence escapeAttributesSeparator(String attribute) - { - CharSequence tmp = Strings.replaceAll(attribute, "~", "~~"); - return Strings.replaceAll(tmp, "-", "~"); - } - /** * Parses the string representation of a {@link java.util.Locale} (for example 'en_GB'). * @@ -268,17 +226,65 @@ public static String readString(IResourceStream resourceStream, Charset charset) } /** - * Reverts the escaping applied by {@linkplain #escapeAttributesSeparator(String)} - unescapes - * occurrences of ~ character in the style and variation attributes with -. + * Encode the {@code part} in the format ~. + * + * If the {@code part} is {@code null} the special value {@link #NULL_VALUE} is used; + * + * @param part + * The string to encode. + * @param buffer + * The buffer into which the {@code part} is encoded. + * @return The {@code buffer} for chaining. + */ + static StringBuilder encodeStringPart(String part, StringBuilder buffer) + { + if (part == null) { + return buffer.append(NULL_VALUE); + } + + int length = part.length(); + return buffer.append(length).append('~').append(part); + } + + /** + * Decodes the {@code encoded} parts of a string decoded by {@link #encodeStringPart(String)}. * - * @param attribute - * the attribute to unescape - * @return the attribute with escaped separator character + * @param encoded + * @return An array containing the parts of {@code encoded}. + * The array can contain {@code null} but is itself never {@code null} */ - public static String unescapeAttributesSeparator(String attribute) + static String[] decodeStringParts(String encoded) { - String tmp = ESCAPED_ATTRIBUTE_PATTERN.matcher(attribute).replaceAll("$1-$2"); - return Strings.replaceAll(tmp, "~~", "~").toString(); + ArrayList result = new ArrayList<>(); + + StringBuilder lengthString = new StringBuilder(); + char[] chars = encoded.toCharArray(); + for (int i = 0; i < chars.length; i++) + { + boolean isAtStartOfPart = lengthString.length() == 0; + if (isAtStartOfPart && chars.length >= i + NULL_VALUE.length() && + String.valueOf(chars, i, NULL_VALUE.length()).equals(NULL_VALUE)) { + result.add(null); + i += NULL_VALUE.length() - 1; + continue; + } + + char c = chars[i]; + if (c >= '0' && c <= '9') { + lengthString.append(c); + } else { + if (isAtStartOfPart || c != '~') { // Not a (valid) resource attribute string + return new String[0]; + } + + int length = Integer.parseInt(lengthString.toString()); + lengthString.setLength(0); // reset the length buffer + result.add(String.valueOf(chars, i + 1, length)); + i += length; + } + } + + return result.toArray(String[]::new); } private ResourceUtil() diff --git a/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/AbstractResourceReferenceMapperOwnTest.java b/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/AbstractResourceReferenceMapperOwnTest.java deleted file mode 100644 index 104d2f90408..00000000000 --- a/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/AbstractResourceReferenceMapperOwnTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.wicket.core.request.mapper; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.apache.wicket.request.IRequestHandler; -import org.apache.wicket.request.Request; -import org.apache.wicket.request.Url; -import org.apache.wicket.resource.ResourceUtil; -import org.junit.jupiter.api.Test; - -/** - * Tests for AbstractResourceReferenceMapper's own methods - */ -class AbstractResourceReferenceMapperOwnTest -{ - @Test - void testEscapeAttributesSeparator() throws Exception - { - AbstractResourceReferenceMapper mapper = new Mapper(); - CharSequence escaped = ResourceUtil.escapeAttributesSeparator("my-style~is~~cool"); - assertEquals("my~style~~is~~~~cool", escaped.toString()); - } - - @Test - void testUnescapeAttributesSeparator() throws Exception - { - AbstractResourceReferenceMapper mapper = new Mapper(); - CharSequence escaped = ResourceUtil.unescapeAttributesSeparator("my~style~~is~~~~cool"); - assertEquals("my-style~is~~cool", escaped.toString()); - } - - /** - * A non-abstract class used for the tests - */ - private static class Mapper extends AbstractResourceReferenceMapper - { - public IRequestHandler mapRequest(Request request) - { - return null; - } - - public int getCompatibilityScore(Request request) - { - return 0; - } - - public Url mapHandler(IRequestHandler requestHandler) - { - return null; - } - } -} diff --git a/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/BasicResourceReferenceMapperTest.java b/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/BasicResourceReferenceMapperTest.java index def27a40688..d6dd3e5fbc8 100644 --- a/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/BasicResourceReferenceMapperTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/BasicResourceReferenceMapperTest.java @@ -83,7 +83,7 @@ void decode1() @Test void decode1A() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference1?en"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference1?2~ennullnull"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); // assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); // TODO use hamcrest or assertj ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -120,7 +120,7 @@ void decode2() @Test void decode2A() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference1?-style&p1=v1&p2=v2"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference1?null5~stylenull&p1=v1&p2=v2"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -139,7 +139,7 @@ void decode2A() @Test void decode3() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference2/name2?en_EN"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference2/name2?5~en_ENnullnull"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); @@ -158,7 +158,7 @@ void decode3() @Test void decode3A() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference2/name2?en_EN-style"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference2/name2?5~en_EN5~stylenull"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -188,7 +188,7 @@ void decode3B() void decode4() { Url url = Url - .parse("wicket/resource/" + CLASS_NAME + "/reference2/name2?en_EN&p1=v1&p2=v2"); + .parse("wicket/resource/" + CLASS_NAME + "/reference2/name2?5~en_ENnullnull&p1=v1&p2=v2"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -206,7 +206,7 @@ void decode4() @Test void decode5() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference3?-style"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference3?null5~stylenull"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -224,7 +224,7 @@ void decode5() @Test void decode6() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference3?-style&p1=v1&p2=v2"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference3?null5~stylenull&p1=v1&p2=v2"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -244,7 +244,7 @@ void decode6() @Test void decode7() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference4?en-style"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference4?2~en5~stylenull"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -262,7 +262,7 @@ void decode7() @Test void decode7A() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference4?sk"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference4?2~sknullnull"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertNull(handler); } @@ -273,7 +273,7 @@ void decode7A() @Test void decode8() { - Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference4?en-style&p1=v1&p2=v2"); + Url url = Url.parse("wicket/resource/" + CLASS_NAME + "/reference4?2~en5~stylenull&p1=v1&p2=v2"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -293,7 +293,7 @@ void decode8() void decode9() { Url url = Url.parse("wicket/resource/" + CLASS_NAME - + "/reference5?en--variation&p1=v1&p2=v2"); + + "/reference5?2~ennull9~variation&p1=v1&p2=v2"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -313,7 +313,7 @@ void decode9() void decode10() { Url url = Url.parse("wicket/resource/" + CLASS_NAME - + "/reference6?en-style-variation&p1=v1&p2=v2"); + + "/reference6?2~en5~style9~variation&p1=v1&p2=v2"); IRequestHandler handler = encoder.mapRequest(getRequest(url)); assertThat(handler).isInstanceOf(ResourceReferenceRequestHandler.class); ResourceReferenceRequestHandler h = (ResourceReferenceRequestHandler)handler; @@ -375,7 +375,7 @@ void encode3() ResourceReferenceRequestHandler handler = new ResourceReferenceRequestHandler(reference2, null); Url url = encoder.mapHandler(handler); - assertEquals("wicket/resource/" + CLASS_NAME + "/reference2/name2?en_EN", url.toString()); + assertEquals("wicket/resource/" + CLASS_NAME + "/reference2/name2?5~en_ENnullnull", url.toString()); } /** @@ -392,7 +392,7 @@ void encode4() parameters); Url url = encoder.mapHandler(handler); - assertEquals("wicket/resource/" + CLASS_NAME + "/reference2/name2?en_EN&p1=v1&p2=v2", + assertEquals("wicket/resource/" + CLASS_NAME + "/reference2/name2?5~en_ENnullnull&p1=v1&p2=v2", url.toString()); } @@ -405,7 +405,7 @@ void encode5() ResourceReferenceRequestHandler handler = new ResourceReferenceRequestHandler(reference3, null); Url url = encoder.mapHandler(handler); - assertEquals("wicket/resource/" + CLASS_NAME + "/reference3?-style", url.toString()); + assertEquals("wicket/resource/" + CLASS_NAME + "/reference3?null5~stylenull", url.toString()); } /** @@ -422,7 +422,7 @@ void encode6() parameters); Url url = encoder.mapHandler(handler); - assertEquals("wicket/resource/" + CLASS_NAME + "/reference3?-style&p1=v1&p2=v2", + assertEquals("wicket/resource/" + CLASS_NAME + "/reference3?null5~stylenull&p1=v1&p2=v2", url.toString()); } @@ -435,7 +435,7 @@ void encode7() ResourceReferenceRequestHandler handler = new ResourceReferenceRequestHandler(reference4, null); Url url = encoder.mapHandler(handler); - assertEquals("wicket/resource/" + CLASS_NAME + "/reference4?en-style", url.toString()); + assertEquals("wicket/resource/" + CLASS_NAME + "/reference4?2~en5~stylenull", url.toString()); } /** @@ -452,7 +452,7 @@ void encode8() parameters); Url url = encoder.mapHandler(handler); - assertEquals("wicket/resource/" + CLASS_NAME + "/reference4?en-style&p1=v1&p2=v2", + assertEquals("wicket/resource/" + CLASS_NAME + "/reference4?2~en5~stylenull&p1=v1&p2=v2", url.toString()); } @@ -466,7 +466,7 @@ void encode9() null); Url url = encoder.mapHandler(handler); - assertEquals("wicket/resource/" + CLASS_NAME + "/reference5?en--variation", url.toString()); + assertEquals("wicket/resource/" + CLASS_NAME + "/reference5?2~ennull9~variation", url.toString()); } /** diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/form/imagebutton/ImageButtonTest.java b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/imagebutton/ImageButtonTest.java index 7e7ffae0304..5403b627119 100644 --- a/wicket-core/src/test/java/org/apache/wicket/markup/html/form/imagebutton/ImageButtonTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/imagebutton/ImageButtonTest.java @@ -38,19 +38,19 @@ void imageButton() throws Exception tester.startPage(Home.class); tester.clickLink("goCanadian"); - tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?en_CA\""); + tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?5~en_CAnullnull\""); tester.clickLink("goChinese"); - tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?zh_CN\""); + tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?5~zh_CNnullnull\""); tester.clickLink("goDanish"); - tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?da_DK\""); + tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?5~da_DKnullnull\""); tester.clickLink("goDutch"); - tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?nl_NL\""); + tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?5~nl_NLnullnull\""); tester.clickLink("goGerman"); - tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?de_DE\""); + tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\\?5~de_DEnullnull\""); tester.clickLink("goUS"); tester.assertContains("resource/org.apache.wicket.markup.html.form.imagebutton.Home/Beer.gif\""); diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageTest.java b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageTest.java index 04e8ad94e6b..9b87d7eca4d 100644 --- a/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/image/ImageTest.java @@ -38,19 +38,19 @@ void test_1() throws Exception tester.startPage(Home.class); tester.clickLink("goCanadian"); - tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?en_CA\""); + tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?5~en_CAnullnull\""); tester.clickLink("goChinese"); - tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?zh_CN\""); + tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?5~zh_CNnullnull\""); tester.clickLink("goDanish"); - tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?da_DK\""); + tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?5~da_DKnullnull\""); tester.clickLink("goDutch"); - tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?nl_NL\""); + tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?5~nl_NLnullnull\""); tester.clickLink("goGerman"); - tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?de_DE\""); + tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\\?5~de_DEnullnull\""); tester.clickLink("goUS"); tester.assertContains("resource/org.apache.wicket.markup.html.image.Home/Beer.gif\""); diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/link/AutolinkPageExpectedResult_1.html b/wicket-core/src/test/java/org/apache/wicket/markup/html/link/AutolinkPageExpectedResult_1.html index fcf1cade818..4e00ff16e50 100644 --- a/wicket-core/src/test/java/org/apache/wicket/markup/html/link/AutolinkPageExpectedResult_1.html +++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/link/AutolinkPageExpectedResult_1.html @@ -25,9 +25,9 @@ Home - - - + + + Home Home Google diff --git a/wicket-core/src/test/java/org/apache/wicket/resource/ResourceUtilTest.java b/wicket-core/src/test/java/org/apache/wicket/resource/ResourceUtilTest.java index 92b84bac256..7a4fe9f74fd 100644 --- a/wicket-core/src/test/java/org/apache/wicket/resource/ResourceUtilTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/resource/ResourceUtilTest.java @@ -32,30 +32,30 @@ class ResourceUtilTest @Test void decodeResourceReferenceAttributesWithString() throws Exception { - String urlParameter = "en_GB-style-variation"; + String urlParameter = "5~en_GB5~style9~variation"; UrlAttributes attributes = ResourceUtil.decodeResourceReferenceAttributes(urlParameter); assertEquals(Locale.UK, attributes.getLocale()); assertEquals("style", attributes.getStyle()); assertEquals("variation", attributes.getVariation()); - attributes = ResourceUtil.decodeResourceReferenceAttributes("it_IT"); + attributes = ResourceUtil.decodeResourceReferenceAttributes("5~it_ITnullnull"); assertEquals(Locale.ITALY, attributes.getLocale()); assertNull(attributes.getStyle()); assertNull(attributes.getVariation()); - attributes = ResourceUtil.decodeResourceReferenceAttributes("-style-variation"); + attributes = ResourceUtil.decodeResourceReferenceAttributes("null5~style9~variation"); assertNull(attributes.getLocale()); assertEquals("style", attributes.getStyle()); assertEquals("variation", attributes.getVariation()); - attributes = ResourceUtil.decodeResourceReferenceAttributes("--variation"); + attributes = ResourceUtil.decodeResourceReferenceAttributes("nullnull9~variation"); assertNull(attributes.getLocale()); assertNull(attributes.getStyle()); assertEquals("variation", attributes.getVariation()); - attributes = ResourceUtil.decodeResourceReferenceAttributes("-style"); + attributes = ResourceUtil.decodeResourceReferenceAttributes("null5~stylenull"); assertNull(attributes.getLocale()); assertEquals("style", attributes.getStyle()); assertNull(attributes.getVariation()); @@ -69,13 +69,13 @@ void decodeResourceReferenceAttributesWithUrl() throws Exception assertEquals(new UrlAttributes(null, null, null), attributes); - url = Url.parse("www.funny.url/?de_DE"); + url = Url.parse("www.funny.url/?5~de_DEnullnull"); attributes = ResourceUtil.decodeResourceReferenceAttributes(url); assertEquals(Locale.GERMANY, attributes.getLocale()); assertNull(attributes.getStyle()); assertNull(attributes.getVariation()); - url = Url.parse("www.funny.url/?-style"); + url = Url.parse("www.funny.url/?null5~stylenull"); attributes = ResourceUtil.decodeResourceReferenceAttributes(url); assertNull(attributes.getLocale()); assertEquals("style", attributes.getStyle()); @@ -90,11 +90,26 @@ void encodeResourceReferenceAttributes() throws Exception attributes = new UrlAttributes(Locale.CANADA_FRENCH, "style", "variation"); - assertEquals("fr_CA-style-variation", ResourceUtil.encodeResourceReferenceAttributes(attributes)); + assertEquals("5~fr_CA5~style9~variation", ResourceUtil.encodeResourceReferenceAttributes(attributes)); attributes = new UrlAttributes(null, null, "variation"); - assertEquals("--variation", ResourceUtil.encodeResourceReferenceAttributes(attributes)); + assertEquals("nullnull9~variation", ResourceUtil.encodeResourceReferenceAttributes(attributes)); + } + + @Test + void encodeAndDecodeVariationShouldBeEqual() throws Exception + { + String[] variations = new String[] {"double--separator", "single-e-inside", "-", "--", "~", "~~"}; + + for (String variation : variations) { + UrlAttributes attributes = new UrlAttributes(null, null, variation); + String encoded = ResourceUtil.encodeResourceReferenceAttributes(attributes); + + attributes = ResourceUtil.decodeResourceReferenceAttributes(encoded); + + assertEquals(variation, attributes.getVariation()); + } } @Test @@ -121,7 +136,7 @@ void encodeResourceReferenceAttributesWithResource() throws Exception Mockito.when(resourceReference.getUrlAttributes()).thenReturn(attributes); ResourceUtil.encodeResourceReferenceAttributes(url, resourceReference); - assertEquals(urlString + "?fr_CA-style-variation", url.toString()); + assertEquals(urlString + "?5~fr_CA5~style9~variation", url.toString()); Mockito.reset(resourceReference); @@ -132,6 +147,6 @@ void encodeResourceReferenceAttributesWithResource() throws Exception Mockito.when(resourceReference.getUrlAttributes()).thenReturn(attributes); ResourceUtil.encodeResourceReferenceAttributes(url, resourceReference); - assertEquals(urlString + "?--variation", url.toString()); + assertEquals(urlString + "?nullnull9~variation", url.toString()); } }