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 019/** 020 * A functional interface identical to {@link Runnable} but allows the {@link #run()} method to throw checked exceptions. 021 * 022 * <p> 023 * This interface is useful when you need to pass arbitrary code snippets to methods that expect a {@link Runnable}, 024 * but your code may throw checked exceptions. Unlike {@link Runnable}, the {@link #run()} method can throw any 025 * {@link Throwable}, making it suitable for exception testing and fluent API patterns. 026 * 027 * <h5 class='section'>Features:</h5> 028 * <ul class='spaced-list'> 029 * <li>Functional interface - can be used with lambda expressions and method references 030 * <li>Exception support - allows checked exceptions to be thrown 031 * <li>Fluent API friendly - enables passing code snippets in method chains 032 * <li>Testing support - useful for exception testing scenarios 033 * </ul> 034 * 035 * <h5 class='section'>Use Cases:</h5> 036 * <ul class='spaced-list'> 037 * <li>Exception testing - verifying that code throws expected exceptions 038 * <li>Fluent interfaces - passing code snippets to builder methods 039 * <li>Conditional execution - wrapping code that may throw exceptions 040 * <li>Error handling - passing error-prone code to handlers 041 * </ul> 042 * 043 * <h5 class='section'>Usage:</h5> 044 * <p class='bjava'> 045 * <jc>// Exception testing</jc> 046 * Snippet <jv>code</jv> = () -> { 047 * <jk>throw new</jk> IllegalArgumentException(<js>"Expected error"</js>); 048 * }; 049 * <jsm>assertThrown</jsm>(IllegalArgumentException.<jk>class</jk>, <jv>code</jv>); 050 * 051 * <jc>// Fluent API usage</jc> 052 * <jv>builder</jv> 053 * .setValue(<js>"test"</js>) 054 * .onError(() -> { 055 * <jk>throw new</jk> ValidationException(<js>"Invalid value"</js>); 056 * }) 057 * .build(); 058 * 059 * <jc>// Conditional execution with exceptions</jc> 060 * <jk>if</jk> (<jv>shouldExecute</jv>) { 061 * <jv>executeSafely</jv>(() -> { 062 * <jk>throw new</jk> IOException(<js>"File not found"</js>); 063 * }); 064 * } 065 * </p> 066 * 067 * <h5 class='section'>Comparison with Runnable:</h5> 068 * <ul class='spaced-list'> 069 * <li><b>Runnable:</b> Cannot throw checked exceptions (must catch and wrap) 070 * <li><b>Snippet:</b> Can throw any {@link Throwable} (checked or unchecked) 071 * <li><b>Runnable:</b> Used for standard Java concurrency patterns 072 * <li><b>Snippet:</b> Used for exception testing and fluent APIs 073 * </ul> 074 * 075 * <h5 class='section'>See Also:</h5><ul> 076 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauEcosystemOverview">Juneau Ecosystem Overview</a> 077 * </ul> 078 */ 079public interface Snippet { 080 081 /** 082 * Executes arbitrary code and optionally throws an exception. 083 * 084 * <p> 085 * This method is the functional method of this interface. It can throw any {@link Throwable}, 086 * including checked exceptions, which distinguishes it from {@link Runnable#run()}. 087 * 088 * <h5 class='section'>Example:</h5> 089 * <p class='bjava'> 090 * Snippet <jv>snippet</jv> = () -> { 091 * <jc>// Code that may throw exceptions</jc> 092 * <jk>if</jk> (<jv>invalid</jv>) { 093 * <jk>throw new</jk> IllegalArgumentException(<js>"Invalid state"</js>); 094 * } 095 * }; 096 * 097 * <jv>snippet</jv>.run(); <jc>// May throw IllegalArgumentException</jc> 098 * </p> 099 * 100 * @throws Throwable Any throwable (checked or unchecked). 101 */ 102 void run() throws Throwable; 103}