001/* 002 * ============================================================================ 003 * Copyright © 2002-2026 by Thomas Thrien. 004 * All Rights Reserved. 005 * ============================================================================ 006 * 007 * Licensed to the public under the agreements of the GNU Lesser General Public 008 * License, version 3.0 (the "License"). You may obtain a copy of the License at 009 * 010 * http://www.gnu.org/licenses/lgpl.html 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 014 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 015 * License for the specific language governing permissions and limitations 016 * under the License. 017 */ 018 019package org.tquadrat.foundation.config; 020 021import org.apiguardian.api.API; 022import org.tquadrat.foundation.annotation.ClassVersion; 023 024import java.io.IOException; 025import java.io.OutputStream; 026import java.util.Optional; 027 028import static org.apiguardian.api.API.Status.STABLE; 029 030/** 031 * <p>{@summary When a configuration bean should be initialised from the 032 * command line, the respective specification interface needs to extend this 033 * interface.}</p> 034 * <p>If none of the getters in the extended interface is annotated with 035 * either 036 * {@link Option @Option} 037 * or 038 * {@link Argument @Argument}, 039 * the compilation failed because the generated class does not implement the 040 * methods from this interface 041 * ({@link #dumpParamFileTemplate(OutputStream)}, 042 * {@link #parseCommandLine(String[])}, 043 * {@link #printUsage(OutputStream, CharSequence)} 044 * and 045 * {@link #retrieveParseErrorMessage()}). The error message will be something 046 * like "<Generated Class> is not abstract".</p> 047 * 048 * @extauthor Thomas Thrien - thomas.thrien@tquadrat.org 049 * @version $Id: CLIBeanSpec.java 1164 2026-03-20 17:38:18Z tquadrat $ 050 * @since 0.0.1 051 * 052 * @UMLGraph.link 053 */ 054@ClassVersion( sourceVersion = "$Id: CLIBeanSpec.java 1164 2026-03-20 17:38:18Z tquadrat $" ) 055@API( status = STABLE, since = "0.0.1" ) 056public interface CLIBeanSpec extends ConfigBeanSpec 057{ 058 /*-----------*\ 059 ====** Constants **======================================================== 060 \*-----------*/ 061 /** 062 * The escape character for argument files: {@value}. 063 */ 064 public static final String ARG_FILE_ESCAPE = "@"; 065 066 /** 067 * The lead-in character for an option name: {@value}. 068 */ 069 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 070 public static final String LEAD_IN = "-"; 071 072 /*---------*\ 073 ====** Methods **========================================================== 074 \*---------*/ 075 /** 076 * Dumps a parameter file template to the given 077 * {@link OutputStream}. 078 * 079 * @param outputStream The target output stream. 080 * @throws IOException Something went wrong when writing to the output 081 * stream. 082 * 083 * @see #parseCommandLine(String[]) 084 */ 085 public void dumpParamFileTemplate( final OutputStream outputStream ) throws IOException; 086 087 /** 088 * <p>{@summary Parses the command line.}<br> 089 * <p>As a result from parsing the given command line arguments, the 090 * accordingly annotated properties will be initialised with the values 091 * from the command line.</p> 092 * <p>Arguments starting with <code>@</code> (like 093 * <code>@param.lst</code>) are treated as a file that contains 094 * further arguments.</p> 095 * <p>Assuming the file {@code param.lst} has the following contents:</p> 096 * <blockquote><pre><code>-opt0 097 * value0 098 * -opt1 099 * value1 100 * -- 101 * arg0 102 * arg1</code></pre></blockquote> 103 * <p>and {@code args} looks like this:</p> 104 * <blockquote><pre><code>-opt value @param.lst arg</code></pre></blockquote>, 105 * <p>the resulting command line arguments set would be:</p> 106 * <blockquote><pre><code>-opt value -opt0 value0 -opt1 value1 -- arg0 arg1 arg</code></pre></blockquote> 107 * <p>In case the file could not be opened for whatever reason, the parameter 108 * will not be replaced – meaning the resulting command line would have 109 * the value <code>@param.lst</code> as one value.</p> 110 * 111 * @param args The command line arguments; usually the same as the 112 * arguments to the method {@code main()}. 113 * @return {@code true} if the command line could be parsed without 114 * issues, {@code false} otherwise. 115 */ 116 @SuppressWarnings( {"MethodCanBeVariableArityMethod", "BooleanMethodNameMustStartWithQuestion"} ) 117 public boolean parseCommandLine( final String [] args ); 118 119 /** 120 * Prints a <i>usage</i> message to the given 121 * {@link OutputStream}. 122 * 123 * @param outputStream The output stream. 124 * @param command The command used to start the program. 125 * @throws IOException A problem occurred on writing to the output stream. 126 */ 127 public void printUsage( final OutputStream outputStream, final CharSequence command ) throws IOException; 128 129 /** 130 * Retrieves the message for the error caused by the last call to 131 * {@link #parseCommandLine(String[])}, 132 * given that this return {@code false}. 133 * 134 * @return An instance of 135 * {@link Optional} 136 * that holds the error message. 137 */ 138 public Optional<String> retrieveParseErrorMessage(); 139} 140// interface CLIBeanSpec 141 142/* 143 * End of File 144 */