/*
* 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 super T> 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 super T> 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 super T> 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 super T> decider) {
Objects.requireNonNull(block);
Objects.requireNonNull(decider);
return #{T t -> do{ block.apply(t); } while(decider.eval(t)); };
}
}