From ec7ea6a6606056dc9a3fee82d443aced696509b3 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Mon, 21 Sep 2015 16:01:38 -0700 Subject: [PATCH] Revamped iterating over arrays to be GWT-compatible. We no longer use reflection for any of that; we have a suite of primitive array helpers that do what is needed. --- .../samskivert/mustache/DefaultCollector.java | 13 ---- .../samskivert/mustache/BasicCollector.java | 74 ++++++++++++------- .../samskivert/mustache/DefaultCollector.java | 18 ----- 3 files changed, 49 insertions(+), 56 deletions(-) diff --git a/src/main/gwt/com/samskivert/super/com/samskivert/mustache/DefaultCollector.java b/src/main/gwt/com/samskivert/super/com/samskivert/mustache/DefaultCollector.java index 2686c1e..c1d1269 100644 --- a/src/main/gwt/com/samskivert/super/com/samskivert/mustache/DefaultCollector.java +++ b/src/main/gwt/com/samskivert/super/com/samskivert/mustache/DefaultCollector.java @@ -3,9 +3,7 @@ package com.samskivert.mustache; -import java.util.Arrays; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; /** @@ -13,17 +11,6 @@ import java.util.Map; */ public class DefaultCollector extends BasicCollector { - @Override - public Iterator toIterator (final Object value) { - Iterator iter = super.toIterator(value); - if (iter != null) return iter; - - if (value.getClass().isArray()) { - return Arrays.asList((Object[])value).iterator(); - } - return null; - } - @Override public Map createFetcherCache () { return new HashMap(); diff --git a/src/main/java/com/samskivert/mustache/BasicCollector.java b/src/main/java/com/samskivert/mustache/BasicCollector.java index 83fb2c2..8be6c82 100644 --- a/src/main/java/com/samskivert/mustache/BasicCollector.java +++ b/src/main/java/com/samskivert/mustache/BasicCollector.java @@ -22,6 +22,15 @@ public abstract class BasicCollector implements Mustache.Collector if (value instanceof Iterator) { return (Iterator)value; } + if (value.getClass().isArray()) { + final ArrayHelper helper = arrayHelper(value); + return new Iterator() { + private int _count = helper.length(value), _idx; + @Override public boolean hasNext () { return _idx < _count; } + @Override public Object next () { return helper.get(value, _idx++); } + @Override public void remove () { throw new UnsupportedOperationException(); } + }; + } return null; } @@ -36,15 +45,7 @@ public abstract class BasicCollector implements Mustache.Collector if (c >= '0' && c <= '9') { if (ctx instanceof List) return LIST_FETCHER; if (ctx instanceof Iterator) return ITER_FETCHER; - if (ctx instanceof Object[]) return OBJECT_ARRAY_FETCHER; - if (ctx instanceof boolean[]) return BOOLEAN_ARRAY_FETCHER; - if (ctx instanceof byte[]) return BYTE_ARRAY_FETCHER; - if (ctx instanceof char[]) return CHAR_ARRAY_FETCHER; - if (ctx instanceof short[]) return SHORT_ARRAY_FETCHER; - if (ctx instanceof int[]) return INT_ARRAY_FETCHER; - if (ctx instanceof long[]) return LONG_ARRAY_FETCHER; - if (ctx instanceof float[]) return FLOAT_ARRAY_FETCHER; - if (ctx instanceof double[]) return DOUBLE_ARRAY_FETCHER; + if (ctx.getClass().isArray()) return arrayHelper(ctx); } return null; @@ -54,6 +55,19 @@ public abstract class BasicCollector implements Mustache.Collector * a standard {@link Map} implementation or something like {@code ConcurrentHashMap}. */ public abstract Map createFetcherCache (); + protected static ArrayHelper arrayHelper (Object ctx) { + if (ctx instanceof Object[]) return OBJECT_ARRAY_HELPER; + if (ctx instanceof boolean[]) return BOOLEAN_ARRAY_HELPER; + if (ctx instanceof byte[]) return BYTE_ARRAY_HELPER; + if (ctx instanceof char[]) return CHAR_ARRAY_HELPER; + if (ctx instanceof short[]) return SHORT_ARRAY_HELPER; + if (ctx instanceof int[]) return INT_ARRAY_HELPER; + if (ctx instanceof long[]) return LONG_ARRAY_HELPER; + if (ctx instanceof float[]) return FLOAT_ARRAY_HELPER; + if (ctx instanceof double[]) return DOUBLE_ARRAY_HELPER; + return null; + } + protected static final Mustache.VariableFetcher MAP_FETCHER = new Mustache.VariableFetcher() { public Object get (Object ctx, String name) throws Exception { Map map = (Map)ctx; @@ -87,7 +101,13 @@ public abstract class BasicCollector implements Mustache.Collector } }; - protected static abstract class ArrayFetcher implements Mustache.VariableFetcher { + protected static final Mustache.VariableFetcher THIS_FETCHER = new Mustache.VariableFetcher() { + public Object get (Object ctx, String name) throws Exception { + return ctx; + } + }; + + protected static abstract class ArrayHelper implements Mustache.VariableFetcher { public Object get (Object ctx, String name) throws Exception { try { return get(ctx, Integer.parseInt(name)); @@ -97,40 +117,44 @@ public abstract class BasicCollector implements Mustache.Collector return Template.NO_FETCHER_FOUND; } } + public abstract int length (Object ctx); protected abstract Object get (Object ctx, int index); } - protected static final ArrayFetcher OBJECT_ARRAY_FETCHER = new ArrayFetcher() { + protected static final ArrayHelper OBJECT_ARRAY_HELPER = new ArrayHelper() { @Override protected Object get (Object ctx, int index) { return ((Object[])ctx)[index]; } + @Override public int length (Object ctx) { return ((Object[])ctx).length; } }; - protected static final ArrayFetcher BOOLEAN_ARRAY_FETCHER = new ArrayFetcher() { + protected static final ArrayHelper BOOLEAN_ARRAY_HELPER = new ArrayHelper() { @Override protected Object get (Object ctx, int index) { return ((boolean[])ctx)[index]; } + @Override public int length (Object ctx) { return ((boolean[])ctx).length; } }; - protected static final ArrayFetcher BYTE_ARRAY_FETCHER = new ArrayFetcher() { + protected static final ArrayHelper BYTE_ARRAY_HELPER = new ArrayHelper() { @Override protected Object get (Object ctx, int index) { return ((byte[])ctx)[index]; } + @Override public int length (Object ctx) { return ((byte[])ctx).length; } }; - protected static final ArrayFetcher CHAR_ARRAY_FETCHER = new ArrayFetcher() { + protected static final ArrayHelper CHAR_ARRAY_HELPER = new ArrayHelper() { @Override protected Object get (Object ctx, int index) { return ((char[])ctx)[index]; } + @Override public int length (Object ctx) { return ((char[])ctx).length; } }; - protected static final ArrayFetcher SHORT_ARRAY_FETCHER = new ArrayFetcher() { + protected static final ArrayHelper SHORT_ARRAY_HELPER = new ArrayHelper() { @Override protected Object get (Object ctx, int index) { return ((short[])ctx)[index]; } + @Override public int length (Object ctx) { return ((short[])ctx).length; } }; - protected static final ArrayFetcher INT_ARRAY_FETCHER = new ArrayFetcher() { + protected static final ArrayHelper INT_ARRAY_HELPER = new ArrayHelper() { @Override protected Object get (Object ctx, int index) { return ((int[])ctx)[index]; } + @Override public int length (Object ctx) { return ((int[])ctx).length; } }; - protected static final ArrayFetcher LONG_ARRAY_FETCHER = new ArrayFetcher() { + protected static final ArrayHelper LONG_ARRAY_HELPER = new ArrayHelper() { @Override protected Object get (Object ctx, int index) { return ((long[])ctx)[index]; } + @Override public int length (Object ctx) { return ((long[])ctx).length; } }; - protected static final ArrayFetcher FLOAT_ARRAY_FETCHER = new ArrayFetcher() { + protected static final ArrayHelper FLOAT_ARRAY_HELPER = new ArrayHelper() { @Override protected Object get (Object ctx, int index) { return ((float[])ctx)[index]; } + @Override public int length (Object ctx) { return ((float[])ctx).length; } }; - protected static final ArrayFetcher DOUBLE_ARRAY_FETCHER = new ArrayFetcher() { + protected static final ArrayHelper DOUBLE_ARRAY_HELPER = new ArrayHelper() { @Override protected Object get (Object ctx, int index) { return ((double[])ctx)[index]; } - }; - - protected static final Mustache.VariableFetcher THIS_FETCHER = new Mustache.VariableFetcher() { - public Object get (Object ctx, String name) throws Exception { - return ctx; - } + @Override public int length (Object ctx) { return ((double[])ctx).length; } }; } diff --git a/src/main/java/com/samskivert/mustache/DefaultCollector.java b/src/main/java/com/samskivert/mustache/DefaultCollector.java index 9e3a8f6..ab4a641 100644 --- a/src/main/java/com/samskivert/mustache/DefaultCollector.java +++ b/src/main/java/com/samskivert/mustache/DefaultCollector.java @@ -20,24 +20,6 @@ import java.util.concurrent.ConcurrentHashMap; */ public class DefaultCollector extends BasicCollector { - @Override - public Iterator toIterator (final Object value) { - Iterator iter = super.toIterator(value); - if (iter != null) return iter; - - if (value.getClass().isArray()) { - return new AbstractList() { - public int size () { - return Array.getLength(value); - } - public Object get (int idx) { - return Array.get(value, idx); - } - }.iterator(); - } - return null; - } - @Override public Mustache.VariableFetcher createFetcher (Object ctx, String name) { Mustache.VariableFetcher fetcher = super.createFetcher(ctx, name);