From 0f45c1da0b372b56d3c3808837a4060778c97834 Mon Sep 17 00:00:00 2001 From: Woonsan Ko Date: Fri, 5 Jan 2018 13:54:03 -0500 Subject: [PATCH 1/3] FREEMARKER-55: cleanups with new #of(StringToIndexMap, Entry...) --- .../core/util/StringToIndexMapTest.java | 32 ++++++++++- .../core/util/StringToIndexMap.java | 55 ++++++++++++------- ...oundFormElementTemplateDirectiveModel.java | 6 +- ...ractHtmlElementTemplateDirectiveModel.java | 44 +++++++-------- ...tmlInputElementTemplateDirectiveModel.java | 22 +++----- .../form/FormTemplateDirectiveModel.java | 36 +++++------- .../form/InputTemplateDirectiveModel.java | 20 +++---- 7 files changed, 115 insertions(+), 100 deletions(-) diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/StringToIndexMapTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/StringToIndexMapTest.java index 3be5783dc..5973c45ea 100644 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/StringToIndexMapTest.java +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/StringToIndexMapTest.java @@ -19,14 +19,19 @@ package org.apache.freemarker.core.util; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; - import org.apache.freemarker.core.util.StringToIndexMap.Entry; import org.junit.Test; import com.google.common.collect.ImmutableList; +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + public class StringToIndexMapTest { @Test @@ -166,4 +171,25 @@ public void testClashingKey() { } } + @Test + public void testEntryInheritance() { + StringToIndexMap base = StringToIndexMap.of("i", 0, "j", 1); + StringToIndexMap derived =StringToIndexMap.of(base, + new StringToIndexMap.Entry("k", 2), + new StringToIndexMap.Entry("l", 3)); + + assertEquals(4, derived.size()); + assertEquals(-1, derived.get("a")); + assertEquals(0, derived.get("i")); + assertEquals(1, derived.get("j")); + assertEquals(2, derived.get("k")); + assertEquals(3, derived.get("l")); + assertEquals(ImmutableList.of("i", "j", "k", "l"), derived.getKeys()); + assertEquals("i", derived.getKeyOfValue(0)); + assertEquals("j", derived.getKeyOfValue(1)); + assertEquals("k", derived.getKeyOfValue(2)); + assertEquals("l", derived.getKeyOfValue(3)); + assertNull(derived.getKeyOfValue(4)); + } + } diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/StringToIndexMap.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/StringToIndexMap.java index 280bc1d0a..79dbabf46 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/StringToIndexMap.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/util/StringToIndexMap.java @@ -19,6 +19,8 @@ package org.apache.freemarker.core.util; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -37,10 +39,6 @@ public final class StringToIndexMap { private static final int MAX_VARIATIONS_TRIED = 4; - /** Input Entries from caller. */ - private final Entry[] inputEntries; - - /** Internal entry buckets. */ private final Entry[] buckets; private final int bucketIndexMask; private final int bucketIndexOverlap; @@ -133,9 +131,26 @@ public static StringToIndexMap of() { return EMPTY; } + /** + * Create a new {@link StringToIndexMap} by inheriting all the entries in {@code baseMap} and appending all + * the entry items in {@code additionalEntries}. + * @param baseMap {@link StringToIndexMap} to inherit entries from + * @param additionalEntries additional entries + * @return a new {@link StringToIndexMap} by adding all the entries in {@code inherited} and appending all + * the entry items in {@code additionalEntries} + */ + public static StringToIndexMap of(StringToIndexMap baseMap, Entry... additionalEntries) { + final int additionalEntriesLength = (additionalEntries != null) ? additionalEntries.length : 0; + List newEntries = new ArrayList<>(baseMap.size() + additionalEntriesLength); + baseMap.collectAllEntriesTo(newEntries); + for (int i = 0; i < additionalEntriesLength; i++) { + newEntries.add(additionalEntries[i]); + } + return of(newEntries.toArray(new Entry[newEntries.size()])); + } + // This is a very frequent case, so we optimize for it a bit. private StringToIndexMap(Entry entry) { - inputEntries = new Entry[] { entry }; buckets = new Entry[] { entry }; bucketIndexMask = 0; bucketIndexOverlap = 0; @@ -148,15 +163,11 @@ private StringToIndexMap(Entry... entries) { private StringToIndexMap(Entry[] entries, int entriesLength) { if (entriesLength == 0) { - inputEntries = null; buckets = null; bucketIndexMask = 0; bucketIndexOverlap = 0; keys = Collections.emptyList(); } else { - inputEntries = new Entry[entriesLength]; - System.arraycopy(entries, 0, inputEntries, 0, entriesLength); - String[] keyArray = new String[entriesLength]; for (int i = 0; i < entriesLength; i++) { keyArray[i] = entries[i].key; @@ -177,7 +188,7 @@ private StringToIndexMap(Entry[] entries, int entriesLength) { filledBucketCnt++; } } - // Ideally, filledBucketCnt == entriesLength. If less, we have buckets with more then 1 element. + // Ideally, filledBucketCnt == entriesLength. If less, we have buckets with more than 1 element. int setupGoodness = filledBucketCnt - entriesLength; if (bestSetup == null || bestSetupGoodness < setupGoodness) { @@ -282,15 +293,6 @@ public void checkIndexRange(int start) { } - /** - * Return a cloned array from the original {@link Entry} array which was given by the caller through directly - * using {@link #of(Entry...)} or {@link #of(Entry[], int)} or indirectly using other methods such as {@link #of(String, int)}. - * @return a cloned array from the original {@link Entry} array which was given by the caller - */ - public Entry[] getInputEntries() { - return inputEntries; - } - private static int getPowerOf2GreaterThanOrEqualTo(int n) { if (n == 0) { return 0; @@ -352,6 +354,21 @@ public String getKeyOfValue(int value) { return null; } + /** + * Traverse all the entries and collect all into the given {@code targetEntryCollection}. + */ + private void collectAllEntriesTo(Collection targetEntryCollection) { + if (buckets == null) { + return; + } + for (Entry entry : buckets) { + while (entry != null) { + targetEntryCollection.add(entry); + entry = entry.nextInSameBucket; + } + } + } + /* // Code used to see how well the elements are spread among the buckets: diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractDataBoundFormElementTemplateDirectiveModel.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractDataBoundFormElementTemplateDirectiveModel.java index 11b47c301..ce37d88f7 100644 --- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractDataBoundFormElementTemplateDirectiveModel.java +++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractDataBoundFormElementTemplateDirectiveModel.java @@ -53,10 +53,6 @@ abstract class AbstractDataBoundFormElementTemplateDirectiveModel extends Abstra private static final String ID_PARAM_NAME = ID_ATTR_NAME; - private static final StringToIndexMap.Entry[] NAMED_ARGS_ENTRIES = { - new StringToIndexMap.Entry(ID_PARAM_NAME, ID_PARAM_IDX) - }; - /** * Returns the argument index of the last predefined named argument item in the {@code argsLayout}. *

