
com.sun.messaging.jmq.util.options.OptionParser Maven / Gradle / Ivy
/*
* Copyright (c) 2000, 2017 Oracle and/or its affiliates. All rights reserved.
* Copyright 2021 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package com.sun.messaging.jmq.util.options;
import java.util.Properties;
/**
* This class is a generic command line options parser. parseArgs() is the entry point for this class.
*
*
* Based on the option descrption table that is passed into parseArgs(), it will go through each command line option in
* the args[] array and add the relevant property name=value pairs in the Properties object that is passed in.
*
*
* REVISIT: should we add a flag to indicate if an exception should be thrown is an option is used and it is not in the
* options table ?
*
*
* parseArgs() will throw an OptionException if the command line option expects an argument in the next element of the
* args[] array and there is none.
*
*
* This class should be subclassed for use in specific applications.
*
* @see OptionType
* @see OptionDesc
*/
public class OptionParser implements OptionType {
/**
* Parses arg list using the specified option description table and returns a Properties object which corresponds to it.
*
* @param args Array containing command line options
* @param optDesc Table defining the valid command line options
* @param prop Properties object that will be used to store the name=value pairs.
*/
public static void parseArgs(String args[], OptionDesc optDesc[], Properties prop) throws OptionException {
if ((args == null) || (optDesc == null) || (prop == null)) {
return;
}
int argsCount = args.length, i;
for (i = 0; i < argsCount; ++i) {
String curOption = args[i];
/*
* Search the options table for a matching option.
*/
int match = findMatchingOption(optDesc, curOption);
/*
* Throw an exception if a match was not found
*/
if (match < 0) {
UnrecognizedOptionException uoe = new UnrecognizedOptionException();
uoe.setOption(curOption);
throw (uoe);
}
OptionDesc matchOpt = optDesc[match];
boolean ignore = matchOpt.ignore;
String optBaseProp = matchOpt.baseProperty, optValue = matchOpt.value, optNameValuePair = matchOpt.nameValuePair, propName = null, propVal = null,
name = null, nvPair = null;
switch (matchOpt.type) {
case OPTION_VALUE_HARDCODED:
propName = optBaseProp;
propVal = optValue;
/*
* If either the name or value is null, throw an exception.
*/
if (propName == null) {
InvalidBasePropNameException ibpe = new InvalidBasePropNameException();
ibpe.setOption(curOption);
throw (ibpe);
}
if (propVal == null) {
InvalidHardCodedValueException ihcve = new InvalidHardCodedValueException();
ihcve.setOption(curOption);
throw (ihcve);
}
break;
case OPTION_VALUE_NEXT_ARG:
/*
* Throw exception if argument holding value of property is missing.
*/
if ((i + 1) >= argsCount) {
MissingArgException mae = new MissingArgException();
mae.setOption(curOption);
throw (mae);
}
propName = optBaseProp;
propVal = args[++i];
/*
* If the name is null, throw an exception.
*/
if (propName == null) {
InvalidBasePropNameException ibpe = new InvalidBasePropNameException();
ibpe.setOption(curOption);
throw (ibpe);
}
break;
case OPTION_VALUE_NEXT_ARG_RES:
/*
* Throw exception if argument holding value of property is missing.
*/
if ((i + 1) >= argsCount) {
MissingArgException mae = new MissingArgException();
mae.setOption(curOption);
throw (mae);
}
nvPair = args[++i];
name = getName(nvPair);
propVal = getValue(nvPair);
/*
* If either the name or value is null, throw an exception.
*/
if ((name == null) || (propVal == null)) {
BadNameValueArgException bnvae = new BadNameValueArgException();
bnvae.setOption(curOption);
bnvae.setArg(nvPair);
throw (bnvae);
}
/*
* If base property is not null, append it to the name portion of the n/v pair.
*
* If base property is null, simply use the name portion of the n/v pair.
*/
if (optBaseProp != null) {
propName = optBaseProp + "." + name;
} else {
propName = name;
}
break;
case OPTION_VALUE_SUFFIX_RES:
try {
nvPair = curOption.substring(matchOpt.option.length());
} catch (IndexOutOfBoundsException ibe) {
MissingArgException mae = new MissingArgException();
mae.setOption(matchOpt.option);
throw (mae);
}
if (nvPair.equals("")) {
MissingArgException mae = new MissingArgException();
mae.setOption(matchOpt.option);
throw (mae);
}
name = getName(nvPair);
propVal = getValue(nvPair);
/*
* If either the name or value is null, throw an exception.
*/
if ((name == null) || (propVal == null)) {
BadNameValueArgException bnvae = new BadNameValueArgException();
bnvae.setOption(matchOpt.option);
bnvae.setArg(nvPair);
throw (bnvae);
}
/*
* If base property is not null, append it to the name portion of the n/v pair.
*
* If base property is null, simply use the name portion of the n/v pair.
*/
if (optBaseProp != null) {
propName = optBaseProp + "." + name;
} else {
propName = name;
}
break;
}
if ((propName != null) && (propVal != null)) {
/*
* REVISIT: Enable this after add 'overwrite' flag to OptionDesc
*
* Check if property alrady exists before writing it. if (prop.containsKey(propName)) { PropertyAlreadyExistsException
* pae = new PropertyAlreadyExistsException(); pae.setOption(curOption); pae.setPropertyName(propName); throw(pae); }
*/
if (!ignore) {
prop.put(propName, propVal);
}
}
/*
* 'optNameValuePair' holds a name value pair that needs to be added to the properties object. This is independent of
* the processing above.
*/
if (optNameValuePair != null) {
String name2 = getName(optNameValuePair), value = getValue(optNameValuePair);
if ((name2 != null) || (value != null)) {
prop.put(name2, value);
}
}
}
}
private static String getName(String nameValuePair) {
if (nameValuePair == null) {
return (null);
}
int index = nameValuePair.indexOf("=");
if (index > 0) {
return (nameValuePair.substring(0, index));
}
return (null);
}
private static String getValue(String nameValuePair) {
if (nameValuePair == null) {
return (null);
}
int index = nameValuePair.indexOf("=");
if (index > 0) {
if (nameValuePair.length() == 1) {
return ("");
} else {
return (nameValuePair.substring(index + 1));
}
}
return (null);
}
private static int findMatchingOption(OptionDesc optDesc[], String arg) {
int matchIndex = -1;
for (int i = 0; i < optDesc.length; ++i) {
int type = optDesc[i].type;
String option = optDesc[i].option;
if (arg.equals(option)) {
return (i);
} else if ((type == OPTION_VALUE_SUFFIX_RES) && (arg.startsWith(option))) {
return (i);
}
}
return (matchIndex);
}
}