Changeset 3201

Show
Ignore:
Timestamp:
05/10/07 16:20:40 (3 years ago)
Author:
michael
Message:

Fixes #14, spent 0.5. Fix taken from Facelets issue 142: https://facelets.dev.java.net/issues/show_bug.cgi?id=142

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/main/java/org/sarugo/xtc/tag/jstl/core/ForEachHandler.java

    r2684 r3201  
    1919import java.util.Collection; 
    2020import java.util.Iterator; 
     21import java.util.List; 
    2122import java.util.Map; 
    2223 
     
    3940public final class ForEachHandler extends TagHandler { 
    4041 
    41         private static class ArrayIterator implements Iterator { 
    42  
    43                 protected final Object array; 
    44  
    45                 protected int i; 
    46  
    47                 protected final int len; 
    48  
    49                 public ArrayIterator(Object src) { 
    50                         this.i = 0; 
    51                         this.array = src; 
    52                         this.len = Array.getLength(src); 
    53                 } 
    54  
    55                 public boolean hasNext() { 
    56                         return this.i < this.len; 
    57                 } 
    58  
    59                 public Object next() { 
    60                         return Array.get(this.array, this.i++); 
    61                 } 
    62  
    63                 public void remove() { 
    64                         throw new UnsupportedOperationException(); 
    65                 } 
    66         } 
    67  
    68         private final TagAttribute begin; 
    69  
    70         private final TagAttribute end; 
    71  
    72         private final TagAttribute items; 
    73  
    74         private final TagAttribute step; 
    75  
    76         private final TagAttribute tranzient; 
    77  
    78         private final TagAttribute var; 
    79  
    80         private final TagAttribute varStatus; 
    81  
    82         /** 
    83          * @param config 
    84          */ 
    85         public ForEachHandler(TagConfig config) { 
    86                 super(config); 
    87                 this.items = this.getAttribute("items"); 
    88                 this.var = this.getAttribute("var"); 
    89                 this.begin = this.getAttribute("begin"); 
    90                 this.end = this.getAttribute("end"); 
    91                 this.step = this.getAttribute("step"); 
    92                 this.varStatus = this.getAttribute("varStatus"); 
    93                 this.tranzient = this.getAttribute("transient"); 
    94  
    95                 if (this.items == null && this.begin != null && this.end == null) { 
    96                         throw new TagAttributeException( 
    97                                         this.tag, 
    98                                         this.begin, 
    99                                         "If the 'items' attribute is not specified, but the 'begin' attribute is, then the 'end' attribute is required"); 
    100                 } 
    101         } 
    102  
    103         public void render(TemplateContext ctx) throws IOException, 
    104                         TemplateException, ELException { 
    105  
    106                 int s = this.getBegin(ctx); 
    107                 int e = this.getEnd(ctx); 
    108                 int m = this.getStep(ctx); 
    109                 Integer sO = this.begin != null ? new Integer(s) : null; 
    110                 Integer eO = this.end != null ? new Integer(e) : null; 
    111                 Integer mO = this.step != null ? new Integer(m) : null; 
    112  
    113                 boolean t = this.getTransient(ctx); 
    114                 Object src = null; 
    115                 ValueExpression srcVE = null; 
    116                 if (this.items != null) { 
    117                         srcVE = this.items.getValueExpression(ctx, Object.class); 
    118                         src = srcVE.getValue(ctx); 
    119                 } else { 
    120                         byte[] b = new byte[e + 1]; 
    121                         for (int i = 0; i < b.length; i++) { 
    122                                 b[i] = (byte) i; 
    123                         } 
    124                         src = b; 
    125                 } 
    126                 if (src != null) { 
    127                         Iterator itr = this.toIterator(src); 
    128                         if (itr != null) { 
    129                                 int i = 0; 
    130  
    131                                 // move to start 
    132                                 while (i < s && itr.hasNext()) { 
    133                                         itr.next(); 
    134                                         i++; 
    135                                 } 
    136  
    137                                 String v = this.getVarName(ctx); 
    138                                 String vs = this.getVarStatusName(ctx); 
    139                                 VariableMapper vars = ctx.getVariableMapper(); 
    140                                 ValueExpression ve = null; 
    141                                 ValueExpression vO = this.capture(v, vars); 
    142                                 ValueExpression vsO = this.capture(vs, vars); 
    143                                 int mi = 0; 
    144                                 Object value = null; 
    145                                 try { 
    146                                         boolean first = true; 
    147                                         while (i <= e && itr.hasNext()) { 
    148                                                 value = itr.next(); 
    149  
    150                                                 // set the var 
    151                                                 if (v != null) { 
    152                                                         if (t || srcVE == null) { 
    153                                                                 ctx.setAttribute(v, value); 
    154                                                         } else { 
    155                                                                 ve = this.getVarExpr(srcVE, src, value, i); 
    156                                                                 vars.setVariable(v, ve); 
    157                                                         } 
    158                                                 } 
    159  
    160                                                 // set the varStatus 
    161                                                 if (vs != null) { 
    162                                                         IterationStatus itrS = new IterationStatus(first, 
    163                                                                         !itr.hasNext(), i, sO, eO, mO); 
    164                                                         if (t || srcVE == null) { 
    165                                                                 ctx.setAttribute(vs, itrS); 
    166                                                         } else { 
    167                                                                 ve = new IterationStatusExpression(itrS); 
    168                                                                 vars.setVariable(vs, ve); 
    169                                                         } 
    170                                                 } 
    171  
    172                                                 // execute body 
    173                                                 this.nextHandler.render(ctx); 
    174  
    175                                                 // increment steps 
    176                                                 mi = 1; 
    177                                                 while (mi < m && itr.hasNext()) { 
    178                                                         itr.next(); 
    179                                                         mi++; 
    180                                                         i++; 
    181                                                 } 
    182                                                 i++; 
    183  
    184                                                 first = false; 
    185                                         } 
    186                                 } finally { 
    187                                         if (v != null) { 
    188                                                 vars.setVariable(v, vO); 
    189                                         } 
    190                                         if (vs != null) { 
    191                                                 vars.setVariable(vs, vsO); 
    192                                         } 
    193                                 } 
    194                         } 
    195                 } 
    196         } 
    197  
    198         private final ValueExpression capture(String name, VariableMapper vars) { 
    199                 if (name != null) { 
    200                         return vars.setVariable(name, null); 
    201                 } 
    202                 return null; 
    203         } 
    204  
    205         private final int getBegin(TemplateContext ctx) { 
    206                 if (this.begin != null) { 
    207                         return this.begin.getInt(ctx); 
    208                 } 
    209                 return 0; 
    210         } 
    211  
    212         private final int getEnd(TemplateContext ctx) { 
    213                 if (this.end != null) { 
    214                         return this.end.getInt(ctx); 
    215                 } 
    216                 return Integer.MAX_VALUE; 
    217         } 
    218  
    219         private final int getStep(TemplateContext ctx) { 
    220                 if (this.step != null) { 
    221                         return this.step.getInt(ctx); 
    222                 } 
    223                 return 1; 
    224         } 
    225  
    226         private final boolean getTransient(TemplateContext ctx) { 
    227                 if (this.tranzient != null) { 
    228                         return this.tranzient.getBoolean(ctx); 
    229                 } 
    230                 return false; 
    231         } 
    232  
    233         private final ValueExpression getVarExpr(ValueExpression ve, Object src, 
    234                         Object value, int i) { 
    235                 if (src instanceof Collection || src.getClass().isArray()) { 
    236                         return new IndexedValueExpression(ve, i); 
    237                 } else if (src instanceof Map && value instanceof Map.Entry) { 
    238                         return new MappedValueExpression(ve, (Map.Entry) value); 
    239                 } 
    240                 throw new IllegalStateException("Cannot create VE for: " + src); 
    241         } 
    242  
    243         private final String getVarName(TemplateContext ctx) { 
    244                 if (this.var != null) { 
    245                         return this.var.getValue(ctx); 
    246                 } 
    247                 return null; 
    248         } 
    249  
    250         private final String getVarStatusName(TemplateContext ctx) { 
    251                 if (this.varStatus != null) { 
    252                         return this.varStatus.getValue(ctx); 
    253                 } 
    254                 return null; 
    255         } 
    256  
    257         private final Iterator toIterator(Object src) { 
    258                 if (src == null) { 
    259                         return null; 
    260                 } else if (src instanceof Collection) { 
    261                         return ((Collection) src).iterator(); 
    262                 } else if (src instanceof Map) { 
    263                         return ((Map) src).entrySet().iterator(); 
    264                 } else if (src.getClass().isArray()) { 
    265                         return new ArrayIterator(src); 
    266                 } else { 
    267                         throw new TagAttributeException(this.tag, this.items, 
    268                                         "Must evaluate to a Collection, Map, Array, or null."); 
    269                 } 
    270         } 
     42    private static class ArrayIterator implements Iterator { 
     43 
     44        protected final Object array; 
     45 
     46        protected int i; 
     47 
     48        protected final int len; 
     49 
     50        public ArrayIterator(Object src) { 
     51            this.i = 0; 
     52            this.array = src; 
     53            this.len = Array.getLength(src); 
     54        } 
     55 
     56        public boolean hasNext() { 
     57            return this.i < this.len; 
     58        } 
     59 
     60        public Object next() { 
     61            return Array.get(this.array, this.i++); 
     62        } 
     63 
     64        public void remove() { 
     65            throw new UnsupportedOperationException(); 
     66        } 
     67    } 
     68 
     69    private final TagAttribute begin; 
     70 
     71    private final TagAttribute end; 
     72 
     73    private final TagAttribute items; 
     74 
     75    private final TagAttribute step; 
     76 
     77    private final TagAttribute tranzient; 
     78 
     79    private final TagAttribute var; 
     80 
     81    private final TagAttribute varStatus; 
     82 
     83    /** 
     84     * @param config 
     85     */ 
     86    public ForEachHandler(TagConfig config) { 
     87        super(config); 
     88        this.items = this.getAttribute("items"); 
     89        this.var = this.getAttribute("var"); 
     90        this.begin = this.getAttribute("begin"); 
     91        this.end = this.getAttribute("end"); 
     92        this.step = this.getAttribute("step"); 
     93        this.varStatus = this.getAttribute("varStatus"); 
     94        this.tranzient = this.getAttribute("transient"); 
     95 
     96        if (this.items == null && this.begin != null && this.end == null) { 
     97            throw new TagAttributeException( 
     98                    this.tag, 
     99                    this.begin, 
     100                    "If the 'items' attribute is not specified, but the 'begin' attribute is, then the 'end' attribute is required"); 
     101        } 
     102    } 
     103 
     104    public void render(TemplateContext ctx) throws IOException, 
     105            TemplateException, ELException { 
     106 
     107        int s = this.getBegin(ctx); 
     108        int e = this.getEnd(ctx); 
     109        int m = this.getStep(ctx); 
     110        Integer sO = this.begin != null ? new Integer(s) : null; 
     111        Integer eO = this.end != null ? new Integer(e) : null; 
     112        Integer mO = this.step != null ? new Integer(m) : null; 
     113 
     114        boolean t = this.getTransient(ctx); 
     115        Object src = null; 
     116        ValueExpression srcVE = null; 
     117        if (this.items != null) { 
     118            srcVE = this.items.getValueExpression(ctx, Object.class); 
     119            src = srcVE.getValue(ctx); 
     120        } else { 
     121            byte[] b = new byte[e + 1]; 
     122            for (int i = 0; i < b.length; i++) { 
     123                b[i] = (byte) i; 
     124            } 
     125            src = b; 
     126        } 
     127        if (src != null) { 
     128            Iterator itr = this.toIterator(src); 
     129            if (itr != null) { 
     130                int i = 0; 
     131 
     132                // move to start 
     133                while (i < s && itr.hasNext()) { 
     134                    itr.next(); 
     135                    i++; 
     136                } 
     137 
     138                String v = this.getVarName(ctx); 
     139                String vs = this.getVarStatusName(ctx); 
     140                VariableMapper vars = ctx.getVariableMapper(); 
     141                ValueExpression ve = null; 
     142                ValueExpression vO = this.capture(v, vars); 
     143                ValueExpression vsO = this.capture(vs, vars); 
     144                int mi = 0; 
     145                Object value = null; 
     146                try { 
     147                    boolean first = true; 
     148                    while (i <= e && itr.hasNext()) { 
     149                        value = itr.next(); 
     150 
     151                        // set the var 
     152                        if (v != null) { 
     153                            if (t || srcVE == null) { 
     154                                ctx.setAttribute(v, value); 
     155                            } else { 
     156                                ve = this.getVarExpr(srcVE, src, value, i); 
     157                                vars.setVariable(v, ve); 
     158                            } 
     159                        } 
     160 
     161                        // set the varStatus 
     162                        if (vs != null) { 
     163                            IterationStatus itrS = new IterationStatus(first, 
     164                                    !itr.hasNext(), i, sO, eO, mO); 
     165                            if (t || srcVE == null) { 
     166                                ctx.setAttribute(vs, itrS); 
     167                            } else { 
     168                                ve = new IterationStatusExpression(itrS); 
     169                                vars.setVariable(vs, ve); 
     170                            } 
     171                        } 
     172 
     173                        // execute body 
     174                        this.nextHandler.render(ctx); 
     175 
     176                        // increment steps 
     177                        mi = 1; 
     178                        while (mi < m && itr.hasNext()) { 
     179                            itr.next(); 
     180                            mi++; 
     181                            i++; 
     182                        } 
     183                        i++; 
     184 
     185                        first = false; 
     186                    } 
     187                } finally { 
     188                    if (v != null) { 
     189                        vars.setVariable(v, vO); 
     190                    } 
     191                    if (vs != null) { 
     192                        vars.setVariable(vs, vsO); 
     193                    } 
     194                } 
     195            } 
     196        } 
     197    } 
     198 
     199    private final ValueExpression capture(String name, VariableMapper vars) { 
     200        if (name != null) { 
     201            return vars.setVariable(name, null); 
     202        } 
     203        return null; 
     204    } 
     205 
     206    private final int getBegin(TemplateContext ctx) { 
     207        if (this.begin != null) { 
     208            return this.begin.getInt(ctx); 
     209        } 
     210        return 0; 
     211    } 
     212 
     213    private final int getEnd(TemplateContext ctx) { 
     214        if (this.end != null) { 
     215            return this.end.getInt(ctx); 
     216        } 
     217        return Integer.MAX_VALUE; 
     218    } 
     219 
     220    private final int getStep(TemplateContext ctx) { 
     221        if (this.step != null) { 
     222            return this.step.getInt(ctx); 
     223        } 
     224        return 1; 
     225    } 
     226 
     227    private final boolean getTransient(TemplateContext ctx) { 
     228        if (this.tranzient != null) { 
     229            return this.tranzient.getBoolean(ctx); 
     230        } 
     231        return false; 
     232    } 
     233 
     234    private final ValueExpression getVarExpr(ValueExpression ve, Object src, 
     235            Object value, int i) { 
     236        if (src instanceof List || src.getClass().isArray()) { 
     237            return new IndexedValueExpression(ve, i); 
     238        } else if (src instanceof Map && value instanceof Map.Entry) { 
     239            return new MappedValueExpression(ve, (Map.Entry) value); 
     240        } else if (src instanceof Collection) { 
     241            return new IteratedValueExpression(ve, value); 
     242        } 
     243        throw new IllegalStateException("Cannot create VE for: " + src); 
     244    } 
     245 
     246    private final String getVarName(TemplateContext ctx) { 
     247        if (this.var != null) { 
     248            return this.var.getValue(ctx); 
     249        } 
     250        return null; 
     251    } 
     252 
     253    private final String getVarStatusName(TemplateContext ctx) { 
     254        if (this.varStatus != null) { 
     255            return this.varStatus.getValue(ctx); 
     256        } 
     257        return null; 
     258    } 
     259 
     260    private final Iterator toIterator(Object src) { 
     261        if (src == null) { 
     262            return null; 
     263        } else if (src instanceof Collection) { 
     264            return ((Collection) src).iterator(); 
     265        } else if (src instanceof Map) { 
     266            return ((Map) src).entrySet().iterator(); 
     267        } else if (src.getClass().isArray()) { 
     268            return new ArrayIterator(src); 
     269        } else { 
     270            throw new TagAttributeException(this.tag, this.items, 
     271                    "Must evaluate to a Collection, Map, Array, or null."); 
     272        } 
     273    } 
    271274 
    272275} 
  • trunk/src/main/java/org/sarugo/xtc/tag/ui/RepeatHandler.java

    r2952 r3201  
    2020import java.util.Collection; 
    2121import java.util.Iterator; 
     22import java.util.List; 
    2223import java.util.Map; 
    2324 
     
    3435import org.sarugo.xtc.tag.jstl.core.ForEachHandler; 
    3536import org.sarugo.xtc.tag.jstl.core.IndexedValueExpression; 
     37import org.sarugo.xtc.tag.jstl.core.IteratedValueExpression; 
    3638import org.sarugo.xtc.tag.jstl.core.MappedValueExpression; 
    3739 
     
    4345public class RepeatHandler extends TagHandler { 
    4446 
    45        private static class ArrayIterator implements Iterator { 
     47    private static class ArrayIterator implements Iterator { 
    4648 
    47                protected final Object array; 
     49        protected final Object array; 
    4850 
    49                protected int i; 
     51        protected int i; 
    5052 
    51                protected final int len; 
     53        protected final int len; 
    5254 
    53                public ArrayIterator(Object src) { 
    54                        this.i = 0; 
    55                        this.array = src; 
    56                        this.len = Array.getLength(src); 
    57                
     55        public ArrayIterator(Object src) { 
     56            this.i = 0; 
     57            this.array = src; 
     58            this.len = Array.getLength(src); 
     59       
    5860 
    59                public boolean hasNext() { 
    60                        return this.i < this.len; 
    61                
     61        public boolean hasNext() { 
     62            return this.i < this.len; 
     63       
    6264 
    63                public Object next() { 
    64                        return Array.get(this.array, this.i++); 
    65                
     65        public Object next() { 
     66            return Array.get(this.array, this.i++); 
     67       
    6668 
    67                public void remove() { 
    68                        throw new UnsupportedOperationException(); 
    69                
    70        
     69        public void remove() { 
     70            throw new UnsupportedOperationException(); 
     71       
     72   
    7173 
    72        private final TagAttribute value; 
     74    private final TagAttribute value; 
    7375 
    74        private final TagAttribute var; 
     76    private final TagAttribute var; 
    7577 
    76        /** 
    77         * @param config 
    78         */ 
    79        public RepeatHandler(TagConfig config) { 
    80                super(config); 
    81                this.value = this.getRequiredAttribute("value"); 
    82                this.var = this.getRequiredAttribute("var"); 
    83        
     78    /** 
     79    * @param config 
     80    */ 
     81    public RepeatHandler(TagConfig config) { 
     82        super(config); 
     83        this.value = this.getRequiredAttribute("value"); 
     84        this.var = this.getRequiredAttribute("var"); 
     85   
    8486 
    85        public void render(TemplateContext ctx) throws IOException, 
    86                        TemplateException, ELException { 
     87    public void render(TemplateContext ctx) throws IOException, 
     88            TemplateException, ELException { 
    8789 
    88                Object src = null; 
    89                ValueExpression srcVE = null; 
    90                if (this.value != null) { 
    91                        srcVE = this.value.getValueExpression(ctx, Object.class); 
    92                        src = srcVE.getValue(ctx); 
    93                
    94                if (src != null) { 
    95                        Iterator itr = this.toIterator(src); 
    96                        if (itr != null) { 
    97                                String v = this.getVarName(ctx); 
    98                                VariableMapper vars = ctx.getVariableMapper(); 
    99                                ValueExpression ve = null; 
    100                                ValueExpression vO = this.capture(v, vars); 
    101                                Object value = null; 
    102                                try { 
    103                                        int i = 0; 
    104                                        while (itr.hasNext()) { 
    105                                                value = itr.next(); 
     90        Object src = null; 
     91        ValueExpression srcVE = null; 
     92        if (this.value != null) { 
     93            srcVE = this.value.getValueExpression(ctx, Object.class); 
     94            src = srcVE.getValue(ctx); 
     95       
     96        if (src != null) { 
     97            Iterator itr = this.toIterator(src); 
     98            if (itr != null) { 
     99                String v = this.getVarName(ctx); 
     100                VariableMapper vars = ctx.getVariableMapper(); 
     101                ValueExpression ve = null; 
     102                ValueExpression vO = this.capture(v, vars); 
     103                Object value = null; 
     104                try { 
     105                    int i = 0; 
     106                    while (itr.hasNext()) { 
     107                        value = itr.next(); 
    106108 
    107                                                // set the var 
    108                                                ve = this.getVarExpr(srcVE, src, value, i); 
    109                                                vars.setVariable(v, ve); 
     109                        // set the var 
     110                        ve = this.getVarExpr(srcVE, src, value, i); 
     111                        vars.setVariable(v, ve); 
    110112 
    111                                                 // execute body 
    112                                                 this.nextHandler.render(ctx); 
    113                                                  
    114                                                 i++; 
    115                                         } 
    116                                 } finally { 
    117                                         if (v != null) { 
    118                                                 vars.setVariable(v, vO); 
    119                                         } 
    120                                 } 
    121                         } 
    122                 } 
    123         } 
     113                        // execute body 
     114                        this.nextHandler.render(ctx); 
    124115 
    125         private final ValueExpression capture(String name, VariableMapper vars) { 
    126                 if (name != null) { 
    127                         return vars.setVariable(name, null); 
    128                 } 
    129                 return null; 
    130         } 
     116                        i++; 
     117                    } 
     118                } finally { 
     119                    if (v != null) { 
     120                        vars.setVariable(v, vO); 
     121                    } 
     122                } 
     123            } 
     124        } 
     125    } 
    131126 
    132         private final ValueExpression getVarExpr(ValueExpression ve, Object src, 
    133                         Object value, int i) { 
    134                 if (src instanceof Collection || src.getClass().isArray()) { 
    135                         return new IndexedValueExpression(ve, i); 
    136                 } else if (src instanceof Map && value instanceof Map.Entry) { 
    137                         return new MappedValueExpression(ve, (Map.Entry) value); 
    138                 } 
    139                 throw new IllegalStateException("Cannot create VE for: " + src); 
    140         } 
     127    private final ValueExpression capture(String name, VariableMapper vars) { 
     128        if (name != null) { 
     129            return vars.setVariable(name, null); 
     130        } 
     131        return null; 
     132    } 
    141133 
    142         private final String getVarName(TemplateContext ctx) { 
    143                 if (this.var != null) { 
    144                         return this.var.getValue(ctx); 
    145                 } 
    146                 return null; 
    147         } 
     134    private final ValueExpression getVarExpr(ValueExpression ve, Object src, 
     135            Object value, int i) { 
     136        if (src instanceof List || src.getClass().isArray()) { 
     137            return new IndexedValueExpression(ve, i); 
     138        } else if (src instanceof Map && value instanceof Map.Entry) { 
     139            return new MappedValueExpression(ve, (Map.Entry) value); 
     140        } else if (src instanceof Collection) { 
     141            return new IteratedValueExpression(ve, value); 
     142        } 
     143        throw new IllegalStateException("Cannot create VE for: " + src); 
     144    } 
    148145 
    149         private final Iterator toIterator(Object src) { 
    150                 if (src == null) { 
    151                         return null; 
    152                 } else if (src instanceof Collection) { 
    153                         return ((Collection) src).iterator(); 
    154                 } else if (src instanceof Map) { 
    155                         return ((Map) src).entrySet().iterator(); 
    156                 } else if (src.getClass().isArray()) { 
    157                         return new ArrayIterator(src); 
    158                 } else { 
    159                         throw new TagAttributeException(this.tag, this.value, 
    160                                         "Must evaluate to a Collection, Map, Array, or null."); 
    161                 } 
    162         } 
     146    private final String getVarName(TemplateContext ctx) { 
     147        if (this.var != null) { 
     148            return this.var.getValue(ctx); 
     149        } 
     150        return null; 
     151    } 
     152 
     153    private final Iterator toIterator(Object src) { 
     154        if (src == null) { 
     155            return null; 
     156        } else if (src instanceof Collection) { 
     157            return ((Collection) src).iterator(); 
     158        } else if (src instanceof Map) { 
     159            return ((Map) src).entrySet().iterator(); 
     160        } else if (src.getClass().isArray()) { 
     161            return new ArrayIterator(src); 
     162        } else { 
     163            throw new TagAttributeException(this.tag, this.value, 
     164                    "Must evaluate to a Collection, Map, Array, or null."); 
     165        } 
     166    } 
    163167 
    164168}