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 }