@@ -75,7 +71,7 @@ protected static int getLastPredefinedNamedArgumentIndex(ArgumentArrayLayout arg ArgumentArrayLayout.create( 1, false, - StringToIndexMap.of(NAMED_ARGS_ENTRIES), + StringToIndexMap.of(ID_PARAM_NAME, ID_PARAM_IDX), true ); diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlElementTemplateDirectiveModel.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlElementTemplateDirectiveModel.java index 8e30dd256..28f8f07b3 100644 --- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlElementTemplateDirectiveModel.java +++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlElementTemplateDirectiveModel.java @@ -38,7 +38,6 @@ import org.apache.freemarker.core.model.TemplateStringModel; import org.apache.freemarker.core.util.CallableUtils; import org.apache.freemarker.core.util.StringToIndexMap; -import org.apache.freemarker.core.util._ArrayUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import org.springframework.web.servlet.support.RequestContext; @@ -105,34 +104,29 @@ abstract class AbstractHtmlElementTemplateDirectiveModel private static final int CSSERRORCLASS_PARAM_IDX = NAMED_ARGS_OFFSET + 16; private static final String CSSERRORCLASS_PARAM_NAME = "cssErrorClass"; - private static final StringToIndexMap.Entry[] NAMED_ARGS_ENTRIES = - _ArrayUtils.addAll( - AbstractDataBoundFormElementTemplateDirectiveModel.ARGS_LAYOUT.getPredefinedNamedArgumentsMap() - .getInputEntries(), - new StringToIndexMap.Entry(CSS_CLASS_PARAM_NAME, CSS_CLASS_PARAM_IDX), - new StringToIndexMap.Entry(CSS_STYLE_PARAM_NAME, CSS_STYLE_PARAM_IDX), - new StringToIndexMap.Entry(LANG_PARAM_NAME, LANG_PARAM_IDX), - new StringToIndexMap.Entry(TITLE_PARAM_NAME, TITLE_PARAM_IDX), - new StringToIndexMap.Entry(DIR_PARAM_NAME, DIR_PARAM_IDX), - new StringToIndexMap.Entry(TABINDEX_PARAM_NAME, TABINDEX_PARAM_IDX), - new StringToIndexMap.Entry(ONCLICK_PARAM_NAME, ONCLICK_PARAM_IDX), - new StringToIndexMap.Entry(ONDBLCLICK_PARAM_NAME, ONDBLCLICK_PARAM_IDX), - new StringToIndexMap.Entry(ONMOUSEDOWN_PARAM_NAME, ONMOUSEDOWN_PARAM_IDX), - new StringToIndexMap.Entry(ONMOUSEUP_PARAM_NAME, ONMOUSEUP_PARAM_IDX), - new StringToIndexMap.Entry(ONMOUSEOVER_PARAM_NAME, ONMOUSEOVER_PARAM_IDX), - new StringToIndexMap.Entry(ONMOUSEMOVE_PARAM_NAME, ONMOUSEMOVE_PARAM_IDX), - new StringToIndexMap.Entry(ONMOUSEOUT_PARAM_NAME, ONMOUSEOUT_PARAM_IDX), - new StringToIndexMap.Entry(ONKEYPRESS_PARAM_NAME, ONKEYPRESS_PARAM_IDX), - new StringToIndexMap.Entry(ONKEYUP_PARAM_NAME, ONKEYUP_PARAM_IDX), - new StringToIndexMap.Entry(ONKEYDOWN_PARAM_NAME, ONKEYDOWN_PARAM_IDX), - new StringToIndexMap.Entry(CSSERRORCLASS_PARAM_NAME, CSSERRORCLASS_PARAM_IDX) - ); - protected static final ArgumentArrayLayout ARGS_LAYOUT = ArgumentArrayLayout.create( 1, false, - StringToIndexMap.of(NAMED_ARGS_ENTRIES), + StringToIndexMap.of(AbstractDataBoundFormElementTemplateDirectiveModel.ARGS_LAYOUT.getPredefinedNamedArgumentsMap(), + new StringToIndexMap.Entry(CSS_CLASS_PARAM_NAME, CSS_CLASS_PARAM_IDX), + new StringToIndexMap.Entry(CSS_STYLE_PARAM_NAME, CSS_STYLE_PARAM_IDX), + new StringToIndexMap.Entry(LANG_PARAM_NAME, LANG_PARAM_IDX), + new StringToIndexMap.Entry(TITLE_PARAM_NAME, TITLE_PARAM_IDX), + new StringToIndexMap.Entry(DIR_PARAM_NAME, DIR_PARAM_IDX), + new StringToIndexMap.Entry(TABINDEX_PARAM_NAME, TABINDEX_PARAM_IDX), + new StringToIndexMap.Entry(ONCLICK_PARAM_NAME, ONCLICK_PARAM_IDX), + new StringToIndexMap.Entry(ONDBLCLICK_PARAM_NAME, ONDBLCLICK_PARAM_IDX), + new StringToIndexMap.Entry(ONMOUSEDOWN_PARAM_NAME, ONMOUSEDOWN_PARAM_IDX), + new StringToIndexMap.Entry(ONMOUSEUP_PARAM_NAME, ONMOUSEUP_PARAM_IDX), + new StringToIndexMap.Entry(ONMOUSEOVER_PARAM_NAME, ONMOUSEOVER_PARAM_IDX), + new StringToIndexMap.Entry(ONMOUSEMOVE_PARAM_NAME, ONMOUSEMOVE_PARAM_IDX), + new StringToIndexMap.Entry(ONMOUSEOUT_PARAM_NAME, ONMOUSEOUT_PARAM_IDX), + new StringToIndexMap.Entry(ONKEYPRESS_PARAM_NAME, ONKEYPRESS_PARAM_IDX), + new StringToIndexMap.Entry(ONKEYUP_PARAM_NAME, ONKEYUP_PARAM_IDX), + new StringToIndexMap.Entry(ONKEYDOWN_PARAM_NAME, ONKEYDOWN_PARAM_IDX), + new StringToIndexMap.Entry(CSSERRORCLASS_PARAM_NAME, CSSERRORCLASS_PARAM_IDX) + ), true ); diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlInputElementTemplateDirectiveModel.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlInputElementTemplateDirectiveModel.java index fd48eaecb..baee0d52b 100644 --- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlInputElementTemplateDirectiveModel.java +++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlInputElementTemplateDirectiveModel.java @@ -33,7 +33,6 @@ import org.apache.freemarker.core.model.TemplateModel; import org.apache.freemarker.core.util.CallableUtils; import org.apache.freemarker.core.util.StringToIndexMap; -import org.apache.freemarker.core.util._ArrayUtils; import org.springframework.web.servlet.support.RequestContext; abstract class AbstractHtmlInputElementTemplateDirectiveModel extends AbstractHtmlElementTemplateDirectiveModel { @@ -59,23 +58,18 @@ abstract class AbstractHtmlInputElementTemplateDirectiveModel extends AbstractHt private static final int READONLY_PARAM_IDX = NAMED_ARGS_OFFSET + 5; private static final String READONLY_PARAM_NAME = "readonly"; - private static final StringToIndexMap.Entry[] NAMED_ARGS_ENTRIES = - _ArrayUtils.addAll( - AbstractHtmlElementTemplateDirectiveModel.ARGS_LAYOUT.getPredefinedNamedArgumentsMap() - .getInputEntries(), - new StringToIndexMap.Entry(ONFOCUS_PARAM_NAME, ONFOCUS_PARAM_IDX), - new StringToIndexMap.Entry(ONBLUR_PARAM_NAME, ONBLUR_PARAM_IDX), - new StringToIndexMap.Entry(ONCHANGE_PARAM_NAME, ONCHANGE_PARAM_IDX), - new StringToIndexMap.Entry(ACCESSKEY_PARAM_NAME, ACCESSKEY_PARAM_IDX), - new StringToIndexMap.Entry(DISABLED_PARAM_NAME, DISABLED_PARAM_IDX), - new StringToIndexMap.Entry(READONLY_PARAM_NAME, READONLY_PARAM_IDX) - ); - protected static final ArgumentArrayLayout ARGS_LAYOUT = ArgumentArrayLayout.create( 1, false, - StringToIndexMap.of(NAMED_ARGS_ENTRIES), + StringToIndexMap.of(AbstractHtmlElementTemplateDirectiveModel.ARGS_LAYOUT.getPredefinedNamedArgumentsMap(), + new StringToIndexMap.Entry(ONFOCUS_PARAM_NAME, ONFOCUS_PARAM_IDX), + new StringToIndexMap.Entry(ONBLUR_PARAM_NAME, ONBLUR_PARAM_IDX), + new StringToIndexMap.Entry(ONCHANGE_PARAM_NAME, ONCHANGE_PARAM_IDX), + new StringToIndexMap.Entry(ACCESSKEY_PARAM_NAME, ACCESSKEY_PARAM_IDX), + new StringToIndexMap.Entry(DISABLED_PARAM_NAME, DISABLED_PARAM_IDX), + new StringToIndexMap.Entry(READONLY_PARAM_NAME, READONLY_PARAM_IDX) + ), true ); diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/FormTemplateDirectiveModel.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/FormTemplateDirectiveModel.java index a453a76cd..985cb7dd1 100644 --- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/FormTemplateDirectiveModel.java +++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/FormTemplateDirectiveModel.java @@ -35,7 +35,6 @@ import org.apache.freemarker.core.model.TemplateStringModel; import org.apache.freemarker.core.util.CallableUtils; import org.apache.freemarker.core.util.StringToIndexMap; -import org.apache.freemarker.core.util._ArrayUtils; import org.apache.freemarker.spring.model.SpringTemplateCallableHashModel; import org.springframework.beans.PropertyAccessor; import org.springframework.http.HttpMethod; @@ -118,30 +117,25 @@ class FormTemplateDirectiveModel extends AbstractHtmlElementTemplateDirectiveMod private static final int METHOD_PARAM_PARAM_IDX = NAMED_ARGS_OFFSET + 12; private static final String METHOD_PARAM_PARAM_NAME = "methodParam"; - private static final StringToIndexMap.Entry[] NAMED_ARGS_ENTRIES = - _ArrayUtils.addAll( - AbstractHtmlElementTemplateDirectiveModel.ARGS_LAYOUT.getPredefinedNamedArgumentsMap() - .getInputEntries(), - new StringToIndexMap.Entry(ACTION_PARAM_NAME, ACTION_PARAM_IDX), - new StringToIndexMap.Entry(METHOD_PARAM_NAME, METHOD_PARAM_IDX), - new StringToIndexMap.Entry(TARGET_PARAM_NAME, TARGET_PARAM_IDX), - new StringToIndexMap.Entry(ENCTYPE_PARAM_NAME, ENCTYPE_PARAM_IDX), - new StringToIndexMap.Entry(ACCEPT_CHARSET_PARAM_NAME, ACCEPT_CHARSET_PARAM_IDX), - new StringToIndexMap.Entry(ONSUBMIT_PARAM_NAME, ONSUBMIT_PARAM_IDX), - new StringToIndexMap.Entry(ONRESET_PARAM_NAME, ONRESET_PARAM_IDX), - new StringToIndexMap.Entry(AUTOCOMPLETE_PARAM_NAME, AUTOCOMPLETE_PARAM_IDX), - new StringToIndexMap.Entry(NAME_PARAM_NAME, NAME_PARAM_IDX), - new StringToIndexMap.Entry(VALUE_PARAM_NAME, VALUE_PARAM_IDX), - new StringToIndexMap.Entry(TYPE_PARAM_NAME, TYPE_PARAM_IDX), - new StringToIndexMap.Entry(SERVLET_RELATIVE_ACTION_PARAM_NAME, SERVLET_RELATIVE_ACTION_PARAM_IDX), - new StringToIndexMap.Entry(METHOD_PARAM_PARAM_NAME, METHOD_PARAM_PARAM_IDX) - ); - protected static final ArgumentArrayLayout ARGS_LAYOUT = ArgumentArrayLayout.create( 1, false, - StringToIndexMap.of(NAMED_ARGS_ENTRIES), + StringToIndexMap.of(AbstractHtmlElementTemplateDirectiveModel.ARGS_LAYOUT.getPredefinedNamedArgumentsMap(), + new StringToIndexMap.Entry(ACTION_PARAM_NAME, ACTION_PARAM_IDX), + new StringToIndexMap.Entry(METHOD_PARAM_NAME, METHOD_PARAM_IDX), + new StringToIndexMap.Entry(TARGET_PARAM_NAME, TARGET_PARAM_IDX), + new StringToIndexMap.Entry(ENCTYPE_PARAM_NAME, ENCTYPE_PARAM_IDX), + new StringToIndexMap.Entry(ACCEPT_CHARSET_PARAM_NAME, ACCEPT_CHARSET_PARAM_IDX), + new StringToIndexMap.Entry(ONSUBMIT_PARAM_NAME, ONSUBMIT_PARAM_IDX), + new StringToIndexMap.Entry(ONRESET_PARAM_NAME, ONRESET_PARAM_IDX), + new StringToIndexMap.Entry(AUTOCOMPLETE_PARAM_NAME, AUTOCOMPLETE_PARAM_IDX), + new StringToIndexMap.Entry(NAME_PARAM_NAME, NAME_PARAM_IDX), + new StringToIndexMap.Entry(VALUE_PARAM_NAME, VALUE_PARAM_IDX), + new StringToIndexMap.Entry(TYPE_PARAM_NAME, TYPE_PARAM_IDX), + new StringToIndexMap.Entry(SERVLET_RELATIVE_ACTION_PARAM_NAME, SERVLET_RELATIVE_ACTION_PARAM_IDX), + new StringToIndexMap.Entry(METHOD_PARAM_PARAM_NAME, METHOD_PARAM_PARAM_IDX) + ), true ); diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/InputTemplateDirectiveModel.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/InputTemplateDirectiveModel.java index a38e3c374..67f63bec8 100644 --- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/InputTemplateDirectiveModel.java +++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/InputTemplateDirectiveModel.java @@ -33,7 +33,6 @@ import org.apache.freemarker.core.model.TemplateModel; import org.apache.freemarker.core.util.CallableUtils; import org.apache.freemarker.core.util.StringToIndexMap; -import org.apache.freemarker.core.util._ArrayUtils; import org.springframework.web.servlet.support.RequestContext; /** @@ -88,22 +87,17 @@ class InputTemplateDirectiveModel extends AbstractHtmlInputElementTemplateDirect private static final int AUTOCOMPLETE_PARAM_IDX = NAMED_ARGS_OFFSET + 4; private static final String AUTOCOMPLETE_PARAM_NAME = "autocomplete"; - private static final StringToIndexMap.Entry[] NAMED_ARGS_ENTRIES = - _ArrayUtils.addAll( - AbstractHtmlInputElementTemplateDirectiveModel.ARGS_LAYOUT.getPredefinedNamedArgumentsMap() - .getInputEntries(), - new StringToIndexMap.Entry(SIZE_PARAM_NAME, SIZE_PARAM_IDX), - new StringToIndexMap.Entry(MAXLENGTH_PARAM_NAME, MAXLENGTH_PARAM_IDX), - new StringToIndexMap.Entry(ALT_PARAM_NAME, ALT_PARAM_IDX), - new StringToIndexMap.Entry(ONSELECT_PARAM_NAME, ONSELECT_PARAM_IDX), - new StringToIndexMap.Entry(AUTOCOMPLETE_PARAM_NAME, AUTOCOMPLETE_PARAM_IDX) - ); - protected static final ArgumentArrayLayout ARGS_LAYOUT = ArgumentArrayLayout.create( 1, false, - StringToIndexMap.of(NAMED_ARGS_ENTRIES), + StringToIndexMap.of(AbstractHtmlInputElementTemplateDirectiveModel.ARGS_LAYOUT.getPredefinedNamedArgumentsMap(), + new StringToIndexMap.Entry(SIZE_PARAM_NAME, SIZE_PARAM_IDX), + new StringToIndexMap.Entry(MAXLENGTH_PARAM_NAME, MAXLENGTH_PARAM_IDX), + new StringToIndexMap.Entry(ALT_PARAM_NAME, ALT_PARAM_IDX), + new StringToIndexMap.Entry(ONSELECT_PARAM_NAME, ONSELECT_PARAM_IDX), + new StringToIndexMap.Entry(AUTOCOMPLETE_PARAM_NAME, AUTOCOMPLETE_PARAM_IDX) + ), true ); From ba39a0bc5031dc1fe02b422895f0518ce7a5e713 Mon Sep 17 00:00:00 2001 From: Woonsan Ko Date: Fri, 5 Jan 2018 13:56:49 -0500 Subject: [PATCH 2/3] FREEMARKER-55: remove unused _ArrayUtils --- .../freemarker/core/util/_ArrayUtilsTest.java | 76 ------------ .../freemarker/core/util/_ArrayUtils.java | 109 ------------------ 2 files changed, 185 deletions(-) delete mode 100644 freemarker-core-test/src/test/java/org/apache/freemarker/core/util/_ArrayUtilsTest.java delete mode 100644 freemarker-core/src/main/java/org/apache/freemarker/core/util/_ArrayUtils.java diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/_ArrayUtilsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/_ArrayUtilsTest.java deleted file mode 100644 index b849bca23..000000000 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/_ArrayUtilsTest.java +++ /dev/null @@ -1,76 +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.freemarker.core.util; - -import java.util.Arrays; - -import org.junit.Test; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - -public class _ArrayUtilsTest { - - @Test - public void testAddAll() { - Object [] arr = _ArrayUtils.addAll(null); - assertTrue(arr.length == 0); - - arr = _ArrayUtils.addAll(null, null); - assertNull(arr); - - Object[] arr1 = { "a", "b", "c" }; - Object[] arr2 = { "1", "2", "3" }; - Object[] arrAll = { "a", "b", "c", "1", "2", "3" }; - - arr = _ArrayUtils.addAll(arr1, null); - assertNotSame(arr1, arr); - assertArrayEquals(arr1, arr); - - arr = _ArrayUtils.addAll(null, arr2); - assertNotSame(arr2, arr); - assertArrayEquals(arr2, arr); - - arr = _ArrayUtils.addAll(arr1, arr2); - assertArrayEquals(arrAll, arr); - } - - @Test - public void testClone() { - assertArrayEquals(null, _ArrayUtils.clone((Object[]) null)); - Object[] original1 = new Object[0]; - Object[] cloned1 = _ArrayUtils.clone(original1); - assertTrue(Arrays.equals(original1, cloned1)); - assertTrue(original1 != cloned1); - - final StringBuilder builder = new StringBuilder("pick"); - original1 = new Object[]{builder, "a", new String[]{"stick"}}; - cloned1 = _ArrayUtils.clone(original1); - assertTrue(Arrays.equals(original1, cloned1)); - assertTrue(original1 != cloned1); - assertSame(original1[0], cloned1[0]); - assertSame(original1[1], cloned1[1]); - assertSame(original1[2], cloned1[2]); - } - -} \ No newline at end of file diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/_ArrayUtils.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/_ArrayUtils.java deleted file mode 100644 index a060f9943..000000000 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/_ArrayUtils.java +++ /dev/null @@ -1,109 +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.freemarker.core.util; - -import java.lang.reflect.Array; - -/** - * Don't use this; used internally by FreeMarker, might changes without notice. - */ -public class _ArrayUtils { - - private _ArrayUtils() { - } - - // Note: Copied from Commons Lang's ArrayUtils (v3.7). - /** - *

Adds all the elements of the given arrays into a new array. - *

The new array contains all of the element of {@code array1} followed - * by all of the elements {@code array2}. When an array is returned, it is always - * a new array. - * - *

-     * ArrayUtils.addAll(null, null)     = null
-     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
-     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
-     * ArrayUtils.addAll([], [])         = []
-     * ArrayUtils.addAll([null], [null]) = [null, null]
-     * ArrayUtils.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]
-     * 
- * - * @param the component type of the array - * @param array1 the first array whose elements are added to the new array, may be {@code null} - * @param array2 the second array whose elements are added to the new array, may be {@code null} - * @return The new array, {@code null} if both arrays are {@code null}. - * The type of the new array is the type of the first array, - * unless the first array is null, in which case the type is the same as the second array. - * @since 2.1 - * @throws IllegalArgumentException if the array types are incompatible - */ - public static T[] addAll(final T[] array1, final T... array2) { - if (array1 == null) { - return clone(array2); - } else if (array2 == null) { - return clone(array1); - } - final Class type1 = array1.getClass().getComponentType(); - @SuppressWarnings("unchecked") // OK, because array is of type T - final T[] joinedArray = (T[]) Array.newInstance(type1, array1.length + array2.length); - System.arraycopy(array1, 0, joinedArray, 0, array1.length); - try { - System.arraycopy(array2, 0, joinedArray, array1.length, array2.length); - } catch (final ArrayStoreException ase) { - // Check if problem was due to incompatible types - /* - * We do this here, rather than before the copy because: - * - it would be a wasted check most of the time - * - safer, in case check turns out to be too strict - */ - final Class type2 = array2.getClass().getComponentType(); - if (!type1.isAssignableFrom(type2)) { - throw new IllegalArgumentException("Cannot store " + type2.getName() + " in an array of " - + type1.getName(), ase); - } - throw ase; // No, so rethrow original - } - return joinedArray; - } - - // Note: Copied from Commons Lang's ArrayUtils (v3). - // Clone - //----------------------------------------------------------------------- - /** - *

Shallow clones an array returning a typecast result and handling - * {@code null}. - * - *

The objects in the array are not cloned, thus there is no special - * handling for multi-dimensional arrays. - * - *

This method returns {@code null} for a {@code null} input array. - * - * @param the component type of the array - * @param array the array to shallow clone, may be {@code null} - * @return the cloned array, {@code null} if {@code null} input - */ - public static T[] clone(final T[] array) { - if (array == null) { - return null; - } - return array.clone(); - } - -} From ce78134ece2ad0df653538ebdd244bd0a5806679 Mon Sep 17 00:00:00 2001 From: Woonsan Ko Date: Fri, 5 Jan 2018 14:20:40 -0500 Subject: [PATCH 3/3] FREEMARKER-55: moving #getLastPredefinedNamedArgumentIndex() to CallableUtils --- .../apache/freemarker/core/util/CallableUtils.java | 14 ++++++++++++++ .../freemarker/core/util/StringToIndexMap.java | 4 ++-- ...DataBoundFormElementTemplateDirectiveModel.java | 14 -------------- .../AbstractHtmlElementTemplateDirectiveModel.java | 4 ++-- ...ractHtmlInputElementTemplateDirectiveModel.java | 4 ++-- .../model/form/FormTemplateDirectiveModel.java | 4 ++-- .../model/form/InputTemplateDirectiveModel.java | 4 ++-- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/CallableUtils.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/CallableUtils.java index e0d371f88..f20017161 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/CallableUtils.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/util/CallableUtils.java @@ -1056,6 +1056,20 @@ public static void checkArgumentCount(int argCnt, int minCnt, int maxCnt, } } + /** + * Returns the argument index of the last predefined named argument item in the {@code argsLayout}. + *

+ * Note: It is strongly assumed that the predefined named arguments map contains only items with indexes, + * starting from the predefined positional argument count and incrementing by one sequentially. + *

+ * @param argsLayout arguments layout + * @return the argument index of the last predefined named argument item in the {@code argsLayout} + */ + public static int getLastPredefinedNamedArgumentIndex(ArgumentArrayLayout argsLayout) { + return argsLayout.getPredefinedPositionalArgumentCount() + argsLayout.getPredefinedNamedArgumentsMap().size() + - 1; + } + private static Object[] getMessagePartExpectedNArgumentButHadM(int argCnt, int minCnt, int maxCnt) { ArrayList desc = new ArrayList<>(20); diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/StringToIndexMap.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/StringToIndexMap.java index 79dbabf46..a2248b1bf 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/StringToIndexMap.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/util/StringToIndexMap.java @@ -142,7 +142,7 @@ public static StringToIndexMap of() { public static StringToIndexMap of(StringToIndexMap baseMap, Entry... additionalEntries) { final int additionalEntriesLength = (additionalEntries != null) ? additionalEntries.length : 0; List newEntries = new ArrayList<>(baseMap.size() + additionalEntriesLength); - baseMap.collectAllEntriesTo(newEntries); + baseMap.collectAllEntriesInto(newEntries); for (int i = 0; i < additionalEntriesLength; i++) { newEntries.add(additionalEntries[i]); } @@ -357,7 +357,7 @@ public String getKeyOfValue(int value) { /** * Traverse all the entries and collect all into the given {@code targetEntryCollection}. */ - private void collectAllEntriesTo(Collection targetEntryCollection) { + private void collectAllEntriesInto(Collection targetEntryCollection) { if (buckets == null) { return; } diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractDataBoundFormElementTemplateDirectiveModel.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractDataBoundFormElementTemplateDirectiveModel.java index ce37d88f7..faa8e78d1 100644 --- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractDataBoundFormElementTemplateDirectiveModel.java +++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractDataBoundFormElementTemplateDirectiveModel.java @@ -53,20 +53,6 @@ abstract class AbstractDataBoundFormElementTemplateDirectiveModel extends Abstra private static final String ID_PARAM_NAME = ID_ATTR_NAME; - /** - * Returns the argument index of the last predefined named argument item in the {@code argsLayout}. - *

- * Note: It is strongly assumed that the predefined named arguments map contains only items with indexes, - * starting from the predefined positional argument count and incrementing by one sequentially. - *

- * @param argsLayout arguments layout - * @return the argument index of the last predefined named argument item in the {@code argsLayout} - */ - protected static int getLastPredefinedNamedArgumentIndex(ArgumentArrayLayout argsLayout) { - return argsLayout.getPredefinedPositionalArgumentCount() + argsLayout.getPredefinedNamedArgumentsMap().size() - - 1; - } - protected static final ArgumentArrayLayout ARGS_LAYOUT = ArgumentArrayLayout.create( 1, diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlElementTemplateDirectiveModel.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlElementTemplateDirectiveModel.java index 28f8f07b3..a29ca0f91 100644 --- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlElementTemplateDirectiveModel.java +++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlElementTemplateDirectiveModel.java @@ -48,8 +48,8 @@ abstract class AbstractHtmlElementTemplateDirectiveModel extends AbstractDataBoundFormElementTemplateDirectiveModel { - private static final int NAMED_ARGS_OFFSET = - getLastPredefinedNamedArgumentIndex(AbstractDataBoundFormElementTemplateDirectiveModel.ARGS_LAYOUT) + 1; + private static final int NAMED_ARGS_OFFSET = CallableUtils + .getLastPredefinedNamedArgumentIndex(AbstractDataBoundFormElementTemplateDirectiveModel.ARGS_LAYOUT) + 1; private static final int CSS_CLASS_PARAM_IDX = NAMED_ARGS_OFFSET; private static final String CSS_CLASS_PARAM_NAME = "cssClass"; diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlInputElementTemplateDirectiveModel.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlInputElementTemplateDirectiveModel.java index baee0d52b..8de04b49e 100644 --- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlInputElementTemplateDirectiveModel.java +++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlInputElementTemplateDirectiveModel.java @@ -37,8 +37,8 @@ abstract class AbstractHtmlInputElementTemplateDirectiveModel extends AbstractHtmlElementTemplateDirectiveModel { - private static final int NAMED_ARGS_OFFSET = - getLastPredefinedNamedArgumentIndex(AbstractHtmlElementTemplateDirectiveModel.ARGS_LAYOUT) + 1; + private static final int NAMED_ARGS_OFFSET = CallableUtils + .getLastPredefinedNamedArgumentIndex(AbstractHtmlElementTemplateDirectiveModel.ARGS_LAYOUT) + 1; private static final int ONFOCUS_PARAM_IDX = NAMED_ARGS_OFFSET; private static final String ONFOCUS_PARAM_NAME = "onfocus"; diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/FormTemplateDirectiveModel.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/FormTemplateDirectiveModel.java index 985cb7dd1..ebfd4c614 100644 --- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/FormTemplateDirectiveModel.java +++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/FormTemplateDirectiveModel.java @@ -75,8 +75,8 @@ class FormTemplateDirectiveModel extends AbstractHtmlElementTemplateDirectiveMod public static final String NAME = "form"; - private static final int NAMED_ARGS_OFFSET = - getLastPredefinedNamedArgumentIndex(AbstractHtmlElementTemplateDirectiveModel.ARGS_LAYOUT) + 1; + private static final int NAMED_ARGS_OFFSET = CallableUtils + .getLastPredefinedNamedArgumentIndex(AbstractHtmlElementTemplateDirectiveModel.ARGS_LAYOUT) + 1; private static final int ACTION_PARAM_IDX = NAMED_ARGS_OFFSET; private static final String ACTION_PARAM_NAME = "action"; diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/InputTemplateDirectiveModel.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/InputTemplateDirectiveModel.java index 67f63bec8..d2a3fff9f 100644 --- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/InputTemplateDirectiveModel.java +++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/InputTemplateDirectiveModel.java @@ -69,8 +69,8 @@ class InputTemplateDirectiveModel extends AbstractHtmlInputElementTemplateDirect public static final String NAME = "input"; - private static final int NAMED_ARGS_OFFSET = - getLastPredefinedNamedArgumentIndex(AbstractHtmlInputElementTemplateDirectiveModel.ARGS_LAYOUT) + 1; + private static final int NAMED_ARGS_OFFSET = CallableUtils + .getLastPredefinedNamedArgumentIndex(AbstractHtmlInputElementTemplateDirectiveModel.ARGS_LAYOUT) + 1; private static final int SIZE_PARAM_IDX = NAMED_ARGS_OFFSET; private static final String SIZE_PARAM_NAME = "size";