##### Coverage Report - org.webmacro.directive.AlternateDirective

Classes in this File | Line Coverage | Branch Coverage | Complexity
AlternateDirective |
11% | 3/27
0% | 0/2
| 2.0;2
Alternator |
0% | 0/5
0% | 0/2
| 2.0;2
IteratorAlternator |
0% | 0/13
0% | 0/6
| 2.0;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 |  |
     }