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 */ 017 package org.apache.commons.collections.functors; 018 019 import java.io.Serializable; 020 import java.util.Collection; 021 import java.util.Iterator; 022 023 import org.apache.commons.collections.Closure; 024 025 /** 026 * Closure implementation that chains the specified closures together. 027 * 028 * @since Commons Collections 3.0 029 * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $ 030 * 031 * @author Stephen Colebourne 032 */ 033 public class ChainedClosure implements Closure, Serializable { 034 035 /** Serial version UID */ 036 private static final long serialVersionUID = -3520677225766901240L; 037 038 /** The closures to call in turn */ 039 private final Closure[] iClosures; 040 041 /** 042 * Factory method that performs validation and copies the parameter array. 043 * 044 * @param closures the closures to chain, copied, no nulls 045 * @return the <code>chained</code> closure 046 * @throws IllegalArgumentException if the closures array is null 047 * @throws IllegalArgumentException if any closure in the array is null 048 */ 049 public static Closure getInstance(Closure[] closures) { 050 FunctorUtils.validate(closures); 051 if (closures.length == 0) { 052 return NOPClosure.INSTANCE; 053 } 054 closures = FunctorUtils.copy(closures); 055 return new ChainedClosure(closures); 056 } 057 058 /** 059 * Create a new Closure that calls each closure in turn, passing the 060 * result into the next closure. The ordering is that of the iterator() 061 * method on the collection. 062 * 063 * @param closures a collection of closures to chain 064 * @return the <code>chained</code> closure 065 * @throws IllegalArgumentException if the closures collection is null 066 * @throws IllegalArgumentException if any closure in the collection is null 067 */ 068 public static Closure getInstance(Collection closures) { 069 if (closures == null) { 070 throw new IllegalArgumentException("Closure collection must not be null"); 071 } 072 if (closures.size() == 0) { 073 return NOPClosure.INSTANCE; 074 } 075 // convert to array like this to guarantee iterator() ordering 076 Closure[] cmds = new Closure[closures.size()]; 077 int i = 0; 078 for (Iterator it = closures.iterator(); it.hasNext();) { 079 cmds[i++] = (Closure) it.next(); 080 } 081 FunctorUtils.validate(cmds); 082 return new ChainedClosure(cmds); 083 } 084 085 /** 086 * Factory method that performs validation. 087 * 088 * @param closure1 the first closure, not null 089 * @param closure2 the second closure, not null 090 * @return the <code>chained</code> closure 091 * @throws IllegalArgumentException if either closure is null 092 */ 093 public static Closure getInstance(Closure closure1, Closure closure2) { 094 if (closure1 == null || closure2 == null) { 095 throw new IllegalArgumentException("Closures must not be null"); 096 } 097 Closure[] closures = new Closure[] { closure1, closure2 }; 098 return new ChainedClosure(closures); 099 } 100 101 /** 102 * Constructor that performs no validation. 103 * Use <code>getInstance</code> if you want that. 104 * 105 * @param closures the closures to chain, not copied, no nulls 106 */ 107 public ChainedClosure(Closure[] closures) { 108 super(); 109 iClosures = closures; 110 } 111 112 /** 113 * Execute a list of closures. 114 * 115 * @param input the input object passed to each closure 116 */ 117 public void execute(Object input) { 118 for (int i = 0; i < iClosures.length; i++) { 119 iClosures[i].execute(input); 120 } 121 } 122 123 /** 124 * Gets the closures, do not modify the array. 125 * @return the closures 126 * @since Commons Collections 3.1 127 */ 128 public Closure[] getClosures() { 129 return iClosures; 130 } 131 132 }