001/* 002 * Cobertura - http://cobertura.sourceforge.net/ 003 * 004 * Copyright (C) 2005 Grzegorz Lukasik 005 * 006 * Note: This file is dual licensed under the GPL and the Apache 007 * Source License (so that it can be used from both the main 008 * Cobertura classes and the ant tasks). 009 * 010 * Cobertura is free software; you can redistribute it and/or modify 011 * it under the terms of the GNU General Public License as published 012 * by the Free Software Foundation; either version 2 of the License, 013 * or (at your option) any later version. 014 * 015 * Cobertura is distributed in the hope that it will be useful, but 016 * WITHOUT ANY WARRANTY; without even the implied warranty of 017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 018 * General Public License for more details. 019 * 020 * You should have received a copy of the GNU General Public License 021 * along with Cobertura; if not, write to the Free Software 022 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 023 * USA 024 */ 025 026package net.sourceforge.cobertura.util; 027 028import java.io.BufferedReader; 029import java.io.File; 030import java.io.FileReader; 031import java.io.FileWriter; 032import java.io.IOException; 033import java.util.ArrayList; 034import java.util.List; 035 036import org.apache.log4j.Logger; 037 038/** 039 * Helper class for storing long command lines inside temporary file. 040 * <p> 041 * Typical usage: 042 * 043 * <pre> 044 * builder = new CommandLineBuilder(); 045 * builder.addArg("--someoption"); 046 * builder.addArg("optionValue"); 047 * ... 048 * builder.saveArgs(); 049 * doSomething(builder.getCommandLineFile()); 050 * builder.dispose(); 051 * </pre> 052 * 053 * It will save options in <code>builder.getCommandLineFile()</code>. Options 054 * will be stored one in a line. To retrieve options from file helper method can 055 * be used (see documentation): 056 * 057 * <pre> 058 * String[] args = CommandLineBuilder.preprocessCommandLineArguments(args); 059 * </pre> 060 * 061 * </p> 062 * 063 * <p> 064 * NOTICE: No protection against line separators in arguments, should be OK for 065 * Cobertura needs. 066 * </p> 067 * <p> 068 * NOTICE: This class depends on local machine settings (line separator, default 069 * encoding). If arguments are saved on different machine than they are loaded, 070 * results are unspecified. No problem in Cobertura. 071 * </p> 072 * 073 * @author Grzegorz Lukasik 074 */ 075public class CommandLineBuilder { 076 private static final Logger logger = Logger 077 .getLogger(CommandLineBuilder.class); 078 079 private static final String LINESEP = System.getProperty("line.separator"); 080 081 // File that will be used to store arguments 082 private File commandLineFile = null; 083 084 // Writer that will be used to write arguments to the file 085 private FileWriter commandLineWriter = null; 086 087 /** 088 * Creates a new instance of the builder. Instances of this class should not 089 * be reused to create many command lines. 090 * 091 * @throws IOException 092 * if problems with creating temporary file for storing command 093 * line occur 094 */ 095 public CommandLineBuilder() throws IOException { 096 commandLineFile = File.createTempFile("cobertura.", ".cmdline"); 097 commandLineFile.deleteOnExit(); 098 commandLineWriter = new FileWriter(commandLineFile); 099 } 100 101 /** 102 * Adds command line argument. Each argument can be thought as a single cell 103 * in array passed to main method. This method should not be used after 104 * arguments were saved. 105 * 106 * @param arg command line argument to save 107 * @throws IOException 108 * if problems with temporary file occur 109 * @throws NullPointerException 110 * if <code>arg</code> is <code>null</code> 111 */ 112 public void addArg(String arg) throws IOException { 113 if( arg==null) 114 throw new NullPointerException(); 115 commandLineWriter.write(arg + LINESEP); 116 } 117 118 119 /** 120 * Adds two command line arguments. Convienience function, calls 121 * {@link #addArg(String)} two times. 122 * 123 * @param arg1 first command line argument to save 124 * @param arg2 second command line argument to save 125 * @throws IOException 126 * if problems with temporary file occur 127 * @throws NullPointerException 128 * if any <code>arg</code> is <code>null</code> 129 */ 130 public void addArg(String arg1, String arg2) throws IOException { 131 addArg(arg1); 132 addArg(arg2); 133 } 134 135 136 /** 137 * Saves options and made file available to use. Use method 138 * {@link #getCommandLineFile} to get the file the arguments are saved in. 139 * 140 * @throws IOException 141 * if problems with temporary file occur 142 */ 143 public void saveArgs() throws IOException { 144 commandLineWriter.flush(); 145 commandLineWriter.close(); 146 } 147 148 /** 149 * Gets absolute path to the file with saved arguments. Notice, that however 150 * this method can be used as soon as an instance of this class is created, 151 * arguments should be read from the file after a call to 152 * {@link #saveArgs} method. 153 * 154 * @return absolute path to the file with arguments 155 */ 156 public String getCommandLineFile() { 157 return commandLineFile.getAbsolutePath(); 158 } 159 160 /** 161 * Explicity frees all resources associated with this instance. Result of 162 * any other method call after disposing an instance of this class is 163 * unspecified. 164 */ 165 public void dispose() { 166 commandLineFile.delete(); 167 } 168 169 /** 170 * Loads arguments from file if <code>--commandsfile</code> option is used. Checks 171 * if passed array contains <code>--commandsfile</code> String, and if 172 * so arguments from file specified in the very next array cell are read. If 173 * there are more then one <code>--commandsfile</code> the result is unspecified. 174 * 175 * @return The list of arguments read from commandsfile, or 176 * <code>args</code> if commandsfile option was not specified 177 * or the file cannot be read. 178 * @throws NullPointerException if args is null, or any argument is null 179 * @throws IllegalArgumentException if --commandsfile is specified as last option 180 * @throws IOException if I/O related error with temporary command line file occur 181 */ 182 public static String[] preprocessCommandLineArguments(String[] args) throws IOException { 183 boolean hasCommandsFile = false; 184 String commandsFileName = null; 185 for (int i = 0; i < args.length; i++) { 186 if ( args[i].equals( "--commandsfile")) { 187 if( i==args.length-1) { 188 throw new IllegalArgumentException("'--commandsfile' specified as last option."); 189 } 190 hasCommandsFile = true; 191 commandsFileName = args[++i]; 192 } 193 } 194 195 if (hasCommandsFile) { 196 List arglist = new ArrayList(); 197 BufferedReader bufferedReader = null; 198 199 try { 200 bufferedReader = new BufferedReader(new FileReader( 201 commandsFileName)); 202 String line; 203 204 while ((line = bufferedReader.readLine()) != null) 205 arglist.add(line); 206 207 } catch (IOException e) { 208 logger.info( "I/O error when reading temporary commands file", e); 209 throw new IOException( "Unable to read temporary commands file " 210 + commandsFileName + "."); 211 } finally { 212 if (bufferedReader != null) { 213 try { 214 bufferedReader.close(); 215 } catch (IOException e) { 216 } 217 } 218 } 219 220 args = (String[]) arglist.toArray(new String[arglist.size()]); 221 } 222 return args; 223 } 224}