+ ChannelProperties.getProperty("app_name"),
Opt.UNARY, Opt.BOOTSTRAP),
HEADLESS(Type.CONFIG,
- "Run Jalview in headless mode. No GUI interface will be created and Jalview will quit after all arguments have been processed.",
+ "Run Jalview in headless mode. No GUI interface will be created and Jalview will quit after all arguments have been processed. "
+ + "Headless mode is assumed if an output file is to be generated, this can be overridden with --gui.",
+ Opt.UNARY, Opt.BOOTSTRAP),
+ GUI(Type.CONFIG,
+ "Do not run Jalview in headless mode. This overrides the assumption of headless mode when an output file is to be generated.",
Opt.UNARY, Opt.BOOTSTRAP),
JABAWS(Type.CONFIG, "Set a different URL to connect to a JABAWS server.",
Opt.STRING, Opt.BOOTSTRAP),
QUESTIONNAIRE(Type.CONFIG,
"Show (or don't show) the questionnaire if one is available.",
true, Opt.BOOLEAN, Opt.BOOTSTRAP),
- USAGESTATS(Type.CONFIG,
- "Send (or don't send) initial launch usage stats.", true,
- Opt.BOOLEAN, Opt.BOOTSTRAP),
+ NOUSAGESTATS(Type.CONFIG, "Don't send initial launch usage stats.",
+ Opt.UNARY, Opt.BOOTSTRAP),
+ NOSTARTUPFILE(Type.CONFIG, "Don't show the default startup file.",
+ Opt.UNARY, Opt.BOOTSTRAP),
WEBSERVICEDISCOVERY(Type.CONFIG,
"Attempt (or don't attempt) to connect to JABAWS web services.",
true, Opt.BOOLEAN, Opt.BOOTSTRAP),
INITSUBSTITUTIONS(Type.CONFIG,
"Set ‑‑substitutions to be initially enabled (or initially disabled).",
true, Opt.BOOLEAN, Opt.BOOTSTRAP, Opt.NOACTION, Opt.SECRET),
+ P(Type.CONFIG, "Set a Jalview preference value for this session.",
+ Opt.PREFIXKEV, Opt.PRESERVECASE, Opt.STRING, Opt.BOOTSTRAP,
+ Opt.MULTI, Opt.NOACTION, Opt.SECRET), // keep this secret for now.
// Opening an alignment
OPEN(Type.OPENING,
"Specifies the title for the open alignment window as string.",
Opt.STRING, Opt.LINKED),
COLOUR(Type.OPENING, "color", // being a bit soft on the Americans!
- "Applies the colour scheme to the open alignment window. Valid values are:\n"
+ "Applies the colour scheme to the open alignment window. Valid values include:\n"
+ "clustal,\n" + "blosum62,\n" + "pc-identity,\n"
+ "zappo,\n" + "taylor,\n" + "gecos-flower,\n"
+ "gecos-blossom,\n" + "gecos-sunset,\n"
+ "turn-propensity,\n" + "buried-index,\n"
+ "nucleotide,\n" + "nucleotide-ambiguity,\n"
+ "purine-pyrimidine,\n" + "rna-helices,\n"
- + "t-coffee-scores,\n" + "sequence-id.",
+ + "t-coffee-scores,\n" + "sequence-id.\n" + "\n"
+ + "Names of user defined colourschemes will also work,\n"
+ + "and jalview colourscheme specifications like\n"
+ + "--colour=\"D,E=red; K,R,H=0022FF; C,c=yellow\"",
Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
FEATURES(Type.OPENING, "Add a feature file or URL to the open alignment.",
Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS),
+ "none,\n" + "jmol,\n" + "chimera,\n" + "chimerax,\n"
+ "pymol.",
Opt.STRING, Opt.LINKED, Opt.MULTI),
- STRUCTUREIMAGE(Type.STRUCTURE,
- "Export an image of a 3D structure opened in JMOL", Opt.STRING,
- Opt.LINKED, Opt.MULTI),
NOTEMPFAC(Type.STRUCTURE,
"Do not show the temperature factor annotation for the preceding --structure.",
Opt.UNARY, Opt.LINKED, Opt.ALLOWALL, Opt.SECRET), // keep this secret
- // until it
- // works!
+ // until it works!
SHOWSSANNOTATIONS(Type.STRUCTURE, null, Opt.BOOLEAN, Opt.LINKED,
Opt.ALLOWALL),
"Output an image of the open alignment window. Format is specified by the subval modifier, a following --type argument or guessed from the file extension. Valid formats/extensions are:\n"
+ "svg,\n" + "png,\n" + "eps,\n" + "html,\n" + "biojs.",
Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS, Opt.ALLOWALL,
- Opt.REQUIREINPUT, Opt.OUTPUT, Opt.PRIMARY),
+ Opt.REQUIREINPUT, Opt.OUTPUTFILE, Opt.PRIMARY),
TYPE(Type.IMAGE,
- "Set the image format for the preceding --image to name. Valid values for name are: svg,\n"
- + "png,\n" + "eps,\n" + "html,\n" + "biojs.",
+ "Set the image format for the preceding --image. Valid values are:\n"
+ + "svg,\n" + "png,\n" + "eps,\n" + "html,\n" + "biojs.",
Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
TEXTRENDERER(Type.IMAGE,
- "Sets whether text in a vector image format (SVG, HTML, EPS) should be rendered as text or vector line-art. Possible values for name are:\n"
+ "Sets whether text in a vector image format (SVG, HTML, EPS) should be rendered as text or vector line-art. Possible values are:\n"
+ "text,\n" + "lineart.",
Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
SCALE(Type.IMAGE,
HEIGHT(Type.IMAGE,
"Sets a height for bitmap image format (PNG) with the width maintaining the aspect ratio. Should be given as a positive integer. If used in conjunction with --scale and --width then the smallest scaling will be used (scale, width and height provide bounds for the image).",
Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+ STRUCTUREIMAGE(Type.STRUCTUREIMAGE,
+ "Export an image of a 3D structure opened in JMOL", Opt.STRING,
+ Opt.LINKED, Opt.MULTI, Opt.OUTPUTFILE),
+ STRUCTUREIMAGETYPE(Type.STRUCTUREIMAGE,
+ "Set the structure image format for the preceding --structureimage. Valid values are:\n"
+ + "svg,\n" + "png,\n" + "eps,\n" + "html,\n" + "biojs.",
+ Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+ STRUCTUREIMAGETEXTRENDERER(Type.STRUCTUREIMAGE,
+ "Sets whether text in a vector structure image format (SVG, EPS) should be rendered as text or vector line-art. Possible values are:\n"
+ + "text,\n" + "lineart.",
+ Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+ STRUCTUREIMAGESCALE(Type.STRUCTUREIMAGE,
+ "Sets a scaling for bitmap structure image format (PNG). Should be given as a floating point number. If used in conjunction with --structureimagewidth and --structureimageheight then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image).",
+ Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+ STRUCTUREIMAGEWIDTH(Type.STRUCTUREIMAGE,
+ "Sets a width for bitmap structure image format (PNG) with the height maintaining the aspect ratio. Should be given as a positive integer. If used in conjunction with --structureimagescale and --structureimageheight then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image).",
+ Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+ STRUCTUREIMAGEHEIGHT(Type.STRUCTUREIMAGE,
+ "Sets a height for bitmap structure image format (PNG) with the width maintaining the aspect ratio. Should be given as a positive integer. If used in conjunction with --structureimagescale and --structureimagewidth then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image).",
+ Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+
OUTPUT(Type.OUTPUT,
"Export the open alignment to file filename. The format name is specified by the subval modifier format=name, a following --format name argument or guessed from the file extension. Valid format names (and file extensions) are:\n"
+ "fasta (fa, fasta, mfa, fastq),\n" + "pfam (pfam),\n"
+ "clustal (aln),\n" + "phylip (phy),\n"
+ "jalview (jvp, jar).",
Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS, Opt.ALLOWALL,
- Opt.REQUIREINPUT, Opt.OUTPUT, Opt.PRIMARY),
+ Opt.REQUIREINPUT, Opt.OUTPUTFILE, Opt.STDOUT, Opt.PRIMARY),
FORMAT(Type.OUTPUT,
"Sets the format for the preceding --output file. Valid formats are:\n"
+ "fasta,\n" + "pfam,\n" + "stockholm,\n" + "pir,\n"
"Move on to a new alignment window. This will ensure --append will start a new alignment window and other linked arguments will apply to the new alignment window.",
Opt.UNARY, Opt.MULTI, Opt.NOACTION, Opt.INCREMENTDEFAULTCOUNTER),
SUBSTITUTIONS(Type.FLOW,
- "The following argument values allow (or don't allow) subsituting filename parts. This is initially true. Valid substitutions are {basename} - the filename-without-extension of the currently --opened file (or first --appended file),\n"
+ "The following argument values allow (or don't allow) subsituting filename parts. This is initially true. Valid substitutions are:\n"
+ + "{basename} - the filename-without-extension of the currently --opened file (or first --appended file),\n"
+ "{dirname} - the directory (folder) name of the currently --opened file (or first --appended file),\n"
+ "{argfilebasename} - the filename-without-extension of the current --argfile,\n"
+ "{argfiledirname} - the directory (folder) name of the current --argfile,\n"
QUIT(Type.FLOW,
"After all files have been opened, appended and output, quit Jalview. In ‑‑headless mode this already happens.",
Opt.UNARY),
+ NOQUIT(Type.FLOW,
+ "Secret arg to not quit after --headless mode for tests",
+ Opt.UNARY, Opt.SECRET),
+ ALLSTRUCTURES(Type.FLOW,
+ "Apply the following 3D structure formatting arguments to all structures within the open alignment.",
+ Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION),
// secret options
TESTOUTPUT(Type.CONFIG,
public static enum Opt
{
- BOOLEAN, // This Arg can be specified as --arg or --noarg to give true or
- // false. A default can be given with setOptions(bool, Opt....).
- // Use ArgParser.isSet(Arg) to see if this arg was not specified.
- STRING, // This Arg can accept a value either through --arg=value or --arg
- // value.
- UNARY, // This Arg is a boolean value, true if present, false if not. Like
- // BOOLEAN but without the --noarg option.
- MULTI, // This Arg can be specified multiple times. Multiple values are
- // stored in the ArgValuesMap (along with their positional index) for
- // each linkedId.
- LINKED, // This Arg can be linked to others through a --arg[linkedId] or
- // --arg[linkedId]=value. If no linkedId is specified then the
- // current default linkedId will be used.
- NODUPLICATEVALUES, // This Arg can only have one value (per linkedId). The
- // first value will be used and subsequent values ignored
- // with a warning.
- BOOTSTRAP, // This Arg value(s) can be determined at an earlier stage than
- // non-BOOTSTRAP Args. Substitutions do not happen in BOOTSTRAP
- // Args and they cannot be linked or contain SubVals. See
- // jalview.bin.argparser.BootstrapArgs.
- GLOB, // This Arg can expand wildcard filename "globs" (e.g.
- // path/*/filename*). If the Arg value is given as --arg filename*
- // then the shell will have expanded the glob already, but if
- // specified as --arg=filename* then the Java glob expansion method
- // will be used (see FileUtils.getFilenamesFromGlob()). Note that this
- // might be different from the shell expansion rules.
- NOACTION, // This Arg does not perform a data task, usually used to control
- // flow in ArgParser.parse(args).
- ALLOWSUBSTITUTIONS, // This Arg allows substitutions in its linkedId,
- // SubVals and values.
- PRIVATE, // This Arg is used internally, and cannot be specified by the
- // user.
- SECRET, // This Arg is used by development processes and although it can be
- // set by the user, it is not displayed to the user.
- ALLOWALL, // This Arg can use the '*' linkedId to apply to all known
- // linkedIds
- INCREMENTDEFAULTCOUNTER, // If an Arg has this option and the default
- // linkedId is used, the defaultLinkedIdCounter is
- // incremented *first*.
- INPUT, // This Arg counts as an input for REQUIREINPUT
- REQUIREINPUT, // This Arg can only be applied via --all if there is an
- // input (i.e. --open or --append)
- OUTPUT, // This Arg provides an output filename. With Opt.ALLOWALL *.ext is
- // shorthand for --all --output={basename}.ext
- STORED, // This Arg resets and creates a new set of "opened" linkedIds
- HELP, // This Arg is a --help type arg
- PRIMARY, // This Arg is the main Arg for its type
- HASTYPE, // This Arg can have an Arg.Type assigned to it (and no value)
- FIRST, // Move this arg to the first in usage statement (within type)
- LAST, // Move this arg to the end in usage statement (within type)
+ /*
+ * A BOOLEAN Arg can be specified as --arg or --noarg to give true or false.
+ * A default can be given with setOptions(bool, Opt....).
+ * Use ArgParser.isSet(Arg) to see if this arg was not specified.
+ */
+ BOOLEAN("can be negated with " + ArgParser.DOUBLEDASH
+ + ArgParser.NEGATESTRING + "..."),
+
+ /*
+ * A STRING Arg will take a value either through --arg=value or --arg value.
+ */
+ STRING("expects a value"),
+ /*
+ * A UNARY Arg is a boolean value, true if present, false if not.
+ * Like BOOLEAN but without the --noarg option.
+ */
+ UNARY(null),
+ /*
+ * A MULTI Arg can be specified multiple times.
+ * Multiple values are stored in the ArgValuesMap (along with their positional index) for each linkedId.
+ */
+ MULTI("can be specified multiple times"),
+ /*
+ * A Linked Arg can be linked to others through a --arg[linkedId] or --arg[linkedId]=value.
+ * If no linkedId is specified then the current default linkedId will be used.
+ */
+ LINKED("is linked to an alignment"),
+ /*
+ * A NODUPLICATES Arg can only have one value (per linkedId).
+ * The first value will be used and subsequent values ignored with a warning.
+ */
+ NODUPLICATEVALUES("cannot have the same value more than once"),
+ /*
+ * A BOOTSTRAP Arg value(s) can be determined at an earlier stage than non-BOOTSTRAP Args.
+ * Substitutions do not happen in BOOTSTRAP Args and they cannot be linked or contain SubVals.
+ * See jalview.bin.argparser.BootstrapArgs.
+ */
+ BOOTSTRAP("a configuration argument"),
+ /*
+ * A GLOB Arg can expand wildcard filename "globs" (e.g. path/* /filename*).
+ * If the Arg value is given as --arg filename* then the shell will have expanded the glob already,
+ * but if specified as --arg=filename* then the Java glob expansion method will be used
+ * (see FileUtils.getFilenamesFromGlob()).
+ * Note that this might be different from the shell expansion rules.
+ */
+ GLOB("can take multiple filenames with wildcards"),
+ /*
+ * A NOACTION Arg does not perform a data task,
+ * usually used to control flow in ArgParser.parse(args).
+ */
+ NOACTION(null),
+ /*
+ * An ALLOWSUBSTITUTIONS Arg allows substitutions in its linkedId,
+ * SubVals and values.
+ */
+ ALLOWSUBSTITUTIONS("values can use substitutions"),
+ /*
+ * A PRIVATE Arg is used internally, and cannot be specified by the user.
+ */
+ PRIVATE(null),
+ /*
+ * A SECRET Arg is used by development processes and although it can be set by the user,
+ * it is not displayed to the user.
+ */
+ SECRET(null),
+ /*
+ * An ALLOWALL Arg can use the '*' linkedId to apply to all known linkedIds
+ */
+ ALLOWALL("can be used with " + ArgParser.DOUBLEDASH + "all"),
+ /*
+ * If an Arg has the INCREMENTDEFAULTCOUNTER option and the default linkedId is used,
+ * the defaultLinkedIdCounter is incremented *first*.
+ */
+ INCREMENTDEFAULTCOUNTER("starts a new default alignment"),
+ /*
+ * An INPUT Arg counts as an input for REQUIREINPUT
+ */
+ INPUT(null),
+ /*
+ * A REQUIREINPUT Arg can only be applied via --all if there is an input
+ * (i.e. --open or --append)
+ */
+ REQUIREINPUT(null),
+ /*
+ * An OUTPUTFILE Arg provides an output filename. With Opt.ALLOWALL *.ext is shorthand for
+ * --all --output={basename}.ext
+ */
+ OUTPUTFILE("output file --headless will be assumed unless --gui used"),
+ /*
+ * A STDOUT Arg can take an output filename that can be '-' to mean print to STDOUT.
+ */
+ STDOUT("allows the output filename '" + ArgParser.STDOUTFILENAME
+ + "' to mean output to STDOUT"),
+ /*
+ * A STORED Arg resets and creates a new set of "opened" linkedIds
+ */
+ STORED(null),
+ /*
+ * A HELP Arg is a --help type arg
+ */
+ HELP("provides a help statement"),
+ /*
+ * A PRIMARY Arg is the main Arg for its type
+ */
+ PRIMARY("is a primary argument for its type"),
+ /*
+ * A HASTYPE Arg can have an Arg.Type assigned to its ArgValue
+ */
+ HASTYPE(null),
+ /*
+ * A FIRST arg gets moved to appear first in the usage statement (within type)
+ */
+ FIRST(null),
+ /*
+ * A LAST arg gets moved to appear last in the usage statement (within type)
+ */
+ LAST(null),
+ /*
+ * After other args are checked, the following args can prefix a KEY=VALUE argument
+ */
+ PREFIXKEV("prefixes key=value"),
+ /*
+ * do not lowercase the name when getting the arg name or arg string
+ */
+ PRESERVECASE(null),
+ //
+ ;
+
+ private String description;
+
+ private Opt()
+ {
+ description = null;
+ }
+
+ private Opt(String description)
+ {
+ this.description = description;
+ }
+
+ public String description()
+ {
+ return description;
+ }
+
}
public static enum Type
PROCESS("arguments used to process an alignment once opened"),
OUTPUT("arguments used to save data from a processed alignment"),
IMAGE("arguments used to export an image of an alignment"),
+ STRUCTUREIMAGE("arguments used to export an image of an structure"),
FLOW("arguments that control processing of the other arguments"), //
ALL("all arguments"), // mostly just a place-holder for --help-all
NONE, // mostly a place-holder for --help
private Arg(Type type, String alternativeName, String description,
boolean defaultBoolean, Opt... options)
{
+ this.type = type;
+ this.description = description;
+ this.defaultBoolValue = defaultBoolean;
+ this.setOptions(options);
this.argNames = alternativeName != null
? new String[]
{ this.getName(), alternativeName }
: new String[]
{ this.getName() };
- this.type = type;
- this.description = description;
- this.defaultBoolValue = defaultBoolean;
- this.setOptions(options);
}
public String argString()
public String getName()
{
- return this.name().toLowerCase(Locale.ROOT).replace('_', '-');
+ String name = hasOption(Opt.PRESERVECASE) ? this.name()
+ : this.name().toLowerCase(Locale.ROOT);
+ return name.replace('_', '-');
}
@Override
return true;
}
+ protected Opt[] getOptions()
+ {
+ return argOptions;
+ }
+
protected void setOptions(Opt... options)
{
this.argOptions = options;
{
StringBuilder sb = new StringBuilder();
- sb.append("usage: jalview [" + Arg.HEADLESS.argString() + "] ["
+ sb.append("usage: jalview [" + Arg.HEADLESS.argString() + "] [["
+ Arg.OPEN.argString() + "/" + Arg.APPEND.argString()
- + " file(s)] [args]");
+ + "] file(s)] [args]");
sb.append(System.lineSeparator());
sb.append(System.lineSeparator());
}
Iterator<Arg> argsI = args.iterator();
+ Type typeSection = null;
while (argsI.hasNext())
{
Arg a = argsI.next();
continue;
}
- appendArgUsage(sb, a, maxArgLength);
+ if (a.getType() != typeSection)
+ {
+ typeSection = a.getType();
+ String typeDescription = a.getType().description();
+ if (typeDescription != null && typeDescription.length() > 0)
+ {
+ // typeDescription = typeDescription.substring(0,
+ // 1).toUpperCase(Locale.ROOT) + typeDescription.substring(1);
+ typeDescription = typeDescription.toUpperCase(Locale.ROOT);
+ sb.append(typeDescription);
+ sb.append(System.lineSeparator());
+ sb.append(System.lineSeparator());
+ }
+ }
+
+ appendArgUsage(sb, a, maxArgLength, Platform.consoleWidth());
if (argsI.hasNext())
+ {
sb.append(System.lineSeparator());
+ }
}
}
return sb.toString();
}
private static void appendArgUsage(StringBuilder sb, Arg a,
- int maxArgLength)
+ int maxArgLength, int maxWidth)
{
boolean first = appendArgAndDescription(sb, null, null, a,
maxArgLength);
List<String> options = new ArrayList<>();
- if (a.hasOption(Opt.BOOLEAN))
- {
- options.add("default " + (a.getDefaultBoolValue() ? a.argString()
- : a.negateArgString()));
- }
-
- if (a.hasOption(Opt.MULTI))
- {
- options.add("multiple");
- }
-
- if (a.hasOption(Opt.LINKED))
- {
- options.add("can be linked");
- }
-
- if (a.hasOption(Opt.GLOB))
- {
- options.add("allows file globs");
- }
-
- if (a.hasOption(Opt.ALLOWSUBSTITUTIONS))
- {
- options.add("allows substitutions");
- }
-
- if (a.hasOption(Opt.ALLOWALL))
+ for (Opt o : EnumSet.allOf(Opt.class))
{
- options.add("can be applied to all linked arguments");
- }
-
- if (a.hasOption(Opt.PRIVATE))
- {
- options.add("for internal use only");
- }
-
- if (a.hasOption(Opt.SECRET))
- {
- options.add("for development use only");
+ if (a.hasOption(o) && o.description() != null)
+ {
+ options.add(o.description());
+ }
}
+ final String optDisplaySeparator = "; ";
if (options.size() > 0)
{
+ int linelength = 0;
+ String spacing = String.format("%-"
+ + (maxArgLength + ARGDESCRIPTIONSEPARATOR.length()) + "s",
+ "");
if (first)
{
sb.append(ARGDESCRIPTIONSEPARATOR);
+ linelength += maxArgLength + ARGDESCRIPTIONSEPARATOR.length();
}
else
{
- sb.append(String.format("%-"
- + (maxArgLength + ARGDESCRIPTIONSEPARATOR.length()) + "s",
- ""));
+ sb.append(spacing);
+ linelength += spacing.length();
+ }
+ if (options.size() > 0)
+ {
+ boolean optFirst = true;
+ Iterator<String> optionsI = options.listIterator();
+ while (optionsI.hasNext())
+ {
+ String desc = optionsI.next();
+ if (optFirst)
+ {
+ sb.append("(");
+ linelength += 1;
+ }
+ int descLength = desc.length()
+ + (optionsI.hasNext() ? optDisplaySeparator.length() : 0);
+ if (linelength + descLength > maxWidth)
+ {
+ sb.append(System.lineSeparator());
+ linelength = 0;
+ sb.append(spacing);
+ linelength += spacing.length();
+ }
+ // sb.append(linelength + "+" + desc.length() + " ");
+ sb.append(desc);
+ linelength += desc.length();
+ if (optionsI.hasNext())
+ {
+ sb.append(optDisplaySeparator);
+ linelength += optDisplaySeparator.length();
+ }
+ optFirst = false;
+ }
+ sb.append(')');
+ sb.append(System.lineSeparator());
}
- sb.append("(");
- sb.append(String.join("; ", options));
- sb.append(')');
- sb.append(System.lineSeparator());
}
}
argSb.append(
a.hasOption(Opt.BOOLEAN) ? booleanArgString(a) : a.argString());
if (a.hasOption(Opt.STRING))
- argSb.append("=value");
+ {
+ if (a.hasOption(Opt.PREFIXKEV))
+ {
+ argSb.append("key=value");
+ }
+ else
+ {
+ argSb.append("=value");
+ }
+ }
return argSb.toString();
}