From 4cfa2e2d98f6877d54da304ef17f096284430908 Mon Sep 17 00:00:00 2001 From: liamfallon Date: Thu, 13 Sep 2018 15:25:32 +0100 Subject: Sonar/Checkstyle in service/plugins Sonar and Checkstyle changes in plugins and services, and knock on changes Issue-ID: POLICY-1034 Change-Id: Iff7df74e54fce2c661dcc2fae75ae93d4cacfe5b Signed-off-by: liamfallon --- .../apex/auth/clieditor/ApexCLIEditorMain.java | 195 ------- .../auth/clieditor/ApexCommandLineEditorMain.java | 198 +++++++ .../apex/auth/clieditor/ApexModelHandler.java | 60 +-- .../policy/apex/auth/clieditor/CLIArgument.java | 144 ------ .../apex/auth/clieditor/CLIArgumentValue.java | 91 ---- .../policy/apex/auth/clieditor/CLICommand.java | 240 --------- .../policy/apex/auth/clieditor/CLICommands.java | 42 -- .../policy/apex/auth/clieditor/CLIEditorLoop.java | 543 ------------------- .../policy/apex/auth/clieditor/CLIException.java | 49 -- .../policy/apex/auth/clieditor/CLILineParser.java | 323 ------------ .../apex/auth/clieditor/CLIParameterParser.java | 159 ------ .../policy/apex/auth/clieditor/CLIParameters.java | 573 -------------------- .../apex/auth/clieditor/CommandLineArgument.java | 144 ++++++ .../auth/clieditor/CommandLineArgumentValue.java | 91 ++++ .../apex/auth/clieditor/CommandLineCommand.java | 240 +++++++++ .../apex/auth/clieditor/CommandLineCommands.java | 42 ++ .../apex/auth/clieditor/CommandLineEditorLoop.java | 544 +++++++++++++++++++ .../apex/auth/clieditor/CommandLineException.java | 49 ++ .../auth/clieditor/CommandLineParameterParser.java | 161 ++++++ .../apex/auth/clieditor/CommandLineParameters.java | 576 +++++++++++++++++++++ .../apex/auth/clieditor/CommandLineParser.java | 323 ++++++++++++ .../policy/apex/auth/clieditor/KeywordNode.java | 12 +- 22 files changed, 2404 insertions(+), 2395 deletions(-) delete mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/ApexCLIEditorMain.java create mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/ApexCommandLineEditorMain.java delete mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIArgument.java delete mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIArgumentValue.java delete mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLICommand.java delete mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLICommands.java delete mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIEditorLoop.java delete mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIException.java delete mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLILineParser.java delete mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIParameterParser.java delete mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIParameters.java create mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineArgument.java create mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineArgumentValue.java create mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineCommand.java create mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineCommands.java create mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineEditorLoop.java create mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineException.java create mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineParameterParser.java create mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineParameters.java create mode 100644 auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineParser.java (limited to 'auth/cli-editor/src/main/java/org') diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/ApexCLIEditorMain.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/ApexCLIEditorMain.java deleted file mode 100644 index 718c75a96..000000000 --- a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/ApexCLIEditorMain.java +++ /dev/null @@ -1,195 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.apex.auth.clieditor; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Set; -import java.util.TreeSet; - -import org.onap.policy.apex.model.utilities.json.JsonHandler; -import org.slf4j.ext.XLogger; -import org.slf4j.ext.XLoggerFactory; - -/** - * This class initiates an Apex CLI editor from a java main method. - * - * @author Liam Fallon (liam.fallon@ericsson.com) - */ -public class ApexCLIEditorMain { - // Get a reference to the logger - private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexCLIEditorMain.class); - - // The editor parameters - private CLIParameters parameters; - - // The CLI commands read in from JSON - private CLICommands commands; - - // The Apex model properties read in from JSON - private ApexModelProperties apexModelProperties; - - // The number of errors encountered in command processing - private int errorCount = 0; - - /** - * Instantiates the Apex CLI editor. - * - * @param args the command line arguments - */ - public ApexCLIEditorMain(final String[] args) { - LOGGER.info("Starting Apex CLI editor {} . . .", Arrays.toString(args)); - - try { - final CLIParameterParser parser = new CLIParameterParser(); - parameters = parser.parse(args); - - if (parameters.isHelpSet()) { - parser.help(ApexCLIEditorMain.class.getCanonicalName()); - return; - } - parameters.validate(); - } catch (final Exception e) { - LOGGER.error("start of Apex command line editor failed, ", e); - errorCount++; - return; - } - - LOGGER.debug("parameters are: {}", parameters.toString()); - - // Read the command definitions - try { - commands = new JsonHandler().read(CLICommands.class, parameters.getMetadataStream()); - } catch (final Exception e) { - LOGGER.error("start of Apex command line editor failed, error reading command metadata from {}", - parameters.getMetadataLocation(), e); - errorCount++; - return; - } - - // The JSON processing returns null if there is an empty file - if (commands == null || commands.getCommandSet().isEmpty()) { - LOGGER.error("start of Apex command line editor failed, no commands found in {}", - parameters.getApexPropertiesLocation()); - errorCount++; - return; - } - - LOGGER.debug("found {} commands", commands.getCommandSet().size()); - - // Read the Apex properties - try { - apexModelProperties = new JsonHandler().read(ApexModelProperties.class, - parameters.getApexPropertiesStream()); - } catch (final Exception e) { - LOGGER.error("start of Apex command line editor failed, error reading Apex model properties from " - + parameters.getApexPropertiesLocation()); - LOGGER.error(e.getMessage()); - errorCount++; - return; - } - - // The JSON processing returns null if there is an empty file - if (apexModelProperties == null) { - LOGGER.error("start of Apex command line editor failed, no Apex model properties found in {}", - parameters.getApexPropertiesLocation()); - errorCount++; - return; - } - - LOGGER.debug("model properties are: {}", apexModelProperties.toString()); - - // Find the system commands - final Set systemCommandNodes = new TreeSet<>(); - for (final CLICommand command : commands.getCommandSet()) { - if (command.isSystemCommand()) { - systemCommandNodes.add(new KeywordNode(command.getName(), command)); - } - } - - // Read in the command hierarchy, this builds a tree of commands - final KeywordNode rootKeywordNode = new KeywordNode("root"); - for (final CLICommand command : commands.getCommandSet()) { - rootKeywordNode.processKeywords(command.getKeywordlist(), command); - } - rootKeywordNode.addSystemCommandNodes(systemCommandNodes); - - // Create the model we will work towards - ApexModelHandler modelHandler = null; - try { - modelHandler = - new ApexModelHandler(apexModelProperties.getProperties(), parameters.getInputModelFileName()); - } catch (final Exception e) { - LOGGER.error("execution of Apex command line editor failed: ", e); - errorCount++; - return; - } - - final CLIEditorLoop cliEditorLoop = - new CLIEditorLoop(apexModelProperties.getProperties(), modelHandler, rootKeywordNode); - try { - errorCount = - cliEditorLoop.runLoop(parameters.getCommandInputStream(), parameters.getOutputStream(), parameters); - - if (errorCount == 0) { - LOGGER.info("Apex CLI editor completed execution"); - } else { - LOGGER.error("execution of Apex command line editor failed: {} command execution failure(s) occurred", - errorCount); - } - } catch (final IOException e) { - LOGGER.error("execution of Apex command line editor failed: " + e.getMessage()); - } - } - - /** - * Get the number of errors encountered in command processing. - * - * @return the number of errors - */ - public int getErrorCount() { - return errorCount; - } - - /** - * Sets the number of errors encountered in command processing. - * - * @param errorCount the number of errors - */ - public void setErrorCount(final int errorCount) { - this.errorCount = errorCount; - } - - - /** - * The main method, kicks off the editor. - * - * @param args the arguments - */ - public static void main(final String[] args) { - final ApexCLIEditorMain cliEditor = new ApexCLIEditorMain(args); - - // Only call system.exit on errors as it brings the JVM down - if (cliEditor.getErrorCount() > 0) { - System.exit(cliEditor.getErrorCount()); - } - } -} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/ApexCommandLineEditorMain.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/ApexCommandLineEditorMain.java new file mode 100644 index 000000000..0df8ac629 --- /dev/null +++ b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/ApexCommandLineEditorMain.java @@ -0,0 +1,198 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.auth.clieditor; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Set; +import java.util.TreeSet; + +import org.onap.policy.apex.model.utilities.json.JsonHandler; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * This class initiates an Apex CLI editor from a java main method. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ApexCommandLineEditorMain { + // Get a reference to the logger + private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexCommandLineEditorMain.class); + + // The editor parameters + private CommandLineParameters parameters; + + // The CLI commands read in from JSON + private CommandLineCommands commands; + + // The Apex model properties read in from JSON + private ApexModelProperties apexModelProperties; + + // The number of errors encountered in command processing + private int errorCount = 0; + + /** + * Instantiates the Apex CLI editor. + * + * @param args the command line arguments + */ + public ApexCommandLineEditorMain(final String[] args) { + String startMessage = "Starting Apex CLI editor " + Arrays.toString(args) + " . . ."; + LOGGER.info(startMessage); + + try { + final CommandLineParameterParser parser = new CommandLineParameterParser(); + parameters = parser.parse(args); + + if (parameters.isHelpSet()) { + parser.help(ApexCommandLineEditorMain.class.getCanonicalName()); + return; + } + parameters.validate(); + } catch (final Exception e) { + LOGGER.error("start of Apex command line editor failed, ", e); + errorCount++; + return; + } + + String message = "parameters are: " + parameters.toString(); + LOGGER.debug(message); + + // Read the command definitions + try { + commands = new JsonHandler().read(CommandLineCommands.class, + parameters.getMetadataStream()); + } catch (final Exception e) { + LOGGER.error("start of Apex command line editor failed, error reading command metadata from {}", + parameters.getMetadataLocation(), e); + errorCount++; + return; + } + + // The JSON processing returns null if there is an empty file + if (commands == null || commands.getCommandSet().isEmpty()) { + LOGGER.error("start of Apex command line editor failed, no commands found in {}", + parameters.getApexPropertiesLocation()); + errorCount++; + return; + } + + LOGGER.debug("found {} commands", commands.getCommandSet().size()); + + // Read the Apex properties + try { + apexModelProperties = new JsonHandler().read(ApexModelProperties.class, + parameters.getApexPropertiesStream()); + } catch (final Exception e) { + LOGGER.error("start of Apex command line editor failed, error reading Apex model properties from " + + parameters.getApexPropertiesLocation()); + LOGGER.error(e.getMessage()); + errorCount++; + return; + } + + // The JSON processing returns null if there is an empty file + if (apexModelProperties == null) { + LOGGER.error("start of Apex command line editor failed, no Apex model properties found in {}", + parameters.getApexPropertiesLocation()); + errorCount++; + return; + } + + String modelPropertiesString = "model properties are: " + apexModelProperties.toString(); + LOGGER.debug(modelPropertiesString); + + // Find the system commands + final Set systemCommandNodes = new TreeSet<>(); + for (final CommandLineCommand command : commands.getCommandSet()) { + if (command.isSystemCommand()) { + systemCommandNodes.add(new KeywordNode(command.getName(), command)); + } + } + + // Read in the command hierarchy, this builds a tree of commands + final KeywordNode rootKeywordNode = new KeywordNode("root"); + for (final CommandLineCommand command : commands.getCommandSet()) { + rootKeywordNode.processKeywords(command.getKeywordlist(), command); + } + rootKeywordNode.addSystemCommandNodes(systemCommandNodes); + + // Create the model we will work towards + ApexModelHandler modelHandler = null; + try { + modelHandler = new ApexModelHandler(apexModelProperties.getProperties(), + parameters.getInputModelFileName()); + } catch (final Exception e) { + LOGGER.error("execution of Apex command line editor failed: ", e); + errorCount++; + return; + } + + final CommandLineEditorLoop cliEditorLoop = new CommandLineEditorLoop(apexModelProperties.getProperties(), + modelHandler, rootKeywordNode); + try { + errorCount = cliEditorLoop.runLoop(parameters.getCommandInputStream(), parameters.getOutputStream(), + parameters); + + if (errorCount == 0) { + LOGGER.info("Apex CLI editor completed execution"); + } else { + LOGGER.error("execution of Apex command line editor failed: {} command execution failure(s) occurred", + errorCount); + } + } catch (final IOException e) { + LOGGER.error("execution of Apex command line editor failed: " + e.getMessage()); + } + } + + /** + * Get the number of errors encountered in command processing. + * + * @return the number of errors + */ + public int getErrorCount() { + return errorCount; + } + + /** + * Sets the number of errors encountered in command processing. + * + * @param errorCount the number of errors + */ + public void setErrorCount(final int errorCount) { + this.errorCount = errorCount; + } + + /** + * The main method, kicks off the editor. + * + * @param args the arguments + */ + public static void main(final String[] args) { + final ApexCommandLineEditorMain cliEditor = new ApexCommandLineEditorMain(args); + + // Only call system.exit on errors as it brings the JVM down + if (cliEditor.getErrorCount() > 0) { + System.exit(cliEditor.getErrorCount()); + } + } +} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/ApexModelHandler.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/ApexModelHandler.java index 2cf2633b2..2e1a4732b 100644 --- a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/ApexModelHandler.java +++ b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/ApexModelHandler.java @@ -24,7 +24,7 @@ import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Properties; -import java.util.TreeMap; +import java.util.SortedMap; import org.onap.policy.apex.model.modelapi.ApexApiResult; import org.onap.policy.apex.model.modelapi.ApexModel; @@ -64,7 +64,7 @@ public class ApexModelHandler { final ApexApiResult result = apexModel.loadFromFile(modelFileName); if (result.isNok()) { - throw new CLIException(result.getMessages().get(0)); + throw new CommandLineException(result.getMessages().get(0)); } } @@ -76,8 +76,8 @@ public class ApexModelHandler { * @param writer A writer to which to write output * @return the result of the executed command */ - public ApexApiResult executeCommand(final CLICommand command, - final TreeMap argumentValues, final PrintWriter writer) { + public ApexApiResult executeCommand(final CommandLineCommand command, + final SortedMap argumentValues, final PrintWriter writer) { // Get the method final Method apiMethod = getCommandMethod(command); @@ -92,22 +92,22 @@ public class ApexModelHandler { writer.println(result); return result; } else { - throw new CLIException( - INVOCATION_OF_SPECIFIED_METHOD + command.getApiMethod() + FAILED_FOR_COMMAND - + command.getName() + "\" the returned object is not an instance of ApexAPIResult"); + throw new CommandLineException(INVOCATION_OF_SPECIFIED_METHOD + command.getApiMethod() + + FAILED_FOR_COMMAND + command.getName() + + "\" the returned object is not an instance of ApexAPIResult"); } } catch (IllegalAccessException | IllegalArgumentException e) { writer.println(INVOCATION_OF_SPECIFIED_METHOD + command.getApiMethod() + FAILED_FOR_COMMAND - + command.getName() + "\""); + + command.getName() + "\""); e.printStackTrace(writer); - throw new CLIException(INVOCATION_OF_SPECIFIED_METHOD + command.getApiMethod() - + FAILED_FOR_COMMAND + command.getName() + "\"", e); + throw new CommandLineException(INVOCATION_OF_SPECIFIED_METHOD + command.getApiMethod() + FAILED_FOR_COMMAND + + command.getName() + "\"", e); } catch (final InvocationTargetException e) { writer.println(INVOCATION_OF_SPECIFIED_METHOD + command.getApiMethod() + FAILED_FOR_COMMAND - + command.getName() + "\""); + + command.getName() + "\""); e.getCause().printStackTrace(writer); - throw new CLIException(INVOCATION_OF_SPECIFIED_METHOD + command.getApiMethod() - + FAILED_FOR_COMMAND + command.getName() + "\"", e); + throw new CommandLineException(INVOCATION_OF_SPECIFIED_METHOD + command.getApiMethod() + FAILED_FOR_COMMAND + + command.getName() + "\"", e); } } @@ -117,9 +117,9 @@ public class ApexModelHandler { * @param command The command * @return the API method */ - private Method getCommandMethod(final CLICommand command) { - final String className = command.getAPIClassName(); - final String methodName = command.getAPIMethodName(); + private Method getCommandMethod(final CommandLineCommand command) { + final String className = command.getApiClassName(); + final String methodName = command.getApiMethodName(); try { final Class apiClass = Class.forName(className); @@ -128,11 +128,11 @@ public class ApexModelHandler { return apiMethod; } } - throw new CLIException("specified method \"" + command.getApiMethod() + "\" not found for command \"" - + command.getName() + "\""); + throw new CommandLineException("specified method \"" + command.getApiMethod() + + "\" not found for command \"" + command.getName() + "\""); } catch (final ClassNotFoundException e) { - throw new CLIException("specified class \"" + command.getApiMethod() + "\" not found for command \"" - + command.getName() + "\""); + throw new CommandLineException("specified class \"" + command.getApiMethod() + "\" not found for command \"" + + command.getName() + "\""); } } @@ -144,26 +144,26 @@ public class ApexModelHandler { * @param apiMethod the method itself * @return the argument list */ - private Object[] getParameterArray(final CLICommand command, final TreeMap argumentValues, - final Method apiMethod) { + private Object[] getParameterArray(final CommandLineCommand command, + final SortedMap argumentValues, final Method apiMethod) { final Object[] parameterArray = new Object[argumentValues.size()]; - int i = 0; + int item = 0; try { for (final Class parametertype : apiMethod.getParameterTypes()) { - final String parameterValue = - argumentValues.get(command.getArgumentList().get(i).getArgumentName()).getValue(); + final String parameterValue = argumentValues.get(command.getArgumentList().get(item).getArgumentName()) + .getValue(); if (parametertype.equals(boolean.class)) { - parameterArray[i] = Boolean.valueOf(parameterValue); + parameterArray[item] = Boolean.valueOf(parameterValue); } else { - parameterArray[i] = parameterValue; + parameterArray[item] = parameterValue; } - i++; + item++; } } catch (final Exception e) { - throw new CLIException("number of argument mismatch on method \"" + command.getApiMethod() - + "\" for command \"" + command.getName() + "\""); + throw new CommandLineException("number of argument mismatch on method \"" + command.getApiMethod() + + "\" for command \"" + command.getName() + "\""); } return parameterArray; diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIArgument.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIArgument.java deleted file mode 100644 index b215f69e4..000000000 --- a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIArgument.java +++ /dev/null @@ -1,144 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.apex.auth.clieditor; - -import org.onap.policy.apex.model.utilities.Assertions; - -/** - * This class holds the definition of an argument of a CLI command. - * - * @author Liam Fallon (liam.fallon@ericsson.com) - */ -public class CLIArgument implements Comparable { - private final String argumentName; - private final boolean nullable; - private final String description; - - /** - * This Constructor constructs a non nullable command line argument with a blank name and - * description. - */ - public CLIArgument() { - this("", false, ""); - } - - /** - * This Constructor constructs a non nullable command line argument with the given name and - * description. - * - * @param incomingArgumentName the argument name - */ - public CLIArgument(final String incomingArgumentName) { - this(incomingArgumentName, false, ""); - } - - /** - * This Constructor constructs a command line argument with the given name, nullability, and - * description. - * - * @param argumentName the argument name - * @param nullable the nullable - * @param description the description - */ - public CLIArgument(final String argumentName, final boolean nullable, final String description) { - this.argumentName = argumentName; - this.nullable = nullable; - this.description = description; - } - - /** - * Gets the argument name. - * - * @return the argument name - */ - public String getArgumentName() { - return argumentName; - } - - /** - * Checks if the argument is nullable. - * - * @return true, if checks if the argument is nullable - */ - public boolean isNullable() { - return nullable; - } - - /** - * Gets the argument description. - * - * @return the argument description - */ - public String getDescription() { - return description; - } - - /** - * Gets the argument help. - * - * @return the argument help - */ - public String getHelp() { - final StringBuilder builder = new StringBuilder(); - builder.append(argumentName); - builder.append(nullable ? ": (O) " : ": (M) "); - builder.append(description); - return builder.toString(); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "CLIArgument [argumentName=" + argumentName + ", nullable=" + nullable + ", description=" + description - + "]"; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Comparable#compareTo(java.lang.Object) - */ - @Override - public int compareTo(final CLIArgument otherArgument) { - Assertions.argumentNotNull(otherArgument, "comparison object may not be null"); - - if (this == otherArgument) { - return 0; - } - if (getClass() != otherArgument.getClass()) { - return this.hashCode() - otherArgument.hashCode(); - } - - final CLIArgument other = otherArgument; - - if (!argumentName.equals(other.argumentName)) { - return argumentName.compareTo(other.argumentName); - } - if (nullable != other.nullable) { - return (this.hashCode() - other.hashCode()); - } - return description.compareTo(otherArgument.description); - } -} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIArgumentValue.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIArgumentValue.java deleted file mode 100644 index d87a8dc5b..000000000 --- a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIArgumentValue.java +++ /dev/null @@ -1,91 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.apex.auth.clieditor; - -/** - * This class represents an argument used on a command and its value. - * - * @author Liam Fallon (liam.fallon@ericsson.com) - */ -public class CLIArgumentValue { - private final CLIArgument cliArgument; - private boolean specified; - private String value; - - /** - * The Constructor creates an argument value for the given argument, has not been set, and has - * no value. - * - * @param cliArgument the argument for which this object is a value - */ - public CLIArgumentValue(final CLIArgument cliArgument) { - this.cliArgument = cliArgument; - specified = false; - value = null; - } - - /** - * Gets the argument for which this object is a value. - * - * @return the argument for which this object is a value - */ - public CLIArgument getCliArgument() { - return cliArgument; - } - - /** - * Checks if the argument value is specified. - * - * @return true, if the argument value is specified - */ - public boolean isSpecified() { - return specified; - } - - /** - * Gets the argument value. - * - * @return the argument value - */ - public String getValue() { - return value; - } - - /** - * Sets the argument value. - * - * @param value the argument value - */ - public void setValue(final String value) { - this.value = value; - specified = true; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "CLIArgumentValue [cliArgument=" + cliArgument + ", specified=" + specified + ", value=" + value + "]"; - } -} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLICommand.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLICommand.java deleted file mode 100644 index 40c0a40a5..000000000 --- a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLICommand.java +++ /dev/null @@ -1,240 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.apex.auth.clieditor; - -import java.util.ArrayList; -import java.util.List; - -import org.onap.policy.apex.model.utilities.Assertions; - -/** - * This class represents a single Apex CLI command that is issued to the Apex Editor Java API - * {@link org.onap.policy.apex.model.modelapi.ApexEditorApi}. - * - * @author Liam Fallon (liam.fallon@ericsson.com) - */ -public class CLICommand implements Comparable { - private String name = ""; - private final List keywordlist = new ArrayList<>(); - private final List argumentList = new ArrayList<>(); - private String apiMethod = ""; - private boolean systemCommand = false; - private String description = ""; - - /** - * Gets the class name of the class that executes this command in the Java API. - * - * @return the class name of the class that executes this command in the Java API - */ - public String getAPIClassName() { - final int lastDotPos = apiMethod.lastIndexOf('.'); - if (lastDotPos == -1) { - throw new CLIException("invalid API method name specified on command \"" + name - + "\", class name not found: " + apiMethod); - } - return apiMethod.substring(0, lastDotPos); - } - - /** - * Gets the method name of the method that executes this command in the Java API. - * - * @return the the method name of the method that executes this command in the Java API - */ - public String getAPIMethodName() { - final int lastDotPos = apiMethod.lastIndexOf('.'); - if (lastDotPos == -1) { - throw new CLIException("invalid API method name specified on command \"" + name - + "\", class name not found: " + apiMethod); - } - if (lastDotPos == apiMethod.length() - 1) { - throw new CLIException("no API method name specified on command \"" + name + "\": " + apiMethod); - } - return apiMethod.substring(lastDotPos + 1); - } - - /** - * Gets the name of the editor command. - * - * @return the name of the editor command - */ - public String getName() { - return name; - } - - /** - * Sets the name of the editor command. - * - * @param name the name of the editor command - */ - public void setName(final String name) { - this.name = name; - } - - /** - * Gets the list of keywords for this command. - * - * @return the list of keywords for this command - */ - public List getKeywordlist() { - return keywordlist; - } - - /** - * Gets the list of arguments for this command. - * - * @return the list of arguments for this command - */ - public List getArgumentList() { - return argumentList; - } - - /** - * Gets the method of the method that executes this command in the Java API. - * - * @return the method of the method that executes this command in the Java API - */ - public String getApiMethod() { - return apiMethod; - } - - /** - * Sets the method of the method that executes this command in the Java API. - * - * @param apiMethod the method of the method that executes this command in the Java API - */ - public void setApiMethod(final String apiMethod) { - this.apiMethod = apiMethod; - } - - /** - * Gets the description of the command. - * - * @return the description of the command - */ - public String getDescription() { - return description; - } - - /** - * Sets the description of the command. - * - * @param description the description of the command - */ - public void setDescription(final String description) { - this.description = description; - } - - /** - * Checks if this command is a system command. - * - * @return true, if this command is a system command - */ - public boolean isSystemCommand() { - return systemCommand; - } - - /** - * Sets whether this command is a system command. - * - * @param systemCommand whether this command is a system command - */ - public void setSystemCommand(final boolean systemCommand) { - this.systemCommand = systemCommand; - } - - /** - * Gets help for this command. - * - * @return the help for this command - */ - public String getHelp() { - final StringBuilder builder = new StringBuilder(); - for (final String keyword : keywordlist) { - builder.append(keyword); - builder.append(' '); - } - builder.append('{'); - builder.append(name); - builder.append("}: "); - builder.append(description); - - for (final CLIArgument argument : argumentList) { - if (argument == null) { - continue; - } - builder.append("\n\t"); - builder.append(argument.getHelp()); - } - return builder.toString(); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "CLICommand [name=" + name + ",keywordlist=" + keywordlist + ", argumentList=" + argumentList - + ", apiMethod=" + apiMethod + ", systemCommand=" + systemCommand + ", description=" + description - + "]"; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Comparable#compareTo(java.lang.Object) - */ - @Override - public int compareTo(final CLICommand otherCommand) { - Assertions.argumentNotNull(otherCommand, "comparison object may not be null"); - - if (this == otherCommand) { - return 0; - } - if (getClass() != otherCommand.getClass()) { - return this.hashCode() - otherCommand.hashCode(); - } - - final CLICommand other = otherCommand; - - for (int i = 0, j = 0;; i++, j++) { - if (i < keywordlist.size() && j < otherCommand.keywordlist.size()) { - if (!keywordlist.get(i).equals(other.keywordlist.get(j))) { - return keywordlist.get(i).compareTo(other.keywordlist.get(j)); - } - } else if (i == keywordlist.size() && j == otherCommand.keywordlist.size()) { - break; - } else if (i == keywordlist.size()) { - return -1; - } else { - return 1; - } - } - if (!argumentList.equals(other.argumentList)) { - return (argumentList.hashCode() - other.argumentList.hashCode()); - } - if (systemCommand != other.systemCommand) { - return (this.hashCode() - other.hashCode()); - } - return apiMethod.compareTo(other.apiMethod); - } -} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLICommands.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLICommands.java deleted file mode 100644 index 4c9bab045..000000000 --- a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLICommands.java +++ /dev/null @@ -1,42 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.apex.auth.clieditor; - -import java.util.Set; -import java.util.TreeSet; - -/** - * This class contains the CLI commands read in from a JSON file. - * - * @author Liam Fallon (liam.fallon@ericsson.com) - */ -public class CLICommands { - private final Set commandList = new TreeSet<>(); - - /** - * Gets the command set. - * - * @return the command set - */ - public Set getCommandSet() { - return commandList; - } -} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIEditorLoop.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIEditorLoop.java deleted file mode 100644 index a574099bf..000000000 --- a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIEditorLoop.java +++ /dev/null @@ -1,543 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.apex.auth.clieditor; - -import static org.onap.policy.apex.model.utilities.TreeMapUtils.findMatchingEntries; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.util.AbstractMap.SimpleEntry; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map.Entry; -import java.util.Properties; -import java.util.TreeMap; - -import org.onap.policy.apex.model.modelapi.ApexApiResult; -import org.onap.policy.apex.model.modelapi.ApexApiResult.Result; -import org.onap.policy.apex.model.utilities.TextFileUtils; -import org.onap.policy.apex.model.utilities.TreeMapUtils; - -/** - * This class implements the editor loop, the loop of execution that continuously executes commands - * until the quit command is issued or EOF is detected on input. - * - * @author Liam Fallon (liam.fallon@ericsson.com) - */ -public class CLIEditorLoop { - // The model handler that is handling the API towards the Apex model being editied - private final ApexModelHandler modelHandler; - - // Holds the current location in the keyword hierarchy - private final ArrayDeque keywordNodeDeque = new ArrayDeque<>(); - - // Logic block tags - private final String logicBlockStartTag; - private final String logicBlockEndTag; - - // File Macro tag - private final String macroFileTag; - - /** - * Initiate the loop with the keyword node tree. - * - * @param properties The CLI editor properties defined for execution - * @param modelHandler the model handler that will handle commands - * @param rootKeywordNode The root keyword node tree - */ - public CLIEditorLoop(final Properties properties, final ApexModelHandler modelHandler, - final KeywordNode rootKeywordNode) { - this.modelHandler = modelHandler; - keywordNodeDeque.push(rootKeywordNode); - - logicBlockStartTag = properties.getProperty("DEFAULT_LOGIC_BLOCK_START_TAG"); - logicBlockEndTag = properties.getProperty("DEFAULT_LOGIC_BLOCK_END_TAG"); - macroFileTag = properties.getProperty("DEFAULT_MACRO_FILE_TAG"); - } - - /** - * Run a command loop. - * - * @param inputStream The stream to read commands from - * @param outputStream The stream to write command output and messages to - * @param parameters The parameters for the CLI editor - * @return the exit code from command processing - * @throws IOException Thrown on exceptions on IO - */ - public int runLoop(final InputStream inputStream, final OutputStream outputStream, final CLIParameters parameters) - throws IOException { - // Readers and writers for input and output - final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); - final PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream)); - - // The parser parses the input lines into commands and arguments - final CLILineParser parser = new CLILineParser(); - - // The main loop for command handing, it continues until EOF on the input stream or until a - // quit command - int errorCount = 0; - ApexApiResult result = new ApexApiResult(); - while (result.getResult() != Result.FINISHED) { - if (!parameters.isIgnoreCommandFailures() && errorCount > 0) { - break; - } - - // Output prompt and get a line of input - writer.print(getPrompt()); - writer.flush(); - String line = reader.readLine(); - if (line == null) { - break; - } - - // Expand any macros in the script - try { - while (line.contains(macroFileTag)) { - line = expandMacroFile(parameters, line); - } - } - // Print any error messages from command parsing and finding - catch (final CLIException e) { - writer.println(e.getMessage()); - errorCount++; - continue; - } - - if (parameters.isEchoSet()) { - writer.println(line); - } - - String logicBlock = null; - if (line.trim().endsWith(logicBlockStartTag)) { - line = line.replace(logicBlockStartTag, "").trim(); - - logicBlock = ""; - while (true) { - String logicLine = reader.readLine(); - if (logicLine == null) { - logicBlock = null; - break; - } - - try { - while (logicLine.contains(macroFileTag)) { - logicLine = expandMacroFile(parameters, logicLine); - } - } - // Print any error messages from command parsing and finding - catch (final CLIException e) { - writer.println(e.getMessage()); - errorCount++; - continue; - } - - if (parameters.isEchoSet()) { - writer.println(logicLine); - } - - if (logicLine.trim().endsWith(logicBlockEndTag)) { - logicBlock += logicLine.replace(logicBlockEndTag, "").trim() + "\n"; - break; - } else { - logicBlock += logicLine + "\n"; - } - } - } - - try { - // Parse the line into a list of commands and arguments - final List commandWords = parser.parse(line, logicBlock); - - // Find the command, if the command is null, then we are simply changing position in - // the hierarchy - final CLICommand command = findCommand(commandWords); - if (command != null) { - // Check the arguments of the command - final TreeMap argumentValues = getArgumentValues(command, commandWords); - - // Execute the command, a FINISHED result means a command causes the loop to - // leave execution - result = executeCommand(command, argumentValues, writer); - if (result.isNok()) { - errorCount++; - } - } - } - // Print any error messages from command parsing and finding - catch (final CLIException e) { - writer.println(e.getMessage()); - errorCount++; - } catch (final Exception e) { - e.printStackTrace(writer); - } - } - - // Get the output model - if (!parameters.isSuppressModelOutputSet()) { - final String modelString = modelHandler.writeModelToString(writer); - - if (parameters.checkSetOutputModelFileName()) { - TextFileUtils.putStringAsTextFile(modelString, parameters.getOutputModelFileName()); - } else { - System.out.println(modelString); - } - } - - reader.close(); - writer.close(); - - return errorCount; - } - - /** - * Output a prompt that indicates where in the keyword hierarchy we are. - * - * @return A string with the prompt - */ - private String getPrompt() { - final StringBuilder builder = new StringBuilder(); - final Iterator keynodeDequeIter = keywordNodeDeque.descendingIterator(); - - while (keynodeDequeIter.hasNext()) { - builder.append('/'); - builder.append(keynodeDequeIter.next().getKeyword()); - } - builder.append("> "); - - return builder.toString(); - } - - /** - * Finds a command for the given input command words. Command words need only ne specified - * enough to uniquely identify them. Therefore, "p s o c" will find the command "policy state - * output create" - * - * @param commandWords The commands and arguments parsed from the command line by the parser - * @return The found command - */ - - private CLICommand findCommand(final List commandWords) { - CLICommand command = null; - - final KeywordNode startKeywordNode = keywordNodeDeque.peek(); - - // Go down through the keywords searching for the command - for (int i = 0; i < commandWords.size(); i++) { - final KeywordNode searchKeywordNode = keywordNodeDeque.peek(); - - // We have got to the arguments, time to stop looking - if (commandWords.get(i).indexOf('=') > 0) { - unwindStack(startKeywordNode); - throw new CLIException("command not found: " + stringAL2String(commandWords)); - } - - // If the node entries found is not equal to one, then we have either no command or more - // than one command matching - final List> foundNodeEntries = - findMatchingEntries(searchKeywordNode.getChildren(), commandWords.get(i)); - if (foundNodeEntries.isEmpty()) { - unwindStack(startKeywordNode); - throw new CLIException("command not found: " + stringAL2String(commandWords)); - } else if (foundNodeEntries.size() > 1) { - unwindStack(startKeywordNode); - throw new CLIException("multiple commands matched: " + stringAL2String(commandWords) + " [" - + nodeAL2String(foundNodeEntries) + ']'); - } - - // Record the fully expanded command word - commandWords.set(i, foundNodeEntries.get(0).getKey()); - - // Check if there is a command - final KeywordNode childKeywordNode = foundNodeEntries.get(0).getValue(); - command = childKeywordNode.getCommand(); - - // If the command is null, we go into a sub mode, otherwise we unwind the stack of - // commands and return the found command - if (command == null) { - keywordNodeDeque.push(childKeywordNode); - } else { - unwindStack(startKeywordNode); - return command; - } - } - - return null; - } - - /** - * Unwind the stack of keyword node entries we have placed on the queue in a command search. - * - * @param startKeywordNode The point on the queue we want to unwind to - */ - private void unwindStack(final KeywordNode startKeywordNode) { - // Unwind the stack - while (true) { - if (keywordNodeDeque.peek().equals(startKeywordNode)) { - return; - } - keywordNodeDeque.pop(); - } - } - - /** - * Check the arguments of the command. - * - * @param command The command to check - * @param commandWords The command words entered - * @return the argument values - */ - private TreeMap getArgumentValues(final CLICommand command, - final List commandWords) { - final TreeMap argumentValues = new TreeMap<>(); - for (final CLIArgument argument : command.getArgumentList()) { - if (argument != null) { - argumentValues.put(argument.getArgumentName(), new CLIArgumentValue(argument)); - } - } - - // Set the value of the arguments - for (final Entry argument : getCommandArguments(commandWords)) { - final List> foundArguments = - TreeMapUtils.findMatchingEntries(argumentValues, argument.getKey()); - if (foundArguments.size() == 0) { - throw new CLIException("command " + stringAL2String(commandWords) + ": " + " argument \"" - + argument.getKey() + "\" not allowed on command"); - } else if (foundArguments.size() > 1) { - throw new CLIException("command " + stringAL2String(commandWords) + ": " + " argument " + argument - + " matches multiple arguments [" + argumentAL2String(foundArguments) + ']'); - } - - // Set the value of the argument, stripping off any quotes - final String argumentValue = argument.getValue().replaceAll("^\"", "").replaceAll("\"$", ""); - foundArguments.get(0).getValue().setValue(argumentValue); - } - - // Now check all mandatory arguments are set - for (final CLIArgumentValue argumentValue : argumentValues.values()) { - // Argument values are null by default so if this argument is not nullable it is - // mandatory - if (!argumentValue.isSpecified() && !argumentValue.getCliArgument().isNullable()) { - throw new CLIException("command " + stringAL2String(commandWords) + ": " + " mandatory argument \"" - + argumentValue.getCliArgument().getArgumentName() + "\" not specified"); - } - } - - return argumentValues; - } - - /** - * Get the arguments of the command, the command words have already been conditioned into an - * array starting with the command words and ending with the arguments as name=value tuples. - * - * @param commandWords The command words entered by the user - * @return the arguments as an entry array list - */ - private ArrayList> getCommandArguments(final List commandWords) { - final ArrayList> arguments = new ArrayList<>(); - - // Iterate over the command words, arguments are of the format name=value - for (final String word : commandWords) { - final int equalsPos = word.indexOf('='); - if (equalsPos > 0) { - arguments.add( - new SimpleEntry<>(word.substring(0, equalsPos), word.substring(equalsPos + 1, word.length()))); - } - } - - return arguments; - } - - /** - * Execute system and editor commands. - * - * @param command The command to execute - * @param argumentValues The arguments input on the command line to invoke the command - * @param writer The writer to use for any output from the command - * @return the result of execution of the command - */ - private ApexApiResult executeCommand(final CLICommand command, - final TreeMap argumentValues, final PrintWriter writer) { - if (command.isSystemCommand()) { - return exceuteSystemCommand(command, writer); - } else { - return modelHandler.executeCommand(command, argumentValues, writer); - } - } - - /** - * Execute system commands. - * - * @param command The command to execute - * @param writer The writer to use for any output from the command - * @return the result of execution of the command - */ - private ApexApiResult exceuteSystemCommand(final CLICommand command, final PrintWriter writer) { - if ("back".equals(command.getName())) { - return executeBackCommand(); - } else if ("help".equals(command.getName())) { - return executeHelpCommand(writer); - } else if ("quit".equals(command.getName())) { - return executeQuitCommand(); - } else { - return new ApexApiResult(Result.SUCCESS); - } - } - - /** - * Execute the "back" command. - * - * @return the result of execution of the command - */ - private ApexApiResult executeBackCommand() { - if (keywordNodeDeque.size() > 1) { - keywordNodeDeque.pop(); - } - return new ApexApiResult(Result.SUCCESS); - } - - /** - * Execute the "quit" command. - * - * @return the result of execution of the command - */ - private ApexApiResult executeQuitCommand() { - return new ApexApiResult(Result.FINISHED); - } - - /** - * Execute the "help" command. - * - * @param writer The writer to use for output from the command - * @return the result of execution of the command - */ - private ApexApiResult executeHelpCommand(final PrintWriter writer) { - for (final CLICommand command : keywordNodeDeque.peek().getCommands()) { - writer.println(command.getHelp()); - } - return new ApexApiResult(Result.SUCCESS); - } - - /** - * Helper method to output an array list of keyword node entries to a string. - * - * @param nodeEntryArrayList the array list of keyword node entries - * @return the string - */ - private String nodeAL2String(final List> nodeEntryArrayList) { - final ArrayList stringArrayList = new ArrayList<>(); - for (final Entry node : nodeEntryArrayList) { - stringArrayList.add(node.getValue().getKeyword()); - } - - return stringAL2String(stringArrayList); - } - - /** - * Helper method to output an array list of argument entries to a string. - * - * @param argumentArrayList the argument array list - * @return the string - */ - private String argumentAL2String(final List> argumentArrayList) { - final ArrayList stringArrayList = new ArrayList<>(); - for (final Entry argument : argumentArrayList) { - stringArrayList.add(argument.getValue().getCliArgument().getArgumentName()); - } - - return stringAL2String(stringArrayList); - } - - /** - * Helper method to output an array list of strings to a string. - * - * @param stringArrayList the array list of strings - * @return the string - */ - private String stringAL2String(final List stringArrayList) { - final StringBuilder builder = new StringBuilder(); - boolean first = true; - for (final String word : stringArrayList) { - if (first) { - first = false; - } else { - builder.append(','); - } - builder.append(word); - } - - return builder.toString(); - } - - /** - * This method reads in the file from a file macro statement, expands the macro, and replaces - * the Macro tag in the line with the file contents. - * - * @param parameters The parameters for the CLI editor - * @param line The line with the macro keyword in it - * @return the expanded line - */ - private String expandMacroFile(final CLIParameters parameters, final String line) { - final int macroTagPos = line.indexOf(macroFileTag); - - // Get the line before and after the macro tag - final String lineBeforeMacroTag = line.substring(0, macroTagPos); - final String lineAfterMacroTag = line.substring(macroTagPos + macroFileTag.length()).replaceAll("^\\s*", ""); - - // Get the file name that is the argument of the Macro tag - final String[] lineWords = lineAfterMacroTag.split("\\s+"); - - if (lineWords.length == 0) { - throw new CLIException("no file name specified for Macro File Tag"); - } - - // Get the macro file name and the remainder of the line after the file name - String macroFileName = lineWords[0]; - final String lineAfterMacroFileName = lineAfterMacroTag.replaceFirst(macroFileName, ""); - - if (macroFileName.length() > 2 && macroFileName.startsWith("\"") && macroFileName.endsWith("\"")) { - macroFileName = macroFileName.substring(1, macroFileName.length() - 1); - } else { - throw new CLIException( - "macro file name \"" + macroFileName + "\" must exist and be quoted with double quotes \"\""); - } - - // Append the working directory to the macro file name - macroFileName = parameters.getWorkingDirectory() + File.separatorChar + macroFileName; - - // Now, get the text file for the argument of the macro - String macroFileContents = null; - try { - macroFileContents = TextFileUtils.getTextFileAsString(macroFileName); - } catch (final IOException e) { - throw new CLIException("file \"" + macroFileName + "\" specified in Macro File Tag not found", e); - } - - return lineBeforeMacroTag + macroFileContents + lineAfterMacroFileName; - } -} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIException.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIException.java deleted file mode 100644 index 94b8c14a6..000000000 --- a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIException.java +++ /dev/null @@ -1,49 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.apex.auth.clieditor; - -/** - * A run time exception used to report parsing and command input errors. - * - * @author Liam Fallon (liam.fallon@ericsson.com) - */ -public class CLIException extends IllegalArgumentException { - private static final long serialVersionUID = 6520231162404452427L; - - /** - * Create a CLIException with a message. - * - * @param message the message - */ - public CLIException(final String message) { - super(message); - } - - /** - * Create a CLIException with a message and an exception. - * - * @param message the message - * @param th the throwable - */ - public CLIException(final String message, final Throwable th) { - super(message, th); - } -} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLILineParser.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLILineParser.java deleted file mode 100644 index 70c2f834b..000000000 --- a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLILineParser.java +++ /dev/null @@ -1,323 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.apex.auth.clieditor; - -import java.util.ArrayList; -import java.util.List; - -/** - * This class chops a command line up into commands, parameters and arguments. - * - * @author Liam Fallon (liam.fallon@ericsson.com) - */ -public class CLILineParser { - - /** - * This method breaks a line of input up into commands, parameters, and arguments. Commands are - * standalone words at the beginning of the line, of which there may be multiple Parameters are - * single words followed by an '=' character Arguments are single words or a block of quoted - * text following an '=' character. - * - *

Format: command [command....] parameter=argument [parameter = argument] - * - *

Examples entity create name=hello description="description of hello" help entity list - * - * @param line The line to parse - * @param logicBlock A block of logic code to be taken literally - * @return the string array list - */ - public List parse(final String line, final String logicBlock) { - return checkFormat( - mergeArguments(mergeEquals( - splitOnEquals(stripAndSplitWords(mergeQuotes(splitOnChar(stripComments(line), '\"')))))), - logicBlock); - } - - /** - * Strip comments from lines, comments start with a # character. - * - * @param line the line - * @return the line without comments - */ - private String stripComments(final String line) { - final int commentPos = line.indexOf('#'); - if (commentPos == -1) { - return line; - } else { - return line.substring(0, commentPos); - } - } - - /** - * This method merges an array with separate quotes into an array with quotes delimiting the - * start and end of quoted words Example [Humpty ],["],[Dumpty sat on the wall],["],[, Humpty - * Dumpty had ],["],["],a ["],[great],["],[ fall] becomes [Humpty ],["Dumpty sat on the - * wall"],[, Humpty Dumpty had ],[""],[a],["great"],[ fall]. - * - * @param wordsSplitOnQuotes the words split on quotes - * @return the merged array list - */ - private ArrayList mergeQuotes(final ArrayList wordsSplitOnQuotes) { - final ArrayList wordsWithQuotesMerged = new ArrayList<>(); - - for (int i = 0; i < wordsSplitOnQuotes.size();) { - if ("\"".equals(wordsSplitOnQuotes.get(i))) { - StringBuilder quotedWord = new StringBuilder(wordsSplitOnQuotes.get(i++)); - - for (; i < wordsSplitOnQuotes.size(); i++) { - quotedWord.append(wordsSplitOnQuotes.get(i)); - if ("\"".equals(wordsSplitOnQuotes.get(i))) { - i++; - break; - } - } - String quotedWordToString = quotedWord.toString(); - if (quotedWordToString.matches("^\".*\"$")) { - wordsWithQuotesMerged.add(quotedWordToString); - } else { - throw new CLIException("trailing quote found in input " + wordsSplitOnQuotes); - } - } else { - wordsWithQuotesMerged.add(wordsSplitOnQuotes.get(i++)); - } - } - - return wordsWithQuotesMerged; - } - - /** - * This method splits the words on an array list into an array list where each portion of the - * line is split into words by '=', quoted words are ignored Example: aaa = bbb = ccc=ddd=eee = - * becomes [aaa ],[=],[bbb ],[=],[ccc],[=],[ddd],[=],[eee ],[=]. - * - * @param words the words - * @return the merged array list - */ - private ArrayList splitOnEquals(final ArrayList words) { - final ArrayList wordsSplitOnEquals = new ArrayList<>(); - - for (final String word : words) { - // Is this a quoted word ? - if (word.startsWith("\"")) { - wordsSplitOnEquals.add(word); - continue; - } - - // Split on equals character - final ArrayList splitWords = splitOnChar(word, '='); - for (final String splitWord : splitWords) { - wordsSplitOnEquals.add(splitWord); - } - } - - return wordsSplitOnEquals; - } - - /** - * This method merges an array with separate equals into an array with equals delimiting the - * start of words Example: [aaa ],[=],[bbb ],[=],[ccc],[=],[ddd],[=],[eee ],[=] becomes [aaa - * ],[= bbb ],[= ccc],[=ddd],[=eee ],[=]. - * - * @param wordsSplitOnEquals the words split on equals - * @return the merged array list - */ - private ArrayList mergeEquals(final ArrayList wordsSplitOnEquals) { - final ArrayList wordsWithEqualsMerged = new ArrayList<>(); - - for (int i = 0; i < wordsSplitOnEquals.size();) { - // Is this a quoted word ? - if (wordsSplitOnEquals.get(i).startsWith("\"")) { - wordsWithEqualsMerged.add(wordsSplitOnEquals.get(i)); - continue; - } - - if ("=".equals(wordsSplitOnEquals.get(i))) { - if (i < wordsSplitOnEquals.size() - 1 && !wordsSplitOnEquals.get(i + 1).startsWith("=")) { - wordsWithEqualsMerged.add(wordsSplitOnEquals.get(i) + wordsSplitOnEquals.get(i + 1)); - i += 2; - } else { - wordsWithEqualsMerged.add(wordsSplitOnEquals.get(i++)); - } - } else { - wordsWithEqualsMerged.add(wordsSplitOnEquals.get(i++)); - } - } - - return wordsWithEqualsMerged; - } - - /** - * This method merges words that start with an '=' character with the previous word if that word - * does not start with an '='. - * - * @param words the words - * @return the merged array list - */ - private ArrayList mergeArguments(final ArrayList words) { - final ArrayList mergedArguments = new ArrayList<>(); - - for (int i = 0; i < words.size(); i++) { - // Is this a quoted word ? - if (words.get(i).startsWith("\"")) { - mergedArguments.add(words.get(i)); - continue; - } - - if (words.get(i).startsWith("=")) { - if (i > 0 && !words.get(i - 1).startsWith("=")) { - mergedArguments.remove(mergedArguments.size() - 1); - mergedArguments.add(words.get(i - 1) + words.get(i)); - } else { - mergedArguments.add(words.get(i)); - } - } else { - mergedArguments.add(words.get(i)); - } - } - - return mergedArguments; - } - - /** - * This method strips all non quoted white space down to single spaces and splits non-quoted - * words into separate words. - * - * @param words the words - * @return the array list with white space stripped and words split - */ - private ArrayList stripAndSplitWords(final ArrayList words) { - final ArrayList strippedAndSplitWords = new ArrayList<>(); - - for (String word : words) { - // Is this a quoted word - if (word.startsWith("\"")) { - strippedAndSplitWords.add(word); - continue; - } - - // Strip white space by replacing all white space with blanks and then removing leading - // and trailing blanks - word = word.replaceAll("\\s+", " ").trim(); - - if (word.length() == 0) { - continue; - } - - // Split on space characters - final String[] splitWords = word.split(" "); - for (final String splitWord : splitWords) { - strippedAndSplitWords.add(splitWord); - } - } - - return strippedAndSplitWords; - } - - /** - * This method splits a line of text into an array list where each portion of the line is split - * into words by a character, with the characters themselves as separate words Example: Humpty - * "Dumpty sat on the wall", Humpty Dumpty had ""a "great" fall becomes [Humpty ],["],[Dumpty - * sat on the wall],["],[, Humpty Dumpty had ],["],["],a ["],[great],["],[ fall]. - * - * @param line the input line - * @param splitChar the split char - * @return the split array list - */ - private ArrayList splitOnChar(final String line, final char splitChar) { - final ArrayList wordsSplitOnQuotes = new ArrayList<>(); - - int currentPos = 0; - while (currentPos != -1) { - final int quotePos = line.indexOf(splitChar, currentPos); - if (quotePos != -1) { - if (currentPos < quotePos) { - wordsSplitOnQuotes.add(line.substring(currentPos, quotePos)); - } - wordsSplitOnQuotes.add("" + splitChar); - currentPos = quotePos + 1; - - if (currentPos == line.length()) { - currentPos = -1; - } - } else { - wordsSplitOnQuotes.add(line.substring(currentPos)); - currentPos = quotePos; - } - } - - return wordsSplitOnQuotes; - } - - /** - * This method checks that an array list containing a command is in the correct format. - * - * @param commandWords the command words - * @param logicBlock A block of logic code to be taken literally - * @return the checked array list - */ - private ArrayList checkFormat(final ArrayList commandWords, final String logicBlock) { - // There should be at least one word - if (commandWords.isEmpty()) { - return commandWords; - } - - // The first word must be alphanumeric, that is a command - if (!commandWords.get(0).matches("^[a-zA-Z0-9]*$")) { - throw new CLIException( - "first command word is not alphanumeric or is not a command: " + commandWords.get(0)); - } - - // Now check that we have a sequence of commands at the beginning - int currentWordPos = 0; - while (currentWordPos < commandWords.size()) { - if (commandWords.get(currentWordPos).matches("^[a-zA-Z0-9]*$")) { - currentWordPos++; - } else { - break; - } - } - - while (currentWordPos < commandWords.size()) { - // From now on we should have a sequence of parameters with arguments delimited by a - // single '=' character - if (currentWordPos < commandWords.size() - 1 || logicBlock == null) { - // No logic block - if (commandWords.get(currentWordPos).matches("^[a-zA-Z0-9]+=[a-zA-Z0-9/\"].*$")) { - currentWordPos++; - } else { - throw new CLIException( - "command argument is not properly formed: " + commandWords.get(currentWordPos)); - } - } else { - // Logic block - if (commandWords.get(currentWordPos).matches("^[a-zA-Z0-9]+=")) { - commandWords.set(currentWordPos, commandWords.get(currentWordPos) + logicBlock); - currentWordPos++; - } else { - throw new CLIException( - "command argument is not properly formed: " + commandWords.get(currentWordPos)); - } - } - } - - return commandWords; - } -} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIParameterParser.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIParameterParser.java deleted file mode 100644 index 8a0c6eff3..000000000 --- a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIParameterParser.java +++ /dev/null @@ -1,159 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.apex.auth.clieditor; - -import java.nio.file.Paths; -import java.util.Arrays; - -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; - -/** - * This class reads and handles command line parameters to the Apex CLI editor. - * - * @author Liam Fallon (liam.fallon@ericsson.com) - */ -public class CLIParameterParser { - private static final int MAX_HELP_LINE_LENGTH = 120; - - // Apache Commons CLI options - private final Options options; - - /** - * Construct the options for the CLI editor. - */ - public CLIParameterParser() { - options = new Options(); - options.addOption(Option.builder("h").longOpt("help").desc("outputs the usage of this command").required(false) - .type(Boolean.class).build()); - options.addOption(Option.builder("m").longOpt("metadata-file").desc("name of the command metadata file to use") - .hasArg().argName("CMD_METADATA_FILE").required(false).type(String.class).build()); - options.addOption( - Option.builder("a").longOpt("model-props-file").desc("name of the apex model properties file to use") - .hasArg().argName("MODEL_PROPS_FILE").required(false).type(String.class).build()); - options.addOption(Option.builder("c").longOpt("command-file") - .desc("name of a file containing editor commands to run into the editor").hasArg() - .argName("COMMAND_FILE").required(false).type(String.class).build()); - options.addOption(Option.builder("l").longOpt("log-file") - .desc("name of a file that will contain command logs from the editor, will log to standard output " - + "if not specified or suppressed with \"-nl\" flag") - .hasArg().argName("LOG_FILE").required(false).type(String.class).build()); - options.addOption(Option.builder("nl").longOpt("no-log") - .desc("if specified, no logging or output of commands to standard output or log file is carried out") - .required(false).type(Boolean.class).build()); - options.addOption(Option.builder("nm").longOpt("no-model-output") - .desc("if specified, no output of a model to standard output or model output file is carried out, " - + "the user can use the \"save\" command in a script to save a model") - .required(false).type(Boolean.class).build()); - options.addOption(Option.builder("i").longOpt("input-model-file") - .desc("name of a file that contains an input model for the editor").hasArg().argName("INPUT_MODEL_FILE") - .required(false).type(String.class).build()); - options.addOption(Option.builder("o").longOpt("output-model-file") - .desc("name of a file that will contain the output model for the editor, " - + "will output model to standard output if not specified or suppressed with \"-nm\" flag") - .hasArg().argName("OUTPUT_MODEL_FILE").required(false).type(String.class).build()); - options.addOption(Option.builder("if").longOpt("ignore-failures") - .desc("true or false, ignore failures of commands in command files and continue executing the " - + "command file") - .hasArg().argName("IGNORE_FAILURES_FLAG").required(false).type(Boolean.class).build()); - options.addOption(Option.builder("wd").longOpt("working-directory") - .desc("the working directory that is the root for the CLI editor and is the root from which to " - + "look for included macro files") - .hasArg().argName("WORKING_DIRECTORY").required(false).type(String.class).build()); - } - - /** - * Parse the command line options. - * - * @param args The arguments - * @return the CLI parameters - */ - public CLIParameters parse(final String[] args) { - CommandLine commandLine = null; - try { - commandLine = new DefaultParser().parse(options, args); - } catch (final ParseException e) { - throw new CLIException("invalid command line arguments specified : " + e.getMessage()); - } - - final CLIParameters parameters = new CLIParameters(); - final String[] remainingArgs = commandLine.getArgs(); - - if (remainingArgs.length > 0) { - throw new CLIException("too many command line arguments specified : " + Arrays.toString(remainingArgs)); - } - - if (commandLine.hasOption('h')) { - parameters.setHelp(true); - } - if (commandLine.hasOption('m')) { - parameters.setMetadataFileName(commandLine.getOptionValue('m')); - } - if (commandLine.hasOption('a')) { - parameters.setApexPorpertiesFileName(commandLine.getOptionValue('a')); - } - if (commandLine.hasOption('c')) { - parameters.setCommandFileName(commandLine.getOptionValue('c')); - } - if (commandLine.hasOption('l')) { - parameters.setLogFileName(commandLine.getOptionValue('l')); - } - if (commandLine.hasOption("nl")) { - parameters.setSuppressLog(true); - } - if (commandLine.hasOption("nm")) { - parameters.setSuppressModelOutput(true); - } - if (commandLine.hasOption('i')) { - parameters.setInputModelFileName(commandLine.getOptionValue('i')); - } - if (commandLine.hasOption('o')) { - parameters.setOutputModelFileName(commandLine.getOptionValue('o')); - } - if (commandLine.hasOption("if")) { - parameters.setIgnoreCommandFailuresSet(true); - parameters.setIgnoreCommandFailures(Boolean.valueOf(commandLine.getOptionValue("if"))); - } else { - parameters.setIgnoreCommandFailuresSet(false); - } - if (commandLine.hasOption("wd")) { - parameters.setWorkingDirectory(commandLine.getOptionValue("wd")); - } else { - parameters.setWorkingDirectory(Paths.get("").toAbsolutePath().toString()); - } - - return parameters; - } - - /** - * Print help information. - * - * @param mainClassName the main class name - */ - public void help(final String mainClassName) { - final HelpFormatter helpFormatter = new HelpFormatter(); - helpFormatter.printHelp(MAX_HELP_LINE_LENGTH, mainClassName + " [options...]", "options", options, ""); - } -} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIParameters.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIParameters.java deleted file mode 100644 index 24356d128..000000000 --- a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CLIParameters.java +++ /dev/null @@ -1,573 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2016-2018 Ericsson. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.apex.auth.clieditor; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.onap.policy.common.utils.resources.ResourceUtils; - -/** - * This class reads and handles command line parameters to the Apex CLI editor. - * - * @author Liam Fallon (liam.fallon@ericsson.com) - */ -public class CLIParameters { - // Default location of the command definition meta data in JSON - private static final String JSON_COMMAND_METADATA_RESOURCE = "etc/editor/Commands.json"; - private static final String APEX_MODEL_PROPERTIES_RESOURCE = "etc/editor/ApexModelProperties.json"; - - // The editor parameters - private boolean helpSet = false; - private String metadataFileName = null; - private String apexPropertiesFileName = null; - private String commandFileName = null; - private String inputModelFileName = null; - private String outputModelFileName = null; - private String workingDirectory = null; - private String logFileName = null; - private boolean echo = false; - private boolean suppressLog = false; - private boolean suppressModelOutput = false; - private boolean ignoreCommandFailuresSet = false; - private boolean ignoreCommandFailures = false; - - /** - * Validates the command line parameters. - */ - public void validate() { - validateReadableFile("Metadata File", metadataFileName); - validateReadableFile("Properties File", apexPropertiesFileName); - validateReadableFile("Command File", commandFileName); - validateReadableFile("Input Model File", inputModelFileName); - validateWritableFile("Output Model File", outputModelFileName); - validateWritableFile("Log File", logFileName); - validateWritableDirectory("Working Directory", workingDirectory); - - if (isSuppressLogSet()) { - setEcho(false); - } else { - if (checkSetCommandFileName()) { - setEcho(true); - if (!checkSetIgnoreCommandFailures()) { - setIgnoreCommandFailures(false); - } - } else { - setEcho(false); - if (!checkSetIgnoreCommandFailures()) { - setIgnoreCommandFailures(true); - } - } - } - } - - /** - * Gets the command metadata for the editor commands as a stream. - * - * @return the command metadata for the editor commands as a stream. - * @throws IOException the IO exception - */ - public InputStream getMetadataStream() throws IOException { - if (metadataFileName == null) { - return ResourceUtils.getResourceAsStream(JSON_COMMAND_METADATA_RESOURCE); - } else { - return new FileInputStream(new File(metadataFileName)); - } - } - - /** - * Gets the location of command metadata for the editor commands. - * - * @return the location of command metadata for the editor commands - */ - public String getMetadataLocation() { - if (metadataFileName == null) { - return "resource: \"" + JSON_COMMAND_METADATA_RESOURCE + "\""; - } else { - return "file: \"" + metadataFileName + "\""; - } - } - - /** - * Gets the properties that are used for command default values as a stream. - * - * @return the properties that are used for command default values as a stream - * @throws IOException the IO exception - */ - public InputStream getApexPropertiesStream() throws IOException { - if (apexPropertiesFileName == null) { - return ResourceUtils.getResourceAsStream(APEX_MODEL_PROPERTIES_RESOURCE); - } else { - return new FileInputStream(new File(apexPropertiesFileName)); - } - } - - /** - * Gets the location of the properties that are used for command default values. - * - * @return the location of the properties that are used for command default values - */ - public String getApexPropertiesLocation() { - if (metadataFileName == null) { - return "resource: \"" + APEX_MODEL_PROPERTIES_RESOURCE + "\""; - } else { - return "file: \"" + apexPropertiesFileName + "\""; - } - } - - /** - * Gets the input stream on which commands are being received. - * - * @return the input stream on which commands are being received - * @throws IOException the IO exception - */ - public InputStream getCommandInputStream() throws IOException { - if (commandFileName == null) { - return System.in; - } else { - return new FileInputStream(new File(commandFileName)); - } - } - - /** - * Gets the output stream on which command result messages are being output. - * - * @return the output stream on which command result messages are being output - * @throws IOException the IO exception - */ - public OutputStream getOutputStream() throws IOException { - // Check if log suppression is active, if so, consume all output on a byte array output stream - if (isSuppressLogSet()) { - return new ByteArrayOutputStream(); - - } - if (logFileName == null) { - return System.out; - } else { - return new FileOutputStream(new File(logFileName), true); - } - } - - /** - * Validate that a file is readable. - * - * @param fileTag the file tag, a tag used for information and error messages - * @param fileName the file name to check - */ - private void validateReadableFile(final String fileTag, final String fileName) { - if (fileName == null) { - return; - } - final File theFile = new File(fileName); - final String prefixExceptionMessage = "File " + fileName + "of type " + fileTag; - - if (!theFile.exists()) { - throw new CLIException(prefixExceptionMessage + " does not exist"); - } - if (!theFile.isFile()) { - throw new CLIException(prefixExceptionMessage + " is not a normal file"); - } - if (!theFile.canRead()) { - throw new CLIException(prefixExceptionMessage + " is ureadable"); - } - } - - /** - * Validate that a file is writable. - * - * @param fileTag the file tag, a tag used for information and error messages - * @param fileName the file name to check - */ - private void validateWritableFile(final String fileTag, final String fileName) { - if (fileName == null) { - return; - } - final File theFile = new File(fileName); - final String prefixExceptionMessage = "File " + fileName + "of type " + fileTag; - if (theFile.exists()) { - if (!theFile.isFile()) { - throw new CLIException(prefixExceptionMessage + " is not a normal file"); - } - if (!theFile.canWrite()) { - throw new CLIException(prefixExceptionMessage + " cannot be written"); - } - } else { - try { - theFile.createNewFile(); - } catch (final IOException e) { - throw new CLIException(prefixExceptionMessage + " cannot be created: ", e); - } - } - } - - /** - * Validate that a directory exists and is writable. - * - * @param directoryTag the directory tag, a tag used for information and error messages - * @param directoryName the directory name to check - */ - private void validateWritableDirectory(final String directoryTag, final String directoryName) { - if (directoryName == null) { - return; - } - final File theDirectory = new File(directoryName); - final String prefixExceptionMessage = "directory " + directoryName + "of type " + directoryTag; - - if (theDirectory.exists()) { - if (!theDirectory.isDirectory()) { - throw new CLIException(prefixExceptionMessage + " is not a directory"); - } - if (!theDirectory.canWrite()) { - throw new CLIException(prefixExceptionMessage + " cannot be written"); - } - } - } - - /** - * Checks if help is set. - * - * @return true, if help is set - */ - public boolean isHelpSet() { - return helpSet; - } - - /** - * Sets whether the help flag is set or not. - * - * @param isHelpSet the value of the help flag - */ - public void setHelp(final boolean isHelpSet) { - this.helpSet = isHelpSet; - } - - /** - * Gets the file name of the command metadata file for the editor commands. - * - * @return the file name of the command metadata file for the editor commands - */ - public String getMetadataFileName() { - return metadataFileName; - } - - /** - * Sets the file name of the command metadata file for the editor commands. - * - * @param metadataFileName the file name of the command metadata file for the editor commands - */ - public void setMetadataFileName(final String metadataFileName) { - this.metadataFileName = metadataFileName.trim(); - } - - /** - * Check if the file name of the command metadata file for the editor commands is set. - * - * @return true, if the file name of the command metadata file for the editor commands is set - */ - public boolean checkSetMetadataFileName() { - return metadataFileName != null && metadataFileName.length() > 0; - } - - /** - * Gets the file name of the file containing properties that are used for command default - * values. - * - * @return the file name of the file containing properties that are used for command default - * values - */ - public String getApexPorpertiesFileName() { - return apexPropertiesFileName; - } - - /** - * Sets the file name of the file containing properties that are used for command default - * values. - * - * @param apexPorpertiesFileName the file name of the file containing properties that are used - * for command default values - */ - public void setApexPorpertiesFileName(final String apexPorpertiesFileName) { - apexPropertiesFileName = apexPorpertiesFileName.trim(); - } - - /** - * Check if the file name of the file containing properties that are used for command default - * values is set. - * - * @return true, if the file name of the file containing properties that are used for command - * default values is set - */ - public boolean checkSetApexPropertiesFileName() { - return apexPropertiesFileName != null && apexPropertiesFileName.length() > 0; - } - - /** - * Gets the name of the file containing commands to be streamed into the CLI editor. - * - * @return the name of the file containing commands to be streamed into the CLI editor - */ - public String getCommandFileName() { - return commandFileName; - } - - /** - * Sets the name of the file containing commands to be streamed into the CLI editor. - * - * @param commandFileName the name of the file containing commands to be streamed into the CLI - * editor - */ - public void setCommandFileName(final String commandFileName) { - this.commandFileName = commandFileName.trim(); - } - - /** - * Check if the name of the file containing commands to be streamed into the CLI editor is set. - * - * @return true, if the name of the file containing commands to be streamed into the CLI editor - * is set - */ - public boolean checkSetCommandFileName() { - return commandFileName != null && commandFileName.length() > 0; - } - - /** - * Gets the name of the file containing the Apex model that will be used to initialize the Apex - * model in the CLI editor. - * - * @return the name of the file containing the Apex model that will be used to initialize the - * Apex model in the CLI editor - */ - public String getInputModelFileName() { - return inputModelFileName; - } - - /** - * Sets the name of the file containing the Apex model that will be used to initialize the Apex - * model in the CLI editor. - * - * @param inputModelFileName the name of the file containing the Apex model that will be used to - * initialize the Apex model in the CLI editor - */ - public void setInputModelFileName(final String inputModelFileName) { - this.inputModelFileName = inputModelFileName.trim(); - } - - /** - * Check if the name of the file containing the Apex model that will be used to initialize the - * Apex model in the CLI editor is set. - * - * @return true, if the name of the file containing the Apex model that will be used to - * initialize the Apex model in the CLI editor is set - */ - public boolean checkSetInputModelFileName() { - return inputModelFileName != null && inputModelFileName.length() > 0; - } - - /** - * Gets the name of the file that the Apex CLI editor will save the Apex model to when it exits. - * - * @return the name of the file that the Apex CLI editor will save the Apex model to when it - * exits - */ - public String getOutputModelFileName() { - return outputModelFileName; - } - - /** - * Sets the name of the file that the Apex CLI editor will save the Apex model to when it exits. - * - * @param outputModelFileName the name of the file that the Apex CLI editor will save the Apex - * model to when it exits - */ - public void setOutputModelFileName(final String outputModelFileName) { - this.outputModelFileName = outputModelFileName.trim(); - } - - /** - * Check if the name of the file that the Apex CLI editor will save the Apex model to when it - * exits is set. - * - * @return true, if the name of the file that the Apex CLI editor will save the Apex model to - * when it exits is set - */ - public boolean checkSetOutputModelFileName() { - return outputModelFileName != null && outputModelFileName.length() > 0; - } - - /** - * Gets the working directory that is the root for CLI editor macro includes. - * - * @return the CLI editor working directory - */ - public String getWorkingDirectory() { - return workingDirectory; - } - - /** - * Sets the working directory that is the root for CLI editor macro includes. - * - * @param workingDirectory the CLI editor working directory - */ - public void setWorkingDirectory(final String workingDirectory) { - this.workingDirectory = workingDirectory.trim(); - } - - /** - * Gets the name of the file to which the Apex CLI editor will log commands and responses. - * - * @return the name of the file to which the Apex CLI editor will log commands and responses - */ - public String getLogFileName() { - return logFileName; - } - - /** - * Sets the name of the file to which the Apex CLI editor will log commands and responses. - * - * @param logFileName the name of the file to which the Apex CLI editor will log commands and - * responses - */ - public void setLogFileName(final String logFileName) { - this.logFileName = logFileName.trim(); - } - - /** - * Check if the name of the file to which the Apex CLI editor will log commands and responses is - * set. - * - * @return true, if the name of the file to which the Apex CLI editor will log commands and - * responses is set - */ - public boolean checkSetLogFileName() { - return logFileName != null; - } - - /** - * Checks if the Apex CLI editor is set to echo commands that have been entered. - * - * @return true, if the Apex CLI editor is set to echo commands that have been entered - */ - public boolean isEchoSet() { - return echo; - } - - /** - * Sets whether the Apex CLI editor should echo commands that have been entered. - * - * @param echo true, if the Apex CLI editor should echo commands that have been entered - */ - public void setEcho(final boolean echo) { - this.echo = echo; - } - - /** - * Checks whether the Apex CLI editor is set to suppress logging of command output. - * - * @return true, if the Apex CLI editor is set to suppress logging of command output. - */ - public boolean isSuppressLogSet() { - return suppressLog; - } - - /** - * Sets whether the Apex CLI editor should suppress logging of command output. - * - * @param suppressLog true, if the Apex CLI editor should suppress logging of command output - */ - public void setSuppressLog(final boolean suppressLog) { - this.suppressLog = suppressLog; - } - - /** - * Checks whether the Apex CLI editor is set to suppress output of its Apex model on exit. - * - * @return true, if checks if the Apex CLI editor is set to suppress output of its Apex model on - * exit - */ - public boolean isSuppressModelOutputSet() { - return suppressModelOutput; - } - - /** - * Sets whether the Apex CLI editor should suppress output of its Apex model on exit. - * - * @param suppressModelOutput true, if the Apex CLI editor should suppress output of its Apex - * model on exit - */ - public void setSuppressModelOutput(final boolean suppressModelOutput) { - this.suppressModelOutput = suppressModelOutput; - } - - /** - * Check if the command failures flag is set. - * - * @return true if the command failures flag has been set - */ - public boolean checkSetIgnoreCommandFailures() { - return ignoreCommandFailuresSet; - } - - /** - * Checks if the command failures flag is set. - * - * @param ignoreCommandFailuresSet true if the command failures flag has been set - */ - public void setIgnoreCommandFailuresSet(final boolean ignoreCommandFailuresSet) { - this.ignoreCommandFailuresSet = ignoreCommandFailuresSet; - } - - /** - * Checks if command failures should be ignored and command execution continue. - * - * @return true if command failures should be ignored - */ - public boolean isIgnoreCommandFailures() { - return ignoreCommandFailures; - } - - /** - * Sets if command errors should be ignored and command execution continue. - * - * @param ignoreCommandFailures true if command errors should be ignored - */ - public void setIgnoreCommandFailures(final boolean ignoreCommandFailures) { - this.ignoreCommandFailures = ignoreCommandFailures; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "CLIParameters [helpSet=" + helpSet + ", metadataFileName=" + metadataFileName - + ", apexPropertiesFileName=" + apexPropertiesFileName + ", commandFileName=" + commandFileName - + ", inputModelFileName=" + inputModelFileName + ", outputModelFileName=" + outputModelFileName - + ", logFileName=" + logFileName + ", echo=" + echo + ", suppressLog=" + suppressLog - + ", suppressModelOutput=" + suppressModelOutput + "]"; - } -} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineArgument.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineArgument.java new file mode 100644 index 000000000..f1a6e7867 --- /dev/null +++ b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineArgument.java @@ -0,0 +1,144 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.auth.clieditor; + +import org.onap.policy.apex.model.utilities.Assertions; + +/** + * This class holds the definition of an argument of a CLI command. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class CommandLineArgument implements Comparable { + private final String argumentName; + private final boolean nullable; + private final String description; + + /** + * This Constructor constructs a non nullable command line argument with a blank name and + * description. + */ + public CommandLineArgument() { + this("", false, ""); + } + + /** + * This Constructor constructs a non nullable command line argument with the given name and + * description. + * + * @param incomingArgumentName the argument name + */ + public CommandLineArgument(final String incomingArgumentName) { + this(incomingArgumentName, false, ""); + } + + /** + * This Constructor constructs a command line argument with the given name, nullability, and + * description. + * + * @param argumentName the argument name + * @param nullable the nullable + * @param description the description + */ + public CommandLineArgument(final String argumentName, final boolean nullable, final String description) { + this.argumentName = argumentName; + this.nullable = nullable; + this.description = description; + } + + /** + * Gets the argument name. + * + * @return the argument name + */ + public String getArgumentName() { + return argumentName; + } + + /** + * Checks if the argument is nullable. + * + * @return true, if checks if the argument is nullable + */ + public boolean isNullable() { + return nullable; + } + + /** + * Gets the argument description. + * + * @return the argument description + */ + public String getDescription() { + return description; + } + + /** + * Gets the argument help. + * + * @return the argument help + */ + public String getHelp() { + final StringBuilder builder = new StringBuilder(); + builder.append(argumentName); + builder.append(nullable ? ": (O) " : ": (M) "); + builder.append(description); + return builder.toString(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "CLIArgument [argumentName=" + argumentName + ", nullable=" + nullable + ", description=" + description + + "]"; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + @Override + public int compareTo(final CommandLineArgument otherArgument) { + Assertions.argumentNotNull(otherArgument, "comparison object may not be null"); + + if (this == otherArgument) { + return 0; + } + if (getClass() != otherArgument.getClass()) { + return this.hashCode() - otherArgument.hashCode(); + } + + final CommandLineArgument other = otherArgument; + + if (!argumentName.equals(other.argumentName)) { + return argumentName.compareTo(other.argumentName); + } + if (nullable != other.nullable) { + return (this.hashCode() - other.hashCode()); + } + return description.compareTo(otherArgument.description); + } +} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineArgumentValue.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineArgumentValue.java new file mode 100644 index 000000000..64059e31b --- /dev/null +++ b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineArgumentValue.java @@ -0,0 +1,91 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.auth.clieditor; + +/** + * This class represents an argument used on a command and its value. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class CommandLineArgumentValue { + private final CommandLineArgument cliArgument; + private boolean specified; + private String value; + + /** + * The Constructor creates an argument value for the given argument, has not been set, and has + * no value. + * + * @param cliArgument the argument for which this object is a value + */ + public CommandLineArgumentValue(final CommandLineArgument cliArgument) { + this.cliArgument = cliArgument; + specified = false; + value = null; + } + + /** + * Gets the argument for which this object is a value. + * + * @return the argument for which this object is a value + */ + public CommandLineArgument getCliArgument() { + return cliArgument; + } + + /** + * Checks if the argument value is specified. + * + * @return true, if the argument value is specified + */ + public boolean isSpecified() { + return specified; + } + + /** + * Gets the argument value. + * + * @return the argument value + */ + public String getValue() { + return value; + } + + /** + * Sets the argument value. + * + * @param value the argument value + */ + public void setValue(final String value) { + this.value = value; + specified = true; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "CLIArgumentValue [cliArgument=" + cliArgument + ", specified=" + specified + ", value=" + value + "]"; + } +} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineCommand.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineCommand.java new file mode 100644 index 000000000..6c651cb6b --- /dev/null +++ b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineCommand.java @@ -0,0 +1,240 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.auth.clieditor; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.policy.apex.model.utilities.Assertions; + +/** + * This class represents a single Apex CLI command that is issued to the Apex Editor Java API + * {@link org.onap.policy.apex.model.modelapi.ApexEditorApi}. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class CommandLineCommand implements Comparable { + private String name = ""; + private final List keywordlist = new ArrayList<>(); + private final List argumentList = new ArrayList<>(); + private String apiMethod = ""; + private boolean systemCommand = false; + private String description = ""; + + /** + * Gets the class name of the class that executes this command in the Java API. + * + * @return the class name of the class that executes this command in the Java API + */ + public String getApiClassName() { + final int lastDotPos = apiMethod.lastIndexOf('.'); + if (lastDotPos == -1) { + throw new CommandLineException("invalid API method name specified on command \"" + name + + "\", class name not found: " + apiMethod); + } + return apiMethod.substring(0, lastDotPos); + } + + /** + * Gets the method name of the method that executes this command in the Java API. + * + * @return the the method name of the method that executes this command in the Java API + */ + public String getApiMethodName() { + final int lastDotPos = apiMethod.lastIndexOf('.'); + if (lastDotPos == -1) { + throw new CommandLineException("invalid API method name specified on command \"" + name + + "\", class name not found: " + apiMethod); + } + if (lastDotPos == apiMethod.length() - 1) { + throw new CommandLineException("no API method name specified on command \"" + name + "\": " + apiMethod); + } + return apiMethod.substring(lastDotPos + 1); + } + + /** + * Gets the name of the editor command. + * + * @return the name of the editor command + */ + public String getName() { + return name; + } + + /** + * Sets the name of the editor command. + * + * @param name the name of the editor command + */ + public void setName(final String name) { + this.name = name; + } + + /** + * Gets the list of keywords for this command. + * + * @return the list of keywords for this command + */ + public List getKeywordlist() { + return keywordlist; + } + + /** + * Gets the list of arguments for this command. + * + * @return the list of arguments for this command + */ + public List getArgumentList() { + return argumentList; + } + + /** + * Gets the method of the method that executes this command in the Java API. + * + * @return the method of the method that executes this command in the Java API + */ + public String getApiMethod() { + return apiMethod; + } + + /** + * Sets the method of the method that executes this command in the Java API. + * + * @param apiMethod the method of the method that executes this command in the Java API + */ + public void setApiMethod(final String apiMethod) { + this.apiMethod = apiMethod; + } + + /** + * Gets the description of the command. + * + * @return the description of the command + */ + public String getDescription() { + return description; + } + + /** + * Sets the description of the command. + * + * @param description the description of the command + */ + public void setDescription(final String description) { + this.description = description; + } + + /** + * Checks if this command is a system command. + * + * @return true, if this command is a system command + */ + public boolean isSystemCommand() { + return systemCommand; + } + + /** + * Sets whether this command is a system command. + * + * @param systemCommand whether this command is a system command + */ + public void setSystemCommand(final boolean systemCommand) { + this.systemCommand = systemCommand; + } + + /** + * Gets help for this command. + * + * @return the help for this command + */ + public String getHelp() { + final StringBuilder builder = new StringBuilder(); + for (final String keyword : keywordlist) { + builder.append(keyword); + builder.append(' '); + } + builder.append('{'); + builder.append(name); + builder.append("}: "); + builder.append(description); + + for (final CommandLineArgument argument : argumentList) { + if (argument == null) { + continue; + } + builder.append("\n\t"); + builder.append(argument.getHelp()); + } + return builder.toString(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "CLICommand [name=" + name + ",keywordlist=" + keywordlist + ", argumentList=" + argumentList + + ", apiMethod=" + apiMethod + ", systemCommand=" + systemCommand + ", description=" + description + + "]"; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + @Override + public int compareTo(final CommandLineCommand otherCommand) { + Assertions.argumentNotNull(otherCommand, "comparison object may not be null"); + + if (this == otherCommand) { + return 0; + } + if (getClass() != otherCommand.getClass()) { + return this.hashCode() - otherCommand.hashCode(); + } + + final CommandLineCommand other = otherCommand; + + for (int i = 0, j = 0;; i++, j++) { + if (i < keywordlist.size() && j < otherCommand.keywordlist.size()) { + if (!keywordlist.get(i).equals(other.keywordlist.get(j))) { + return keywordlist.get(i).compareTo(other.keywordlist.get(j)); + } + } else if (i == keywordlist.size() && j == otherCommand.keywordlist.size()) { + break; + } else if (i == keywordlist.size()) { + return -1; + } else { + return 1; + } + } + if (!argumentList.equals(other.argumentList)) { + return (argumentList.hashCode() - other.argumentList.hashCode()); + } + if (systemCommand != other.systemCommand) { + return (this.hashCode() - other.hashCode()); + } + return apiMethod.compareTo(other.apiMethod); + } +} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineCommands.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineCommands.java new file mode 100644 index 000000000..45d8a4bd3 --- /dev/null +++ b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineCommands.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.auth.clieditor; + +import java.util.Set; +import java.util.TreeSet; + +/** + * This class contains the CLI commands read in from a JSON file. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class CommandLineCommands { + private final Set commandList = new TreeSet<>(); + + /** + * Gets the command set. + * + * @return the command set + */ + public Set getCommandSet() { + return commandList; + } +} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineEditorLoop.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineEditorLoop.java new file mode 100644 index 000000000..7a34ce7c1 --- /dev/null +++ b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineEditorLoop.java @@ -0,0 +1,544 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.auth.clieditor; + +import static org.onap.policy.apex.model.utilities.TreeMapUtils.findMatchingEntries; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.util.AbstractMap.SimpleEntry; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.TreeMap; + +import org.onap.policy.apex.model.modelapi.ApexApiResult; +import org.onap.policy.apex.model.modelapi.ApexApiResult.Result; +import org.onap.policy.apex.model.utilities.TextFileUtils; +import org.onap.policy.apex.model.utilities.TreeMapUtils; + +/** + * This class implements the editor loop, the loop of execution that continuously executes commands until the quit + * command is issued or EOF is detected on input. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class CommandLineEditorLoop { + // The model handler that is handling the API towards the Apex model being editied + private final ApexModelHandler modelHandler; + + // Holds the current location in the keyword hierarchy + private final ArrayDeque keywordNodeDeque = new ArrayDeque<>(); + + // Logic block tags + private final String logicBlockStartTag; + private final String logicBlockEndTag; + + // File Macro tag + private final String macroFileTag; + + /** + * Initiate the loop with the keyword node tree. + * + * @param properties The CLI editor properties defined for execution + * @param modelHandler the model handler that will handle commands + * @param rootKeywordNode The root keyword node tree + */ + public CommandLineEditorLoop(final Properties properties, final ApexModelHandler modelHandler, + final KeywordNode rootKeywordNode) { + this.modelHandler = modelHandler; + keywordNodeDeque.push(rootKeywordNode); + + logicBlockStartTag = properties.getProperty("DEFAULT_LOGIC_BLOCK_START_TAG"); + logicBlockEndTag = properties.getProperty("DEFAULT_LOGIC_BLOCK_END_TAG"); + macroFileTag = properties.getProperty("DEFAULT_MACRO_FILE_TAG"); + } + + /** + * Run a command loop. + * + * @param inputStream The stream to read commands from + * @param outputStream The stream to write command output and messages to + * @param parameters The parameters for the CLI editor + * @return the exit code from command processing + * @throws IOException Thrown on exceptions on IO + */ + public int runLoop(final InputStream inputStream, final OutputStream outputStream, + final CommandLineParameters parameters) throws IOException { + // Readers and writers for input and output + final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); + final PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream)); + + // The parser parses the input lines into commands and arguments + final CommandLineParser parser = new CommandLineParser(); + + // The main loop for command handing, it continues until EOF on the input stream or until a + // quit command + int errorCount = 0; + ApexApiResult result = new ApexApiResult(); + while (result.getResult() != Result.FINISHED) { + if (!parameters.isIgnoreCommandFailures() && errorCount > 0) { + break; + } + + // Output prompt and get a line of input + writer.print(getPrompt()); + writer.flush(); + String line = reader.readLine(); + if (line == null) { + break; + } + + // Expand any macros in the script + try { + while (line.contains(macroFileTag)) { + line = expandMacroFile(parameters, line); + } + } + // Print any error messages from command parsing and finding + catch (final CommandLineException e) { + writer.println(e.getMessage()); + errorCount++; + continue; + } + + if (parameters.isEchoSet()) { + writer.println(line); + } + + String logicBlock = null; + if (line.trim().endsWith(logicBlockStartTag)) { + line = line.replace(logicBlockStartTag, "").trim(); + + logicBlock = ""; + while (true) { + String logicLine = reader.readLine(); + if (logicLine == null) { + logicBlock = null; + break; + } + + try { + while (logicLine.contains(macroFileTag)) { + logicLine = expandMacroFile(parameters, logicLine); + } + } + // Print any error messages from command parsing and finding + catch (final CommandLineException e) { + writer.println(e.getMessage()); + errorCount++; + continue; + } + + if (parameters.isEchoSet()) { + writer.println(logicLine); + } + + if (logicLine.trim().endsWith(logicBlockEndTag)) { + logicBlock += logicLine.replace(logicBlockEndTag, "").trim() + "\n"; + break; + } else { + logicBlock += logicLine + "\n"; + } + } + } + + try { + // Parse the line into a list of commands and arguments + final List commandWords = parser.parse(line, logicBlock); + + // Find the command, if the command is null, then we are simply changing position in + // the hierarchy + final CommandLineCommand command = findCommand(commandWords); + if (command != null) { + // Check the arguments of the command + final TreeMap argumentValues = getArgumentValues(command, + commandWords); + + // Execute the command, a FINISHED result means a command causes the loop to + // leave execution + result = executeCommand(command, argumentValues, writer); + if (result.isNok()) { + errorCount++; + } + } + } + // Print any error messages from command parsing and finding + catch (final CommandLineException e) { + writer.println(e.getMessage()); + errorCount++; + } catch (final Exception e) { + e.printStackTrace(writer); + } + } + + // Get the output model + if (!parameters.isSuppressModelOutputSet()) { + final String modelString = modelHandler.writeModelToString(writer); + + if (parameters.checkSetOutputModelFileName()) { + TextFileUtils.putStringAsTextFile(modelString, parameters.getOutputModelFileName()); + } else { + System.out.println(modelString); + } + } + + reader.close(); + writer.close(); + + return errorCount; + } + + /** + * Output a prompt that indicates where in the keyword hierarchy we are. + * + * @return A string with the prompt + */ + private String getPrompt() { + final StringBuilder builder = new StringBuilder(); + final Iterator keynodeDequeIter = keywordNodeDeque.descendingIterator(); + + while (keynodeDequeIter.hasNext()) { + builder.append('/'); + builder.append(keynodeDequeIter.next().getKeyword()); + } + builder.append("> "); + + return builder.toString(); + } + + /** + * Finds a command for the given input command words. Command words need only ne specified enough to uniquely + * identify them. Therefore, "p s o c" will find the command "policy state output create" + * + * @param commandWords The commands and arguments parsed from the command line by the parser + * @return The found command + */ + + private CommandLineCommand findCommand(final List commandWords) { + CommandLineCommand command = null; + + final KeywordNode startKeywordNode = keywordNodeDeque.peek(); + + // Go down through the keywords searching for the command + for (int i = 0; i < commandWords.size(); i++) { + final KeywordNode searchKeywordNode = keywordNodeDeque.peek(); + + // We have got to the arguments, time to stop looking + if (commandWords.get(i).indexOf('=') > 0) { + unwindStack(startKeywordNode); + throw new CommandLineException("command not found: " + stringAL2String(commandWords)); + } + + // If the node entries found is not equal to one, then we have either no command or more + // than one command matching + final List> foundNodeEntries = findMatchingEntries( + searchKeywordNode.getChildren(), commandWords.get(i)); + if (foundNodeEntries.isEmpty()) { + unwindStack(startKeywordNode); + throw new CommandLineException("command not found: " + stringAL2String(commandWords)); + } else if (foundNodeEntries.size() > 1) { + unwindStack(startKeywordNode); + throw new CommandLineException("multiple commands matched: " + stringAL2String(commandWords) + " [" + + nodeAL2String(foundNodeEntries) + ']'); + } + + // Record the fully expanded command word + commandWords.set(i, foundNodeEntries.get(0).getKey()); + + // Check if there is a command + final KeywordNode childKeywordNode = foundNodeEntries.get(0).getValue(); + command = childKeywordNode.getCommand(); + + // If the command is null, we go into a sub mode, otherwise we unwind the stack of + // commands and return the found command + if (command == null) { + keywordNodeDeque.push(childKeywordNode); + } else { + unwindStack(startKeywordNode); + return command; + } + } + + return null; + } + + /** + * Unwind the stack of keyword node entries we have placed on the queue in a command search. + * + * @param startKeywordNode The point on the queue we want to unwind to + */ + private void unwindStack(final KeywordNode startKeywordNode) { + // Unwind the stack + while (true) { + if (keywordNodeDeque.peek().equals(startKeywordNode)) { + return; + } + keywordNodeDeque.pop(); + } + } + + /** + * Check the arguments of the command. + * + * @param command The command to check + * @param commandWords The command words entered + * @return the argument values + */ + private TreeMap getArgumentValues(final CommandLineCommand command, + final List commandWords) { + final TreeMap argumentValues = new TreeMap<>(); + for (final CommandLineArgument argument : command.getArgumentList()) { + if (argument != null) { + argumentValues.put(argument.getArgumentName(), new CommandLineArgumentValue(argument)); + } + } + + // Set the value of the arguments + for (final Entry argument : getCommandArguments(commandWords)) { + final List> foundArguments = TreeMapUtils + .findMatchingEntries(argumentValues, argument.getKey()); + if (foundArguments.size() == 0) { + throw new CommandLineException("command " + stringAL2String(commandWords) + ": " + " argument \"" + + argument.getKey() + "\" not allowed on command"); + } else if (foundArguments.size() > 1) { + throw new CommandLineException("command " + stringAL2String(commandWords) + ": " + " argument " + + argument + " matches multiple arguments [" + argumentAL2String(foundArguments) + ']'); + } + + // Set the value of the argument, stripping off any quotes + final String argumentValue = argument.getValue().replaceAll("^\"", "").replaceAll("\"$", ""); + foundArguments.get(0).getValue().setValue(argumentValue); + } + + // Now check all mandatory arguments are set + for (final CommandLineArgumentValue argumentValue : argumentValues.values()) { + // Argument values are null by default so if this argument is not nullable it is + // mandatory + if (!argumentValue.isSpecified() && !argumentValue.getCliArgument().isNullable()) { + throw new CommandLineException("command " + stringAL2String(commandWords) + ": " + + " mandatory argument \"" + argumentValue.getCliArgument().getArgumentName() + + "\" not specified"); + } + } + + return argumentValues; + } + + /** + * Get the arguments of the command, the command words have already been conditioned into an array starting with the + * command words and ending with the arguments as name=value tuples. + * + * @param commandWords The command words entered by the user + * @return the arguments as an entry array list + */ + private ArrayList> getCommandArguments(final List commandWords) { + final ArrayList> arguments = new ArrayList<>(); + + // Iterate over the command words, arguments are of the format name=value + for (final String word : commandWords) { + final int equalsPos = word.indexOf('='); + if (equalsPos > 0) { + arguments.add(new SimpleEntry<>(word.substring(0, equalsPos), + word.substring(equalsPos + 1, word.length()))); + } + } + + return arguments; + } + + /** + * Execute system and editor commands. + * + * @param command The command to execute + * @param argumentValues The arguments input on the command line to invoke the command + * @param writer The writer to use for any output from the command + * @return the result of execution of the command + */ + private ApexApiResult executeCommand(final CommandLineCommand command, + final TreeMap argumentValues, final PrintWriter writer) { + if (command.isSystemCommand()) { + return exceuteSystemCommand(command, writer); + } else { + return modelHandler.executeCommand(command, argumentValues, writer); + } + } + + /** + * Execute system commands. + * + * @param command The command to execute + * @param writer The writer to use for any output from the command + * @return the result of execution of the command + */ + private ApexApiResult exceuteSystemCommand(final CommandLineCommand command, final PrintWriter writer) { + if ("back".equals(command.getName())) { + return executeBackCommand(); + } else if ("help".equals(command.getName())) { + return executeHelpCommand(writer); + } else if ("quit".equals(command.getName())) { + return executeQuitCommand(); + } else { + return new ApexApiResult(Result.SUCCESS); + } + } + + /** + * Execute the "back" command. + * + * @return the result of execution of the command + */ + private ApexApiResult executeBackCommand() { + if (keywordNodeDeque.size() > 1) { + keywordNodeDeque.pop(); + } + return new ApexApiResult(Result.SUCCESS); + } + + /** + * Execute the "quit" command. + * + * @return the result of execution of the command + */ + private ApexApiResult executeQuitCommand() { + return new ApexApiResult(Result.FINISHED); + } + + /** + * Execute the "help" command. + * + * @param writer The writer to use for output from the command + * @return the result of execution of the command + */ + private ApexApiResult executeHelpCommand(final PrintWriter writer) { + for (final CommandLineCommand command : keywordNodeDeque.peek().getCommands()) { + writer.println(command.getHelp()); + } + return new ApexApiResult(Result.SUCCESS); + } + + /** + * Helper method to output an array list of keyword node entries to a string. + * + * @param nodeEntryArrayList the array list of keyword node entries + * @return the string + */ + private String nodeAL2String(final List> nodeEntryArrayList) { + final ArrayList stringArrayList = new ArrayList<>(); + for (final Entry node : nodeEntryArrayList) { + stringArrayList.add(node.getValue().getKeyword()); + } + + return stringAL2String(stringArrayList); + } + + /** + * Helper method to output an array list of argument entries to a string. + * + * @param argumentArrayList the argument array list + * @return the string + */ + private String argumentAL2String(final List> argumentArrayList) { + final ArrayList stringArrayList = new ArrayList<>(); + for (final Entry argument : argumentArrayList) { + stringArrayList.add(argument.getValue().getCliArgument().getArgumentName()); + } + + return stringAL2String(stringArrayList); + } + + /** + * Helper method to output an array list of strings to a string. + * + * @param stringArrayList the array list of strings + * @return the string + */ + private String stringAL2String(final List stringArrayList) { + final StringBuilder builder = new StringBuilder(); + boolean first = true; + for (final String word : stringArrayList) { + if (first) { + first = false; + } else { + builder.append(','); + } + builder.append(word); + } + + return builder.toString(); + } + + /** + * This method reads in the file from a file macro statement, expands the macro, and replaces the Macro tag in the + * line with the file contents. + * + * @param parameters The parameters for the CLI editor + * @param line The line with the macro keyword in it + * @return the expanded line + */ + private String expandMacroFile(final CommandLineParameters parameters, final String line) { + final int macroTagPos = line.indexOf(macroFileTag); + + // Get the line before and after the macro tag + final String lineBeforeMacroTag = line.substring(0, macroTagPos); + final String lineAfterMacroTag = line.substring(macroTagPos + macroFileTag.length()).replaceAll("^\\s*", ""); + + // Get the file name that is the argument of the Macro tag + final String[] lineWords = lineAfterMacroTag.split("\\s+"); + + if (lineWords.length == 0) { + throw new CommandLineException("no file name specified for Macro File Tag"); + } + + // Get the macro file name and the remainder of the line after the file name + String macroFileName = lineWords[0]; + final String lineAfterMacroFileName = lineAfterMacroTag.replaceFirst(macroFileName, ""); + + if (macroFileName.length() > 2 && macroFileName.startsWith("\"") && macroFileName.endsWith("\"")) { + macroFileName = macroFileName.substring(1, macroFileName.length() - 1); + } else { + throw new CommandLineException("macro file name \"" + macroFileName + + "\" must exist and be quoted with double quotes \"\""); + } + + // Append the working directory to the macro file name + macroFileName = parameters.getWorkingDirectory() + File.separatorChar + macroFileName; + + // Now, get the text file for the argument of the macro + String macroFileContents = null; + try { + macroFileContents = TextFileUtils.getTextFileAsString(macroFileName); + } catch (final IOException e) { + throw new CommandLineException("file \"" + macroFileName + "\" specified in Macro File Tag not found", e); + } + + return lineBeforeMacroTag + macroFileContents + lineAfterMacroFileName; + } +} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineException.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineException.java new file mode 100644 index 000000000..4ff17458e --- /dev/null +++ b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineException.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.auth.clieditor; + +/** + * A run time exception used to report parsing and command input errors. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class CommandLineException extends IllegalArgumentException { + private static final long serialVersionUID = 6520231162404452427L; + + /** + * Create a CLIException with a message. + * + * @param message the message + */ + public CommandLineException(final String message) { + super(message); + } + + /** + * Create a CLIException with a message and an exception. + * + * @param message the message + * @param th the throwable + */ + public CommandLineException(final String message, final Throwable th) { + super(message, th); + } +} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineParameterParser.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineParameterParser.java new file mode 100644 index 000000000..a37d07fab --- /dev/null +++ b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineParameterParser.java @@ -0,0 +1,161 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.auth.clieditor; + +import java.nio.file.Paths; +import java.util.Arrays; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; + +/** + * This class reads and handles command line parameters to the Apex CLI editor. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class CommandLineParameterParser { + private static final int MAX_HELP_LINE_LENGTH = 120; + + // Apache Commons CLI options + private final Options options; + + /** + * Construct the options for the CLI editor. + */ + public CommandLineParameterParser() { + options = new Options(); + options.addOption(Option.builder("h").longOpt("help").desc("outputs the usage of this command").required(false) + .type(Boolean.class).build()); + options.addOption(Option.builder("m").longOpt("metadata-file").desc("name of the command metadata file to use") + .hasArg().argName("CMD_METADATA_FILE").required(false).type(String.class).build()); + options.addOption(Option.builder("a").longOpt("model-props-file") + .desc("name of the apex model properties file to use").hasArg().argName("MODEL_PROPS_FILE") + .required(false).type(String.class).build()); + options.addOption(Option.builder("c").longOpt("command-file") + .desc("name of a file containing editor commands to run into the editor").hasArg() + .argName("COMMAND_FILE").required(false).type(String.class).build()); + options.addOption(Option.builder("l").longOpt("log-file").desc( + "name of a file that will contain command logs from the editor, will log to standard output " + + "if not specified or suppressed with \"-nl\" flag") + .hasArg().argName("LOG_FILE").required(false).type(String.class).build()); + options.addOption(Option.builder("nl").longOpt("no-log").desc( + "if specified, no logging or output of commands to standard output or log file is carried out") + .required(false).type(Boolean.class).build()); + options.addOption(Option.builder("nm").longOpt("no-model-output").desc( + "if specified, no output of a model to standard output or model output file is carried out, " + + "the user can use the \"save\" command in a script to save a model") + .required(false).type(Boolean.class).build()); + options.addOption(Option.builder("i").longOpt("input-model-file") + .desc("name of a file that contains an input model for the editor").hasArg() + .argName("INPUT_MODEL_FILE").required(false).type(String.class).build()); + options.addOption(Option.builder("o").longOpt("output-model-file") + .desc("name of a file that will contain the output model for the editor, " + + "will output model to standard output if not specified " + + "or suppressed with \"-nm\" flag") + .hasArg().argName("OUTPUT_MODEL_FILE").required(false).type(String.class).build()); + options.addOption(Option.builder("if").longOpt("ignore-failures") + .desc("true or false, ignore failures of commands in command files and continue executing the " + + "command file") + .hasArg().argName("IGNORE_FAILURES_FLAG").required(false).type(Boolean.class).build()); + options.addOption(Option.builder("wd").longOpt("working-directory") + .desc("the working directory that is the root for the CLI editor and is the root from which to " + + "look for included macro files") + .hasArg().argName("WORKING_DIRECTORY").required(false).type(String.class).build()); + } + + /** + * Parse the command line options. + * + * @param args The arguments + * @return the CLI parameters + */ + public CommandLineParameters parse(final String[] args) { + CommandLine commandLine = null; + try { + commandLine = new DefaultParser().parse(options, args); + } catch (final ParseException e) { + throw new CommandLineException("invalid command line arguments specified : " + e.getMessage()); + } + + final CommandLineParameters parameters = new CommandLineParameters(); + final String[] remainingArgs = commandLine.getArgs(); + + if (remainingArgs.length > 0) { + throw new CommandLineException( + "too many command line arguments specified : " + Arrays.toString(remainingArgs)); + } + + if (commandLine.hasOption('h')) { + parameters.setHelp(true); + } + if (commandLine.hasOption('m')) { + parameters.setMetadataFileName(commandLine.getOptionValue('m')); + } + if (commandLine.hasOption('a')) { + parameters.setApexPorpertiesFileName(commandLine.getOptionValue('a')); + } + if (commandLine.hasOption('c')) { + parameters.setCommandFileName(commandLine.getOptionValue('c')); + } + if (commandLine.hasOption('l')) { + parameters.setLogFileName(commandLine.getOptionValue('l')); + } + if (commandLine.hasOption("nl")) { + parameters.setSuppressLog(true); + } + if (commandLine.hasOption("nm")) { + parameters.setSuppressModelOutput(true); + } + if (commandLine.hasOption('i')) { + parameters.setInputModelFileName(commandLine.getOptionValue('i')); + } + if (commandLine.hasOption('o')) { + parameters.setOutputModelFileName(commandLine.getOptionValue('o')); + } + if (commandLine.hasOption("if")) { + parameters.setIgnoreCommandFailuresSet(true); + parameters.setIgnoreCommandFailures(Boolean.valueOf(commandLine.getOptionValue("if"))); + } else { + parameters.setIgnoreCommandFailuresSet(false); + } + if (commandLine.hasOption("wd")) { + parameters.setWorkingDirectory(commandLine.getOptionValue("wd")); + } else { + parameters.setWorkingDirectory(Paths.get("").toAbsolutePath().toString()); + } + + return parameters; + } + + /** + * Print help information. + * + * @param mainClassName the main class name + */ + public void help(final String mainClassName) { + final HelpFormatter helpFormatter = new HelpFormatter(); + helpFormatter.printHelp(MAX_HELP_LINE_LENGTH, mainClassName + " [options...]", "options", options, ""); + } +} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineParameters.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineParameters.java new file mode 100644 index 000000000..9a03dcfde --- /dev/null +++ b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineParameters.java @@ -0,0 +1,576 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.auth.clieditor; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.onap.policy.common.utils.resources.ResourceUtils; + +/** + * This class reads and handles command line parameters to the Apex CLI editor. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class CommandLineParameters { + // Recurring string constants + private static final String OF_TYPE_TAG = "of type "; + + // Default location of the command definition meta data in JSON + private static final String JSON_COMMAND_METADATA_RESOURCE = "etc/editor/Commands.json"; + private static final String APEX_MODEL_PROPERTIES_RESOURCE = "etc/editor/ApexModelProperties.json"; + + // The editor parameters + private boolean helpSet = false; + private String metadataFileName = null; + private String apexPropertiesFileName = null; + private String commandFileName = null; + private String inputModelFileName = null; + private String outputModelFileName = null; + private String workingDirectory = null; + private String logFileName = null; + private boolean echo = false; + private boolean suppressLog = false; + private boolean suppressModelOutput = false; + private boolean ignoreCommandFailuresSet = false; + private boolean ignoreCommandFailures = false; + + /** + * Validates the command line parameters. + */ + public void validate() { + validateReadableFile("Metadata File", metadataFileName); + validateReadableFile("Properties File", apexPropertiesFileName); + validateReadableFile("Command File", commandFileName); + validateReadableFile("Input Model File", inputModelFileName); + validateWritableFile("Output Model File", outputModelFileName); + validateWritableFile("Log File", logFileName); + validateWritableDirectory("Working Directory", workingDirectory); + + if (isSuppressLogSet()) { + setEcho(false); + } else { + if (checkSetCommandFileName()) { + setEcho(true); + if (!checkSetIgnoreCommandFailures()) { + setIgnoreCommandFailures(false); + } + } else { + setEcho(false); + if (!checkSetIgnoreCommandFailures()) { + setIgnoreCommandFailures(true); + } + } + } + } + + /** + * Gets the command metadata for the editor commands as a stream. + * + * @return the command metadata for the editor commands as a stream. + * @throws IOException the IO exception + */ + public InputStream getMetadataStream() throws IOException { + if (metadataFileName == null) { + return ResourceUtils.getResourceAsStream(JSON_COMMAND_METADATA_RESOURCE); + } else { + return new FileInputStream(new File(metadataFileName)); + } + } + + /** + * Gets the location of command metadata for the editor commands. + * + * @return the location of command metadata for the editor commands + */ + public String getMetadataLocation() { + if (metadataFileName == null) { + return "resource: \"" + JSON_COMMAND_METADATA_RESOURCE + "\""; + } else { + return "file: \"" + metadataFileName + "\""; + } + } + + /** + * Gets the properties that are used for command default values as a stream. + * + * @return the properties that are used for command default values as a stream + * @throws IOException the IO exception + */ + public InputStream getApexPropertiesStream() throws IOException { + if (apexPropertiesFileName == null) { + return ResourceUtils.getResourceAsStream(APEX_MODEL_PROPERTIES_RESOURCE); + } else { + return new FileInputStream(new File(apexPropertiesFileName)); + } + } + + /** + * Gets the location of the properties that are used for command default values. + * + * @return the location of the properties that are used for command default values + */ + public String getApexPropertiesLocation() { + if (metadataFileName == null) { + return "resource: \"" + APEX_MODEL_PROPERTIES_RESOURCE + "\""; + } else { + return "file: \"" + apexPropertiesFileName + "\""; + } + } + + /** + * Gets the input stream on which commands are being received. + * + * @return the input stream on which commands are being received + * @throws IOException the IO exception + */ + public InputStream getCommandInputStream() throws IOException { + if (commandFileName == null) { + return System.in; + } else { + return new FileInputStream(new File(commandFileName)); + } + } + + /** + * Gets the output stream on which command result messages are being output. + * + * @return the output stream on which command result messages are being output + * @throws IOException the IO exception + */ + public OutputStream getOutputStream() throws IOException { + // Check if log suppression is active, if so, consume all output on a byte array output stream + if (isSuppressLogSet()) { + return new ByteArrayOutputStream(); + + } + if (logFileName == null) { + return System.out; + } else { + return new FileOutputStream(new File(logFileName), true); + } + } + + /** + * Validate that a file is readable. + * + * @param fileTag the file tag, a tag used for information and error messages + * @param fileName the file name to check + */ + private void validateReadableFile(final String fileTag, final String fileName) { + if (fileName == null) { + return; + } + final File theFile = new File(fileName); + final String prefixExceptionMessage = "File " + fileName + OF_TYPE_TAG + fileTag; + + if (!theFile.exists()) { + throw new CommandLineException(prefixExceptionMessage + " does not exist"); + } + if (!theFile.isFile()) { + throw new CommandLineException(prefixExceptionMessage + " is not a normal file"); + } + if (!theFile.canRead()) { + throw new CommandLineException(prefixExceptionMessage + " is ureadable"); + } + } + + /** + * Validate that a file is writable. + * + * @param fileTag the file tag, a tag used for information and error messages + * @param fileName the file name to check + */ + private void validateWritableFile(final String fileTag, final String fileName) { + if (fileName == null) { + return; + } + final File theFile = new File(fileName); + final String prefixExceptionMessage = "File " + fileName + OF_TYPE_TAG + fileTag; + if (theFile.exists()) { + if (!theFile.isFile()) { + throw new CommandLineException(prefixExceptionMessage + " is not a normal file"); + } + if (!theFile.canWrite()) { + throw new CommandLineException(prefixExceptionMessage + " cannot be written"); + } + } else { + try { + theFile.createNewFile(); + } catch (final IOException e) { + throw new CommandLineException(prefixExceptionMessage + " cannot be created: ", e); + } + } + } + + /** + * Validate that a directory exists and is writable. + * + * @param directoryTag the directory tag, a tag used for information and error messages + * @param directoryName the directory name to check + */ + private void validateWritableDirectory(final String directoryTag, final String directoryName) { + if (directoryName == null) { + return; + } + final File theDirectory = new File(directoryName); + final String prefixExceptionMessage = "directory " + directoryName + OF_TYPE_TAG + directoryTag; + + if (theDirectory.exists()) { + if (!theDirectory.isDirectory()) { + throw new CommandLineException(prefixExceptionMessage + " is not a directory"); + } + if (!theDirectory.canWrite()) { + throw new CommandLineException(prefixExceptionMessage + " cannot be written"); + } + } + } + + /** + * Checks if help is set. + * + * @return true, if help is set + */ + public boolean isHelpSet() { + return helpSet; + } + + /** + * Sets whether the help flag is set or not. + * + * @param isHelpSet the value of the help flag + */ + public void setHelp(final boolean isHelpSet) { + this.helpSet = isHelpSet; + } + + /** + * Gets the file name of the command metadata file for the editor commands. + * + * @return the file name of the command metadata file for the editor commands + */ + public String getMetadataFileName() { + return metadataFileName; + } + + /** + * Sets the file name of the command metadata file for the editor commands. + * + * @param metadataFileName the file name of the command metadata file for the editor commands + */ + public void setMetadataFileName(final String metadataFileName) { + this.metadataFileName = metadataFileName.trim(); + } + + /** + * Check if the file name of the command metadata file for the editor commands is set. + * + * @return true, if the file name of the command metadata file for the editor commands is set + */ + public boolean checkSetMetadataFileName() { + return metadataFileName != null && metadataFileName.length() > 0; + } + + /** + * Gets the file name of the file containing properties that are used for command default + * values. + * + * @return the file name of the file containing properties that are used for command default + * values + */ + public String getApexPorpertiesFileName() { + return apexPropertiesFileName; + } + + /** + * Sets the file name of the file containing properties that are used for command default + * values. + * + * @param apexPorpertiesFileName the file name of the file containing properties that are used + * for command default values + */ + public void setApexPorpertiesFileName(final String apexPorpertiesFileName) { + apexPropertiesFileName = apexPorpertiesFileName.trim(); + } + + /** + * Check if the file name of the file containing properties that are used for command default + * values is set. + * + * @return true, if the file name of the file containing properties that are used for command + * default values is set + */ + public boolean checkSetApexPropertiesFileName() { + return apexPropertiesFileName != null && apexPropertiesFileName.length() > 0; + } + + /** + * Gets the name of the file containing commands to be streamed into the CLI editor. + * + * @return the name of the file containing commands to be streamed into the CLI editor + */ + public String getCommandFileName() { + return commandFileName; + } + + /** + * Sets the name of the file containing commands to be streamed into the CLI editor. + * + * @param commandFileName the name of the file containing commands to be streamed into the CLI + * editor + */ + public void setCommandFileName(final String commandFileName) { + this.commandFileName = commandFileName.trim(); + } + + /** + * Check if the name of the file containing commands to be streamed into the CLI editor is set. + * + * @return true, if the name of the file containing commands to be streamed into the CLI editor + * is set + */ + public boolean checkSetCommandFileName() { + return commandFileName != null && commandFileName.length() > 0; + } + + /** + * Gets the name of the file containing the Apex model that will be used to initialize the Apex + * model in the CLI editor. + * + * @return the name of the file containing the Apex model that will be used to initialize the + * Apex model in the CLI editor + */ + public String getInputModelFileName() { + return inputModelFileName; + } + + /** + * Sets the name of the file containing the Apex model that will be used to initialize the Apex + * model in the CLI editor. + * + * @param inputModelFileName the name of the file containing the Apex model that will be used to + * initialize the Apex model in the CLI editor + */ + public void setInputModelFileName(final String inputModelFileName) { + this.inputModelFileName = inputModelFileName.trim(); + } + + /** + * Check if the name of the file containing the Apex model that will be used to initialize the + * Apex model in the CLI editor is set. + * + * @return true, if the name of the file containing the Apex model that will be used to + * initialize the Apex model in the CLI editor is set + */ + public boolean checkSetInputModelFileName() { + return inputModelFileName != null && inputModelFileName.length() > 0; + } + + /** + * Gets the name of the file that the Apex CLI editor will save the Apex model to when it exits. + * + * @return the name of the file that the Apex CLI editor will save the Apex model to when it + * exits + */ + public String getOutputModelFileName() { + return outputModelFileName; + } + + /** + * Sets the name of the file that the Apex CLI editor will save the Apex model to when it exits. + * + * @param outputModelFileName the name of the file that the Apex CLI editor will save the Apex + * model to when it exits + */ + public void setOutputModelFileName(final String outputModelFileName) { + this.outputModelFileName = outputModelFileName.trim(); + } + + /** + * Check if the name of the file that the Apex CLI editor will save the Apex model to when it + * exits is set. + * + * @return true, if the name of the file that the Apex CLI editor will save the Apex model to + * when it exits is set + */ + public boolean checkSetOutputModelFileName() { + return outputModelFileName != null && outputModelFileName.length() > 0; + } + + /** + * Gets the working directory that is the root for CLI editor macro includes. + * + * @return the CLI editor working directory + */ + public String getWorkingDirectory() { + return workingDirectory; + } + + /** + * Sets the working directory that is the root for CLI editor macro includes. + * + * @param workingDirectory the CLI editor working directory + */ + public void setWorkingDirectory(final String workingDirectory) { + this.workingDirectory = workingDirectory.trim(); + } + + /** + * Gets the name of the file to which the Apex CLI editor will log commands and responses. + * + * @return the name of the file to which the Apex CLI editor will log commands and responses + */ + public String getLogFileName() { + return logFileName; + } + + /** + * Sets the name of the file to which the Apex CLI editor will log commands and responses. + * + * @param logFileName the name of the file to which the Apex CLI editor will log commands and + * responses + */ + public void setLogFileName(final String logFileName) { + this.logFileName = logFileName.trim(); + } + + /** + * Check if the name of the file to which the Apex CLI editor will log commands and responses is + * set. + * + * @return true, if the name of the file to which the Apex CLI editor will log commands and + * responses is set + */ + public boolean checkSetLogFileName() { + return logFileName != null; + } + + /** + * Checks if the Apex CLI editor is set to echo commands that have been entered. + * + * @return true, if the Apex CLI editor is set to echo commands that have been entered + */ + public boolean isEchoSet() { + return echo; + } + + /** + * Sets whether the Apex CLI editor should echo commands that have been entered. + * + * @param echo true, if the Apex CLI editor should echo commands that have been entered + */ + public void setEcho(final boolean echo) { + this.echo = echo; + } + + /** + * Checks whether the Apex CLI editor is set to suppress logging of command output. + * + * @return true, if the Apex CLI editor is set to suppress logging of command output. + */ + public boolean isSuppressLogSet() { + return suppressLog; + } + + /** + * Sets whether the Apex CLI editor should suppress logging of command output. + * + * @param suppressLog true, if the Apex CLI editor should suppress logging of command output + */ + public void setSuppressLog(final boolean suppressLog) { + this.suppressLog = suppressLog; + } + + /** + * Checks whether the Apex CLI editor is set to suppress output of its Apex model on exit. + * + * @return true, if checks if the Apex CLI editor is set to suppress output of its Apex model on + * exit + */ + public boolean isSuppressModelOutputSet() { + return suppressModelOutput; + } + + /** + * Sets whether the Apex CLI editor should suppress output of its Apex model on exit. + * + * @param suppressModelOutput true, if the Apex CLI editor should suppress output of its Apex + * model on exit + */ + public void setSuppressModelOutput(final boolean suppressModelOutput) { + this.suppressModelOutput = suppressModelOutput; + } + + /** + * Check if the command failures flag is set. + * + * @return true if the command failures flag has been set + */ + public boolean checkSetIgnoreCommandFailures() { + return ignoreCommandFailuresSet; + } + + /** + * Checks if the command failures flag is set. + * + * @param ignoreCommandFailuresSet true if the command failures flag has been set + */ + public void setIgnoreCommandFailuresSet(final boolean ignoreCommandFailuresSet) { + this.ignoreCommandFailuresSet = ignoreCommandFailuresSet; + } + + /** + * Checks if command failures should be ignored and command execution continue. + * + * @return true if command failures should be ignored + */ + public boolean isIgnoreCommandFailures() { + return ignoreCommandFailures; + } + + /** + * Sets if command errors should be ignored and command execution continue. + * + * @param ignoreCommandFailures true if command errors should be ignored + */ + public void setIgnoreCommandFailures(final boolean ignoreCommandFailures) { + this.ignoreCommandFailures = ignoreCommandFailures; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "CLIParameters [helpSet=" + helpSet + ", metadataFileName=" + metadataFileName + + ", apexPropertiesFileName=" + apexPropertiesFileName + ", commandFileName=" + commandFileName + + ", inputModelFileName=" + inputModelFileName + ", outputModelFileName=" + outputModelFileName + + ", logFileName=" + logFileName + ", echo=" + echo + ", suppressLog=" + suppressLog + + ", suppressModelOutput=" + suppressModelOutput + "]"; + } +} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineParser.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineParser.java new file mode 100644 index 000000000..aa74f4ba3 --- /dev/null +++ b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/CommandLineParser.java @@ -0,0 +1,323 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.auth.clieditor; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class chops a command line up into commands, parameters and arguments. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class CommandLineParser { + + /** + * This method breaks a line of input up into commands, parameters, and arguments. Commands are + * standalone words at the beginning of the line, of which there may be multiple Parameters are + * single words followed by an '=' character Arguments are single words or a block of quoted + * text following an '=' character. + * + *

Format: command [command....] parameter=argument [parameter = argument] + * + *

Examples entity create name=hello description="description of hello" help entity list + * + * @param line The line to parse + * @param logicBlock A block of logic code to be taken literally + * @return the string array list + */ + public List parse(final String line, final String logicBlock) { + return checkFormat( + mergeArguments(mergeEquals( + splitOnEquals(stripAndSplitWords(mergeQuotes(splitOnChar(stripComments(line), '\"')))))), + logicBlock); + } + + /** + * Strip comments from lines, comments start with a # character. + * + * @param line the line + * @return the line without comments + */ + private String stripComments(final String line) { + final int commentPos = line.indexOf('#'); + if (commentPos == -1) { + return line; + } else { + return line.substring(0, commentPos); + } + } + + /** + * This method merges an array with separate quotes into an array with quotes delimiting the + * start and end of quoted words Example [Humpty ],["],[Dumpty sat on the wall],["],[, Humpty + * Dumpty had ],["],["],a ["],[great],["],[ fall] becomes [Humpty ],["Dumpty sat on the + * wall"],[, Humpty Dumpty had ],[""],[a],["great"],[ fall]. + * + * @param wordsSplitOnQuotes the words split on quotes + * @return the merged array list + */ + private ArrayList mergeQuotes(final ArrayList wordsSplitOnQuotes) { + final ArrayList wordsWithQuotesMerged = new ArrayList<>(); + + for (int i = 0; i < wordsSplitOnQuotes.size();) { + if ("\"".equals(wordsSplitOnQuotes.get(i))) { + StringBuilder quotedWord = new StringBuilder(wordsSplitOnQuotes.get(i++)); + + for (; i < wordsSplitOnQuotes.size(); i++) { + quotedWord.append(wordsSplitOnQuotes.get(i)); + if ("\"".equals(wordsSplitOnQuotes.get(i))) { + i++; + break; + } + } + String quotedWordToString = quotedWord.toString(); + if (quotedWordToString.matches("^\".*\"$")) { + wordsWithQuotesMerged.add(quotedWordToString); + } else { + throw new CommandLineException("trailing quote found in input " + wordsSplitOnQuotes); + } + } else { + wordsWithQuotesMerged.add(wordsSplitOnQuotes.get(i++)); + } + } + + return wordsWithQuotesMerged; + } + + /** + * This method splits the words on an array list into an array list where each portion of the + * line is split into words by '=', quoted words are ignored Example: aaa = bbb = ccc=ddd=eee = + * becomes [aaa ],[=],[bbb ],[=],[ccc],[=],[ddd],[=],[eee ],[=]. + * + * @param words the words + * @return the merged array list + */ + private ArrayList splitOnEquals(final ArrayList words) { + final ArrayList wordsSplitOnEquals = new ArrayList<>(); + + for (final String word : words) { + // Is this a quoted word ? + if (word.startsWith("\"")) { + wordsSplitOnEquals.add(word); + continue; + } + + // Split on equals character + final ArrayList splitWords = splitOnChar(word, '='); + for (final String splitWord : splitWords) { + wordsSplitOnEquals.add(splitWord); + } + } + + return wordsSplitOnEquals; + } + + /** + * This method merges an array with separate equals into an array with equals delimiting the + * start of words Example: [aaa ],[=],[bbb ],[=],[ccc],[=],[ddd],[=],[eee ],[=] becomes [aaa + * ],[= bbb ],[= ccc],[=ddd],[=eee ],[=]. + * + * @param wordsSplitOnEquals the words split on equals + * @return the merged array list + */ + private ArrayList mergeEquals(final ArrayList wordsSplitOnEquals) { + final ArrayList wordsWithEqualsMerged = new ArrayList<>(); + + for (int i = 0; i < wordsSplitOnEquals.size();) { + // Is this a quoted word ? + if (wordsSplitOnEquals.get(i).startsWith("\"")) { + wordsWithEqualsMerged.add(wordsSplitOnEquals.get(i)); + continue; + } + + if ("=".equals(wordsSplitOnEquals.get(i))) { + if (i < wordsSplitOnEquals.size() - 1 && !wordsSplitOnEquals.get(i + 1).startsWith("=")) { + wordsWithEqualsMerged.add(wordsSplitOnEquals.get(i) + wordsSplitOnEquals.get(i + 1)); + i += 2; + } else { + wordsWithEqualsMerged.add(wordsSplitOnEquals.get(i++)); + } + } else { + wordsWithEqualsMerged.add(wordsSplitOnEquals.get(i++)); + } + } + + return wordsWithEqualsMerged; + } + + /** + * This method merges words that start with an '=' character with the previous word if that word + * does not start with an '='. + * + * @param words the words + * @return the merged array list + */ + private ArrayList mergeArguments(final ArrayList words) { + final ArrayList mergedArguments = new ArrayList<>(); + + for (int i = 0; i < words.size(); i++) { + // Is this a quoted word ? + if (words.get(i).startsWith("\"")) { + mergedArguments.add(words.get(i)); + continue; + } + + if (words.get(i).startsWith("=")) { + if (i > 0 && !words.get(i - 1).startsWith("=")) { + mergedArguments.remove(mergedArguments.size() - 1); + mergedArguments.add(words.get(i - 1) + words.get(i)); + } else { + mergedArguments.add(words.get(i)); + } + } else { + mergedArguments.add(words.get(i)); + } + } + + return mergedArguments; + } + + /** + * This method strips all non quoted white space down to single spaces and splits non-quoted + * words into separate words. + * + * @param words the words + * @return the array list with white space stripped and words split + */ + private ArrayList stripAndSplitWords(final ArrayList words) { + final ArrayList strippedAndSplitWords = new ArrayList<>(); + + for (String word : words) { + // Is this a quoted word + if (word.startsWith("\"")) { + strippedAndSplitWords.add(word); + continue; + } + + // Strip white space by replacing all white space with blanks and then removing leading + // and trailing blanks + word = word.replaceAll("\\s+", " ").trim(); + + if (word.length() == 0) { + continue; + } + + // Split on space characters + final String[] splitWords = word.split(" "); + for (final String splitWord : splitWords) { + strippedAndSplitWords.add(splitWord); + } + } + + return strippedAndSplitWords; + } + + /** + * This method splits a line of text into an array list where each portion of the line is split + * into words by a character, with the characters themselves as separate words Example: Humpty + * "Dumpty sat on the wall", Humpty Dumpty had ""a "great" fall becomes [Humpty ],["],[Dumpty + * sat on the wall],["],[, Humpty Dumpty had ],["],["],a ["],[great],["],[ fall]. + * + * @param line the input line + * @param splitChar the split char + * @return the split array list + */ + private ArrayList splitOnChar(final String line, final char splitChar) { + final ArrayList wordsSplitOnQuotes = new ArrayList<>(); + + int currentPos = 0; + while (currentPos != -1) { + final int quotePos = line.indexOf(splitChar, currentPos); + if (quotePos != -1) { + if (currentPos < quotePos) { + wordsSplitOnQuotes.add(line.substring(currentPos, quotePos)); + } + wordsSplitOnQuotes.add("" + splitChar); + currentPos = quotePos + 1; + + if (currentPos == line.length()) { + currentPos = -1; + } + } else { + wordsSplitOnQuotes.add(line.substring(currentPos)); + currentPos = quotePos; + } + } + + return wordsSplitOnQuotes; + } + + /** + * This method checks that an array list containing a command is in the correct format. + * + * @param commandWords the command words + * @param logicBlock A block of logic code to be taken literally + * @return the checked array list + */ + private ArrayList checkFormat(final ArrayList commandWords, final String logicBlock) { + // There should be at least one word + if (commandWords.isEmpty()) { + return commandWords; + } + + // The first word must be alphanumeric, that is a command + if (!commandWords.get(0).matches("^[a-zA-Z0-9]*$")) { + throw new CommandLineException( + "first command word is not alphanumeric or is not a command: " + commandWords.get(0)); + } + + // Now check that we have a sequence of commands at the beginning + int currentWordPos = 0; + while (currentWordPos < commandWords.size()) { + if (commandWords.get(currentWordPos).matches("^[a-zA-Z0-9]*$")) { + currentWordPos++; + } else { + break; + } + } + + while (currentWordPos < commandWords.size()) { + // From now on we should have a sequence of parameters with arguments delimited by a + // single '=' character + if (currentWordPos < commandWords.size() - 1 || logicBlock == null) { + // No logic block + if (commandWords.get(currentWordPos).matches("^[a-zA-Z0-9]+=[a-zA-Z0-9/\"].*$")) { + currentWordPos++; + } else { + throw new CommandLineException( + "command argument is not properly formed: " + commandWords.get(currentWordPos)); + } + } else { + // Logic block + if (commandWords.get(currentWordPos).matches("^[a-zA-Z0-9]+=")) { + commandWords.set(currentWordPos, commandWords.get(currentWordPos) + logicBlock); + currentWordPos++; + } else { + throw new CommandLineException( + "command argument is not properly formed: " + commandWords.get(currentWordPos)); + } + } + } + + return commandWords; + } +} diff --git a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/KeywordNode.java b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/KeywordNode.java index 6be5c6846..c8bc7a083 100644 --- a/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/KeywordNode.java +++ b/auth/cli-editor/src/main/java/org/onap/policy/apex/auth/clieditor/KeywordNode.java @@ -37,7 +37,7 @@ import org.onap.policy.apex.model.utilities.Assertions; public class KeywordNode implements Comparable { private final String keyword; private final TreeMap children; - private CLICommand command; + private CommandLineCommand command; /** * This Constructor creates a keyword node with the given keyword and no command. @@ -54,7 +54,7 @@ public class KeywordNode implements Comparable { * @param keyword the keyword of the keyword node * @param command the command associated with this keyword */ - public KeywordNode(final String keyword, final CLICommand command) { + public KeywordNode(final String keyword, final CommandLineCommand command) { Assertions.argumentNotNull(keyword, "commands may not be null"); this.keyword = keyword; @@ -70,7 +70,7 @@ public class KeywordNode implements Comparable { * @param keywordList the list of keywords to process on this keyword node * @param incomingCommand the command */ - public void processKeywords(final List keywordList, final CLICommand incomingCommand) { + public void processKeywords(final List keywordList, final CommandLineCommand incomingCommand) { if (keywordList.isEmpty()) { this.command = incomingCommand; return; @@ -128,7 +128,7 @@ public class KeywordNode implements Comparable { * * @return the command of this keyword node */ - public CLICommand getCommand() { + public CommandLineCommand getCommand() { return command; } @@ -147,8 +147,8 @@ public class KeywordNode implements Comparable { * * @return the commands */ - public Set getCommands() { - final Set commandSet = new TreeSet<>(); + public Set getCommands() { + final Set commandSet = new TreeSet<>(); for (final KeywordNode child : children.values()) { if (child.getCommand() != null) { -- cgit 1.2.3-korg