All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.flink.api.java.utils.RequiredParameters Maven / Gradle / Ivy

There is a newer version: 1.20.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.flink.api.java.utils;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Facility to manage required parameters in user defined functions.
 *
 * @deprecated These classes will be dropped in the next version. Use {@link ParameterTool} or a
 *     third-party command line parsing library instead.
 */
@Deprecated
public class RequiredParameters {

    private static final String HELP_TEXT_PARAM_DELIMITER = "\t";
    private static final String HELP_TEXT_LINE_DELIMITER = "\n";
    private static final int HELP_TEXT_LENGTH_PER_PARAM = 100;

    private HashMap data;

    public RequiredParameters() {
        this.data = new HashMap<>();
    }

    /**
     * Add a parameter based on its name.
     *
     * @param name - the name of the parameter
     * @return - an {@link Option} object representing the parameter
     * @throws RequiredParametersException if an option with the same name is already defined
     */
    public Option add(String name) throws RequiredParametersException {
        if (!this.data.containsKey(name)) {
            Option option = new Option(name);
            this.data.put(name, option);
            return option;
        } else {
            throw new RequiredParametersException("Option with key " + name + " already exists.");
        }
    }

    /**
     * Add a parameter encapsulated in an {@link Option} object.
     *
     * @param option - the parameter
     * @throws RequiredParametersException if an option with the same name is already defined
     */
    public void add(Option option) throws RequiredParametersException {
        if (!this.data.containsKey(option.getName())) {
            this.data.put(option.getName(), option);
        } else {
            throw new RequiredParametersException(
                    "Option with key " + option.getName() + " already exists.");
        }
    }

