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.microservice.*;
019import org.apache.juneau.utils.*;
020
021/**
022 * Implements a command that can be invoked from the console of the microservice.
023 *
024 * <p>
025 * Console commands allow you to interact with your microservice through the system console.
026 *
027 * <p>
028 * Console commands are associated with the microservice through the following:
029 * <ul>
030 *    <li>The <js>"Console/commands"</js> configuration value.
031 *       <br>This is a comma-delimited list of fully-qualified names of classes implementing this interface.
032 *       <br>When associated this way, the implementation class must have a no-arg constructor.
033 *    <li>Specifying commands via the {@link MicroserviceBuilder#consoleCommands(Class...)} method.
034 *       <br>This allows you to override the default implementation above and augment or replace the list
035 *          with your own implementation objects.
036 * </ul>
037 *
038 * <p>
039 * For example, the {@link HelpCommand} is used to provide help on other commands.
040 *
041 * <p class='bcode w800'>
042 *    Running class 'JettyMicroservice' using config file 'examples.cfg'.
043 *    Server started on port 10000
044 *
045 *    List of available commands:
046 *       exit -- Shut down service
047 *       restart -- Restarts service
048 *       help -- Commands help
049 *       echo -- Echo command
050 *
051 *    &gt; <span style='color:green'>help help</span>
052 *    NAME
053 *       help -- Commands help
054 *
055 *    SYNOPSIS
056 *       help [command]
057 *
058 *    DESCRIPTION
059 *       When called without arguments, prints the descriptions of all available commands.
060 *       Can also be called with one or more arguments to get detailed information on a command.
061 *
062 *    EXAMPLES
063 *       List all commands:
064 *          &gt; help
065 *
066 *       List help on the help command:
067 *          &gt; help help
068 *
069 *    &gt;
070 * </p>
071 *
072 * <p>
073 * The arguments are available as an {@link Args} object which allows for easy accessed to parsed command lines.
074 * Some simple examples of valid command lines:
075 *
076 * <p class='bcode w800'>
077 *    <jc>// mycommand</jc>
078 *    args.get("0");  <jc>// "mycommand"</jc>
079 *
080 *    <jc>// mycommand arg1 arg2</jc>
081 *    args.get("0");  <jc>// "mycommand"</jc>
082 *    args.get("1");  <jc>// "arg1"</jc>
083 *    args.get("2");  <jc>// "arg2"</jc>
084 *
085 *    <jc>// mycommand -optArg1 foo bar -optArg2 baz qux</jc>
086 *    args.get("0");  <jc>// "mycommand"</jc>
087 *    args.get("optArg1", String[].class);  <jc>// ["foo","bar"]</jc>
088 *    args.get("optArg2", String[].class);  <jc>// ["baz","qux"]</jc>
089 *
090 *    <jc>// mycommand -optArg1 "foo bar" -optArg2 'baz qux'</jc>
091 *    args.get("0");  <jc>// "mycommand"</jc>
092 *    args.get("optArg1", String[].class);  <jc>// ["foo bar"]</jc>
093 *    args.get("optArg2", String[].class);  <jc>// ["baz qux"]</jc>
094 * </p>
095 */
096public abstract class ConsoleCommand {
097
098   /**
099    * Returns the name of the command.
100    *
101    * <p>
102    * Example:  <js>"help"</js> for the help command.
103    *
104    * @return
105    *    The name of the command.
106    *    <br>Must not be <jk>null</jk> or contain spaces.
107    */
108   abstract public String getName();
109
110   /**
111    * Returns the usage synopsis of the command.
112    *
113    * <p>
114    * Example:  <js>"help [command ...]"
115    *
116    * <p>
117    * The default implementation just returns the name, which implies the command takes no additional arguments.
118    *
119    * @return The synopsis of the command.
120    */
121   public String getSynopsis() {
122      return getName();
123   }
124
125   /**
126    * Returns a one-line localized description of the command.
127    *
128    * <p>
129    * The locale should be the system locale.
130    *
131    * @return
132    *    The localized description of the command.
133    *    <br>Can be <jk>null</jk> if there is no information.
134    */
135   public String getInfo() {
136      return null;
137   }
138
139   /**
140    * Returns localized details of the command.
141    *
142    * <p>
143    * The locale should be the system locale.
144    *
145    * @return
146    *    The localized details of the command.
147    *    <br>Can be <jk>null</jk> if there is no additional description.
148    */
149   public String getDescription() {
150      return null;
151   }
152
153   /**
154    * Returns localized examples of the command.
155    *
156    * <p>
157    * The locale should be the system locale.
158    *
159    * @return
160    *    The localized examples of the command.
161    *    <br>Can be <jk>null</jk> if there is no examples.
162    */
163   public String getExamples() {
164      return null;
165   }
166
167   /**
168    * Executes a command.
169    * @param in The console reader.
170    * @param out The console writer.
171    * @param args The command arguments.  The first argument is always the command itself.
172    *
173    * @return
174    *    <jk>true</jk> if the console read thread should exit.
175    *    <br>Normally you want to return <jk>true</jk> if your action is causing the microservice to exit or restart.
176    * @throws Exception
177    *    Any thrown exception will simply be sent to STDERR.
178    */
179   abstract public boolean execute(Scanner in, PrintWriter out, Args args) throws Exception;
180}