001/*
002 * ============================================================================
003 * Copyright © 2002-2023 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 static java.lang.annotation.ElementType.METHOD;
022import static java.lang.annotation.RetentionPolicy.CLASS;
023import static org.apiguardian.api.API.Status.STABLE;
024
025import java.lang.annotation.Documented;
026import java.lang.annotation.Retention;
027import java.lang.annotation.Target;
028import java.util.MissingResourceException;
029import java.util.ResourceBundle;
030
031import org.apiguardian.api.API;
032import org.tquadrat.foundation.annotation.ClassVersion;
033import org.tquadrat.foundation.config.cli.CmdLineValueHandler;
034import org.tquadrat.foundation.config.cli.DateValueHandler;
035
036/**
037 *  <p>{@summary This annotation is used in the context of a configuration bean
038 *  specification to mark a property that receives the value of a command line
039 *  argument.} It will be placed to the getter for the property.</p>
040 *  <p>A command line argument will be identified by its relative position on
041 *  the parameter list, after any
042 *  {@linkplain Option command line options}.
043 *  Therefore it has an index, where an option has a name.</p>
044 *
045 *  @extauthor Thomas Thrien - thomas.thrien@tquadrat.org
046 *  @thanks Kohsuke Kawaguchi - kk@kohsuke.org
047 *  @thanks Mark Sinke
048 *  @version $Id: Argument.java 1061 2023-09-25 16:32:43Z tquadrat $
049 *  @since 0.0.1
050 *
051 *  @UMLGraph.link
052 */
053@ClassVersion( sourceVersion = "$Id: Argument.java 1061 2023-09-25 16:32:43Z tquadrat $" )
054@Documented
055@Retention( CLASS )
056@Target( METHOD )
057@API( status = STABLE, since = "0.0.1" )
058public @interface Argument
059{
060        /*------------*\
061    ====** Attributes **=======================================================
062        \*------------*/
063    /**
064     *  <p>{@summary Some value handlers (like the
065     *  {@link DateValueHandler DateValueHandler})
066     *  use this field for additional validation information, like a format
067     *  String.} It is ignored by most others.</p>
068     *  <p>Refer to the documentation of those value handlers for the exact
069     *  contents specification.</p>
070     *
071     *  @return The extended format specification according to the option
072     *      handler, or the empty String.
073     */
074    String format() default "";
075
076    /**
077     *  <p>{@summary Specifies the
078     *  {@linkplain CmdLineValueHandler command line value handler}
079     *  that translates the command line argument value to the type of the
080     *  target property and places that value to the property.}</p>
081     *  <p>The default value {@code CmdLineValueHandler.class} indicates that
082     *  the effective {@code CmdLineValueHandler} implementation will be
083     *  inferred from the type of the annotated property.</p>
084     *  <p>If it is set to a class that extends
085     *  {@link CmdLineValueHandler},
086     *  an instance of that class will be created (therefore it has to provide
087     *  a constructor with the signature
088     *  {@code &lt;<i>Constructor</i>&gt;(CLIDefinition, BiConsumer)})
089     *  that is used as the handler. This is convenient for defining a
090     *  non-standard option parsing semantics.</p>
091     *  <p><b>Example</b></p>
092     *  <pre><code>
093     *  // this is a normal &quot;-r&quot; option
094     *  &#064;Option()
095     *  boolean getFlag();
096     *
097     *  // This causes that MyHandler is used instead of the default handler
098     *  // provided for boolean
099     *  &#064;Option( handler = MyHandler.class )
100     *  boolean getYesNo();</code></pre>
101     *
102     *  @return The {@code CmdLineValueHandler} implementation.
103     */
104    public Class<?> handler() default CmdLineValueHandler.class;
105
106    /**
107     *  A command line argument is identified by its relative position on the
108     *  command line, instead by a name. The first position has the index 0,
109     *  the second is 1 and so on.
110     *
111     *  @return The index for the argument.
112     */
113    int index();
114
115    /**
116     *  <p>{@summary A name for the argument that is used in messages.}</p>
117     *  <p>If left unspecified, that name is inferred from the name of the
118     *  configuration property itself.</p>
119     *
120     *  @return A meta variable string.
121     */
122    String metaVar() default "";
123
124    /**
125     *  A flag that indicates whether the argument is multivalued, for
126     *  mappings to a
127     *  {@link java.util.Collection Collection}.
128     *  As this will consume all remaining arguments from the command line,
129     *  the annotated property has to be the last argument.
130     *
131     *  @return {@code true} if the argument is multivalued,
132     *      {@code false} otherwise.
133     */
134    boolean multiValued() default false;
135
136    /**
137     *  A flag that specifies whether this argument is mandatory. This implies
138     *  that all previous arguments (those with lower indexes) are mandatory as
139     *  well.
140     *
141     *  @return {@code true} if the argument is mandatory,
142     *      {@code false} otherwise.
143     */
144    boolean required() default false;
145
146    /**
147     *  <p>{@summary A help text that will be displayed in the usage output if
148     *  {@link ConfigBeanSpec#getResourceBundle() ConfigBeanSpec.getResourceBundle()}
149     *  returns no
150     *  {@link ResourceBundle ResourceBundle}
151     *  instance or the call to
152     *  {@link ResourceBundle#getString(String) getString()}
153     *  with the value of
154     *  {@link #usageKey()}
155     *  on the retrieved resources throws a
156     *  {@link MissingResourceException}.}</p>
157     *  <p>The default is the empty String.</p>
158     *
159     *  @return The usage help text.
160     */
161    String usage() default "";
162
163    /**
164     *  <p>{@summary The
165     *  {@linkplain ResourceBundle#getString(String) resource bundle key}
166     *  for a help text that will be displayed in the usage output.}</p>
167     *  <p>If not specified, the value will be derived from the name of the
168     *  property like this:</p>
169     *  <pre><code>  USAGE_&lt;<i>PropertyName</i>&gt;</code></pre>
170     *  <p>The text will be retrieved from the
171     *  {@link java.util.ResourceBundle ResourceBundle}
172     *  that is returned from
173     *  {@link org.tquadrat.foundation.config.ConfigBeanSpec#getResourceBundle() ConfigBeanSpec.getResourceBundle()};
174     *  if that is {@code null} the value of
175     *  {@link #usage()}
176     *  is taken instead.</p>
177     *  <p>This allows to localise the usage output.</p>
178     *
179     *  @return The resource bundle key for the usage text.
180     *
181     *  @see org.tquadrat.foundation.config.spi.CLIDefinition#USAGE_KEY_FORMAT
182     */
183    String usageKey() default "";
184}
185//  annotation Argument
186
187/*
188 *  End of File
189 */