    /**
     * Check for all required parameters defined: - has a value been passed - if not, does the
     * parameter have an associated default value - does the type of the parameter match the one
     * defined in RequiredParameters - does the value provided in the parameterTool adhere to the
     * choices defined in the option.
     *
     * 

If any check fails, a RequiredParametersException is thrown * * @param parameterTool - parameters supplied by the user. * @return the updated ParameterTool containing all the required parameters * @throws RequiredParametersException if any of the specified checks fail */ public ParameterTool applyTo(ParameterTool parameterTool) throws RequiredParametersException { List missingArguments = new LinkedList<>(); HashMap newParameters = new HashMap<>(parameterTool.toMap()); for (Option o : data.values()) { if (newParameters.containsKey(o.getName())) { if (Objects.equals(newParameters.get(o.getName()), ParameterTool.NO_VALUE_KEY)) { // the parameter has been passed, but no value, check if there is a default // value checkAndApplyDefaultValue(o, newParameters); } else { // a value has been passed in the parameterTool, now check if it adheres to all // constraints checkAmbiguousValues(o, newParameters); checkIsCastableToDefinedType(o, newParameters); checkChoices(o, newParameters); } } else { // check if there is a default name or a value passed for a possibly defined // alternative name. if (hasNoDefaultValueAndNoValuePassedOnAlternativeName(o, newParameters)) { missingArguments.add(o.getName()); } } } if (!missingArguments.isEmpty()) { throw new RequiredParametersException( this.missingArgumentsText(missingArguments), missingArguments); } return ParameterTool.fromMap(newParameters); } // check if the given parameter has a default value and add it to the passed map if that is the // case // else throw an exception private void checkAndApplyDefaultValue(Option o, Map data) throws RequiredParametersException { if (hasNoDefaultValueAndNoValuePassedOnAlternativeName(o, data)) { throw new RequiredParametersException( "No default value for undefined parameter " + o.getName()); } } // check if the value in the given map which corresponds to the name of the given option // is castable to the type of the option (if any is defined) private void checkIsCastableToDefinedType(Option o, Map data) throws RequiredParametersException { if (o.hasType() && !o.isCastableToDefinedType(data.get(o.getName()))) { throw new RequiredParametersException( "Value for parameter " + o.getName() + " cannot be cast to type " + o.getType()); } } // check if the value in the given map which corresponds to the name of the given option // adheres to the list of given choices for the param in the options (if any are defined) private void checkChoices(Option o, Map data) throws RequiredParametersException { if (o.getChoices().size() > 0 && !o.getChoices().contains(data.get(o.getName()))) { throw new RequiredParametersException( "Value " + data.get(o.getName()) + " is not in the list of valid choices for key " + o.getName()); } } // move value passed on alternative name to standard name or apply default value if any defined // else return true to indicate parameter is 'really' missing private boolean hasNoDefaultValueAndNoValuePassedOnAlternativeName( Option o, Map data) throws RequiredParametersException { if (o.hasAlt() && data.containsKey(o.getAlt())) { data.put(o.getName(), data.get(o.getAlt())); } else { if (o.hasDefaultValue()) { data.put(o.getName(), o.getDefaultValue()); if (o.hasAlt()) { data.put(o.getAlt(), o.getDefaultValue()); } } else { return true; } } return false; } // given that the map contains a value for the name of the option passed // check if it also contains a value for the shortName in option (if any is defined) private void checkAmbiguousValues(Option o, Map data) throws RequiredParametersException { if (data.containsKey(o.getAlt()) && !Objects.equals(data.get(o.getAlt()), ParameterTool.NO_VALUE_KEY)) { throw new RequiredParametersException( "Value passed for parameter " + o.getName() + " is ambiguous. Value passed for short and long name."); } } /** * Build a help text for the defined parameters. * *

The format of the help text will be: Required Parameters: \t -:shortName:, --:name: \t * :helpText: \t default: :defaultValue: \t choices: :choices: \n * * @return a formatted help String. */ public String getHelp() { StringBuilder sb = new StringBuilder(data.size() * HELP_TEXT_LENGTH_PER_PARAM); sb.append("Required Parameters:"); sb.append(HELP_TEXT_LINE_DELIMITER); for (Option o : data.values()) { sb.append(this.helpText(o)); } sb.append(HELP_TEXT_LINE_DELIMITER); return sb.toString(); } /** * Build a help text for the defined parameters and list the missing arguments at the end of the * text. * *

The format of the help text will be: Required Parameters: \t -:shortName:, --:name: \t * :helpText: \t default: :defaultValue: \t choices: :choices: \n * *

Missing parameters: \t param1 param2 ... paramN * * @param missingArguments - a list of missing parameters * @return a formatted help String. */ public String getHelp(List missingArguments) { return this.getHelp() + this.missingArgumentsText(missingArguments); } /** * for the given option create a line for the help text. The line looks like: \t -:shortName:, * --:name: \t :helpText: \t default: :defaultValue: \t choices: :choices: */ private String helpText(Option option) { StringBuilder sb = new StringBuilder(HELP_TEXT_LENGTH_PER_PARAM); sb.append(HELP_TEXT_PARAM_DELIMITER); // if there is a short name, add it. if (option.hasAlt()) { sb.append("-"); sb.append(option.getAlt()); sb.append(", "); } // add the name sb.append("--"); sb.append(option.getName()); sb.append(HELP_TEXT_PARAM_DELIMITER); // if there is a help text, add it if (option.getHelpText() != null) { sb.append(option.getHelpText()); sb.append(HELP_TEXT_PARAM_DELIMITER); } // if there is a default value, add it. if (option.hasDefaultValue()) { sb.append("default: "); sb.append(option.getDefaultValue()); sb.append(HELP_TEXT_PARAM_DELIMITER); } // if there is a list of choices add it. if (!option.getChoices().isEmpty()) { sb.append("choices: "); for (String choice : option.getChoices()) { sb.append(choice); sb.append(" "); } } sb.append(HELP_TEXT_LINE_DELIMITER); return sb.toString(); } private String missingArgumentsText(List missingArguments) { StringBuilder sb = new StringBuilder(missingArguments.size() * 10); sb.append("Missing arguments for:"); sb.append(HELP_TEXT_LINE_DELIMITER); for (String arg : missingArguments) { sb.append(arg); sb.append(" "); } return sb.toString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy