001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.collections4; 018 019import java.util.Collection; 020import java.util.Map; 021 022import org.apache.commons.collections4.functors.ChainedTransformer; 023import org.apache.commons.collections4.functors.CloneTransformer; 024import org.apache.commons.collections4.functors.ClosureTransformer; 025import org.apache.commons.collections4.functors.ConstantTransformer; 026import org.apache.commons.collections4.functors.EqualPredicate; 027import org.apache.commons.collections4.functors.ExceptionTransformer; 028import org.apache.commons.collections4.functors.FactoryTransformer; 029import org.apache.commons.collections4.functors.InstantiateTransformer; 030import org.apache.commons.collections4.functors.InvokerTransformer; 031import org.apache.commons.collections4.functors.MapTransformer; 032import org.apache.commons.collections4.functors.NOPTransformer; 033import org.apache.commons.collections4.functors.PredicateTransformer; 034import org.apache.commons.collections4.functors.StringValueTransformer; 035import org.apache.commons.collections4.functors.SwitchTransformer; 036 037/** 038 * <code>TransformerUtils</code> provides reference implementations and 039 * utilities for the Transformer functor interface. The supplied transformers are: 040 * <ul> 041 * <li>Invoker - returns the result of a method call on the input object 042 * <li>Clone - returns a clone of the input object 043 * <li>Constant - always returns the same object 044 * <li>Closure - performs a Closure and returns the input object 045 * <li>Predicate - returns the result of the predicate as a Boolean 046 * <li>Factory - returns a new object from a factory 047 * <li>Chained - chains two or more transformers together 048 * <li>Switch - calls one transformer based on one or more predicates 049 * <li>SwitchMap - calls one transformer looked up from a Map 050 * <li>Instantiate - the Class input object is instantiated 051 * <li>Map - returns an object from a supplied Map 052 * <li>Null - always returns null 053 * <li>NOP - returns the input object, which should be immutable 054 * <li>Exception - always throws an exception 055 * <li>StringValue - returns a <code>java.lang.String</code> representation of the input object 056 * </ul> 057 * All the supplied transformers are Serializable. 058 * 059 * @since 3.0 060 * @version $Id: TransformerUtils.html 972421 2015-11-14 20:00:04Z tn $ 061 */ 062public class TransformerUtils { 063 064 /** 065 * This class is not normally instantiated. 066 */ 067 private TransformerUtils() {} 068 069 /** 070 * Gets a transformer that always throws an exception. 071 * This could be useful during testing as a placeholder. 072 * 073 * @param <I> the input type 074 * @param <O> the output type 075 * @return the transformer 076 * @see org.apache.commons.collections4.functors.ExceptionTransformer 077 */ 078 public static <I, O> Transformer<I, O> exceptionTransformer() { 079 return ExceptionTransformer.<I, O>exceptionTransformer(); 080 } 081 082 /** 083 * Gets a transformer that always returns null. 084 * 085 * @param <I> the input type 086 * @param <O> the output type 087 * @return the transformer 088 * @see org.apache.commons.collections4.functors.ConstantTransformer 089 */ 090 public static <I, O> Transformer<I, O> nullTransformer() { 091 return ConstantTransformer.<I, O>nullTransformer(); 092 } 093 094 /** 095 * Gets a transformer that returns the input object. 096 * The input object should be immutable to maintain the 097 * contract of Transformer (although this is not checked). 098 * 099 * @param <T> the input/output type 100 * @return the transformer 101 * @see org.apache.commons.collections4.functors.NOPTransformer 102 */ 103 public static <T> Transformer<T, T> nopTransformer() { 104 return NOPTransformer.<T>nopTransformer(); 105 } 106 107 /** 108 * Gets a transformer that returns a clone of the input 109 * object. The input object will be cloned using one of these 110 * techniques (in order): 111 * <ul> 112 * <li>public clone method 113 * <li>public copy constructor 114 * <li>serialization clone 115 * <ul> 116 * 117 * @param <T> the input/output type 118 * @return the transformer 119 * @see org.apache.commons.collections4.functors.CloneTransformer 120 */ 121 public static <T> Transformer<T, T> cloneTransformer() { 122 return CloneTransformer.<T>cloneTransformer(); 123 } 124 125 /** 126 * Creates a Transformer that will return the same object each time the 127 * transformer is used. 128 * 129 * @param <I> the input type 130 * @param <O> the output type 131 * @param constantToReturn the constant object to return each time in the transformer 132 * @return the transformer. 133 * @see org.apache.commons.collections4.functors.ConstantTransformer 134 */ 135 public static <I, O> Transformer<I, O> constantTransformer(final O constantToReturn) { 136 return ConstantTransformer.constantTransformer(constantToReturn); 137 } 138 139 /** 140 * Creates a Transformer that calls a Closure each time the transformer is used. 141 * The transformer returns the input object. 142 * 143 * @param <T> the input/output type 144 * @param closure the closure to run each time in the transformer, not null 145 * @return the transformer 146 * @throws IllegalArgumentException if the closure is null 147 * @see org.apache.commons.collections4.functors.ClosureTransformer 148 */ 149 public static <T> Transformer<T, T> asTransformer(final Closure<? super T> closure) { 150 return ClosureTransformer.closureTransformer(closure); 151 } 152 153 /** 154 * Creates a Transformer that calls a Predicate each time the transformer is used. 155 * The transformer will return either Boolean.TRUE or Boolean.FALSE. 156 * 157 * @param <T> the input type 158 * @param predicate the predicate to run each time in the transformer, not null 159 * @return the transformer 160 * @throws IllegalArgumentException if the predicate is null 161 * @see org.apache.commons.collections4.functors.PredicateTransformer 162 */ 163 public static <T> Transformer<T, Boolean> asTransformer(final Predicate<? super T> predicate) { 164 return PredicateTransformer.predicateTransformer(predicate); 165 } 166 167 /** 168 * Creates a Transformer that calls a Factory each time the transformer is used. 169 * The transformer will return the value returned by the factory. 170 * 171 * @param <I> the input type 172 * @param <O> the output type 173 * @param factory the factory to run each time in the transformer, not null 174 * @return the transformer 175 * @throws IllegalArgumentException if the factory is null 176 * @see org.apache.commons.collections4.functors.FactoryTransformer 177 */ 178 public static <I, O> Transformer<I, O> asTransformer(final Factory<? extends O> factory) { 179 return FactoryTransformer.factoryTransformer(factory); 180 } 181 182 /** 183 * Create a new Transformer that calls each transformer in turn, passing the 184 * result into the next transformer. 185 * 186 * @param <T> the input/output type 187 * @param transformers an array of transformers to chain 188 * @return the transformer 189 * @throws IllegalArgumentException if the transformers array or any of the transformers is null 190 * @see org.apache.commons.collections4.functors.ChainedTransformer 191 */ 192 public static <T> Transformer<T, T> chainedTransformer( 193 final Transformer<? super T, ? extends T>... transformers) { 194 return ChainedTransformer.chainedTransformer(transformers); 195 } 196 197 /** 198 * Create a new Transformer that calls each transformer in turn, passing the 199 * result into the next transformer. The ordering is that of the iterator() 200 * method on the collection. 201 * 202 * @param <T> the input/output type 203 * @param transformers a collection of transformers to chain 204 * @return the transformer 205 * @throws IllegalArgumentException if the transformers collection or any of the transformers is null 206 * @see org.apache.commons.collections4.functors.ChainedTransformer 207 */ 208 public static <T> Transformer<T, T> chainedTransformer( 209 final Collection<? extends Transformer<T, T>> transformers) { 210 return ChainedTransformer.chainedTransformer(transformers); 211 } 212 213 /** 214 * Create a new Transformer that calls one of two transformers depending 215 * on the specified predicate. 216 * 217 * @param <I> the input type 218 * @param <O> the output type 219 * @param predicate the predicate to switch on 220 * @param trueTransformer the transformer called if the predicate is true 221 * @param falseTransformer the transformer called if the predicate is false 222 * @return the transformer 223 * @throws IllegalArgumentException if either the predicate or transformer is null 224 * @see org.apache.commons.collections4.functors.SwitchTransformer 225 */ 226 @SuppressWarnings("unchecked") 227 public static <I, O> Transformer<I, O> switchTransformer(final Predicate<? super I> predicate, 228 final Transformer<? super I, ? extends O> trueTransformer, 229 final Transformer<? super I, ? extends O> falseTransformer) { 230 return SwitchTransformer.switchTransformer(new Predicate[] { predicate }, 231 new Transformer[] { trueTransformer }, falseTransformer); 232 } 233 234 /** 235 * Create a new Transformer that calls one of the transformers depending 236 * on the predicates. The transformer at array location 0 is called if the 237 * predicate at array location 0 returned true. Each predicate is evaluated 238 * until one returns true. If no predicates evaluate to true, null is returned. 239 * 240 * @param <I> the input type 241 * @param <O> the output type 242 * @param predicates an array of predicates to check 243 * @param transformers an array of transformers to call 244 * @return the transformer 245 * @throws IllegalArgumentException if the either array is null or empty 246 * @throws IllegalArgumentException if any element in the arrays is null 247 * @throws IllegalArgumentException if the arrays are different sizes 248 * @see org.apache.commons.collections4.functors.SwitchTransformer 249 */ 250 public static <I, O> Transformer<I, O> switchTransformer(final Predicate<? super I>[] predicates, 251 final Transformer<? super I, ? extends O>[] transformers) { 252 return SwitchTransformer.<I, O>switchTransformer(predicates, transformers, null); 253 } 254 255 /** 256 * Create a new Transformer that calls one of the transformers depending 257 * on the predicates. The transformer at array location 0 is called if the 258 * predicate at array location 0 returned true. Each predicate is evaluated 259 * until one returns true. If no predicates evaluate to true, the default 260 * transformer is called. If the default transformer is null, null is returned. 261 * 262 * @param <I> the input type 263 * @param <O> the output type 264 * @param predicates an array of predicates to check 265 * @param transformers an array of transformers to call 266 * @param defaultTransformer the default to call if no predicate matches, null means return null 267 * @return the transformer 268 * @throws IllegalArgumentException if the either array is null or empty 269 * @throws IllegalArgumentException if any element in the arrays is null 270 * @throws IllegalArgumentException if the arrays are different sizes 271 * @see org.apache.commons.collections4.functors.SwitchTransformer 272 */ 273 public static <I, O> Transformer<I, O> switchTransformer(final Predicate<? super I>[] predicates, 274 final Transformer<? super I, ? extends O>[] transformers, 275 final Transformer<? super I, ? extends O> defaultTransformer) { 276 return SwitchTransformer.<I, O>switchTransformer(predicates, transformers, defaultTransformer); 277 } 278 279 /** 280 * Create a new Transformer that calls one of the transformers depending 281 * on the predicates. 282 * <p> 283 * The Map consists of Predicate keys and Transformer values. A transformer 284 * is called if its matching predicate returns true. Each predicate is evaluated 285 * until one returns true. If no predicates evaluate to true, the default 286 * transformer is called. The default transformer is set in the map with a 287 * null key. If no default transformer is set, null will be returned in a default 288 * case. The ordering is that of the iterator() method on the entryset collection 289 * of the map. 290 * 291 * @param <I> the input type 292 * @param <O> the output type 293 * @param predicatesAndTransformers a map of predicates to transformers 294 * @return the transformer 295 * @throws IllegalArgumentException if the map is null or empty 296 * @throws IllegalArgumentException if any transformer in the map is null 297 * @throws ClassCastException if the map elements are of the wrong type 298 * @see org.apache.commons.collections4.functors.SwitchTransformer 299 */ 300 public static <I, O> Transformer<I, O> switchTransformer( 301 final Map<Predicate<I>, Transformer<I, O>> predicatesAndTransformers) { 302 return SwitchTransformer.<I, O>switchTransformer(predicatesAndTransformers); 303 } 304 305 /** 306 * Create a new Transformer that uses the input object as a key to find the 307 * transformer to call. 308 * <p> 309 * The Map consists of object keys and Transformer values. A transformer 310 * is called if the input object equals the key. If there is no match, the 311 * default transformer is called. The default transformer is set in the map 312 * using a null key. If no default is set, null will be returned in a default case. 313 * 314 * @param <I> the input type 315 * @param <O> the output type 316 * @param objectsAndTransformers a map of objects to transformers 317 * @return the transformer 318 * @throws IllegalArgumentException if the map is null or empty 319 * @throws IllegalArgumentException if any transformer in the map is null 320 * @see org.apache.commons.collections4.functors.SwitchTransformer 321 */ 322 @SuppressWarnings("unchecked") 323 public static <I, O> Transformer<I, O> switchMapTransformer( 324 final Map<I, Transformer<I, O>> objectsAndTransformers) { 325 326 if (objectsAndTransformers == null) { 327 throw new IllegalArgumentException("The object and transformer map must not be null"); 328 } 329 final Transformer<? super I, ? extends O> def = objectsAndTransformers.remove(null); 330 final int size = objectsAndTransformers.size(); 331 final Transformer<? super I, ? extends O>[] trs = new Transformer[size]; 332 final Predicate<I>[] preds = new Predicate[size]; 333 int i = 0; 334 for (final Map.Entry<I, Transformer<I, O>> entry : objectsAndTransformers.entrySet()) { 335 preds[i] = EqualPredicate.<I>equalPredicate(entry.getKey()); 336 trs[i++] = entry.getValue(); 337 } 338 return TransformerUtils.<I, O>switchTransformer(preds, trs, def); 339 } 340 341 /** 342 * Gets a Transformer that expects an input Class object that it will instantiate. 343 * 344 * @param <T> the output type 345 * @return the transformer 346 * @see org.apache.commons.collections4.functors.InstantiateTransformer 347 */ 348 public static <T> Transformer<Class<? extends T>, T> instantiateTransformer() { 349 return InstantiateTransformer.<T>instantiateTransformer(); 350 } 351 352 /** 353 * Creates a Transformer that expects an input Class object that it will 354 * instantiate. The constructor used is determined by the arguments specified 355 * to this method. 356 * 357 * @param <T> the output type 358 * @param paramTypes parameter types for the constructor, can be null 359 * @param args the arguments to pass to the constructor, can be null 360 * @return the transformer 361 * @throws IllegalArgumentException if the paramTypes and args don't match 362 * @see org.apache.commons.collections4.functors.InstantiateTransformer 363 */ 364 public static <T> Transformer<Class<? extends T>, T> instantiateTransformer( 365 final Class<?>[] paramTypes, final Object[] args) { 366 return InstantiateTransformer.<T>instantiateTransformer(paramTypes, args); 367 } 368 369 /** 370 * Creates a Transformer that uses the passed in Map to transform the input 371 * object (as a simple lookup). 372 * 373 * @param <I> the input type 374 * @param <O> the output type 375 * @param map the map to use to transform the objects 376 * @return the transformer, or a {@link ConstantTransformer#NULL_INSTANCE} if the {@code map} is {@code null} 377 * @see org.apache.commons.collections4.functors.MapTransformer 378 */ 379 public static <I, O> Transformer<I, O> mapTransformer(final Map<? super I, ? extends O> map) { 380 return MapTransformer.mapTransformer(map); 381 } 382 383 /** 384 * Gets a Transformer that invokes a method on the input object. 385 * The method must have no parameters. If the input object is null, 386 * null is returned. 387 * <p> 388 * For example, <code>TransformerUtils.invokerTransformer("getName");</code> 389 * will call the <code>getName/code> method on the input object to 390 * determine the transformer result. 391 * 392 * @param <I> the input type 393 * @param <O> the output type 394 * @param methodName the method name to call on the input object, may not be null 395 * @return the transformer 396 * @throws IllegalArgumentException if the methodName is null. 397 * @see org.apache.commons.collections4.functors.InvokerTransformer 398 */ 399 public static <I, O> Transformer<I, O> invokerTransformer(final String methodName) { 400 return InvokerTransformer.<I, O>invokerTransformer(methodName, null, null); 401 } 402 403 /** 404 * Gets a Transformer that invokes a method on the input object. 405 * The method parameters are specified. If the input object is {@code null}, 406 * {@code null} is returned. 407 * 408 * @param <I> the input type 409 * @param <O> the output type 410 * @param methodName the name of the method 411 * @param paramTypes the parameter types 412 * @param args the arguments 413 * @return the transformer 414 * @throws IllegalArgumentException if the method name is null or the paramTypes and args don't match 415 * @see org.apache.commons.collections4.functors.InvokerTransformer 416 */ 417 public static <I, O> Transformer<I, O> invokerTransformer(final String methodName, final Class<?>[] paramTypes, 418 final Object[] args) { 419 return InvokerTransformer.<I, O>invokerTransformer(methodName, paramTypes, args); 420 } 421 422 /** 423 * Gets a transformer that returns a <code>java.lang.String</code> 424 * representation of the input object. This is achieved via the 425 * <code>toString</code> method, <code>null</code> returns 'null'. 426 * 427 * @param <T> the input type 428 * @return the transformer 429 * @see org.apache.commons.collections4.functors.StringValueTransformer 430 */ 431 public static <T> Transformer<T, String> stringValueTransformer() { 432 return StringValueTransformer.<T>stringValueTransformer(); 433 } 434 435}