Coverage Report - org.webmacro.directive.AlternateDirective
 
Classes in this File Line Coverage Branch Coverage Complexity
AlternateDirective
11%
3/27
0%
0/2
2
Alternator
0%
0/5
0%
0/2
2
IteratorAlternator
0%
0/13
0%
0/6
2
 
 1  
 /*
 2  
  * Copyright (C) 1998-2000 Semiotek Inc.  All Rights Reserved.
 3  
  *
 4  
  * Redistribution and use in source and binary forms, with or without
 5  
  * modification, are permitted under the terms of either of the following
 6  
  * Open Source licenses:
 7  
  *
 8  
  * The GNU General Public License, version 2, or any later version, as
 9  
  * published by the Free Software Foundation
 10  
  * (http://www.fsf.org/copyleft/gpl.html);
 11  
  *
 12  
  *  or
 13  
  *
 14  
  * The Semiotek Public License (http://webmacro.org/LICENSE.)
 15  
  *
 16  
  * This software is provided "as is", with NO WARRANTY, not even the
 17  
  * implied warranties of fitness to purpose, or merchantability. You
 18  
  * assume all risks and liabilities associated with its use.
 19  
  *
 20  
  * See www.webmacro.org for more information on the WebMacro project.
 21  
  */
 22  
 package org.webmacro.directive;
 23  
 import java.io.IOException;
 24  
 import java.util.ArrayList;
 25  
 import java.util.Iterator;
 26  
 import java.util.List;
 27  
 
 28  
 import org.webmacro.Context;
 29  
 import org.webmacro.FastWriter;
 30  
 import org.webmacro.Macro;
 31  
 import org.webmacro.PropertyException;
 32  
 import org.webmacro.TemplateVisitor;
 33  
 import org.webmacro.engine.BuildContext;
 34  
 import org.webmacro.engine.BuildException;
 35  
 import org.webmacro.engine.Variable;
 36  
 /**
 37  
  * 
 38  
  * Use the #alternate directive to create an "alternating" variable, 
 39  
  * for creating tables that use a different background color for each line, etc.
 40  
  * <p>
 41  
  * <pre>
 42  
  * 
 43  
  *  Syntax:
 44  
  * 
 45  
  *    #alternate &lt;i&gt;var-reference&lt;/i&gt; through &lt;i&gt;expression&lt;/i&gt;
 46  
  * 
 47  
  *  Example:
 48  
  * 
 49  
  *    #alternate $color through [ &quot;red&quot;, &quot;blue&quot;, &quot;green&quot; ]
 50  
  * 
 51  
  *    #foreach $row in $rows {
 52  
  * 
 53  
  * <TR BGCOLOR=$color>
 54  
  *  ... blah blah ...
 55  
  * 
 56  
  *    }
 57  
  * 
 58  
  * </pre>
 59  
  * 
 60  
  * <p>
 61  
  * 
 62  
  * <i>expression</i> can be any "list" type understood by WebMacro: Object[],
 63  
  * 
 64  
  * java.util.List, java.util.Iterator, java.util.Enumeration, or any other
 65  
  * 
 66  
  * object that has either of the following method signatures:
 67  
  * <p>
 68  
  * 
 69  
  * <pre>
 70  
  * 
 71  
  *     public Iterator iterator ();
 72  
  * 
 73  
  *            or
 74  
  * 
 75  
  *     public Enumeration elements ();
 76  
  * 
 77  
  * </pre>
 78  
  * 
 79  
  * <p>
 80  
  * 
 81  
  * The first time $color is evaluated, it will have the value "red". The next
 82  
  * time it is evaluated, it will have the value "blue", and so on through the list. 
 83  
  * When it gets to the end of the list, it wraps back around to the beginning.
 84  
  * 
 85  
  */
 86  0
 public class AlternateDirective extends Directive
 87  
 {
 88  
         private static final int ALTERNATE_TARGET = 1;
 89  
         private static final int ALTERNATE_THROUGH = 2;
 90  
         private static final int ALTERNATE_LIST = 3;
 91  
         private Variable target;
 92  
         private Object list;
 93  
         private static final ArgDescriptor[]
 94  2
         myArgs = new ArgDescriptor[] {
 95  
         new LValueArg(ALTERNATE_TARGET),
 96  
         new KeywordArg(ALTERNATE_THROUGH, "through"),
 97  
         new RValueArg(ALTERNATE_LIST)
 98  
         };
 99  
         private static final DirectiveDescriptor
 100  2
         myDescr = new DirectiveDescriptor("alternate", null, myArgs, null);
 101  
         public static DirectiveDescriptor getDescriptor()
 102  
         {
 103  6
                 return myDescr;
 104  
         }
 105  
         public Object build(DirectiveBuilder builder,
 106  
         BuildContext bc)
 107  
         throws BuildException
 108  
         {
 109  
                 try
 110  
                 {
 111  0
                         target = (Variable) builder.getArg(ALTERNATE_TARGET, bc);
 112  
                 }
 113  0
                 catch (ClassCastException e)
 114  
                 {
 115  0
                         throw new NotVariableBuildException(myDescr.name, e);
 116  0
                 }
 117  0
                 list = builder.getArg(ALTERNATE_LIST, bc);
 118  0
                 return this;
 119  
         }
 120  
         public void write(FastWriter out, Context context)
 121  
         throws PropertyException, IOException
 122  
         {
 123  0
                 Object l = null;
 124  
                 try
 125  
                 {
 126  0
                         if (list instanceof Macro)
 127  0
                                 l = ((Macro) list).evaluate(context);
 128  
                         else
 129  0
                                 l = list;
 130  0
                         Iterator itr = context.getBroker()._propertyOperators
 131  
                                         .getIterator(l);
 132  0
                         target.setValue(context, new IteratorAlternator(itr));
 133  
                 }
 134  0
                 catch (Exception e)
 135  
                 {
 136  0
                         String warning = "#alternate: list argument is not a list: " + l;
 137  0
                         writeWarning(warning, context, out);
 138  0
                         return;
 139  0
                 }
 140  0
         }
 141  
         public void accept(TemplateVisitor v)
 142  
         {
 143  0
                 v.beginDirective(myDescr.name);
 144  0
                 v.visitDirectiveArg("AlternateTarget", target);
 145  0
                 v.visitDirectiveArg("AlternateList", list);
 146  0
                 v.endDirective();
 147  0
         }
 148  
 }
 149  0
 abstract class Alternator implements Macro
 150  
 {
 151  
         public abstract Object evaluate(Context context);
 152  
         public void write(FastWriter out, Context context)
 153  
                         throws PropertyException, IOException
 154  
         {
 155  0
                 Object o = evaluate(context);
 156  0
                 if (o != null)
 157  0
                         out.write(o.toString());
 158  0
         }
 159  
 }
 160  
 class IteratorAlternator extends Alternator
 161  
 {
 162  
         private Iterator<Object> itr;
 163  
         private List<Object> list;
 164  0
         private int index = -1;
 165  
         public IteratorAlternator(Iterator<Object> itr)
 166  0
         {
 167  0
                 this.itr = itr;
 168  0
                 this.list = new ArrayList<Object>();
 169  0
         }
 170  
         public Object evaluate(Context context)
 171  
         {
 172  
                 Object o;
 173  0
                 if (index == -1 && itr.hasNext())
 174  
                 {
 175  0
                         o = itr.next();
 176  0
                         list.add(o);
 177  
                 }
 178  
                 else
 179  
                 {
 180  0
                         index++;
 181  0
                         if (index == list.size())
 182  0
                                 index = 0;
 183  0
                         o = list.get(index);
 184  
                 }
 185  0
                 return o;
 186  
         }
 187  
 }