| /* |
| * 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") |
| showHelpInfo() |
| return |
| } |
| val commands = clusters[args[0]] |
| if (commands == null) { |
| logger.log(Level.INFO, "Unknown cluster: " + args[0]) |
| showHelpInfo() |
| 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.setArgumentValues(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.name) { |
| return command |
| } |
| } |
| return null |
| } |
| |
| private fun getGlobalCommand( |
| commands: List<Command>, |
| commandName: String, |
| attributeName: String |
| ): Command? { |
| for (command in commands) { |
| if (commandName == command.name && attributeName == command.getAttribute()) { |
| return command |
| } |
| } |
| return null |
| } |
| |
| private fun showHelpInfo() { |
| logger.log(Level.INFO, "Usage:") |
| logger.log(Level.INFO, " 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, |
| " kotlin-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.name |
| 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( |
| " kotlin-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.name) { |
| 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( |
| " kotlin-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.name) { |
| 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.name |
| 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(" %s %s\n", clusterName, arguments) |
| val helpText = command.helpText |
| 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) |
| } |
| } |