001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.microservice.console;
014
015import java.io.*;
016import java.util.*;
017
018import org.apache.juneau.collections.*;
019
020/**
021 * Implements a command that can be invoked from the console of the microservice.
022 *
023 * <p>
024 * Console commands allow you to interact with your microservice through the system console.
025 *
026 * <p>
027 * Console commands are associated with the microservice through the following:
028 * <ul>
029 *    <li>The <js>"Console/commands"</js> configuration value.
030 *       <br>This is a comma-delimited list of fully-qualified names of classes implementing this interface.
031 *       <br>When associated this way, the implementation class must have a no-arg constructor.
032 *    <li>Specifying commands via the {@link org.apache.juneau.microservice.Microservice.Builder#consoleCommands(Class...)} method.
033 *       <br>This allows you to override the default implementation above and augment or replace the list
034 *          with your own implementation objects.
035 * </ul>
036 *
037 * <p>
038 * For example, the {@link HelpCommand} is used to provide help on other commands.
039 *
040 * <p class='bconsole'>
041 *    Running class 'JettyMicroservice' using config file 'examples.cfg'.
042 *    Server started on port 10000
043 *
044 *    List of available commands:
045 *       exit -- Shut down service
046 *       restart -- Restarts service
047 *       help -- Commands help
048 *       echo -- Echo command
049 *
050 *    &gt; <span style='color:green'>help help</span>
051 *    NAME
052 *       help -- Commands help
053 *
054 *    SYNOPSIS
055 *       help [command]
056 *
057 *    DESCRIPTION
058 *       When called without arguments, prints the descriptions of all available commands.
059 *       Can also be called with one or more arguments to get detailed information on a command.
060 *
061 *    EXAMPLES
062 *       List all commands:
063 *          &gt; help
064 *
065 *       List help on the help command:
066 *          &gt; help help
067 *
068 *    &gt;
069 * </p>
070 *
071 * <p>
072 * The arguments are available as an {@link Args} object which allows for easy accessed to parsed command lines.
073 * Some simple examples of valid command lines:
074 *
075 * <p class='bjava'>
076 *    <jc>// mycommand</jc>
077 *    <jv>args</jv>.get(<js>"0"</js>);  <jc>// "mycommand"</jc>
078 *
079 *    <jc>// mycommand arg1 arg2</jc>
080 *    <jv>args</jv>.get(<js>"0"</js>);  <jc>// "mycommand"</jc>
081 *    <jv>args</jv>.get(<js>"1"</js>);  <jc>// "arg1"</jc>
082 *    <jv>args</jv>.get(<js>"2"</js>);  <jc>// "arg2"</jc>
083 *
084 *    <jc>// mycommand -optArg1 foo bar -optArg2 baz qux</jc>
085 *    <jv>args</jv>.get(<js>"0"</js>);  <jc>// "mycommand"</jc>
086 *    <jv>args</jv>.get(<js>"optArg1"</js>, String[].<jk>class</jk>);  <jc>// ["foo","bar"]</jc>
087 *    <jv>args</jv>.get(<js>"optArg2"</js>, String[].<jk>class</jk>);  <jc>// ["baz","qux"]</jc>
088 *
089 *    <jc>// mycommand -optArg1 "foo bar" -optArg2 'baz qux'</jc>
090 *    <jv>args</jv>.get(<js>"0"</js>);  <jc>// "mycommand"</jc>
091 *    <jv>args</jv>.get(<js>"optArg1"</js>, String[].<jk>class</jk>);  <jc>// ["foo bar"]</jc>
092 *    <jv>args</jv>.get(<js>"optArg2"</js>, String[].<jk>class</jk>);  <jc>// ["baz qux"]</jc>
093 * </p>
094 *
095 * <h5 class='section'>See Also:</h5><ul>
096 *    <li class='link'><a class="doclink" href="../../../../../index.html#juneau-microservice-core">juneau-microservice-core</a>
097 * </ul>
098 */
099public abstract class ConsoleCommand {
100
101   /**
102    * Returns the name of the command.
103    *
104    * <p>
105    * Example:  <js>"help"</js> for the help command.
106    *
107    * @return
108    *    The name of the command.
109    *    <br>Must not be <jk>null</jk> or contain spaces.
110    */
111   abstract public String getName();
112
113   /**
114    * Returns the usage synopsis of the command.
115    *
116    * <p>
117    * Example:  <js>"help [command ...]"
118    *
119    * <p>
120    * The default implementation just returns the name, which implies the command takes no additional arguments.
121    *
122    * @return The synopsis of the command.
123    */
124   public String getSynopsis() {
125      return getName();
126   }
127
128   /**
129    * Returns a one-line localized description of the command.
130    *
131    * <p>
132    * The locale should be the system locale.
133    *
134    * @return
135    *    The localized description of the command.
136    *    <br>Can be <jk>null</jk> if there is no information.
137    */
138   public String getInfo() {
139      return null;
140   }
141
142   /**
143    * Returns localized details of the command.
144    *
145    * <p>
146    * The locale should be the system locale.
147    *
148    * @return
149    *    The localized details of the command.
150    *    <br>Can be <jk>null</jk> if there is no additional description.
151    */
152   public String getDescription() {
153      return null;
154   }
155
156   /**
157    * Returns localized examples of the command.
158    *
159    * <p>
160    * The locale should be the system locale.
161    *
162    * @return
163    *    The localized examples of the command.
164    *    <br>Can be <jk>null</jk> if there is no examples.
165    */
166   public String getExamples() {
167      return null;
168   }
169
170   /**
171    * Executes a command.
172    * @param in The console reader.
173    * @param out The console writer.
174    * @param args The command arguments.  The first argument is always the command itself.
175    *
176    * @return
177    *    <jk>true</jk> if the console read thread should exit.
178    *    <br>Normally you want to return <jk>true</jk> if your action is causing the microservice to exit or restart.
179    * @throws Exception
180    *    Any thrown exception will simply be sent to STDERR.
181    */
182   abstract public boolean execute(Scanner in, PrintWriter out, Args args) throws Exception;
183}