From 0c8c9c8fe67e5817561ec583f7639c59a95352dc Mon Sep 17 00:00:00 2001 From: Alexander Diewald <diewald@fortiss.org> Date: Wed, 15 Apr 2020 18:07:58 +0200 Subject: [PATCH] Kernel: Add a CLI service * Allows registering command line switches and their handlers from plugin activators (start method). * The handler execution must be executed after ALL other services were started. For instance, this can be done from the RCP. * Handlers support consuming a switch and an additional argument. Issue-Ref: 3993 Issue-Url: https://af3-developer.fortiss.org/issues/3993 Signed-off-by: Alexander Diewald <diewald@fortiss.org> --- .../fortiss/tooling/kernel/extension/.ratings | 1 + .../extension/ICommandLineSwitchHandler.java | 37 ++++++++ .../fortiss/tooling/kernel/internal/.ratings | 1 + .../internal/CommandLineInterfaceService.java | 94 +++++++++++++++++++ .../fortiss/tooling/kernel/service/.ratings | 1 + .../service/ICommandLineInterfaceService.java | 47 ++++++++++ 6 files changed, 181 insertions(+) create mode 100644 org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/ICommandLineSwitchHandler.java create mode 100644 org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/CommandLineInterfaceService.java create mode 100644 org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/service/ICommandLineInterfaceService.java diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/.ratings index 5e2380be4..1ee9c9e35 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/.ratings +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/.ratings @@ -1,3 +1,4 @@ +ICommandLineSwitchHandler.java 1df397bf5b1a2af7040f5e73bfe7f3bd239d47c5 YELLOW IConnectionCompositor.java 82188750593a08df75a5f21fd91d4b41f72593fd GREEN IConstraintChecker.java a6d76e332ece919adb990397dd5ef6aaa542ea7d GREEN IEclipseResourcePostLoadProvider.java e842bb7485ef27917092ffc60af8a57e475d01d6 GREEN diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/ICommandLineSwitchHandler.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/ICommandLineSwitchHandler.java new file mode 100644 index 000000000..1df397bf5 --- /dev/null +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/ICommandLineSwitchHandler.java @@ -0,0 +1,37 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2020 fortiss GmbH | +| | +| 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 org.fortiss.tooling.kernel.extension; + +/** + * Defines an entry point to process command line arguments following a switch. Each implementing + * class must be accompanied with an extension point definition that defines the (string) identifier + * of the switch. The registered classes are executed after all services are started. + * + * @author diewald + */ +public interface ICommandLineSwitchHandler { + + /** Indicates whether the handler expects an additional argument after the registered switch. */ + boolean hasAdditionalArgument(); + + /** + * Entry point to handle the given {@code argument} given at the command line. + * + * @param argument + * String argument following a switch's identifier . + */ + void handleCLISwitch(String argument); +} diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings index deae784c2..788c8c7c5 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings @@ -1,3 +1,4 @@ +CommandLineInterfaceService.java 6b5c94c52702f773c60b181eff52204ab379b248 YELLOW CommandStackService.java 957bda69b5feb91f002aed4d25ed334e92801e7e GREEN ConnectionCompositorService.java d69a60cd7a3d06e91d24fd32b9c00125ea71e0dd GREEN ConstraintCheckerService.java 459b5eb717598e7e8bb71a0c87e57ea85cb00e4b GREEN diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/CommandLineInterfaceService.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/CommandLineInterfaceService.java new file mode 100644 index 000000000..6b5c94c52 --- /dev/null +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/CommandLineInterfaceService.java @@ -0,0 +1,94 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2020 fortiss GmbH | +| | +| 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 org.fortiss.tooling.kernel.internal; + +import static org.fortiss.tooling.kernel.utils.LoggingUtils.error; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.Platform; +import org.fortiss.tooling.kernel.ToolingKernelActivator; +import org.fortiss.tooling.kernel.extension.ICommandLineSwitchHandler; +import org.fortiss.tooling.kernel.service.ICommandLineInterfaceService; + +/** + * Implementation of the {@link ICommandLineInterfaceService}. + * + * @author diewald + */ +public class CommandLineInterfaceService implements ICommandLineInterfaceService { + + /** Singleton instance of the {@link ICommandLineInterfaceService} service. */ + private static CommandLineInterfaceService INSTANCE = new CommandLineInterfaceService(); + + /** Guard for executing the CLI switch only once during the applications lifetime. */ + private boolean handlersExecuted = false; + + /** Associates CLI switches with their handlers. */ + private Map<String, ICommandLineSwitchHandler> switchHandlerMap = new HashMap<>(); + + /** Hiding constructor. */ + private CommandLineInterfaceService() { + // Prevent external instantiation. + } + + /** Returns the {@link CommandLineInterfaceService} singleton. */ + public static synchronized CommandLineInterfaceService getInstance() { + return INSTANCE; + } + + /** {@inheritDoc} */ + @Override + public void executeHandlers() { + if(handlersExecuted) { + error(ToolingKernelActivator.getDefault(), "The " + + CommandLineInterfaceService.class.getSimpleName() + + " was asked more than one to process command line switches. The subsequent " + + "calls were NOT executed. Please report this issue to the developers."); + return; + } + handlersExecuted = true; + + String[] args = Platform.getApplicationArgs(); + for(int cliIdx = 0; cliIdx < args.length; ++cliIdx) { + String cliSwitch = args[cliIdx]; + ICommandLineSwitchHandler cliHandler = switchHandlerMap.get(cliSwitch); + if(cliHandler != null) { + String argument = + cliHandler.hasAdditionalArgument() ? argument = args[++cliIdx] : null; + cliHandler.handleCLISwitch(argument); + } else { + error(ToolingKernelActivator.getDefault(), + "Could not parse the argument " + cliSwitch + "."); + } + } + } + + /** {@inheritDoc} */ + @Override + public void registerHandler(String cliSwitch, ICommandLineSwitchHandler cliHandler) { + if(switchHandlerMap.containsKey(cliSwitch)) { + ICommandLineSwitchHandler activeHandler = switchHandlerMap.get(cliSwitch); + error(ToolingKernelActivator.getDefault(), + "The CLI switch " + cliSwitch + " is already registered with the handler " + + activeHandler.getClass().getSimpleName() + " and won't be replaced."); + return; + } + + switchHandlerMap.put(cliSwitch, cliHandler); + } +} diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/service/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/service/.ratings index c0b2fd39e..9ea5e6db4 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/service/.ratings +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/service/.ratings @@ -1,3 +1,4 @@ +ICommandLineInterfaceService.java b8b67b758f9af720968279ef7af9e2ef4f393f62 YELLOW ICommandStackService.java 678dcd1a6ab435ed0870fa2a9ec48ce47f25a187 GREEN IConnectionCompositorService.java 0cdf4568b2cd3e95ea195df90a84699eff36442b GREEN IConstraintCheckerService.java 291e53297aaea213e07e78f63350938ee2c7b155 GREEN diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/service/ICommandLineInterfaceService.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/service/ICommandLineInterfaceService.java new file mode 100644 index 000000000..b8b67b758 --- /dev/null +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/service/ICommandLineInterfaceService.java @@ -0,0 +1,47 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2020 fortiss GmbH | +| | +| 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 org.fortiss.tooling.kernel.service; + +import org.fortiss.tooling.kernel.extension.ICommandLineSwitchHandler; +import org.fortiss.tooling.kernel.internal.CommandLineInterfaceService; + +/** + * Service to register handlers for command line switches and their arguments. The handlers are + * executed after the startup of all other service to ensure the presence of the full feature set + * when this service is executed. + * + * @author diewald + */ +public interface ICommandLineInterfaceService { + + /** Returns the internal implemenation of the {@link ICommandLineInterfaceService}. */ + public static ICommandLineInterfaceService getInstance() { + return CommandLineInterfaceService.getInstance(); + } + + /** + * Executes the registered {@link ICommandLineSwitchHandler}s for the switches that have been + * passed to the program executable. This method can be executed only once during the + * application lifecycle, otherwise it degenerates to a no-op. + */ + void executeHandlers(); + + /** + * Registers an {@link ICommandLineSwitchHandler} that is executed if the given switch has + * been passed to the program executable. + */ + void registerHandler(String cliSwitch, ICommandLineSwitchHandler cliHandler); +} -- GitLab