From 3847784c2216884eb1cbff84ea64609ebf41e212 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Thu, 9 Mar 2023 09:32:26 -0800 Subject: [PATCH] [java-matter-controller] Convert Java to Kotlin Phase III (#25578) * [java-matter-controller] Convert Java to Kotlin Phase III * Address review comments --- examples/java-matter-controller/BUILD.gn | 14 +- .../controller/commands/common/Argument.java | 164 --------- .../controller/commands/common/Argument.kt | 157 +++++++++ .../{ArgumentType.java => ArgumentType.kt} | 11 +- .../controller/commands/common/Command.java | 269 --------------- .../controller/commands/common/Command.kt | 256 +++++++++++++++ .../commands/common/CommandManager.java | 308 ----------------- .../commands/common/CommandManager.kt | 310 ++++++++++++++++++ ...ntialsIssuer.java => CredentialsIssuer.kt} | 9 +- .../controller/commands/common/IPAddress.java | 24 -- .../controller/commands/common/IPAddress.kt | 34 ++ .../commands/common/MatterCommand.java | 121 ------- .../commands/common/MatterCommand.kt | 116 +++++++ .../commands/discover/DiscoverCommand.kt | 2 +- .../DiscoverCommissionablesCommand.kt | 2 +- .../discover/DiscoverCommissionersCommand.kt | 2 +- .../commands/pairing/CloseSessionCommand.kt | 2 +- .../PairOnNetworkLongImWriteCommand.kt | 1 - .../commands/pairing/PairingCommand.kt | 4 +- 19 files changed, 895 insertions(+), 911 deletions(-) delete mode 100644 examples/java-matter-controller/java/src/com/matter/controller/commands/common/Argument.java create mode 100644 examples/java-matter-controller/java/src/com/matter/controller/commands/common/Argument.kt rename examples/java-matter-controller/java/src/com/matter/controller/commands/common/{ArgumentType.java => ArgumentType.kt} (85%) delete mode 100644 examples/java-matter-controller/java/src/com/matter/controller/commands/common/Command.java create mode 100644 examples/java-matter-controller/java/src/com/matter/controller/commands/common/Command.kt delete mode 100644 examples/java-matter-controller/java/src/com/matter/controller/commands/common/CommandManager.java create mode 100644 examples/java-matter-controller/java/src/com/matter/controller/commands/common/CommandManager.kt rename examples/java-matter-controller/java/src/com/matter/controller/commands/common/{CredentialsIssuer.java => CredentialsIssuer.kt} (78%) delete mode 100644 examples/java-matter-controller/java/src/com/matter/controller/commands/common/IPAddress.java create mode 100644 examples/java-matter-controller/java/src/com/matter/controller/commands/common/IPAddress.kt delete mode 100644 examples/java-matter-controller/java/src/com/matter/controller/commands/common/MatterCommand.java create mode 100644 examples/java-matter-controller/java/src/com/matter/controller/commands/common/MatterCommand.kt diff --git a/examples/java-matter-controller/BUILD.gn b/examples/java-matter-controller/BUILD.gn index 76eb438d5377a2..7724d5fcd80516 100644 --- a/examples/java-matter-controller/BUILD.gn +++ b/examples/java-matter-controller/BUILD.gn @@ -27,14 +27,7 @@ java_library("java") { ] sources = [ - "java/src/com/matter/controller/commands/common/Argument.java", - "java/src/com/matter/controller/commands/common/ArgumentType.java", - "java/src/com/matter/controller/commands/common/Command.java", - "java/src/com/matter/controller/commands/common/CommandManager.java", - "java/src/com/matter/controller/commands/common/CredentialsIssuer.java", "java/src/com/matter/controller/commands/common/FutureResult.java", - "java/src/com/matter/controller/commands/common/IPAddress.java", - "java/src/com/matter/controller/commands/common/MatterCommand.java", "java/src/com/matter/controller/commands/common/RealResult.java", ] @@ -50,6 +43,13 @@ kotlin_binary("java-matter-controller") { sources = [ "java/src/com/matter/controller/Main.kt", + "java/src/com/matter/controller/commands/common/Argument.kt", + "java/src/com/matter/controller/commands/common/ArgumentType.kt", + "java/src/com/matter/controller/commands/common/Command.kt", + "java/src/com/matter/controller/commands/common/CommandManager.kt", + "java/src/com/matter/controller/commands/common/CredentialsIssuer.kt", + "java/src/com/matter/controller/commands/common/IPAddress.kt", + "java/src/com/matter/controller/commands/common/MatterCommand.kt", "java/src/com/matter/controller/commands/discover/DiscoverCommand.kt", "java/src/com/matter/controller/commands/discover/DiscoverCommissionablesCommand.kt", "java/src/com/matter/controller/commands/discover/DiscoverCommissionersCommand.kt", diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/Argument.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/Argument.java deleted file mode 100644 index 746ae78f4d3dfe..00000000000000 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/Argument.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2022 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.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import javax.annotation.Nullable; - -public final class Argument { - private final String mName; - private final ArgumentType mType; - private final long mMin; - private final long mMax; - private final Object mValue; - private final Optional mDesc; - private final boolean mOptional; - - boolean isOptional() { - return mOptional; - } - - public Argument(String name, IPAddress value, boolean optional) { - this.mName = name; - this.mType = ArgumentType.ADDRESS; - this.mMin = 0; - this.mMax = 0; - this.mValue = value; - this.mDesc = Optional.empty(); - this.mOptional = optional; - } - - public Argument(String name, StringBuffer value, @Nullable String desc, boolean optional) { - this.mName = name; - this.mType = ArgumentType.STRING; - this.mMin = 0; - this.mMax = 0; - this.mValue = value; - this.mDesc = Optional.ofNullable(desc); - this.mOptional = optional; - } - - public Argument(String name, AtomicBoolean value, @Nullable String desc, boolean optional) { - this.mName = name; - this.mType = ArgumentType.BOOL; - this.mMin = 0; - this.mMax = 0; - this.mValue = value; - this.mDesc = Optional.ofNullable(desc); - this.mOptional = optional; - } - - public Argument( - String name, - short min, - short max, - AtomicInteger value, - @Nullable String desc, - boolean optional) { - this.mName = name; - this.mType = ArgumentType.NUMBER_INT16; - this.mMin = min; - this.mMax = max; - this.mValue = value; - this.mDesc = Optional.ofNullable(desc); - this.mOptional = optional; - } - - public Argument( - String name, int min, int max, AtomicInteger value, @Nullable String desc, boolean optional) { - this.mName = name; - this.mType = ArgumentType.NUMBER_INT32; - this.mMin = min; - this.mMax = max; - this.mValue = value; - this.mDesc = Optional.ofNullable(desc); - this.mOptional = optional; - } - - public Argument( - String name, long min, long max, AtomicLong value, @Nullable String desc, boolean optional) { - this.mName = name; - this.mType = ArgumentType.NUMBER_INT64; - this.mMin = min; - this.mMax = max; - this.mValue = value; - this.mDesc = Optional.ofNullable(desc); - this.mOptional = optional; - } - - public String getName() { - return mName; - } - - public ArgumentType getType() { - return mType; - } - - public Object getValue() { - return mValue; - } - - public Optional getDesc() { - return mDesc; - } - - public void setValue(String value) { - boolean isValidArgument = false; - - switch (mType) { - case ATTRIBUTE: - String str = (String) mValue; - isValidArgument = value.equals(str); - break; - case NUMBER_INT16: - AtomicInteger numShort = (AtomicInteger) mValue; - numShort.set(Integer.parseInt(value)); - isValidArgument = (numShort.intValue() >= mMin && numShort.intValue() <= mMax); - break; - case NUMBER_INT32: - AtomicInteger num = (AtomicInteger) mValue; - num.set(Integer.parseInt(value)); - isValidArgument = (num.intValue() >= mMin && num.intValue() <= mMax); - break; - case NUMBER_INT64: - AtomicLong numLong = (AtomicLong) mValue; - numLong.set(Long.parseLong(value)); - isValidArgument = (numLong.intValue() >= mMin && numLong.intValue() <= mMax); - break; - case ADDRESS: - try { - IPAddress ipAddress = (IPAddress) mValue; - ipAddress.setAddress(InetAddress.getByName(value)); - isValidArgument = true; - } catch (UnknownHostException e) { - isValidArgument = false; - } - break; - } - - if (!isValidArgument) { - throw new IllegalArgumentException("Invalid argument " + mName + ": " + value); - } - } -} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/Argument.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/Argument.kt new file mode 100644 index 00000000000000..76e633a82a144a --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/Argument.kt @@ -0,0 +1,157 @@ +/* + * 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.net.InetAddress +import java.net.UnknownHostException +import java.util.concurrent.atomic.AtomicBoolean +import java.util.concurrent.atomic.AtomicInteger +import java.util.concurrent.atomic.AtomicLong + +class Argument { + val name: String + val type: ArgumentType + private val minValue: Long + private val maxValue: Long + val value: Any + val desc: String? + val isOptional: Boolean + + constructor(name: String, value: IPAddress, optional: Boolean) { + this.name = name + type = ArgumentType.ADDRESS + minValue = 0 + maxValue = 0 + this.value = value + desc = null + isOptional = optional + } + + constructor(name: String, value: StringBuffer, desc: String?, optional: Boolean) { + this.name = name + type = ArgumentType.STRING + minValue = 0 + maxValue = 0 + this.value = value + this.desc = desc + isOptional = optional + } + + constructor(name: String, value: AtomicBoolean, desc: String?, optional: Boolean) { + this.name = name + type = ArgumentType.BOOL + minValue = 0 + maxValue = 0 + this.value = value + this.desc = desc + isOptional = optional + } + + constructor( + name: String, + min: Short, + max: Short, + value: AtomicInteger, + desc: String?, + optional: Boolean + ) { + this.name = name + type = ArgumentType.NUMBER_INT16 + minValue = min.toLong() + maxValue = max.toLong() + this.value = value + this.desc = desc + isOptional = optional + } + + constructor( + name: String, min: Int, max: Int, value: AtomicInteger, desc: String?, optional: Boolean + ) { + this.name = name + type = ArgumentType.NUMBER_INT32 + minValue = min.toLong() + maxValue = max.toLong() + this.value = value + this.desc = desc + isOptional = optional + } + + constructor( + name: String, min: Short, max: Short, value: AtomicLong, desc: String?, optional: Boolean + ) { + this.name = name + type = ArgumentType.NUMBER_INT32 + minValue = min.toLong() + maxValue = max.toLong() + this.value = value + this.desc = desc + isOptional = optional + } + + constructor( + name: String, min: Long, max: Long, value: AtomicLong, desc: String?, optional: Boolean + ) { + this.name = name + type = ArgumentType.NUMBER_INT64 + minValue = min + maxValue = max + this.value = value + this.desc = desc + isOptional = optional + } + + fun setValue(value: String) { + var isValidArgument = false + when (type) { + ArgumentType.ATTRIBUTE -> { + val str = this.value as String + isValidArgument = value == str + } + + ArgumentType.NUMBER_INT16 -> { + val numShort = this.value as AtomicInteger + numShort.set(value.toInt()) + isValidArgument = numShort.toInt() >= minValue && numShort.toInt() <= maxValue + } + + ArgumentType.NUMBER_INT32 -> { + val num = this.value as AtomicInteger + num.set(value.toInt()) + isValidArgument = num.toInt() >= minValue && num.toInt() <= maxValue + } + + ArgumentType.NUMBER_INT64 -> { + val numLong = this.value as AtomicLong + numLong.set(value.toLong()) + isValidArgument = numLong.toInt() >= minValue && numLong.toInt() <= maxValue + } + + ArgumentType.ADDRESS -> isValidArgument = try { + val ipAddress = this.value as IPAddress + ipAddress.setAddress(InetAddress.getByName(value)) + true + } catch (e: UnknownHostException) { + false + } + + else -> { + } + } + require(isValidArgument) { "Invalid argument " + name + ": " + value } + } +} \ No newline at end of file diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/ArgumentType.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/ArgumentType.kt similarity index 85% rename from examples/java-matter-controller/java/src/com/matter/controller/commands/common/ArgumentType.java rename to examples/java-matter-controller/java/src/com/matter/controller/commands/common/ArgumentType.kt index e3ecccc923d1dc..900465c98eb61b 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/ArgumentType.java +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/ArgumentType.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Project CHIP Authors + * Copyright (c) 2023 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,10 +15,9 @@ * limitations under the License. * */ +package com.matter.controller.commands.common -package com.matter.controller.commands.common; - -public enum ArgumentType { +enum class ArgumentType { NUMBER_INT8, NUMBER_INT16, NUMBER_INT32, @@ -36,5 +35,5 @@ public enum ArgumentType { VECTOR_BOOL, VECTOR16, VECTOR32, - VECTOR_CUSTOM, -} + VECTOR_CUSTOM +} \ No newline at end of file diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/Command.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/Command.java deleted file mode 100644 index cca9fc6c384918..00000000000000 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/Command.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (c) 2022 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.ArrayList; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import javax.annotation.Nullable; - -/** - * @brief Matter Controller command - * @details The base class of all the commands the Matter Controller supports, which are actions - * that may be performed. Commands are verb-like, such as pair a Matter device or discover - * Matter devices from the environment. - */ -public abstract class Command { - private static final String OPTIONAL_ARGUMENT_PREFIX = "--"; - private static final int OPTIONAL_ARGUMENT_PREFIX_LENGTH = 2; - private final String mName; - private final ArrayList mArgs = new ArrayList(); - private final Optional mHelpText; - - public Command(String commandName) { - this.mName = commandName; - this.mHelpText = Optional.empty(); - } - - public Command(String commandName, @Nullable String helpText) { - this.mName = commandName; - this.mHelpText = Optional.ofNullable(helpText); - } - - public final String getName() { - return mName; - } - - public final Optional getHelpText() { - return mHelpText; - } - - /** - * @brief Get attribute argument if it exists, there is at most one Attribute argument per command - * @return A pointer to an Optional where the Attribute argument will be stored - */ - public final Optional getAttribute() { - return mArgs - .stream() - .filter(arg -> arg.getType() == ArgumentType.ATTRIBUTE) - .findFirst() - .map(arg -> (String) arg.getValue()); - } - - public final String getArgumentName(int index) { - return mArgs.get(index).getName(); - } - - public final int getArgumentsCount() { - return mArgs.size(); - } - - public final boolean getArgumentIsOptional(int index) { - return mArgs.get(index).isOptional(); - } - - /** - * @brief Get argument description if it exists - * @return A pointer to an Optional where the argument description will be stored - */ - public final Optional getArgumentDescription(int index) { - return mArgs.get(index).getDesc(); - } - - public final void addArgumentToList(Argument arg, boolean optional) { - if (arg.isOptional() || mArgs.isEmpty()) { - // Safe to just append to the end of a list. - mArgs.add(arg); - return; - } - - // mandatory arg needs to be inserted before the optional arguments. - int index = 0; - while (index < mArgs.size() && !mArgs.get(index).isOptional()) { - index++; - } - - // Insert before the first optional arg. - mArgs.add(index, arg); - } - - /** - * @brief Add a bool command argument - * @param name The name that will be displayed in the command help - * @param out A pointer to a MutableInteger where the argv value will be stored - * @param desc The description of the argument that will be displayed in the command help - * @param optional Indicate if an optional argument - * @return The number of arguments currently added to the command - */ - public final void addArgument( - String name, AtomicBoolean out, @Nullable String desc, boolean optional) { - Argument arg = new Argument(name, out, desc, optional); - addArgumentToList(arg, optional); - } - - /** - * @brief Add a short command argument - * @param name The name that will be displayed in the command help - * @param min The minimum value of the argv value - * @param max The minimum value of the argv value - * @param out A pointer to a MutableInteger where the argv value will be stored - * @param desc The description of the argument that will be displayed in the command help - * @param optional Indicate if an optional argument - * @return The number of arguments currently added to the command - */ - public final void addArgument( - String name, - short min, - short max, - AtomicInteger out, - @Nullable String desc, - boolean optional) { - Argument arg = new Argument(name, min, max, out, desc, optional); - addArgumentToList(arg, optional); - } - - /** - * @brief Add an int command argument - * @param name The name that will be displayed in the command help - * @param min The minimum value of the argv value - * @param max The minimum value of the argv value - * @param out A pointer to a MutableInteger where the argv value will be stored - * @param desc The description of the argument that will be displayed in the command help - * @param optional Indicate if an optional argument - * @return The number of arguments currently added to the command - */ - public final void addArgument( - String name, int min, int max, AtomicInteger out, @Nullable String desc, boolean optional) { - Argument arg = new Argument(name, min, max, out, desc, optional); - addArgumentToList(arg, optional); - } - - /** - * @brief Add a long Integer command argument - * @param name The name that will be displayed in the command help - * @param min The minimum value of the argv value - * @param max The minimum value of the argv value - * @param out A pointer to a MutableInteger where the argv value will be stored - * @param desc The description of the argument that will be displayed in the command help - * @param optional Indicate if an optional argument - * @return The number of arguments currently added to the command - */ - public final void addArgument( - String name, short min, short max, AtomicLong out, @Nullable String desc, boolean optional) { - Argument arg = new Argument(name, min, max, out, desc, optional); - addArgumentToList(arg, optional); - } - - /** - * @brief Add a long Integer command argument - * @param name The name that will be displayed in the command help - * @param min The minimum value of the argv value - * @param max The minimum value of the argv value - * @param out A pointer to a MutableInteger where the argv value will be stored - * @param desc The description of the argument that will be displayed in the command help - * @param optional Indicate if an optional argument - * @return The number of arguments currently added to the command - */ - public final void addArgument( - String name, long min, long max, AtomicLong out, @Nullable String desc, boolean optional) { - Argument arg = new Argument(name, min, max, out, desc, optional); - addArgumentToList(arg, optional); - } - - /** - * @brief Add an IP address command argument - * @param name The name that will be displayed in the command help - * @param out A pointer to a IPAddress where the argv value will be stored - * @param optional Indicate if an optional argument - * @return The number of arguments currently added to the command - */ - public final void addArgument(String name, IPAddress out, boolean optional) { - Argument arg = new Argument(name, out, optional); - addArgumentToList(arg, optional); - } - - /** - * @brief Add a String command argument - * @param name The name that will be displayed in the command help - * @param out A pointer to a StringBuffer where the argv value will be stored - * @param desc The description of the argument that will be displayed in the command help - * @param optional Indicate if an optional argument - * @return The number of arguments currently added to the command - */ - public final void addArgument( - String name, StringBuffer out, @Nullable String desc, boolean optional) { - Argument arg = new Argument(name, out, desc, optional); - addArgumentToList(arg, optional); - } - - /** - * @brief Initialize command arguments - * @param argc The number of arguments to a command (Does not include command itself) - * @param args Supplied command-line arguments as an array of String objects. - */ - public final void initArguments(int argc, String[] args) { - int mandatoryArgsCount = 0; - int currentIndex = 0; - - for (Argument arg : mArgs) { - if (!arg.isOptional()) { - mandatoryArgsCount++; - } - } - - if (argc < mandatoryArgsCount) { - throw new IllegalArgumentException( - "initArguments: Wrong arguments number: " + argc + " instead of " + mandatoryArgsCount); - } - - // Initialize mandatory arguments - for (int i = 0; i < mandatoryArgsCount; i++) { - initArgument(currentIndex++, args[i]); - } - - // Initialize optional arguments - // Optional arguments expect a name and a value, so i is increased by 2 on every step. - for (int i = mandatoryArgsCount; i < argc; i += 2) { - // optional arguments starts with OPTIONAL_ARGUMENT_PREFIX - if (args[i].length() <= OPTIONAL_ARGUMENT_PREFIX_LENGTH - && !args[i].startsWith(OPTIONAL_ARGUMENT_PREFIX)) { - throw new IllegalArgumentException("initArguments: Invalid optional argument: " + args[i]); - } - - if (args[i] - .substring(OPTIONAL_ARGUMENT_PREFIX_LENGTH) - .equals(mArgs.get(currentIndex).getName())) { - if (i + 1 >= argc) { - throw new IllegalArgumentException( - "initArguments: Optional argument " + args[i] + " missing value"); - } - - initArgument(currentIndex++, args[i + 1]); - } - } - } - - public void initArgument(int argIndex, String argValue) { - mArgs.get(argIndex).setValue(argValue); - } - - public abstract void run() throws Exception; -} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/Command.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/Command.kt new file mode 100644 index 00000000000000..1a0f8655a9c2bf --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/Command.kt @@ -0,0 +1,256 @@ +/* + * 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.ArrayList +import java.util.concurrent.atomic.AtomicBoolean +import java.util.concurrent.atomic.AtomicInteger +import java.util.concurrent.atomic.AtomicLong + +/** + * @brief Matter Controller command + * @details The base class of all the commands the Matter Controller supports, which are actions + * that may be performed. Commands are verb-like, such as pair a Matter device or discover + * Matter devices from the environment. + */ +abstract class Command( + private val name: String, + private val helpText: String? = null) { + private val arguments = ArrayList() + + fun getName(): String { + return name + } + + fun getHelpText(): String? { + return helpText + } + + fun getArgumentName(index: Int): String { + return arguments[index].name + } + + fun getArgumentsCount(): Int { + return arguments.size + } + + fun getArgumentIsOptional(index: Int): Boolean { + return arguments[index].isOptional + } + + /** + * @brief Get attribute argument if it exists, there is at most one Attribute argument per command + * @return A pointer to an Optional where the Attribute argument will be stored + */ + fun getAttribute(): String? { + return arguments.find { arg -> arg.type === ArgumentType.ATTRIBUTE }?.value as? String + } + + /** + * @brief Get argument description if it exists + * @return A pointer to an Optional where the argument description will be stored + */ + fun getArgumentDescription(index: Int): String? { + return arguments[index].desc + } + + fun addArgumentToList(arg: Argument) { + if (arg.isOptional || arguments.isEmpty()) { + // Safe to just append to the end of a list. + arguments.add(arg) + return + } + + // mandatory arg needs to be inserted before the optional arguments. + var index = 0 + while (index < arguments.size && !arguments[index].isOptional) { + index++ + } + + // Insert before the first optional arg. + arguments.add(index, arg) + } + + /** + * @brief Add a bool command argument + * @param name The name that will be displayed in the command help + * @param out A pointer to a AtomicBoolean where the argv value will be stored + * @param desc The description of the argument that will be displayed in the command help + * @param optional Indicate if an optional argument + * @return The number of arguments currently added to the command + */ + fun addArgument( + name: String?, out: AtomicBoolean?, desc: String?, optional: Boolean + ) { + val arg = Argument(name!!, out!!, desc, optional) + addArgumentToList(arg) + } + + /** + * @brief Add a short command argument + * @param name The name that will be displayed in the command help + * @param min The minimum value of the argv value + * @param max The minimum value of the argv value + * @param out A pointer to a AtomicInteger where the argv value will be stored + * @param desc The description of the argument that will be displayed in the command help + * @param optional Indicate if an optional argument + * @return The number of arguments currently added to the command + */ + fun addArgument( + name: String?, + min: Short, + max: Short, + out: AtomicInteger?, + desc: String?, + optional: Boolean + ) { + val arg = Argument(name!!, min, max, out!!, desc, optional) + addArgumentToList(arg) + } + + /** + * @brief Add an int command argument + * @param name The name that will be displayed in the command help + * @param min The minimum value of the argv value + * @param max The minimum value of the argv value + * @param out A pointer to a AtomicInteger where the argv value will be stored + * @param desc The description of the argument that will be displayed in the command help + * @param optional Indicate if an optional argument + * @return The number of arguments currently added to the command + */ + fun addArgument( + name: String?, min: Int, max: Int, out: AtomicInteger?, desc: String?, optional: Boolean + ) { + val arg = Argument(name!!, min, max, out!!, desc, optional) + addArgumentToList(arg) + } + + /** + * @brief Add a long Integer command argument + * @param name The name that will be displayed in the command help + * @param min The minimum value of the argv value + * @param max The minimum value of the argv value + * @param out A pointer to a MutableInteger where the argv value will be stored + * @param desc The description of the argument that will be displayed in the command help + * @param optional Indicate if an optional argument + * @return The number of arguments currently added to the command + */ + fun addArgument( + name: String?, min: Short, max: Short, out: AtomicLong?, desc: String?, optional: Boolean + ) { + val arg = Argument(name!!, min, max, out!!, desc, optional) + addArgumentToList(arg) + } + + /** + * @brief Add a long Integer command argument + * @param name The name that will be displayed in the command help + * @param min The minimum value of the argv value + * @param max The minimum value of the argv value + * @param out A pointer to a AtomicLong where the argv value will be stored + * @param desc The description of the argument that will be displayed in the command help + * @param optional Indicate if an optional argument + * @return The number of arguments currently added to the command + */ + fun addArgument( + name: String?, min: Long, max: Long, out: AtomicLong?, desc: String?, optional: Boolean + ) { + val arg = Argument(name!!, min, max, out!!, desc, optional) + addArgumentToList(arg) + } + + /** + * @brief Add an IP address command argument + * @param name The name that will be displayed in the command help + * @param out A pointer to a IPAddress where the argv value will be stored + * @param optional Indicate if an optional argument + * @return The number of arguments currently added to the command + */ + fun addArgument(name: String?, out: IPAddress?, optional: Boolean) { + val arg = Argument(name!!, out!!, optional) + addArgumentToList(arg) + } + + /** + * @brief Add a String command argument + * @param name The name that will be displayed in the command help + * @param out A pointer to a StringBuffer where the argv value will be stored + * @param desc The description of the argument that will be displayed in the command help + * @param optional Indicate if an optional argument + * @return The number of arguments currently added to the command + */ + fun addArgument( + name: String?, out: StringBuffer?, desc: String?, optional: Boolean + ) { + val arg = Argument(name!!, out!!, desc, optional) + addArgumentToList(arg) + } + + /** + * @brief Initialize command arguments + * @param args Supplied command-line arguments as an array of String objects. + */ + fun initArguments(args: Array) { + val argc = args.size + var mandatoryArgsCount = 0 + var currentIndex = 0 + for (arg in arguments) { + if (!arg.isOptional) { + mandatoryArgsCount++ + } + } + require(argc >= mandatoryArgsCount) { "initArguments: Wrong arguments number: $argc instead of $mandatoryArgsCount" } + + // Initialize mandatory arguments + for (i in 0 until mandatoryArgsCount) { + initArgument(currentIndex++, args[i]) + } + + // Initialize optional arguments + // Optional arguments expect a name and a value, so it is increased by 2 on every step. + var i = mandatoryArgsCount + while (i < argc) { + + // optional arguments starts with OPTIONAL_ARGUMENT_PREFIX + require( + !(args[i].length <= OPTIONAL_ARGUMENT_PREFIX_LENGTH + && !args[i].startsWith(OPTIONAL_ARGUMENT_PREFIX)) + ) { "initArguments: Invalid optional argument: " + args[i] } + if (args[i] + .substring(OPTIONAL_ARGUMENT_PREFIX_LENGTH) + == arguments[currentIndex].name + ) { + require(i + 1 < argc) { "initArguments: Optional argument " + args[i] + " missing value" } + initArgument(currentIndex++, args[i + 1]) + } + i += 2 + } + } + + fun initArgument(argIndex: Int, argValue: String?) { + arguments[argIndex].setValue(argValue!!) + } + + @Throws(Exception::class) + abstract fun run() + + companion object { + private const val OPTIONAL_ARGUMENT_PREFIX = "--" + private const val OPTIONAL_ARGUMENT_PREFIX_LENGTH = 2 + } +} \ No newline at end of file diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/CommandManager.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/CommandManager.java deleted file mode 100644 index 202c6763a2187e..00000000000000 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/CommandManager.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (c) 2022 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.List; -import java.util.Map; -import java.util.Optional; -import java.util.logging.Level; -import java.util.logging.Logger; - -public final class CommandManager { - private final Map> mClusters = new HashMap>(); - private static Logger logger = Logger.getLogger(CommandManager.class.getName()); - - public final void register(String clusterName, List commandsList) { - mClusters.put(clusterName, commandsList); - } - - public final void run(String[] args) throws Exception { - Command command; - - if (args.length < 1) { - logger.log(Level.INFO, "Missing cluster name"); - showClusters(); - return; - } - - List commands = mClusters.get(args[0]); - if (commands == null) { - logger.log(Level.INFO, "Unknown cluster: " + args[0]); - showClusters(); - return; - } - - if (args.length < 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 new IllegalArgumentException(); - } - } else if (isEventCommand(args[1])) { - if (args.length < 3) { - logger.log(Level.INFO, "Missing event name"); - showClusterEvents(args[0], args[1], commands); - throw new 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 new IllegalArgumentException(); - } - } else { - if (args.length < 3) { - logger.log(Level.INFO, "Missing attribute name"); - showClusterAttributes(args[0], args[1], commands); - throw new 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 new IllegalArgumentException(); - } - } - - // need skip over binary and command name and only get arguments - String[] temp = Arrays.copyOfRange(args, 2, args.length); - - try { - command.initArguments(temp.length, temp); - } catch (IllegalArgumentException e) { - logger.log(Level.INFO, "Arguments init failed with exception: " + e.getMessage()); - showCommand(args[0], command); - System.exit(1); - } - - command.run(); - } - - private boolean isAttributeCommand(String commandName) { - return commandName.equals("read") - || commandName.equals("write") - || commandName.equals("subscribe"); - } - - private boolean isEventCommand(String commandName) { - return commandName.equals("read-event") || commandName.equals("subscribe-event"); - } - - private boolean isGlobalCommand(String commandName) { - return isAttributeCommand(commandName) || isEventCommand(commandName); - } - - private Command getCommand(List commands, String commandName) { - for (Command command : commands) { - if (commandName.equals(command.getName())) { - return command; - } - } - - return null; - } - - private Command getGlobalCommand( - List commands, String commandName, String attributeName) { - for (Command command : commands) { - if (commandName.equals(command.getName()) && attributeName.equals(command.getAttribute())) { - return command; - } - } - - return null; - } - - private void 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 (String key : mClusters.keySet()) { - System.out.printf(" | * %-82s|\n", key.toLowerCase()); - } - - logger.log( - Level.INFO, - " +-------------------------------------------------------------------------------------+"); - } - - private void showCluster(String clusterName, List commands) { - 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, - " +-------------------------------------------------------------------------------------+"); - boolean readCommand = false; - boolean writeCommand = false; - boolean subscribeCommand = false; - boolean readEventCommand = false; - boolean subscribeEventCommand = false; - - for (Command command : commands) { - boolean shouldPrint = true; - String cmdName = command.getName(); - if (isGlobalCommand(cmdName)) { - if (cmdName.equals("read") && !readCommand) { - readCommand = true; - } else if (cmdName.equals("write") && !writeCommand) { - writeCommand = true; - } else if (cmdName.equals("subscribe") && !subscribeCommand) { - subscribeCommand = true; - } else if (cmdName.equals("read-event") && !readEventCommand) { - readEventCommand = true; - } else if (cmdName.equals("subscribe-event") && !subscribeEventCommand) { - subscribeEventCommand = true; - } else { - shouldPrint = false; - } - } - - if (shouldPrint) { - System.out.printf(" | * %-82s|\n", cmdName); - } - } - logger.log( - Level.INFO, - " +-------------------------------------------------------------------------------------+\n"); - } - - private void showClusterAttributes( - String clusterName, String commandName, List commands) { - 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 command : commands) { - if (commandName.equals(command.getName())) { - System.out.printf(" | * %-82s|\n", command.getAttribute().get()); - } - } - logger.log( - Level.INFO, - " +-------------------------------------------------------------------------------------+"); - } - - private void showClusterEvents(String clusterName, String commandName, List commands) { - 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 command : commands) { - if (commandName.equals(command.getName())) { - System.out.printf(" | * %-82s|\n", command.getAttribute().get()); - } - } - logger.log( - Level.INFO, - " +-------------------------------------------------------------------------------------+"); - } - - private void showCommand(String clusterName, Command command) { - logger.log(Level.INFO, "Usage:"); - - String arguments = command.getName(); - String description = ""; - - int argumentsCount = command.getArgumentsCount(); - for (int i = 0; i < argumentsCount; i++) { - String arg = ""; - boolean isOptional = command.getArgumentIsOptional(i); - if (isOptional) { - arg += "[--"; - } - arg += command.getArgumentName(i); - if (isOptional) { - arg += "]"; - } - arguments += " "; - arguments += arg; - - Optional argDescription = command.getArgumentDescription(i); - if (argDescription.isPresent()) { - description += "\n"; - description += arg; - description += ":\n "; - description += argDescription.get(); - description += "\n"; - } - } - System.out.format(" java-matter-controller %s %s\n", clusterName, arguments); - - Optional helpText = command.getHelpText(); - if (helpText.isPresent()) { - System.out.format("\n%s\n", helpText.get()); - } - - if (!description.isEmpty()) { - logger.log(Level.INFO, description); - } - } -} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/CommandManager.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/CommandManager.kt new file mode 100644 index 00000000000000..f6fdf19aced744 --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/CommandManager.kt @@ -0,0 +1,310 @@ +/* + * 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> = HashMap() + fun register(clusterName: String, commandsList: List) { + clusters[clusterName] = commandsList + } + + @Throws(Exception::class) + fun run(args: Array) { + 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, commandName: String): Command? { + for (command in commands) { + if (commandName == command.getName()) { + return command + } + } + return null + } + + private fun getGlobalCommand( + commands: List, 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) { + 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 + ) { + 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 + ) { + 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) + } +} \ No newline at end of file diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/CredentialsIssuer.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/CredentialsIssuer.kt similarity index 78% rename from examples/java-matter-controller/java/src/com/matter/controller/commands/common/CredentialsIssuer.java rename to examples/java-matter-controller/java/src/com/matter/controller/commands/common/CredentialsIssuer.kt index a77508ea35a1bf..85bc35dde1a674 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/CredentialsIssuer.java +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/CredentialsIssuer.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Project CHIP Authors + * Copyright (c) 2023 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,12 +15,11 @@ * limitations under the License. * */ - -package com.matter.controller.commands.common; +package com.matter.controller.commands.common /** * @brief Credentials Issuer for the Command * @details Contains all credential information of the issuer of the command, such as operational - * credentials for a given fabric, the DAC verifier of the commisioner, etc .. + * credentials for a given fabric, the DAC verifier of the commisioner, etc .. */ -public class CredentialsIssuer {} +class CredentialsIssuer \ No newline at end of file diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/IPAddress.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/IPAddress.java deleted file mode 100644 index d419db43f25686..00000000000000 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/IPAddress.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.matter.controller.commands.common; - -import java.net.InetAddress; - -public final class IPAddress { - private InetAddress address; - - public IPAddress(InetAddress address) { - this.address = address; - } - - public void setAddress(InetAddress address) { - this.address = address; - } - - @Override - public String toString() { - return address.toString(); - } - - public String getHostAddress() { - return address.getHostAddress(); - } -} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/IPAddress.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/IPAddress.kt new file mode 100644 index 00000000000000..938cf0ce893326 --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/IPAddress.kt @@ -0,0 +1,34 @@ +/* + * 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.net.InetAddress + +class IPAddress(private var address: InetAddress) { + fun setAddress(address: InetAddress) { + this.address = address + } + + fun getHostAddress(): String { + return address.hostAddress + } + + override fun toString(): String { + return address.toString() + } +} \ No newline at end of file diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/MatterCommand.java b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/MatterCommand.java deleted file mode 100644 index 6af420375e2f8c..00000000000000 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/MatterCommand.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2022 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 chip.devicecontroller.ChipDeviceController; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicLong; -import java.util.logging.Logger; - -public abstract class MatterCommand extends Command { - private final ChipDeviceController mChipDeviceController; - private final Optional mCredIssuerCmds; - private final StringBuffer mCommissionerName = new StringBuffer(); - private final StringBuffer mPaaTrustStorePath = new StringBuffer(); - private final StringBuffer mCDTrustStorePath = new StringBuffer(); - private final AtomicLong mCommissionerNodeId = new AtomicLong(); - private final AtomicBoolean mUseMaxSizedCerts = new AtomicBoolean(); - private final AtomicBoolean mOnlyAllowTrustedCdKeys = new AtomicBoolean(); - private FutureResult mFutureResult = new FutureResult(); - private static Logger logger = Logger.getLogger(MatterCommand.class.getName()); - - public MatterCommand( - ChipDeviceController controller, String commandName, CredentialsIssuer credIssuerCmds) { - this(controller, commandName, credIssuerCmds, null); - } - - public MatterCommand( - ChipDeviceController controller, - String commandName, - CredentialsIssuer credIssuerCmds, - String helpText) { - super(commandName, helpText); - this.mCredIssuerCmds = Optional.ofNullable(credIssuerCmds); - this.mChipDeviceController = controller; - - addArgument( - "paa-trust-store-path", - mPaaTrustStorePath, - "Path to directory holding PAA certificate information. Can be absolute or relative to the current working " - + "directory.", - true); - addArgument( - "cd-trust-store-path", - mCDTrustStorePath, - "Path to directory holding CD certificate information. Can be absolute or relative to the current working " - + "directory.", - true); - addArgument( - "commissioner-name", - mCommissionerName, - "Name of fabric to use. Valid values are \"alpha\", \"beta\", \"gamma\", and integers greater than or equal to " - + "4. The default if not specified is \"alpha\".", - true); - addArgument( - "commissioner-nodeid", - 0, - Long.MAX_VALUE, - mCommissionerNodeId, - "The node id to use for java-matter-controller. If not provided, kTestControllerNodeId (112233, 0x1B669) will be used.", - true); - addArgument( - "use-max-sized-certs", - mUseMaxSizedCerts, - "Maximize the size of operational certificates. If not provided or 0 (\"false\"), normally sized operational " - + "certificates are generated.", - true); - addArgument( - "only-allow-trusted-cd-keys", - mOnlyAllowTrustedCdKeys, - "Only allow trusted CD verifying keys (disallow test keys). If not provided or 0 (\"false\"), untrusted CD " - + "verifying keys are allowed. If 1 (\"true\"), test keys are disallowed.", - true); - } - - // This method returns the commissioner instance to be used for running the command. - public ChipDeviceController currentCommissioner() { - return mChipDeviceController; - } - - /////////// Command Interface ///////// - @Override - public void run() throws Exception { - runCommand(); - } - - protected abstract void runCommand(); - - public final void setSuccess() { - mFutureResult.setRealResult(RealResult.Success()); - } - - public final void setFailure(String error) { - mFutureResult.setRealResult(RealResult.Error(error)); - } - - public final void waitCompleteMs(long timeoutMs) { - mFutureResult.setTimeoutMs(timeoutMs); - mFutureResult.waitResult(); - } - - public final void clear() { - mFutureResult.clear(); - } -} diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/common/MatterCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/MatterCommand.kt new file mode 100644 index 00000000000000..208213beef6818 --- /dev/null +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/common/MatterCommand.kt @@ -0,0 +1,116 @@ +/* + * 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 chip.devicecontroller.ChipDeviceController +import java.util.concurrent.atomic.AtomicBoolean +import java.util.concurrent.atomic.AtomicLong +import java.util.logging.Logger + +abstract class MatterCommand( + private val chipDeviceController: ChipDeviceController, + private val credIssuerCmds: CredentialsIssuer?, + commandName: String, + helpText: String? = null +) : Command(commandName, helpText) { + private val commissionerName = StringBuffer() + private val paaTrustStorePath = StringBuffer() + private val cdTrustStorePath = StringBuffer() + private val commissionerNodeId: AtomicLong = AtomicLong() + private val useMaxSizedCerts: AtomicBoolean = AtomicBoolean() + private val onlyAllowTrustedCdKeys: AtomicBoolean = AtomicBoolean() + private val futureResult = FutureResult() + + init { + addArgument( + "paa-trust-store-path", + paaTrustStorePath, + "Path to directory holding PAA certificate information. Can be absolute or relative to the current working " + + "directory.", + true + ) + addArgument( + "cd-trust-store-path", + cdTrustStorePath, + "Path to directory holding CD certificate information. Can be absolute or relative to the current working " + + "directory.", + true + ) + addArgument( + "commissioner-name", + commissionerName, + "Name of fabric to use. Valid values are \"alpha\", \"beta\", \"gamma\", and integers greater than or equal to " + + "4. The default if not specified is \"alpha\".", + true + ) + addArgument( + "commissioner-nodeid", + 0, Long.MAX_VALUE, + commissionerNodeId, + "The node id to use for java-matter-controller. If not provided, kTestControllerNodeId (112233, 0x1B669) will be used.", + true + ) + addArgument( + "use-max-sized-certs", + useMaxSizedCerts, + "Maximize the size of operational certificates. If not provided or 0 (\"false\"), normally sized operational " + + "certificates are generated.", + true + ) + addArgument( + "only-allow-trusted-cd-keys", + onlyAllowTrustedCdKeys, + "Only allow trusted CD verifying keys (disallow test keys). If not provided or 0 (\"false\"), untrusted CD " + + "verifying keys are allowed. If 1 (\"true\"), test keys are disallowed.", + true + ) + } + + // This method returns the commissioner instance to be used for running the command. + fun currentCommissioner(): ChipDeviceController { + return chipDeviceController + } + + /////////// Command Interface ///////// + @Throws(Exception::class) + override fun run() { + runCommand() + } + + protected abstract fun runCommand() + fun setSuccess() { + futureResult.setRealResult(RealResult.Success()) + } + + fun setFailure(error: String?) { + futureResult.setRealResult(RealResult.Error(error)) + } + + fun waitCompleteMs(timeoutMs: Long) { + futureResult.setTimeoutMs(timeoutMs) + futureResult.waitResult() + } + + fun clear() { + futureResult.clear() + } + + companion object { + private val logger = Logger.getLogger(MatterCommand::class.java.name) + } +} \ No newline at end of file diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommand.kt index 2d570a6eb0ef7a..706675d7a6bd8f 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommand.kt @@ -23,7 +23,7 @@ import com.matter.controller.commands.common.MatterCommand import java.util.concurrent.atomic.AtomicLong class DiscoverCommand(controller: ChipDeviceController, credsIssuer: CredentialsIssuer?) : - MatterCommand(controller, "resolve", credsIssuer) { + MatterCommand(controller, credsIssuer, "resolve") { private val nodeId: AtomicLong = AtomicLong() private val fabricId: AtomicLong = AtomicLong() diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommissionablesCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommissionablesCommand.kt index 8475510b433d01..3c73bc1c07220f 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommissionablesCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommissionablesCommand.kt @@ -25,7 +25,7 @@ import java.util.concurrent.TimeUnit class DiscoverCommissionablesCommand( controller: ChipDeviceController, credsIssuer: CredentialsIssuer? -) : MatterCommand(controller, "commissionables", credsIssuer) { +) : MatterCommand(controller, credsIssuer, "commissionables") { override fun runCommand() { currentCommissioner().discoverCommissionableNodes() diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommissionersCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommissionersCommand.kt index ebc0ec1343a9eb..37d9c0838875d5 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommissionersCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/discover/DiscoverCommissionersCommand.kt @@ -23,6 +23,6 @@ import com.matter.controller.commands.common.MatterCommand class DiscoverCommissionersCommand( controller: ChipDeviceController, credsIssuer: CredentialsIssuer? -) : MatterCommand(controller, "commissioners", credsIssuer) { +) : MatterCommand(controller, credsIssuer, "commissioners") { override fun runCommand() {} } diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/CloseSessionCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/CloseSessionCommand.kt index 60fd5ef3bf86ea..86d7be807fc2d9 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/CloseSessionCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/CloseSessionCommand.kt @@ -24,7 +24,7 @@ import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicLong class CloseSessionCommand(controller: ChipDeviceController, credsIssuer: CredentialsIssuer?) : - MatterCommand(controller, "close-session", credsIssuer) { + MatterCommand(controller, credsIssuer, "close-session") { private val destinationId: AtomicLong = AtomicLong() private val timeoutSecs: AtomicInteger = AtomicInteger() diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt index 46f65fb39d1087..16c9d0b95a2d0b 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt @@ -25,7 +25,6 @@ import chip.devicecontroller.model.ChipAttributePath import com.matter.controller.commands.common.CredentialsIssuer import java.util.logging.Level import java.util.logging.Logger -import javax.annotation.Nullable class PairOnNetworkLongImWriteCommand( controller: ChipDeviceController, credsIssue: CredentialsIssuer? diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt index 2c73c78a7af75a..a6df1b0b450f6a 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt @@ -31,12 +31,12 @@ import java.util.logging.Logger abstract class PairingCommand( controller: ChipDeviceController, - commandName: String?, + commandName: String, credsIssuer: CredentialsIssuer?, private val pairingMode: PairingModeType = PairingModeType.NONE, private val networkType: PairingNetworkType = PairingNetworkType.NONE, private val filterType: DiscoveryFilterType = DiscoveryFilterType.NONE -) : MatterCommand(controller, commandName, credsIssuer), ChipDeviceController.CompletionListener { +) : MatterCommand(controller, credsIssuer, commandName), ChipDeviceController.CompletionListener { private val remoteAddr: IPAddress = IPAddress(InetAddress.getByName("::1")) private val nodeId = AtomicLong() private val discoveryFilterCode = AtomicLong()