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.lang.reflect.Array; 23 import java.util.List; 24 import org.apache.velocity.tools.config.DefaultKey; 25 26 /** 27 * Tool for working with Lists and arrays in Velocity templates. 28 * <p> 29 * With the release of Velocity 1.6, this class is largely obsolete since 30 * Velocity 1.6 now allows all List methods to be called on arrays 31 * within templates. 32 * </p> 33 * <p> 34 * It provides a method to get and set specified elements. 35 * Also provides methods to perform the following actions to Lists and arrays: 36 * <ul> 37 * <li>Check if it is empty.</li> 38 * <li>Check if it contains a certain element.</li> 39 * </ul> 40 * </p> 41 * <p><pre> 42 * Example uses: 43 * $primes -> new int[] {2, 3, 5, 7} 44 * $lists.size($primes) -> 4 45 * $lists.get($primes, 2) -> 5 46 * $lists.set($primes, 2, 1) -> (primes[2] becomes 1) 47 * $lists.get($primes, 2) -> 1 48 * $lists.isEmpty($primes) -> false 49 * $lists.contains($primes, 7) -> true 50 * 51 * Example tools.xml config (if you want to use this with VelocityView): 52 * <tools> 53 * <toolbox scope="application"> 54 * <tool class="org.apache.velocity.tools.generic.ListTool"/> 55 * </toolbox> 56 * </tools> 57 * </pre></p> 58 * 59 * <p>This tool is entirely threadsafe, and has no instance members. 60 * It may be used in any scope (request, session, or application). 61 * </p> 62 * 63 * @author <a href="mailto:shinobu@ieee.org">Shinobu Kawai</a> 64 * @version $Id: $ 65 * @since VelocityTools 1.2 66 */ 67 @Deprecated 68 @DefaultKey("lists") 69 public class ListTool 70 { 71 /** 72 * Gets the specified element of a List/array. 73 * It will return null under the following conditions: 74 * <ul> 75 * <li><code>list</code> is null.</li> 76 * <li><code>list</code> is not a List/array.</li> 77 * <li><code>list</code> doesn't have an <code>index</code>th value.</li> 78 * </ul> 79 * @param list the List/array object. 80 * @param index the index of the List/array to get. 81 * @return the specified element of the List/array. 82 */ 83 public Object get(Object list, int index) 84 { 85 if (isArray(list)) 86 { 87 return getFromArray(list, index); 88 } 89 if (!isList(list)) 90 { 91 return null; 92 } 93 94 try 95 { 96 return ((List) list).get(index); 97 } 98 catch (IndexOutOfBoundsException e) 99 { 100 // The index was wrong. 101 return null; 102 } 103 } 104 105 /** 106 * Gets the specified element of an array. 107 * @param array the array object. 108 * @param index the index of the array to get. 109 * @return the specified element of the array. 110 */ 111 private Object getFromArray(Object array, int index) 112 { 113 try 114 { 115 return Array.get(array, index); 116 } 117 catch (IndexOutOfBoundsException e) 118 { 119 // The index was wrong. 120 return null; 121 } 122 } 123 124 /** 125 * Sets the specified element of a List/array. 126 * It will return null under the following conditions: 127 * <ul> 128 * <li><code>list</code> is null.</li> 129 * <li><code>list</code> is not a List/array.</li> 130 * <li><code>list</code> doesn't have an <code>index</code>th value.</li> 131 * </ul> 132 * @param list the List/array object. 133 * @param index the index of the List/array to set. 134 * @param value the element to set. 135 * @return blank if set, null if not set. 136 */ 137 public Object set(Object list, int index, Object value) 138 { 139 if (isArray(list)) 140 { 141 return setToArray(list, index, value); 142 } 143 if (!isList(list)) 144 { 145 return null; 146 } 147 148 try 149 { 150 ((List) list).set(index, value); 151 return ""; 152 } 153 catch (IndexOutOfBoundsException e) 154 { 155 // The index was wrong. 156 return null; 157 } 158 } 159 160 /** 161 * Sets the specified element of an array. 162 * @param array the array object. 163 * @param index the index of the array to set. 164 * @param value the element to set. 165 * @return blank if set, null if not set. 166 */ 167 private Object setToArray(Object array, int index, Object value) 168 { 169 try 170 { 171 Array.set(array, index, value); 172 return ""; 173 } 174 catch (IndexOutOfBoundsException e) 175 { 176 // The index was wrong. 177 return null; 178 } 179 } 180 181 /** 182 * Gets the size of a List/array. 183 * It will return null under the following conditions: 184 * <ul> 185 * <li><code>list</code> is null.</li> 186 * <li><code>list</code> is not a List/array.</li> 187 * </ul> 188 * @param list the List object. 189 * @return the size of the List. 190 */ 191 public Integer size(Object list) 192 { 193 if (isArray(list)) 194 { 195 // Thanks to Eric Fixler for this refactor. 196 return Integer.valueOf(Array.getLength(list)); 197 } 198 if (!isList(list)) 199 { 200 return null; 201 } 202 203 return Integer.valueOf(((List) list).size()); 204 } 205 206 /** 207 * Checks if an object is an array. 208 * @param object the object to check. 209 * @return <code>true</code> if the object is an array. 210 */ 211 public boolean isArray(Object object) 212 { 213 if (object == null) 214 { 215 return false; 216 } 217 return object.getClass().isArray(); 218 } 219 220 /** 221 * Checks if an object is a List. 222 * @param object the object to check. 223 * @return <code>true</code> if the object is a List. 224 */ 225 public boolean isList(Object object) 226 { 227 return object instanceof List; 228 } 229 230 /** 231 * Checks if a List/array is empty. 232 * @param list the List/array to check. 233 * @return <code>true</code> if the List/array is empty. 234 */ 235 public Boolean isEmpty(Object list) 236 { 237 Integer size = size(list); 238 if (size == null) 239 { 240 return null; 241 } 242 243 return Boolean.valueOf(size.intValue() == 0); 244 } 245 246 /** 247 * Checks if a List/array contains a certain element. 248 * @param list the List/array to check. 249 * @param element the element to check. 250 * @return <code>true</code> if the List/array contains the element. 251 */ 252 public Boolean contains(Object list, Object element) 253 { 254 if (isArray(list)) 255 { 256 return arrayContains(list, element); 257 } 258 if (!isList(list)) 259 { 260 return null; 261 } 262 263 return Boolean.valueOf(((List) list).contains(element)); 264 } 265 266 /** 267 * Checks if an array contains a certain element. 268 * @param array the array to check. 269 * @param element the element to check. 270 * @return <code>true</code> if the array contains the element. 271 */ 272 private Boolean arrayContains(Object array, Object element) 273 { 274 int size = size(array).intValue(); 275 276 for (int index = 0; index < size; ++index) 277 { 278 if (equals(element, getFromArray(array, index))) 279 { 280 return Boolean.TRUE; 281 } 282 } 283 return Boolean.FALSE; 284 } 285 286 /** 287 * Check if two objects are equal. 288 * @param what an object 289 * @param with another object. 290 * @return <code>true</code> if the two objects are equal. 291 */ 292 private boolean equals(Object what, Object with) 293 { 294 if (what == null) 295 { 296 return with == null; 297 } 298 299 return what.equals(with); 300 } 301 302 }