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.juneau.commons.function;
018
019import static org.apache.juneau.commons.utils.Shorts.*;
020
021
022/**
023 * A functional interface representing an operation that accepts five arguments and returns no result.
024 *
025 * <p>
026 * This interface extends the standard Java {@link java.util.function.Consumer} pattern to support
027 * five-argument consumers. It's useful when you need to pass operations with five parameters to methods
028 * that expect functional interfaces, such as in iteration, builders, or callback patterns.
029 *
030 * <h5 class='section'>Features:</h5>
031 * <ul class='spaced-list'>
032 *    <li>Functional interface - can be used with lambda expressions and method references
033 *    <li>Composition support - provides {@link #andThen(Consumer5)} for operation chaining
034 *    <li>Side-effect operations - designed for operations that perform side effects rather than return values
035 * </ul>
036 *
037 * <h5 class='section'>Use Cases:</h5>
038 * <ul class='spaced-list'>
039 *    <li>Five-argument operations in iteration patterns
040 *    <li>Builder methods that accept five-parameter operations
041 *    <li>Callback patterns with five parameters
042 *    <li>Event handlers that process five values
043 * </ul>
044 *
045 * <h5 class='section'>Usage:</h5>
046 * <p class='bjava'>
047 *    <jc>// Lambda expression</jc>
048 *    Consumer5&lt;String,Integer,Boolean,Double,Long&gt; <jv>printer</jv> = (<jv>name</jv>, <jv>age</jv>, <jv>active</jv>, <jv>score</jv>, <jv>timestamp</jv>) -&gt;
049 *       System.<jsf>out</jsf>.println(<jv>name</jv> + <js>": age="</js> + <jv>age</jv> + <js>", active="</js> + <jv>active</jv> + <js>", score="</js> + <jv>score</jv> + <js>", time="</js> + <jv>timestamp</jv>);
050 *    <jv>printer</jv>.apply(<js>"Alice"</js>, 30, <jk>true</jk>, 95.5, 1234567890L);
051 *
052 *    <jc>// Operation composition</jc>
053 *    Consumer5&lt;String,Integer,Boolean,Double,Long&gt; <jv>validate</jv> = (<jv>s</jv>, <jv>i</jv>, <jv>b</jv>, <jv>d</jv>, <jv>l</jv>) -&gt; {
054 *       <jk>if</jk> (<jv>i</jv> &lt; 0 || <jv>d</jv> &lt; 0 || <jv>l</jv> &lt; 0) <jk>throw new</jk> IllegalArgumentException();
055 *    };
056 *    Consumer5&lt;String,Integer,Boolean,Double,Long&gt; <jv>process</jv> = (<jv>s</jv>, <jv>i</jv>, <jv>b</jv>, <jv>d</jv>, <jv>l</jv>) -&gt; <jsm>process</jsm>(<jv>s</jv>, <jv>i</jv>, <jv>b</jv>, <jv>d</jv>, <jv>l</jv>);
057 *    Consumer5&lt;String,Integer,Boolean,Double,Long&gt; <jv>validateAndProcess</jv> = <jv>validate</jv>.andThen(<jv>process</jv>);
058 *    <jv>validateAndProcess</jv>.apply(<js>"data"</js>, 42, <jk>true</jk>, 10.5, 9876543210L);  <jc>// Validates then processes</jc>
059 * </p>
060 *
061 * <h5 class='section'>See Also:</h5><ul>
062 *    <li class='jc'>{@link Consumer2} - Two-argument consumer
063 *    <li class='jc'>{@link Consumer3} - Three-argument consumer
064 *    <li class='jc'>{@link Consumer4} - Four-argument consumer
065 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauCommons">juneau-commons</a>
066 * </ul>
067 *
068 * @param <A> The type of the first argument to the operation.
069 * @param <B> The type of the second argument to the operation.
070 * @param <C> The type of the third argument to the operation.
071 * @param <D> The type of the fourth argument to the operation.
072 * @param <E> The type of the fifth argument to the operation.
073 */
074@FunctionalInterface
075@SuppressWarnings({
076   "java:S1192" // Duplicated literals (argument/property names) read more clearly inline than as constants
077})
078public interface Consumer5<A,B,C,D,E> {
079
080   /**
081    * Returns a composed {@link Consumer5} that performs, in sequence, this operation followed by the {@code after} operation.
082    *
083    * <p>
084    * This method enables operation composition, allowing you to chain multiple operations together.
085    * If performing either operation throws an exception, it is relayed to the caller of the composed operation.
086    * If performing this operation throws an exception, the {@code after} operation will not be performed.
087    *
088    * <h5 class='section'>Example:</h5>
089    * <p class='bjava'>
090    *    Consumer5&lt;String,Integer,Boolean,Double,Long&gt; <jv>log</jv> = (<jv>s</jv>, <jv>i</jv>, <jv>b</jv>, <jv>d</jv>, <jv>l</jv>) -&gt; <jsm>logger</jsm>.info(<jv>s</jv> + <js>": "</js> + <jv>i</jv> + <js>", "</js> + <jv>b</jv> + <js>", "</js> + <jv>d</jv> + <js>", "</js> + <jv>l</jv>);
091    *    Consumer5&lt;String,Integer,Boolean,Double,Long&gt; <jv>store</jv> = (<jv>s</jv>, <jv>i</jv>, <jv>b</jv>, <jv>d</jv>, <jv>l</jv>) -&gt; <jv>cache</jv>.put(<jv>s</jv>, <jv>i</jv>, <jv>b</jv>, <jv>d</jv>, <jv>l</jv>);
092    *    Consumer5&lt;String,Integer,Boolean,Double,Long&gt; <jv>logAndStore</jv> = <jv>log</jv>.andThen(<jv>store</jv>);
093    *    <jv>logAndStore</jv>.apply(<js>"data"</js>, 100, <jk>true</jk>, 50.0, 1234567890L);  <jc>// Logs and stores</jc>
094    * </p>
095    *
096    * @param after The operation to perform after this operation. Must not be <jk>null</jk>.
097    * @return A composed {@link Consumer5} that performs in sequence this operation followed by the {@code after} operation.
098    * @throws NullPointerException if {@code after} is <jk>null</jk>.
099    */
100   default Consumer5<A,B,C,D,E> andThen(Consumer5<? super A,? super B,? super C,? super D,? super E> after) {
101      reqnn("after", after);
102      return (A a, B b, C c, D d, E e) -> {
103         apply(a, b, c, d, e);
104         after.apply(a, b, c, d, e);
105      };
106   }
107
108   /**
109    * Performs this operation on the given arguments.
110    *
111    * <h5 class='section'>Example:</h5>
112    * <p class='bjava'>
113    *    Consumer5&lt;String,Integer,Boolean,Double,Long&gt; <jv>handler</jv> = (<jv>key</jv>, <jv>value</jv>, <jv>flag</jv>, <jv>weight</jv>, <jv>time</jv>) -&gt; {
114    *       <jv>map</jv>.put(<jv>key</jv>, <jv>value</jv>);
115    *       <jk>if</jk> (<jv>flag</jv>) <jv>cache</jv>.invalidate(<jv>key</jv>);
116    *       <jv>stats</jv>.record(<jv>weight</jv>, <jv>time</jv>);
117    *    };
118    *    <jv>handler</jv>.apply(<js>"user"</js>, 12345, <jk>true</jk>, 1.5, 9876543210L);
119    * </p>
120    *
121    * @param a The first operation argument.
122    * @param b The second operation argument.
123    * @param c The third operation argument.
124    * @param d The fourth operation argument.
125    * @param e The fifth operation argument.
126    */
127   void apply(A a, B b, C c, D d, E e);
128}