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