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    * Returns the name of the command.
107    *
108    * <p>
109    * Example:  <js>"help"</js> for the help command.
110    *
111    * @return
112    *    The name of the command.
113    *    <br>Must not be <jk>null</jk> or contain spaces.
114    */
115   abstract public String getName();
116
117   /**
118    * Returns the usage synopsis of the command.
119    *
120    * <p>
121    * Example:  <js>"help [command ...]"
122    *
123    * <p>
124    * The default implementation just returns the name, which implies the command takes no additional arguments.
125    *
126    * @return The synopsis of the command.
127    */
128   public String getSynopsis() {
129      return getName();
130   }
131
132   /**
133    * Returns a one-line localized description of the command.
134    *
135    * <p>
136    * The locale should be the system locale.
137    *
138    * @return
139    *    The localized description of the command.
140    *    <br>Can be <jk>null</jk> if there is no information.
141    */
142   public String getInfo() {
143      return null;
144   }
145
146   /**
147    * Returns localized details of the command.
148    *
149    * <p>
150    * The locale should be the system locale.
151    *
152    * @return
153    *    The localized details of the command.
154    *    <br>Can be <jk>null</jk> if there is no additional description.
155    */
156   public String getDescription() {
157      return null;
158   }
159
160   /**
161    * Returns localized examples of the command.
162    *
163    * <p>
164    * The locale should be the system locale.
165    *
166    * @return
167    *    The localized examples of the command.
168    *    <br>Can be <jk>null</jk> if there is no examples.
169    */
170   public String getExamples() {
171      return null;
172   }
173
174   /**
175    * Executes a command.
176    * @param in The console reader.
177    * @param out The console writer.
178    * @param args The command arguments.  The first argument is always the command itself.
179    *
180    * @return
181    *    <jk>true</jk> if the console read thread should exit.
182    *    <br>Normally you want to return <jk>true</jk> if your action is causing the microservice to exit or restart.
183    * @throws Exception
184    *    Any thrown exception will simply be sent to STDERR.
185    */
186   abstract public boolean execute(Scanner in, PrintWriter out, Args args) throws Exception;
187}