1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * ident "%Z%%M% %I% %E% SMI" 24 * 25 * Copyright 1998-2002 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 package com.sun.dhcpmgr.cli.common; 29 30 import java.lang.IllegalArgumentException; 31 import java.text.MessageFormat; 32 33 /** 34 * This class provides the functionality for parsing command line 35 * arguments (similar to getsubopt(3C)). 36 * <br> 37 * After constructing an instance of it, getNextSubOption() can be used 38 * to get the next suboption. getSubOptionArg() can be used to get the argument 39 * for that option. 40 * 41 */ 42 public class GetSubOpt { 43 44 /** 45 * Delimiter between suboptions. 46 */ 47 public final static String OPTION_DELIM = ","; 48 49 /** 50 * Delimiter between suboption and suboption argument. 51 */ 52 public final static String VALUE_DELIM = "="; 53 54 /** 55 * List of suboptions. 56 */ 57 protected String subOptions; 58 59 /** 60 * The length of the suboptions. 61 */ 62 private final int subOptionsLen; 63 64 /** 65 * Current position with in suboptions. 66 */ 67 protected int index; 68 69 /** 70 * Last suboption found. 71 */ 72 protected String subOption; 73 74 /** 75 * Last suboption argument found. 76 */ 77 protected String value; 78 79 /** 80 * Prepare a GetSubOpt object. 81 * 82 * @param subOptions 83 * String containing the list of suboptions. This value was most likely 84 * returned as an option argument by <i>GetOpt</i>. 85 */ 86 public GetSubOpt(String subOptions) { 87 if (subOptions == null) { 88 this.subOptions = null; 89 } else { 90 this.subOptions = subOptions.trim(); 91 } 92 93 index = 0; 94 subOptionsLen = subOptions.length(); 95 } 96 97 /** 98 * Get the next suboption. The suboptions arguement is available from 99 * calling <i>getSubOptionArg()</i>. 100 * 101 * @return 102 * The next suboption. 103 * @exception IllegalArgumentException 104 * Thrown when no more suboptions remain. 105 */ 106 public String getNextSubOption() throws IllegalArgumentException { 107 108 subOption = null; 109 value = null; 110 111 while (subOption == null || subOption.length() == 0) { 112 113 if (!hasMoreSubOptions()) { 114 String format = 115 ResourceStrings.getString("getsubopt_end_of_optionarg"); 116 Object[] args = new Object[0]; 117 String msg = MessageFormat.format(format, args); 118 throw new IllegalArgumentException(msg); 119 } 120 121 int optionIndex = subOptions.indexOf(OPTION_DELIM, index); 122 int valueIndex = subOptions.indexOf(VALUE_DELIM, index); 123 124 if (optionIndex == -1 && valueIndex == -1) { 125 // Last suboption and no value. 126 subOption = subOptions.substring(index); 127 index = subOptionsLen; 128 } else if (valueIndex == -1 || 129 (optionIndex != -1 && optionIndex < valueIndex)) { 130 // Suboption has no value. 131 subOption = subOptions.substring(index, optionIndex); 132 index = optionIndex + OPTION_DELIM.length(); 133 } else { 134 // Suboption with value. 135 subOption = subOptions.substring(index, valueIndex); 136 index = valueIndex + VALUE_DELIM.length(); 137 138 boolean quoted = false; 139 int endIndex; 140 141 if (index < subOptionsLen && 142 (subOptions.charAt(index) == '\"' || 143 subOptions.charAt(index) == '\'')) { 144 // Value is quoted. 145 endIndex = 146 subOptions.indexOf(subOptions.charAt(index), index + 1); 147 148 // Missing close quote. 149 if (endIndex == -1) { 150 String format = 151 ResourceStrings.getString( 152 "getsubopt_missing_close_quote"); 153 Object[] args = new Object[1]; 154 args[0] = subOption; 155 String msg = MessageFormat.format(format, args); 156 throw new IllegalArgumentException(msg); 157 } 158 159 quoted = true; 160 index++; 161 } else { 162 // Value is not quoted. 163 endIndex = subOptions.indexOf(OPTION_DELIM, index); 164 165 if (endIndex == -1) { 166 endIndex = subOptionsLen; 167 } 168 } 169 170 value = subOptions.substring(index, endIndex); 171 index = endIndex; 172 173 // Skip closing quote. 174 if (quoted) { 175 index++; 176 } 177 178 /* 179 * Ensure that either the end of the suboptions has been 180 * reached or the next suboption is ready for parsing. For 181 * example, quoted values must not contain characters between 182 * the closing quote and OPTION_DELIM. 183 */ 184 if (optionIndex >= 0) { 185 if (index < subOptionsLen && 186 !subOptions.startsWith(OPTION_DELIM, index)) { 187 String format = 188 ResourceStrings.getString( 189 "getsubopt_malformed_value"); 190 Object[] args = new Object[1]; 191 args[0] = subOption; 192 String msg = MessageFormat.format(format, args); 193 throw new IllegalArgumentException(msg); 194 } 195 196 index += OPTION_DELIM.length(); 197 } 198 } 199 } 200 201 return subOption; 202 } 203 204 /** 205 * Indicates whether more suboptions exist. 206 * 207 * @return 208 * True if at least one more suboption exists, otherwise false. 209 */ 210 public boolean hasMoreSubOptions() throws IllegalArgumentException { 211 if (subOptions == null) { 212 return false; 213 } 214 215 // Skip over leading OPTION_DELIMs. 216 while (index < subOptionsLen && 217 subOptions.indexOf(OPTION_DELIM, index) == index) { 218 index += OPTION_DELIM.length(); 219 } 220 221 /* 222 * Ensure that there really is a suboption present. If a 223 * VALUE_DELIM has been found the suboption string is missing. 224 */ 225 if (index < subOptionsLen && 226 subOptions.indexOf(VALUE_DELIM, index) == index) { 227 String format = 228 ResourceStrings.getString( 229 "getsubopt_value_without_suboption"); 230 Object[] args = new Object[0]; 231 String msg = MessageFormat.format(format, args); 232 throw new IllegalArgumentException(msg); 233 } 234 235 return (index < subOptionsLen); 236 } 237 238 /** 239 * Get the current suboptions argument, or null if no argument is present. 240 * 241 * @return 242 * String containing the current suboptions argument, or null if the 243 * no argument is present. 244 */ 245 public String getSubOptionArg() { 246 return value; 247 } 248 } 249