/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE
* or https://OpenDS.dev.java.net/OpenDS.LICENSE.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
* add the following below this CDDL HEADER, with the fields enclosed
* by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
*/
package org.opends.server.util.args;
import org.opends.messages.Message;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import static org.opends.messages.UtilityMessages.*;
import static org.opends.server.util.StaticUtils.*;
/**
* This class defines a data structure for holding information about a
* subcommand that may be used with the subcommand argument parser. The
* subcommand has a name, a description, and a set of arguments.
*/
public class SubCommand
{
// Indicates whether this subCommand should be hidden in the usage
// information.
private boolean isHidden;
// The mapping between the short argument IDs and the arguments for this
// subcommand.
private HashMap<Character,Argument> shortIDMap;
// The mapping between the long argument IDs and the arguments for this
// subcommand.
private HashMap<String,Argument> longIDMap;
// The list of arguments associated with this subcommand.
private LinkedList<Argument> arguments;
// The description for this subcommand.
private Message description;
// The name of this subcommand.
private String name;
// The argument parser with which this subcommand is associated.
private SubCommandArgumentParser parser;
// Indicates whether this parser will allow additional unnamed
// arguments at the end of the list.
private boolean allowsTrailingArguments;
// The maximum number of unnamed trailing arguments that may be
// provided.
private int maxTrailingArguments;
// The minimum number of unnamed trailing arguments that may be
// provided.
private int minTrailingArguments;
// The display name that will be used for the trailing arguments in
// the usage information.
private String trailingArgsDisplayName;
/**
* Creates a new subcommand with the provided information. The
* subcommand will be automatically registered with the associated
* parser.
*
* @param parser
* The argument parser with which this subcommand is
* associated.
* @param name
* The name of this subcommand.
* @param description
* The description of this subcommand.
* @throws ArgumentException
* If the associated argument parser already has a
* subcommand with the same name.
*/
public SubCommand(SubCommandArgumentParser parser, String name,
Message description) throws ArgumentException
{
this(parser, name, false, 0, 0, null, description);
}
/**
* Creates a new subcommand with the provided information. The
* subcommand will be automatically registered with the associated
* parser.
*
* @param parser
* The argument parser with which this subcommand is
* associated.
* @param name
* The name of this subcommand.
* @param allowsTrailingArguments
* Indicates whether this parser allows unnamed trailing
* arguments to be provided.
* @param minTrailingArguments
* The minimum number of unnamed trailing arguments that
* must be provided. A value less than or equal to zero
* indicates that no minimum will be enforced.
* @param maxTrailingArguments
* The maximum number of unnamed trailing arguments that
* may be provided. A value less than or equal to zero
* indicates that no maximum will be enforced.
* @param trailingArgsDisplayName
* The display name that should be used as a placeholder
* for unnamed trailing arguments in the generated usage
* information.
* @param description
* The description of this subcommand.
* @throws ArgumentException
* If the associated argument parser already has a
* subcommand with the same name.
*/
public SubCommand(SubCommandArgumentParser parser, String name,
boolean allowsTrailingArguments, int minTrailingArguments,
int maxTrailingArguments, String trailingArgsDisplayName,
Message description) throws ArgumentException
{
this.parser = parser;
this.name = name;
this.description = description;
this.allowsTrailingArguments = allowsTrailingArguments;
this.minTrailingArguments = minTrailingArguments;
this.maxTrailingArguments = maxTrailingArguments;
this.trailingArgsDisplayName = trailingArgsDisplayName;
this.isHidden = false;
String nameToCheck = name;
if (parser.longArgumentsCaseSensitive())
{
nameToCheck = toLowerCase(name);
}
if (parser.hasSubCommand(nameToCheck))
{
Message message = ERR_ARG_SUBCOMMAND_DUPLICATE_SUBCOMMAND.get(name);
throw new ArgumentException(message);
}
parser.addSubCommand(this);
shortIDMap = new HashMap<Character,Argument>();
longIDMap = new HashMap<String,Argument>();
arguments = new LinkedList<Argument>();
}
/**
* Retrieves the name of this subcommand.
*
* @return The name of this subcommand.
*/
public String getName()
{
return name;
}
/**
* Retrieves the description for this subcommand.
*
* @return The description for this subcommand.
*/
public Message getDescription()
{
return description;
}
/**
* Retrieves the set of arguments for this subcommand.
*
* @return The set of arguments for this subcommand.
*/
public LinkedList<Argument> getArguments()
{
return arguments;
}
/**
* Retrieves the subcommand argument with the specified short identifier.
*
* @param shortID The short identifier of the argument to retrieve.
*
* @return The subcommand argument with the specified short identifier, or
* <CODE>null</CODE> if there is none.
*/
public Argument getArgument(Character shortID)
{
return shortIDMap.get(shortID);
}
/**
* Retrieves the subcommand argument with the specified long identifier.
*
* @param longID The long identifier of the argument to retrieve.
*
* @return The subcommand argument with the specified long identifier, or
* <CODE>null</CODE> if there is none.
*/
public Argument getArgument(String longID)
{
return longIDMap.get(longID);
}
/**
* Retrieves the subcommand argument with the specified name.
*
* @param name The name of the argument to retrieve.
*
* @return The subcommand argument with the specified name, or
* <CODE>null</CODE> if there is no such argument.
*/
public Argument getArgumentForName(String name)
{
for (Argument a : arguments)
{
if (a.getName().equals(name))
{
return a;
}
}
return null;
}
/**
* Adds the provided argument for use with this subcommand.
*
* @param argument The argument to add for use with this subcommand.
*
* @throws ArgumentException If either the short ID or long ID for the
* argument conflicts with that of another
* argument already associated with this
* subcommand.
*/
public void addArgument(Argument argument)
throws ArgumentException
{
String argumentName = argument.getName();
for (Argument a : arguments)
{
if (argumentName.equals(a.getName()))
{
Message message =
ERR_ARG_SUBCOMMAND_DUPLICATE_ARGUMENT_NAME.get(name, argumentName);
throw new ArgumentException(message);
}
}
if (parser.hasGlobalArgument(argumentName))
{
Message message =
ERR_ARG_SUBCOMMAND_ARGUMENT_GLOBAL_CONFLICT.get(argumentName, name);
throw new ArgumentException(message);
}
Character shortID = argument.getShortIdentifier();
if (shortID != null)
{
if (shortIDMap.containsKey(shortID))
{
Message message = ERR_ARG_SUBCOMMAND_DUPLICATE_SHORT_ID.
get(argumentName, name, String.valueOf(shortID),
shortIDMap.get(shortID).getName());
throw new ArgumentException(message);
}
Argument arg = parser.getGlobalArgumentForShortID(shortID);
if (arg != null)
{
Message message = ERR_ARG_SUBCOMMAND_ARGUMENT_SHORT_ID_GLOBAL_CONFLICT.
get(argumentName, name, String.valueOf(shortID), arg.getName());
throw new ArgumentException(message);
}
}
String longID = argument.getLongIdentifier();
if (longID != null)
{
if (! parser.longArgumentsCaseSensitive())
{
longID = toLowerCase(longID);
}
if (longIDMap.containsKey(longID))
{
Message message = ERR_ARG_SUBCOMMAND_DUPLICATE_LONG_ID.get(
argumentName, name, argument.getLongIdentifier(),
longIDMap.get(longID).getName());
throw new ArgumentException(message);
}
Argument arg = parser.getGlobalArgumentForLongID(longID);
if (arg != null)
{
Message message = ERR_ARG_SUBCOMMAND_ARGUMENT_LONG_ID_GLOBAL_CONFLICT.
get(argumentName, name, argument.getLongIdentifier(),
arg.getName());
throw new ArgumentException(message);
}
}
arguments.add(argument);
if (shortID != null)
{
shortIDMap.put(shortID, argument);
}
if (longID != null)
{
longIDMap.put(longID, argument);
}
}
/**
* Indicates whether this sub-command will allow unnamed trailing
* arguments. These will be arguments at the end of the list that
* are not preceded by either a long or short identifier and will
* need to be manually parsed by the application using this parser.
* Note that once an unnamed trailing argument has been identified,
* all remaining arguments will be classified as such.
*
* @return <CODE>true</CODE> if this sub-command allows unnamed
* trailing arguments, or <CODE>false</CODE> if it does
* not.
*/
public boolean allowsTrailingArguments()
{
return allowsTrailingArguments;
}
/**
* Retrieves the minimum number of unnamed trailing arguments that
* must be provided.
*
* @return The minimum number of unnamed trailing arguments that
* must be provided, or a value less than or equal to zero
* if no minimum will be enforced.
*/
public int getMinTrailingArguments()
{
return minTrailingArguments;
}
/**
* Retrieves the maximum number of unnamed trailing arguments that
* may be provided.
*
* @return The maximum number of unnamed trailing arguments that may
* be provided, or a value less than or equal to zero if no
* maximum will be enforced.
*/
public int getMaxTrailingArguments()
{
return maxTrailingArguments;
}
/**
* Retrieves the trailing arguments display name.
*
* @return Returns the trailing arguments display name.
*/
public String getTrailingArgumentsDisplayName()
{
return trailingArgsDisplayName;
}
/**
* Retrieves the set of unnamed trailing arguments that were provided on the
* command line.
*
* @return The set of unnamed trailing arguments that were provided on the
* command line.
*/
public ArrayList<String> getTrailingArguments()
{
return parser.getTrailingArguments();
}
/**
* Indicates whether this subcommand should be hidden from the usage
* information.
*
* @return <CODE>true</CODE> if this subcommand should be hidden
* from the usage information, or <CODE>false</CODE> if
* not.
*/
public boolean isHidden()
{
return isHidden;
}
/**
* Specifies whether this subcommand should be hidden from the usage
* information.
*
* @param isHidden
* Indicates whether this subcommand should be hidden from
* the usage information.
*/
public void setHidden(boolean isHidden)
{
this.isHidden = isHidden;
}
}