View Javadoc

1   package org.apache.velocity.tools.generic;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.Collection;
23  
24  /**
25   * Utility class for easily alternating over values in a list.
26   *
27   * <p><b>Example usage:</b>
28   * <pre>
29   * java...
30   *      String[] myColors = new String[]{"red", "blue"};
31   *      context.put("color", new Alternator(myColors));
32   *      String[] myStyles = new String[]{"hip", "fly", "groovy"};
33   *      // demonstrate manual alternation with this one
34   *      context.put("style", new Alternator(false, myStyles));
35   *
36   * template...
37   *      #foreach( $foo in [1..5] )
38   *       $foo is $color and $style.next
39   *      #end
40   *
41   * output...
42   *      1 is red and hip
43   *      2 is blue and fly
44   *      3 is red and groovy
45   *      4 is blue and hip
46   *      5 is red and fly
47   * </pre></p>
48   *
49   * @since Velocity Tools 1.2
50   * @version $Id: Alternator.java 603419 2007-12-12 00:04:07Z nbubna $
51   */
52  public class Alternator
53  {
54      private Object[] list;
55      private int index = 0;
56      private boolean auto = true;
57  
58      /**
59       * Creates a new Alternator for the specified list.  Alternation
60       * defaults to automatic.
61       */
62      public Alternator(Object... list)
63      {
64          this(true, list);
65      }
66  
67      /**
68       * Creates a new Alternator for the specified list with the specified
69       * automatic shifting preference.
70       *
71       * @param auto See {@link #setAuto(boolean auto)}.
72       * @param list The elements to alternate over
73       */
74      public Alternator(boolean auto, Object... list)
75      {
76          this.auto = auto;
77          if (list.length == 1 && list[0] instanceof Collection)
78          {
79              this.list = ((Collection)list[0]).toArray();
80          }
81          else
82          {
83              this.list = list;
84          }
85      }
86  
87      /**
88       * @return Whether this Alternator shifts the list index
89       * automatically after a call to {@link #toString()}.
90       */
91      public boolean isAuto()
92      {
93          return auto;
94      }
95  
96      /**
97       * If set to true, the list index will shift automatically after a
98       * call to toString().
99       */
100     public void setAuto(boolean auto)
101     {
102         this.auto = auto;
103     }
104 
105     /**
106      * Manually shifts the list index. If it reaches the end of the list,
107      * it will start over again at zero.
108      */
109     public void shift()
110     {
111         index = (index + 1) % list.length;
112     }
113 
114     /**
115      * Returns the current item without shifting the list index.
116      */
117     public Object getCurrent()
118     {
119         return list[index];
120     }
121 
122     /**
123      * Returns the current item, then shifts the list index.
124      */
125     public Object getNext()
126     {
127         Object o = getCurrent();
128         shift();
129         return o;
130     }
131 
132     /**
133      * Returns a string representation of the current item or
134      * <code>null</code> if the current item is null.  <b>If {@link
135      * #auto} is true, this will shift after returning the current
136      * item</b>.
137      */
138     public String toString()
139     {
140         Object o = list[index];
141         if (auto)
142         {
143             shift();
144         }
145         if (o == null)
146         {
147             return null;
148         }
149         return o.toString();
150     }
151 
152 }