1. /*
  2. * Copyright 2001-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.collections.functors;
  17. import java.io.Serializable;
  18. import java.util.Collection;
  19. import java.util.Iterator;
  20. import org.apache.commons.collections.Closure;
  21. /**
  22. * Closure implementation that chains the specified closures together.
  23. *
  24. * @since Commons Collections 3.0
  25. * @version $Revision: 1.5 $ $Date: 2004/03/13 17:17:03 $
  26. *
  27. * @author Stephen Colebourne
  28. */
  29. public class ChainedClosure implements Closure, Serializable {
  30. /** Serial version UID */
  31. static final long serialVersionUID = -3520677225766901240L;
  32. /** The closures to call in turn */
  33. private final Closure[] iClosures;
  34. /**
  35. * Factory method that performs validation and copies the parameter array.
  36. *
  37. * @param closures the closures to chain, copied, no nulls
  38. * @return the <code>chained</code> closure
  39. * @throws IllegalArgumentException if the closures array is null
  40. * @throws IllegalArgumentException if any closure in the array is null
  41. */
  42. public static Closure getInstance(Closure[] closures) {
  43. FunctorUtils.validate(closures);
  44. if (closures.length == 0) {
  45. return NOPClosure.INSTANCE;
  46. }
  47. closures = FunctorUtils.copy(closures);
  48. return new ChainedClosure(closures);
  49. }
  50. /**
  51. * Create a new Closure that calls each closure in turn, passing the
  52. * result into the next closure. The ordering is that of the iterator()
  53. * method on the collection.
  54. *
  55. * @param closures a collection of closures to chain
  56. * @return the <code>chained</code> closure
  57. * @throws IllegalArgumentException if the closures collection is null
  58. * @throws IllegalArgumentException if any closure in the collection is null
  59. */
  60. public static Closure getInstance(Collection closures) {
  61. if (closures == null) {
  62. throw new IllegalArgumentException("Closure collection must not be null");
  63. }
  64. if (closures.size() == 0) {
  65. return NOPClosure.INSTANCE;
  66. }
  67. // convert to array like this to guarantee iterator() ordering
  68. Closure[] cmds = new Closure[closures.size()];
  69. int i = 0;
  70. for (Iterator it = closures.iterator(); it.hasNext();) {
  71. cmds[i++] = (Closure) it.next();
  72. }
  73. FunctorUtils.validate(cmds);
  74. return new ChainedClosure(cmds);
  75. }
  76. /**
  77. * Factory method that performs validation.
  78. *
  79. * @param closure1 the first closure, not null
  80. * @param closure2 the second closure, not null
  81. * @return the <code>chained</code> closure
  82. * @throws IllegalArgumentException if either closure is null
  83. */
  84. public static Closure getInstance(Closure closure1, Closure closure2) {
  85. if (closure1 == null || closure2 == null) {
  86. throw new IllegalArgumentException("Closures must not be null");
  87. }
  88. Closure[] closures = new Closure[] { closure1, closure2 };
  89. return new ChainedClosure(closures);
  90. }
  91. /**
  92. * Constructor that performs no validation.
  93. * Use <code>getInstance</code> if you want that.
  94. *
  95. * @param closures the closures to chain, not copied, no nulls
  96. */
  97. public ChainedClosure(Closure[] closures) {
  98. super();
  99. iClosures = closures;
  100. }
  101. /**
  102. * Execute a list of closures.
  103. *
  104. * @param input the input object passed to each closure
  105. */
  106. public void execute(Object input) {
  107. for (int i = 0; i < iClosures.length; i++) {
  108. iClosures[i].execute(input);
  109. }
  110. }
  111. /**
  112. * Gets the closures, do not modify the array.
  113. * @return the closures
  114. * @since Commons Collections 3.1
  115. */
  116. public Closure[] getClosures() {
  117. return iClosures;
  118. }
  119. }