1010import java .util .Comparator ;
1111import java .util .Enumeration ;
1212import java .util .HashSet ;
13+ import java .util .Iterator ;
1314import java .util .List ;
1415import java .util .ArrayList ;
16+ import java .util .Arrays ;
1517import java .util .zip .ZipEntry ;
1618import java .util .zip .ZipFile ;
1719
4042public class JavaSourceUtilsOptions implements AutoCloseable {
4143 public static final String HELP_STRING = "[-v] [<-a|--aar> AAR]* [<-j|--jar> JAR]* [<-s|--source> DIRS]*\n " +
4244 "\t [--bootclasspath CLASSPATH]\n " +
43- "\t [<-P|--output-params> OUT.params.txt] [<-D|--output-javadoc> OUT.xml] FILES" ;
45+ "\t [<-P|--output-params> OUT.params.txt] [<-D|--output-javadoc> OUT.xml]\n " +
46+ "\t [@RESPONSE-FILE]* FILES" ;
4447
4548 public static boolean verboseOutput ;
4649
@@ -111,14 +114,15 @@ private final TypeSolver createTypeSolver(ParserConfiguration config) throws IOE
111114 return typeSolver ;
112115 }
113116
114- public static JavaSourceUtilsOptions parse (final String [] args ) throws IOException {
115- final JavaSourceUtilsOptions options = new JavaSourceUtilsOptions ();
117+ private final JavaSourceUtilsOptions parse (Iterator <String > args ) throws IOException {
118+ if (args == null || !args .hasNext ())
119+ return this ;
116120
117- for ( int i = 0 ; i < args .length ; ++ i ) {
118- final String arg = args [ i ] ;
121+ while ( args .hasNext () ) {
122+ String arg = args . next () ;
119123 switch (arg ) {
120124 case "-bootclasspath" : {
121- final String bootClassPath = getOptionValue (args , ++ i , arg );
125+ final String bootClassPath = getNextOptionValue (args , arg );
122126 final ArrayList <File > files = new ArrayList <File >();
123127 for (final String cp : bootClassPath .split (File .pathSeparator )) {
124128 final File file = new File (cp );
@@ -129,46 +133,46 @@ public static JavaSourceUtilsOptions parse(final String[] args) throws IOExcepti
129133 files .add (file );
130134 }
131135 for (int j = files .size (); j > 0 ; --j ) {
132- options . jarFiles .add (0 , files .get (j -1 ));
136+ jarFiles .add (0 , files .get (j -1 ));
133137 }
134- options . haveBootClassPath = true ;
138+ haveBootClassPath = true ;
135139 break ;
136140 }
137141 case "-a" :
138142 case "--aar" : {
139- final File file = getOptionFile (args , ++ i , arg );
143+ final File file = getNextOptionFile (args , arg );
140144 if (file == null ) {
141145 break ;
142146 }
143- options . aarFiles .add (file );
147+ aarFiles .add (file );
144148 break ;
145149 }
146150 case "-j" :
147151 case "--jar" : {
148- final File file = getOptionFile (args , ++ i , arg );
152+ final File file = getNextOptionFile (args , arg );
149153 if (file == null ) {
150154 break ;
151155 }
152- options . jarFiles .add (file );
156+ jarFiles .add (file );
153157 break ;
154158 }
155159 case "-s" :
156160 case "--source" : {
157- final File dir = getOptionFile (args , ++ i , arg );
161+ final File dir = getNextOptionFile (args , arg );
158162 if (dir == null ) {
159163 break ;
160164 }
161- options . sourceDirectoryFiles .add (dir );
165+ sourceDirectoryFiles .add (dir );
162166 break ;
163167 }
164168 case "-D" :
165169 case "--output-javadoc" : {
166- options . outputJavadocXml = getOptionValue (args , ++ i , arg );
170+ outputJavadocXml = getNextOptionValue (args , arg );
167171 break ;
168172 }
169173 case "-P" :
170174 case "--output-params" : {
171- options . outputParamsTxt = getOptionValue (args , ++ i , arg );
175+ outputParamsTxt = getNextOptionValue (args , arg );
172176 break ;
173177 }
174178 case "-v" : {
@@ -180,37 +184,63 @@ public static JavaSourceUtilsOptions parse(final String[] args) throws IOExcepti
180184 return null ;
181185 }
182186 default : {
183- final File file = getOptionFile (args , i , "FILES" );
184- if (file == null )
187+ if (arg .startsWith ("@" )) {
188+ // response file?
189+ final String responseFileName = arg .substring (1 );
190+ final File responseFile = new File (responseFileName );
191+ if (responseFile .exists ()) {
192+ final Iterator <String > lines =
193+ Files .readAllLines (responseFile .toPath ())
194+ .stream ()
195+ .filter (line -> line .length () > 0 && !line .startsWith ("#" ))
196+ .iterator ();
197+
198+ final JavaSourceUtilsOptions r = parse (lines );
199+ if (r == null )
200+ return null ;
201+ break ;
202+ }
203+ }
204+ final File file = new File (arg );
205+ if (!file .exists ()) {
206+ System .err .println (App .APP_NAME + ": warning: invalid file path for option `FILES`: " + arg );
185207 break ;
208+ }
186209
187210 if (file .isDirectory ()) {
188- options . sourceDirectoryFiles .add (file );
211+ sourceDirectoryFiles .add (file );
189212 Files .walk (file .toPath ())
190213 .filter (f -> Files .isRegularFile (f ) && f .getFileName ().toString ().endsWith (".java" ))
191214 .map (Path ::toFile )
192- .forEach (f -> options . inputFiles .add (f ));
215+ .forEach (f -> inputFiles .add (f ));
193216 break ;
194217 }
195218 if (file .getName ().endsWith (".java" )) {
196- options . inputFiles .add (file );
219+ inputFiles .add (file );
197220 break ;
198221 }
199222 if (!file .getName ().endsWith (".jar" ) && !file .getName ().endsWith (".zip" )) {
200223 System .err .println (App .APP_NAME + ": warning: ignoring input file `" + file .getAbsolutePath () +"`." );
201224 break ;
202225 }
203- if (options . extractedTempDir == null ) {
204- options . extractedTempDir = Files .createTempDirectory ("ji-jst" ).toFile ();
226+ if (extractedTempDir == null ) {
227+ extractedTempDir = Files .createTempDirectory ("ji-jst" ).toFile ();
205228 }
206- File toDir = new File (options . extractedTempDir , file .getName ());
207- options . sourceDirectoryFiles .add (toDir );
208- extractTo (file , toDir , options . inputFiles );
229+ File toDir = new File (extractedTempDir , file .getName ());
230+ sourceDirectoryFiles .add (toDir );
231+ extractTo (file , toDir , inputFiles );
209232 break ;
210233 }
211234 }
212235 }
213- return options ;
236+ return this ;
237+ }
238+
239+ public static JavaSourceUtilsOptions parse (final String [] args ) throws IOException {
240+ final JavaSourceUtilsOptions options = new JavaSourceUtilsOptions ();
241+ final Iterator <String > a = Arrays .stream (args ).iterator ();
242+
243+ return options .parse (a );
214244 }
215245
216246 private static void extractTo (final File zipFilePath , final File toDir , final Collection <File > inputFiles ) throws IOException {
@@ -235,18 +265,18 @@ private static void extractTo(final File zipFilePath, final File toDir, final Co
235265 }
236266 }
237267
238- static String getOptionValue (final String [] args , final int index , final String option ) {
239- if (index >= args .length )
268+ static String getNextOptionValue (final Iterator < String > args , final String option ) {
269+ if (! args .hasNext () )
240270 throw new IllegalArgumentException (
241- "Expected required value for option `" + option + "` at index " + index + " ." );
242- return args [ index ] ;
271+ "Expected required value for option `" + option + "`." );
272+ return args . next () ;
243273 }
244274
245- static File getOptionFile (final String [] args , final int index , final String option ) {
246- if (index >= args .length )
275+ static File getNextOptionFile (final Iterator < String > args , final String option ) {
276+ if (! args .hasNext () )
247277 throw new IllegalArgumentException (
248- "Expected required value for option `" + option + "` at index " + index + " ." );
249- final String fileName = args [ index ] ;
278+ "Expected required value for option `" + option + "`." );
279+ final String fileName = args . next () ;
250280 final File file = new File (fileName );
251281 if (!file .exists ()) {
252282 System .err .println (App .APP_NAME + ": warning: invalid file path for option `" + option + "`: " + fileName );
0 commit comments