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 &#x0040;Option}
037 *  or
038 *  {@link Argument &#x0040;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 &quot;&lt;Generated Class&gt; is not abstract&quot;.</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>&#64;</code> (like
093     *  <code>&#64;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 &#64;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>&#64;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 */