1 28 29 package net.sourceforge.cruisecontrol.builders; 30 31 import java.io.File ; 32 import java.io.FileInputStream ; 33 import java.io.FileOutputStream ; 34 import java.io.IOException ; 35 import java.util.ArrayList ; 36 import java.util.List ; 37 import java.util.Map ; 38 39 import net.sourceforge.cruisecontrol.Builder; 40 import net.sourceforge.cruisecontrol.CruiseControlException; 41 import net.sourceforge.cruisecontrol.util.EmptyElementFilter; 42 import net.sourceforge.cruisecontrol.util.ValidationHelper; 43 import net.sourceforge.cruisecontrol.util.DateUtil; 44 45 import org.apache.log4j.Logger; 46 import org.jdom.Attribute; 47 import org.jdom.CDATA; 48 import org.jdom.Element; 49 import org.jdom.filter.ContentFilter; 50 import org.jdom.input.SAXBuilder; 51 import org.xml.sax.XMLFilter ; 52 53 public class NantBuilder extends Builder { 54 55 protected static final String DEFAULT_LOGGER = "NAnt.Core.XmlLogger"; 56 private static final Logger LOG = Logger.getLogger(NantBuilder.class); 57 private String nantWorkingDir = null; 58 private String buildFile = "default.build"; 59 private String target = ""; 60 private String tempFileName = "log.xml"; 61 private boolean useLogger; 62 private List properties = new ArrayList (); 63 private boolean useDebug = false; 64 private boolean useQuiet = false; 65 private String loggerClassName = DEFAULT_LOGGER; 66 private File saveLogDir = null; 67 private String targetFramework = null; 68 private long timeout = ScriptRunner.NO_TIMEOUT; 69 70 public void validate() throws CruiseControlException { 71 super.validate(); 72 73 ValidationHelper.assertIsSet(buildFile, "buildFile", this.getClass()); 74 ValidationHelper.assertIsSet(target, "target", this.getClass()); 75 76 ValidationHelper.assertFalse(useDebug && useQuiet, "'useDebug' and 'useQuiet' can't be used together"); 77 78 if (saveLogDir != null) { 79 ValidationHelper.assertTrue(saveLogDir.isDirectory(), "'saveLogDir' must exist and be a directory"); 80 } 81 } 82 83 87 public Element build(Map buildProperties) throws CruiseControlException { 88 89 File workingDir = nantWorkingDir != null ? new File (nantWorkingDir) : null; 90 NantScript script = getNantScript(); 91 script.setBuildFile(buildFile); 92 script.setBuildProperties(buildProperties); 93 script.setNantProperties(properties); 94 script.setLoggerClassName(loggerClassName); 95 script.setTarget(target); 96 script.setTargetFramework(targetFramework); 97 script.setTempFileName(tempFileName); 98 script.setUseDebug(useDebug); 99 script.setUseLogger(useLogger); 101 script.setUseQuiet(useQuiet); 102 103 long startTime = System.currentTimeMillis(); 104 105 ScriptRunner scriptRunner = new ScriptRunner(); 106 boolean scriptCompleted = scriptRunner.runScript(workingDir, script, timeout); 107 long endTime = System.currentTimeMillis(); 108 109 File logFile = new File (nantWorkingDir, tempFileName); 110 Element buildLogElement; 111 if (!scriptCompleted) { 112 LOG.warn("Build timeout timer of " + timeout + " seconds has expired"); 113 buildLogElement = new Element("build"); 114 buildLogElement.setAttribute("error", "build timeout"); 115 } else { 116 buildLogElement = getNantLogAsElement(logFile); 118 saveNantLog(logFile); 119 logFile.delete(); 120 } 121 final Element element = translateNantErrorElements(buildLogElement); 122 element.setAttribute("time", DateUtil.getDurationAsString((endTime - startTime))); 123 return element; 124 } 125 126 public Element buildWithTarget(Map properties, String buildTarget) throws CruiseControlException { 127 String origTarget = target; 128 try { 129 target = buildTarget; 130 return build(properties); 131 } finally { 132 target = origTarget; 133 } 134 } 135 136 protected NantScript getNantScript() { 138 return new NantScript(); 139 } 140 141 149 public void setSaveLogDir(String dir) { 150 saveLogDir = null; 151 152 if (dir != null && !dir.trim().equals("")) { 153 saveLogDir = new File (dir.trim()); 154 } 155 } 156 157 165 public void setNantWorkingDir(String dir) { 166 nantWorkingDir = dir; 167 } 168 169 174 public void setTempFile(String tempFileName) { 175 this.tempFileName = tempFileName; 176 } 177 178 184 public void setTarget(String target) { 185 this.target = target; 186 } 187 188 195 public void setBuildFile(String buildFile) { 196 this.buildFile = buildFile; 197 } 198 199 204 public void setUseLogger(boolean useLogger) { 205 this.useLogger = useLogger; 206 } 207 208 void saveNantLog(File logFile) { 209 if (saveLogDir == null) { 210 return; 211 } 212 213 try { 214 File newNantLogFile = new File (saveLogDir, tempFileName); 215 newNantLogFile.createNewFile(); 216 217 FileInputStream in = new FileInputStream (logFile); 218 FileOutputStream out = new FileOutputStream (newNantLogFile); 219 220 byte[] buf = new byte[1024]; 221 int len; 222 while ((len = in.read(buf)) > 0) { 223 out.write(buf, 0, len); 224 } 225 in.close(); 226 out.close(); 227 } catch (IOException ioe) { 228 LOG.error(ioe); 229 LOG.error("Unable to create file: " + new File (saveLogDir, tempFileName)); 230 } 231 } 232 233 public Property createProperty() { 234 Property property = new Property(); 235 properties.add(property); 236 return property; 237 } 238 239 protected Element getNantLogAsElement(File file) throws CruiseControlException { 240 if (!file.exists()) { 241 throw new CruiseControlException("NAnt logfile " + file.getAbsolutePath() + " does not exist."); 242 } 243 try { 244 SAXBuilder builder = new SAXBuilder("org.apache.xerces.parsers.SAXParser"); 245 246 XMLFilter emptyTaskFilter = new EmptyElementFilter("task"); 249 XMLFilter emptyMessageFilter = new EmptyElementFilter("message"); 250 emptyMessageFilter.setParent(emptyTaskFilter); 251 builder.setXMLFilter(emptyMessageFilter); 252 return builder.build(file).getRootElement(); 253 } catch (Exception ee) { 254 if (ee instanceof CruiseControlException) { 255 throw (CruiseControlException) ee; 256 } 257 File saveFile = new File (file.getParentFile(), System.currentTimeMillis() + file.getName()); 258 file.renameTo(saveFile); 259 throw new CruiseControlException("Error reading : " + file.getAbsolutePath() + ". Saved as : " 260 + saveFile.getAbsolutePath(), ee); 261 } 262 } 263 264 public void setUseDebug(boolean debug) { 265 useDebug = debug; 266 } 267 268 public void setUseQuiet(boolean quiet) { 269 useQuiet = quiet; 270 } 271 272 public String getLoggerClassName() { 273 return loggerClassName; 274 } 275 276 public void setLoggerClassName(String logger) { 277 loggerClassName = logger; 278 } 279 280 public void setTargetFramework(String framework) { 281 this.targetFramework = framework; 282 } 283 284 protected Element translateNantErrorElements(Element buildLogElement) throws CruiseControlException { 285 buildLogElement.setName("build"); 286 Element failure = buildLogElement.getChild("failure"); 287 if (failure != null) { 288 Element buildError = failure.getChild("builderror"); 289 if (buildError == null) { 290 throw new CruiseControlException("Expected a builderror element under build/failure"); 291 } 292 Element message = buildError.getChild("message"); 293 if (message == null) { 294 throw new CruiseControlException("Expected a message element under build/failure/builderror"); 295 } 296 List matches = message.getContent(new ContentFilter(ContentFilter.CDATA)); 297 if (matches.size() == 0) { 298 throw new CruiseControlException("Expected CDATA content in build/failure/builderror/message/element"); 299 } 300 String errorMessage = ((CDATA) matches.get(0)).getText(); 301 buildLogElement.setAttribute(new Attribute("error", errorMessage)); 302 } 303 return buildLogElement; 304 } 305 308 public void setTimeout(long timeout) { 309 this.timeout = timeout; 310 } 311 } 312 | Popular Tags |