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 * > <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 * > help 068 * 069 * List help on the help command: 070 * > help help 071 * 072 * > 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}