1 37 38 package net.sourceforge.cruisecontrol.builders; 39 40 import java.io.File ; 41 import java.io.FileInputStream ; 42 import java.io.FileOutputStream ; 43 import java.io.IOException ; 44 import java.util.ArrayList ; 45 import java.util.List ; 46 import java.util.Map ; 47 48 import net.sourceforge.cruisecontrol.Builder; 49 import net.sourceforge.cruisecontrol.CruiseControlException; 50 import net.sourceforge.cruisecontrol.util.EmptyElementFilter; 51 import net.sourceforge.cruisecontrol.util.Util; 52 import net.sourceforge.cruisecontrol.util.ValidationHelper; 53 54 import org.apache.log4j.Logger; 55 import org.jdom.Element; 56 import org.jdom.input.SAXBuilder; 57 import org.xml.sax.SAXException ; 58 import org.xml.sax.XMLFilter ; 59 import org.xml.sax.helpers.XMLFilterImpl ; 60 61 66 public class AntBuilder extends Builder { 67 68 protected static final String DEFAULT_LOGGER = "org.apache.tools.ant.XmlLogger"; 69 private static final Logger LOG = Logger.getLogger(AntBuilder.class); 70 71 private String antWorkingDir = null; 72 private String buildFile = "build.xml"; 73 private String target = ""; 74 private String tempFileName = "log.xml"; 75 private String antScript; 76 private String antHome; 77 private boolean useLogger; 78 private List args = new ArrayList (); 79 private List properties = new ArrayList (); 80 private boolean useDebug = false; 81 private boolean useQuiet = false; 82 private String loggerClassName = DEFAULT_LOGGER; 83 private File saveLogDir = null; 84 private long timeout = ScriptRunner.NO_TIMEOUT; 85 private boolean wasValidated = false; 86 87 public void validate() throws CruiseControlException { 88 super.validate(); 89 90 ValidationHelper.assertIsSet(buildFile, "buildfile", this.getClass()); 91 ValidationHelper.assertIsSet(target, "target", this.getClass()); 92 ValidationHelper.assertFalse(useDebug && useQuiet, 93 "'useDebug' and 'useQuiet' can't be used together"); 94 95 if (!useLogger && (useDebug || useQuiet)) { 96 LOG.warn("usedebug and usequiet are ignored if uselogger is not set to 'true'!"); 97 } 98 99 if (saveLogDir != null) { 100 ValidationHelper.assertTrue(saveLogDir.isDirectory(), "'saveLogDir' must exist and be a directory"); 101 } 102 103 ValidationHelper.assertFalse(antScript != null && antHome != null, 104 "'antHome' and 'antscript' cannot both be set"); 105 106 if (antHome != null) { 107 final File antHomeFile = new File (antHome); 108 ValidationHelper.assertTrue(antHomeFile.exists() && antHomeFile.isDirectory(), 109 "'antHome' must exist and be a directory. Expected to find " 110 + antHomeFile.getAbsolutePath()); 111 112 final File antScriptInAntHome = new File (findAntScript(Util.isWindows())); 113 ValidationHelper.assertTrue(antScriptInAntHome.exists() && antScriptInAntHome.isFile(), 114 "'antHome' must contain an ant execution script. Expected to find " 115 + antScriptInAntHome.getAbsolutePath()); 116 117 antScript = antScriptInAntHome.getAbsolutePath(); 118 } 119 120 if (antScript != null && !args.isEmpty()) { 121 LOG.warn("jvmargs will be ignored if you specify anthome or your own antscript!"); 122 } 123 124 wasValidated = true; 125 } 126 127 131 public Element build(Map buildProperties) throws CruiseControlException { 132 if (!wasValidated) { 133 throw new IllegalStateException ("This builder was never validated." 134 + " The build method should not be getting called."); 135 } 136 137 validateBuildFileExists(); 138 139 AntScript script = new AntScript(); 140 script.setBuildProperties(buildProperties); 141 script.setProperties(properties); 142 script.setUseLogger(useLogger); 143 script.setUseScript(antScript != null); 144 script.setWindows(Util.isWindows()); 145 script.setAntScript(antScript); 146 script.setArgs(args); 147 script.setBuildFile(buildFile); 148 script.setTarget(target); 149 script.setLoggerClassName(loggerClassName); 150 script.setTempFileName(tempFileName); 151 script.setUseDebug(useDebug); 152 script.setUseQuiet(useQuiet); 153 script.setSystemClassPath(getSystemClassPath()); 154 155 File workingDir = antWorkingDir != null ? new File (antWorkingDir) : null; 156 157 boolean scriptCompleted = new ScriptRunner().runScript(workingDir, script, timeout); 158 159 File logFile = new File (antWorkingDir, tempFileName); 160 Element buildLogElement; 161 if (!scriptCompleted) { 162 LOG.warn("Build timeout timer of " + timeout + " seconds has expired"); 163 buildLogElement = new Element("build"); 164 buildLogElement.setAttribute("error", "build timeout"); 165 if (logFile.exists()) { 168 try { 169 buildLogElement.setText(Util.readFileToString(logFile)); 170 } catch (IOException likely) { 171 } 172 } 173 } else { 174 buildLogElement = getAntLogAsElement(logFile); 176 saveAntLog(logFile); 177 logFile.delete(); 178 } 179 return buildLogElement; 180 } 181 182 public Element buildWithTarget(Map properties, String buildTarget) throws CruiseControlException { 183 String origTarget = target; 184 try { 185 target = buildTarget; 186 return build(properties); 187 } finally { 188 target = origTarget; 189 } 190 } 191 192 void validateBuildFileExists() throws CruiseControlException { 193 File build = new File (buildFile); 194 if (!build.isAbsolute() && antWorkingDir != null) { 195 build = new File (antWorkingDir, buildFile); 196 } 197 ValidationHelper.assertExists(build, "buildfile", this.getClass()); 198 } 199 200 201 209 public void setSaveLogDir(String dir) { 210 saveLogDir = null; 211 212 if (dir != null && !dir.trim().equals("")) { 213 saveLogDir = new File (dir.trim()); 214 } 215 } 216 217 void saveAntLog(File logFile) { 218 if (saveLogDir == null) { 219 return; 220 } 221 222 try { 223 File newAntLogFile = new File (saveLogDir, tempFileName); 224 newAntLogFile.createNewFile(); 225 226 FileInputStream in = new FileInputStream (logFile); 227 FileOutputStream out = new FileOutputStream (newAntLogFile); 228 229 byte[] buf = new byte[1024]; 230 int len; 231 while ((len = in.read(buf)) > 0) { 232 out.write(buf, 0, len); 233 } 234 in.close(); 235 out.close(); 236 } catch (IOException ioe) { 237 LOG.error(ioe); 238 LOG.error("Unable to create file: " + new File (saveLogDir, tempFileName)); 239 } 240 } 241 242 250 public void setAntWorkingDir(String dir) { 251 antWorkingDir = dir; 252 } 253 254 260 public void setAntScript(String antScript) { 261 this.antScript = antScript; 262 } 263 264 269 public void setAntHome(String antHome) { 270 this.antHome = antHome; 271 } 272 273 277 protected String findAntScript(boolean isWindows) throws CruiseControlException { 278 if (antHome == null) { 279 throw new CruiseControlException("anthome attribute not set."); 280 } 281 282 if (isWindows) { 283 return antHome + "\\bin\\ant.bat"; 284 } else { 285 return antHome + "/bin/ant"; 286 } 287 } 288 289 294 public void setTempFile(String tempFileName) { 295 this.tempFileName = tempFileName; 296 } 297 298 303 public void setTarget(String target) { 304 this.target = target; 305 } 306 307 313 public void setBuildFile(String buildFile) { 314 this.buildFile = buildFile; 315 } 316 317 322 public void setUseLogger(boolean useLogger) { 323 this.useLogger = useLogger; 324 } 325 326 public Object createJVMArg() { 327 JVMArg arg = new JVMArg(); 328 args.add(arg); 329 return arg; 330 } 331 332 public Property createProperty() { 333 Property property = new Property(); 334 properties.add(property); 335 return property; 336 } 337 338 protected String getSystemClassPath() { 339 return System.getProperty("java.class.path"); 340 } 341 342 protected static Element getAntLogAsElement(File file) throws CruiseControlException { 343 if (!file.exists()) { 344 throw new CruiseControlException("ant logfile " + file.getAbsolutePath() + " does not exist."); 345 } else if (file.length() == 0) { 346 throw new CruiseControlException("ant logfile " + file.getAbsolutePath() 347 + " is empty. Your build probably failed. Check your CruiseControl logs."); 348 } 349 350 try { 351 SAXBuilder builder = new SAXBuilder("org.apache.xerces.parsers.SAXParser"); 352 353 XMLFilter piFilter = new XMLFilterImpl () { 357 public void processingInstruction(String target, String data) throws SAXException { 358 if (target.equals("xml:stylesheet")) { target = "xml-stylesheet"; } 359 super.processingInstruction(target, data); 360 } 361 }; 362 363 XMLFilter emptyTaskFilter = new EmptyElementFilter("task"); 365 emptyTaskFilter.setParent(piFilter); 366 XMLFilter emptyMessageFilter = new EmptyElementFilter("message"); 367 emptyMessageFilter.setParent(emptyTaskFilter); 368 builder.setXMLFilter(emptyMessageFilter); 369 return builder.build(file).getRootElement(); 370 } catch (Exception ee) { 371 if (ee instanceof CruiseControlException) { 372 throw (CruiseControlException) ee; 373 } 374 File saveFile = new File (file.getParentFile(), System.currentTimeMillis() + file.getName()); 375 file.renameTo(saveFile); 376 throw new CruiseControlException("Error reading : " + file.getAbsolutePath() 377 + ". Saved as : " + saveFile.getAbsolutePath(), ee); 378 } 379 } 380 381 public void setUseDebug(boolean debug) { 382 useDebug = debug; 383 } 384 385 public void setUseQuiet(boolean quiet) { 386 useQuiet = quiet; 387 } 388 389 public String getLoggerClassName() { 390 return loggerClassName; 391 } 392 393 public void setLoggerClassName(String string) { 394 loggerClassName = string; 395 } 396 397 public class JVMArg { 398 private String arg; 399 400 public void setArg(String arg) { 401 this.arg = arg; 402 } 403 404 public String getArg() { 405 return arg; 406 } 407 } 408 411 public void setTimeout(long timeout) { 412 this.timeout = timeout; 413 } 414 } 415 | Popular Tags |