/* * The contents of this file are subject to the terms of the Common Development and * Distribution License (the License). You may not use this file except in compliance with the * License. * * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the * specific language governing permission and limitations under the License. * * When distributing Covered Software, include this CDDL Header Notice in each file and include * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL * Header, with the fields enclosed by brackets [] replaced by your own identifying * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2006-2008 Sun Microsystems, Inc. * Portions copyright 2014-2016 ForgeRock AS. */ package com.forgerock.opendj.cli; import static com.forgerock.opendj.cli.CliMessages.ERR_MCARG_VALUE_NOT_ALLOWED; import java.util.Arrays; import java.util.Collection; import java.util.LinkedList; import java.util.List; import org.forgerock.i18n.LocalizableMessageBuilder; /** * This class defines an argument type that will only accept one or more of a * specific set of string values. * * @param * The type of values returned by this argument. */ public final class MultiChoiceArgument extends Argument { /** * Returns a builder which can be used for incrementally constructing a new * {@link MultiChoiceArgument}. * * @param * The type of values returned by this argument. * @param longIdentifier * The generic long identifier that will be used to refer to this argument. * @return A builder to continue building the {@link MultiChoiceArgument}. */ public static Builder builder(final String longIdentifier) { return new Builder<>(longIdentifier); } /** A fluent API for incrementally constructing {@link MultiChoiceArgument}. */ public static final class Builder extends ArgumentBuilder, V, MultiChoiceArgument> { private final List allowedValues = new LinkedList<>(); private Builder(final String longIdentifier) { super(longIdentifier); } @Override Builder getThis() { return this; } /** * Specifies the set of values that are allowed for the {@link MultiChoiceArgument}. * * @param allowedValues * The {@link MultiChoiceArgument} allowed values. * @return This builder. */ public Builder allowedValues(final Collection allowedValues) { this.allowedValues.addAll(allowedValues); return getThis(); } /** * Specifies the set of values that are allowed for the {@link MultiChoiceArgument}. * * @param allowedValues * The {@link MultiChoiceArgument} allowed values. * @return This builder. */ @SuppressWarnings("unchecked") public final Builder allowedValues(final V... allowedValues) { this.allowedValues.addAll(Arrays.asList(allowedValues)); return getThis(); } @Override public MultiChoiceArgument buildArgument() throws ArgumentException { return new MultiChoiceArgument<>(this, allowedValues); } } /** The set of values that will be allowed for use with this argument. */ private final Collection allowedValues; private MultiChoiceArgument(final Builder builder, final Collection allowedValues) throws ArgumentException { super(builder); this.allowedValues = allowedValues; } /** * Retrieves the string value for this argument. If it has multiple values, * then the first will be returned. If it does not have any values, then the * default value will be returned. * * @return The string value for this argument, or null if there * are no values and no default value has been given. * @throws ArgumentException * The value cannot be parsed. */ public V getTypedValue() throws ArgumentException { final String v = super.getValue(); if (v == null) { return null; } for (final V allowedValue : allowedValues) { if (allowedValue.toString().equalsIgnoreCase(v)) { return allowedValue; } } throw new IllegalStateException("This MultiChoiceArgument value is not part of the allowed values."); } /** * Indicates whether the provided value is acceptable for use in this * argument. * * @param valueString * The value for which to make the determination. * @param invalidReason * A buffer into which the invalid reason may be written if the * value is not acceptable. * @return true if the value is acceptable, or * false if it is not. */ @Override public boolean valueIsAcceptable(final String valueString, final LocalizableMessageBuilder invalidReason) { for (final V allowedValue : allowedValues) { if (allowedValue.toString().equalsIgnoreCase(valueString)) { return true; } } invalidReason.append(ERR_MCARG_VALUE_NOT_ALLOWED.get(longIdentifier, valueString)); return false; } }