001 /*--------------------------------------------------------------------------+ 002 $Id: CommandLineTokenStream.java 26283 2010-02-18 11:18:57Z juergens $ 003 | | 004 | Copyright 2005-2010 Technische Universitaet Muenchen | 005 | | 006 | Licensed under the Apache License, Version 2.0 (the "License"); | 007 | you may not use this file except in compliance with the License. | 008 | You may obtain a copy of the License at | 009 | | 010 | http://www.apache.org/licenses/LICENSE-2.0 | 011 | | 012 | Unless required by applicable law or agreed to in writing, software | 013 | distributed under the License is distributed on an "AS IS" BASIS, | 014 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 015 | See the License for the specific language governing permissions and | 016 | limitations under the License. | 017 +--------------------------------------------------------------------------*/ 018 package edu.tum.cs.commons.options; 019 020 import java.util.LinkedList; 021 import java.util.Queue; 022 023 /** 024 * This class preprocesses the command line arguments by splitting them into 025 * several tokens. It supports the GNU style syntax as described in 026 * {@link edu.tum.cs.commons.options.CommandLine}. 027 * 028 * @author Benjamin Hummel 029 * @author $Author: juergens $ 030 * 031 * @version $Rev: 26283 $ 032 * @levd.rating GREEN Hash: D702FFBA7BE4D5C8637EEE2993924D3B 033 */ 034 public class CommandLineTokenStream { 035 036 /** Queue storing remaining short options (results from option chaining). */ 037 private final Queue<Character> shortOptionQueue = new LinkedList<Character>(); 038 039 /** Pending parameter (possibly remaining from the last long option read). */ 040 private String pendingParam = null; 041 042 /** Queue storing all remaining arguments. */ 043 private final Queue<String> argQueue = new LinkedList<String>(); 044 045 /** 046 * Constructs a new CommandLineTokenStream on the given arguments. 047 * 048 * @param args 049 */ 050 public CommandLineTokenStream(String[] args) { 051 for (String a : args) { 052 argQueue.add(a); 053 } 054 } 055 056 /** 057 * Returns whether a further token is available. 058 */ 059 public boolean hasNext() { 060 return !argQueue.isEmpty() || !shortOptionQueue.isEmpty() 061 || pendingParam != null; 062 } 063 064 /** 065 * Returns whether the next token is available and is a short option. 066 */ 067 public boolean nextIsShortOption() { 068 if (!shortOptionQueue.isEmpty()) { 069 return true; 070 } 071 if (pendingParam != null || argQueue.isEmpty()) { 072 return false; 073 } 074 String next = argQueue.peek(); 075 return next.length() >= 2 && next.charAt(0) == '-' 076 && next.charAt(1) != '-'; 077 } 078 079 /** 080 * Returns whether the next token is available and is a long option. 081 */ 082 public boolean nextIsLongOption() { 083 if (!shortOptionQueue.isEmpty() || pendingParam != null 084 || argQueue.isEmpty()) { 085 return false; 086 } 087 return argQueue.peek().startsWith("--"); 088 } 089 090 /** 091 * Returns whether the next token is available and can be used as a file 092 * argument. 093 */ 094 public boolean nextIsFileArgument() { 095 if (!shortOptionQueue.isEmpty() || pendingParam != null 096 || argQueue.isEmpty()) { 097 return false; 098 } 099 return !argQueue.peek().startsWith("-"); 100 } 101 102 /** 103 * Returns whether the next token is available and can be used as a 104 * parameter to an option. 105 */ 106 public boolean nextIsParameter() { 107 if (!shortOptionQueue.isEmpty()) { 108 return false; 109 } 110 if (pendingParam != null) { 111 return true; 112 } 113 return !argQueue.isEmpty(); 114 } 115 116 /** 117 * Returns the next token as a plain string. 118 */ 119 public String next() { 120 if (!shortOptionQueue.isEmpty()) { 121 return "-" + shortOptionQueue.poll(); 122 } 123 if (pendingParam != null) { 124 String result = pendingParam; 125 pendingParam = null; 126 return result; 127 } 128 return argQueue.poll(); 129 } 130 131 /** 132 * Returns the next token as a short option. 133 */ 134 public char nextShortOption() { 135 if (!nextIsShortOption()) { 136 throw new IllegalStateException("No short option available!"); 137 } 138 if (shortOptionQueue.isEmpty()) { 139 String arg = argQueue.poll(); 140 for (int i = 1; i < arg.length(); ++i) { 141 shortOptionQueue.add(arg.charAt(i)); 142 } 143 } 144 return shortOptionQueue.poll(); 145 } 146 147 /** 148 * Returns the next token as a long option. 149 */ 150 public String nextLongOption() { 151 if (!nextIsLongOption()) { 152 throw new IllegalStateException("No long option available!"); 153 } 154 String res = argQueue.poll().substring(2); 155 if (res.contains("=")) { 156 String[] parts = res.split("=", 2); 157 res = parts[0]; 158 pendingParam = parts[1]; 159 } 160 return res; 161 } 162 }