blob: f6fdf19aced74411e67626af51b38a504243253c [file] [log] [blame]
/*
* Copyright (c) 2023 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.matter.controller.commands.common
import java.util.Arrays
import java.util.HashMap
import java.util.logging.Level
import java.util.logging.Logger
import kotlin.collections.MutableMap
class CommandManager {
private val clusters: MutableMap<String, List<Command>> = HashMap()
fun register(clusterName: String, commandsList: List<Command>) {
clusters[clusterName] = commandsList
}
@Throws(Exception::class)
fun run(args: Array<String>) {
val command: Command?
if (args.size < 1) {
logger.log(Level.INFO, "Missing cluster name")
showClusters()
return
}
val commands = clusters[args[0]]
if (commands == null) {
logger.log(Level.INFO, "Unknown cluster: " + args[0])
showClusters()
return
}
if (args.size < 2) {
logger.log(Level.INFO, "Missing command name")
showCluster(args[0], commands)
return
}
if (!isGlobalCommand(args[0])) {
command = getCommand(commands, args[1])
if (command == null) {
System.out.printf("Unknown command: %s", args[1])
showCluster(args[0], commands)
throw IllegalArgumentException()
}
} else if (isEventCommand(args[1])) {
if (args.size < 3) {
logger.log(Level.INFO, "Missing event name")
showClusterEvents(args[0], args[1], commands)
throw IllegalArgumentException()
}
command = getGlobalCommand(commands, args[1], args[2])
if (command == null) {
logger.log(Level.INFO, "Unknown event: " + args[2])
showClusterEvents(args[0], args[1], commands)
throw IllegalArgumentException()
}
} else {
if (args.size < 3) {
logger.log(Level.INFO, "Missing attribute name")
showClusterAttributes(args[0], args[1], commands)
throw IllegalArgumentException()
}
command = getGlobalCommand(commands, args[1], args[2])
if (command == null) {
logger.log(Level.INFO, "Unknown attribute: " + args[2])
showClusterAttributes(args[0], args[1], commands)
throw IllegalArgumentException()
}
}
// need skip over binary and command name and only get arguments
val temp = Arrays.copyOfRange(args, 2, args.size)
try {
command.initArguments(temp)
} catch (e: IllegalArgumentException) {
logger.log(Level.INFO, "Arguments init failed with exception: " + e.message)
showCommand(args[0], command)
System.exit(1)
}
command.run()
}
private fun isAttributeCommand(commandName: String): Boolean {
return commandName == "read" || commandName == "write" || commandName == "subscribe"
}
private fun isEventCommand(commandName: String): Boolean {
return commandName == "read-event" || commandName == "subscribe-event"
}
private fun isGlobalCommand(commandName: String): Boolean {
return isAttributeCommand(commandName) || isEventCommand(commandName)
}
private fun getCommand(commands: List<Command>, commandName: String): Command? {
for (command in commands) {
if (commandName == command.getName()) {
return command
}
}
return null
}
private fun getGlobalCommand(
commands: List<Command>, commandName: String, attributeName: String
): Command? {
for (command in commands) {
if (commandName == command.getName() && attributeName == command.getAttribute()) {
return command
}
}
return null
}
private fun showClusters() {
logger.log(Level.INFO, "Usage:")
logger.log(
Level.INFO, " java-matter-controller cluster_name command_name [param1 param2 ...]"
)
logger.log(Level.INFO, "\n")
logger.log(
Level.INFO,
" +-------------------------------------------------------------------------------------+"
)
logger.log(
Level.INFO,
" | Clusters: |"
)
logger.log(
Level.INFO,
" +-------------------------------------------------------------------------------------+"
)
for (key in clusters.keys) {
System.out.printf(" | * %-82s|\n", key)
}
logger.log(
Level.INFO,
" +-------------------------------------------------------------------------------------+"
)
}
private fun showCluster(clusterName: String, commands: List<Command>) {
logger.log(Level.INFO, "Usage:")
logger.log(
Level.INFO,
" java-matter-controller $clusterName command_name [param1 param2 ...]"
)
logger.log(Level.INFO, "\n")
logger.log(
Level.INFO,
" +-------------------------------------------------------------------------------------+"
)
logger.log(
Level.INFO,
" | Commands: |"
)
logger.log(
Level.INFO,
" +-------------------------------------------------------------------------------------+"
)
var readCommand = false
var writeCommand = false
var subscribeCommand = false
var readEventCommand = false
var subscribeEventCommand = false
for (command in commands) {
var shouldPrint = true
val cmdName = command.getName()
if (isGlobalCommand(cmdName)) {
if (cmdName == "read" && !readCommand) {
readCommand = true
} else if (cmdName == "write" && !writeCommand) {
writeCommand = true
} else if (cmdName == "subscribe" && !subscribeCommand) {
subscribeCommand = true
} else if (cmdName == "read-event" && !readEventCommand) {
readEventCommand = true
} else if (cmdName == "subscribe-event" && !subscribeEventCommand) {
subscribeEventCommand = true
} else {
shouldPrint = false
}
}
if (shouldPrint) {
System.out.printf(" | * %-82s|\n", cmdName)
}
}
logger.log(
Level.INFO,
" +-------------------------------------------------------------------------------------+\n"
)
}
private fun showClusterAttributes(
clusterName: String, commandName: String, commands: List<Command>
) {
logger.log(Level.INFO, "Usage:")
System.out.printf(
" java-matter-controller %s %s attribute-name [param1 param2 ...]\n",
clusterName, commandName
)
logger.log(Level.INFO, "\n")
logger.log(
Level.INFO,
" +-------------------------------------------------------------------------------------+"
)
logger.log(
Level.INFO,
" | Attributes: |"
)
logger.log(
Level.INFO,
" +-------------------------------------------------------------------------------------+"
)
for (command in commands) {
if (commandName == command.getName()) {
System.out.printf(" | * %-82s|\n", command.getAttribute())
}
}
logger.log(
Level.INFO,
" +-------------------------------------------------------------------------------------+"
)
}
private fun showClusterEvents(
clusterName: String, commandName: String, commands: List<Command>
) {
logger.log(Level.INFO, "Usage:")
System.out.printf(
" java-matter-controller %s %s event-name [param1 param2 ...]\n",
clusterName, commandName
)
logger.log(Level.INFO, "\n")
logger.log(
Level.INFO,
" +-------------------------------------------------------------------------------------+"
)
logger.log(
Level.INFO,
" | Events: |"
)
logger.log(
Level.INFO,
" +-------------------------------------------------------------------------------------+"
)
for (command in commands) {
if (commandName == command.getName()) {
System.out.printf(" | * %-82s|\n", command.getAttribute())
}
}
logger.log(
Level.INFO,
" +-------------------------------------------------------------------------------------+"
)
}
private fun showCommand(clusterName: String, command: Command) {
logger.log(Level.INFO, "Usage:")
var arguments: String? = command.getName()
var description = ""
val argumentsCount = command.getArgumentsCount()
for (i in 0 until argumentsCount) {
var arg = ""
val isOptional = command.getArgumentIsOptional(i)
if (isOptional) {
arg += "[--"
}
arg += command.getArgumentName(i)
if (isOptional) {
arg += "]"
}
arguments += " "
arguments += arg
val argDescription = command.getArgumentDescription(i)
if (argDescription != null) {
description += "\n"
description += arg
description += ":\n "
description += argDescription
description += "\n"
}
}
System.out.format(" java-matter-controller %s %s\n", clusterName, arguments)
val helpText = command.getHelpText()
if (helpText != null) {
System.out.format("\n%s\n", helpText)
}
if (!description.isEmpty()) {
logger.log(Level.INFO, description)
}
}
companion object {
private val logger = Logger.getLogger(CommandManager::class.java.name)
}
}