/* * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.util.functions; import java.util.List; import java.util.Objects; /** * Static utility methods pertaining to {@code Block} instances. * *

All of the returned Blocks are serializable if given serializable * parameters. */ public final class Blocks { /** * A Block who's {@code apply} method does nothing. */ public static final Block NOP = #{Object t -> }; /** * A Block who's {@code apply} method ensures that the input is not * {@code null}. */ public static final Block REQUIRE_NON_NULL = #{Object t -> Objects.requireNonNull(t);}; /** * singleton utility class */ private Blocks() { throw new AssertionError("No instances!"); } /** * Returns a Block who's {@code apply} method does nothing. * * @param The type of input objects to {@code apply} * @return a Block who's {@code apply} method does nothing. */ public static Block nop() { return (Block) NOP; } /** * Returns a Block who's {@code apply} method ensures that the input is not * {@code null}. * * @param The type of input objects to {@code apply} * @return a Block who's {@code apply} method ensures that the input is not * {@code null} */ public static Block requireNonNull() { return (Block) REQUIRE_NON_NULL; } /** * Returns a Block which performs in sequence the {@code apply} methods of * multiple Blocks. This Block's {@code apply} method is performed followed * by the {@code apply} method of the specified Block operation. * * @param The type of input objects to {@code apply} * @param first the first Block operation in the chain * @param second an additional Block which will be chained after the * {@code first} Block * @return a Block which performs in sequence the {@code first} and * {@code second} Blocks */ public static , T> Block chain( B first, B second) { Objects.requireNonNull(first); Objects.requireNonNull(second); return #{ T t -> first.apply(t); second.apply(t); }; } /** * Returns a Block which performs in sequence the {@code apply} methods of * multiple Blocks. This Block's {@code apply} method is performed followed * by the {@code apply} methods of the specified Block operations. * * @param The type of input objects to {@code apply} * @param first the first Block operation in the chain * @param sequence additional Blocks to be chained after the first Block. A * copy is made of the sequence * @return a Block which performs in sequence the {@code apply} method of * this Block and the {@code apply} methods of the specified Block * operations */ @SafeVarargs public static , T> Block chain(B... sequence) { B blocks[] = Predicates.safeCopyOf(sequence); if(0 == blocks.length) { throw new IllegalArgumentException("no blocks"); } return #{ T t -> for(B block : blocks) block.apply(t); }; } /** * Returns a Block which performs in sequence the {@code apply} methods of * multiple Blocks. * * @param The type of input objects to {@code apply} * @param first The first Block operation in the chain * @param sequence additional Blocks to be chained after the first Block. A * copy is made of the sequence * @return a block that when applied to a {@code t} applies all of the * specified blocks in sequential oder */ @SafeVarargs public static , T> Block chain( B first, B... sequence) { B blocks[] = Predicates.safeCopyOf(first, sequence); return #{ T t -> first.apply(t);for(B block : blocks) block.apply(t); }; } /** * Returns a Block which performs in sequence the {@code apply} methods of * multiple Blocks. * * @param The type of input objects to {@code apply} * @param components The blocks to be executed. A copy is made of the * components. * @return a block that when applied to a {@code t} applies all of the * specified blocks in sequential oder. */ public static , T> Block chain( Iterable sequence) { List blocks = Predicates.safeCopyOf(sequence); if(blocks.isEmpty()) { throw new IllegalArgumentException("no blocks"); } return #{T t -> for(B block : blocks) block.apply(t);}; } /** * Returns a Block which performs in sequence the {@code apply} methods of * multiple Blocks. * * @param The type of input objects to {@code apply} * @param first the first block in the chain. * @param components The blocks to be executed. A copy is made of the * components. * @return a block that when applied to a {@code t} applies all of the * specified blocks in sequential oder. */ public static , T> Block chain( Block first, Iterable sequence) { List blocks = Predicates.safeCopyOf( (B) first, sequence); return #{T t -> for(B block : blocks) block.apply(t);}; } /** * Returns a Block which repeatedly performs the {@code apply} method of * this Block. * * @param block Block to {@code apply} repeatedly * @param count number of repetitions of the {@code apply} method to perform. * @return a Block which repeatedly performs the {@code apply} method of * this Block */ public static Block repeat(Block block, int times) { Objects.requireNonNull(block); if(times < 0) { throw new IllegalArgumentException("negative times");} return #{ T t -> for(int i = 0; i < times; i++) block.apply(t); }; } /** * Returns a Block which repeatedly performs the {@code apply} method of * this Block. The repetitions are terminated when the provided predicate * returns {@code false}. The predicate is tested after each iteration. * * @param block Block to {@code apply} repeatedly * @param decider a predicate which determines whether to continue * calling the {@code apply} method * @return a Block which repeatedly performs the {@code apply} method of * this Block. */ public static Block repeatWhile(Block block, Predicate decider) { Objects.requireNonNull(block); Objects.requireNonNull(decider); return #{T t -> while(decider.eval(t)) block.apply(t); }; } /** * Returns a Block which repeatedly performs the {@code apply} method of * this Block. The repetitions are terminated when the provided predicate * returns {@code false}. The predicate is tested after each iteration. * * @param block Block to {@code apply} repeatedly. * @param decider a predicate which determines whether to continue * calling the {@code apply} method. * @return a Block which repeatedly performs the {@code apply} method of * this Block. */ public static Block repeatUntil(Block block, Predicate decider) { Objects.requireNonNull(block); Objects.requireNonNull(decider); return #{T t -> do{ block.apply(t); } while(decider.eval(t)); }; } }