1 20 package org.apache.cactus.integration.ant; 21 22 import java.io.File ; 23 import java.net.MalformedURLException ; 24 import java.net.URL ; 25 import java.util.ArrayList ; 26 import java.util.Enumeration ; 27 import java.util.List ; 28 import java.util.ResourceBundle ; 29 30 import org.apache.cactus.integration.ant.container.Container; 31 import org.apache.cactus.integration.ant.container.ContainerRunner; 32 import org.apache.cactus.integration.ant.deployment.DeployableFile; 33 import org.apache.cactus.integration.ant.deployment.EarParser; 34 import org.apache.cactus.integration.ant.deployment.WarParser; 35 import org.apache.cactus.integration.ant.util.AntLog; 36 import org.apache.cactus.integration.ant.util.AntTaskFactory; 37 import org.apache.cactus.integration.ant.util.DefaultAntTaskFactory; 38 import org.apache.cactus.integration.ant.util.PropertySet; 39 import org.apache.tools.ant.BuildException; 40 import org.apache.tools.ant.Project; 41 import org.apache.tools.ant.taskdefs.optional.junit.JUnitTask; 42 import org.apache.tools.ant.taskdefs.optional.junit.JUnitTest; 43 import org.apache.tools.ant.types.Environment; 44 import org.apache.tools.ant.types.Path; 45 import org.apache.tools.ant.types.Environment.Variable; 46 47 53 public class CactusTask extends JUnitTask 54 { 55 57 60 private ContainerSet containerSet; 61 62 66 private File earFile; 67 68 71 private File warFile; 72 73 76 private List systemProperties = new ArrayList (); 77 78 82 private Path containerClasspath; 83 84 86 91 public CactusTask() throws Exception 92 { 93 } 96 97 99 102 public void init() 103 { 104 super.init(); 105 106 addClasspathEntry("/org/aspectj/lang/JoinPoint.class"); 107 addClasspathEntry("/org/apache/cactus/ServletTestCase.class"); 108 addClasspathEntry( 109 "/org/apache/cactus/integration/ant/CactusTask.class"); 110 addClasspathEntry("/org/apache/commons/logging/Log.class"); 111 addClasspathEntry("/org/apache/commons/httpclient/HttpClient.class"); 112 } 113 114 117 public void execute() throws BuildException 118 { 119 if ((this.warFile == null) && (this.earFile == null)) 120 { 121 throw new BuildException("You must specify either the [warfile] or " 122 + "the [earfile] attribute"); 123 } 124 125 if ((this.warFile != null) && (this.earFile != null)) 126 { 127 throw new BuildException("You must specify either the [warfile] or " 128 + "the [earfile] attribute but not both"); 129 } 130 131 DeployableFile deployableFile; 133 if (this.warFile != null) 134 { 135 deployableFile = WarParser.parse(this.warFile); 136 } 137 else 138 { 139 deployableFile = EarParser.parse(this.earFile); 140 } 141 142 addRedirectorNameProperties(deployableFile); 143 144 if (this.containerSet == null) 145 { 146 log("No containers specified, tests will run locally", 147 Project.MSG_VERBOSE); 148 super.execute(); 149 } 150 else 151 { 152 Container[] containers = this.containerSet.getContainers(); 153 Variable contextUrl = new Variable(); 154 contextUrl.setKey("cactus.contextURL"); 155 addSysproperty(contextUrl); 156 157 AntTaskFactory antTaskFactory = new DefaultAntTaskFactory( 158 getProject(), getTaskName(), getLocation(), getOwningTarget()); 159 160 for (int i = 0; i < containers.length; i++) 161 { 162 containers[i].setAntTaskFactory(antTaskFactory); 163 containers[i].setLog(new AntLog(this)); 164 165 DeployableFile thisDeployable = null; 169 try 170 { 171 thisDeployable = (DeployableFile) deployableFile.clone(); 172 } 173 catch (CloneNotSupportedException e) 174 { 175 throw new BuildException(e); 176 } 177 containers[i].setDeployableFile(thisDeployable); 178 179 if (containers[i].getTestContext() != null) 184 { 185 thisDeployable.setTestContext( 186 containers[i].getTestContext()); 187 } 188 189 containers[i].setSystemProperties( 190 (Variable[]) this.systemProperties.toArray( 191 new Variable[0])); 192 193 containers[i].setContainerClasspath(this.containerClasspath); 195 196 if (containers[i].isEnabled()) 197 { 198 containers[i].init(); 199 log("--------------------------------------------------" 200 + "---------------", 201 Project.MSG_INFO); 202 log("Running tests against " + containers[i].getName(), 203 Project.MSG_INFO); 204 log("--------------------------------------------------" 205 + "---------------", 206 Project.MSG_INFO); 207 contextUrl.setValue( 208 "http://localhost:" + containers[i].getPort() + "/" 209 + thisDeployable.getTestContext()); 210 executeInContainer(containers[i], thisDeployable); 211 } 212 } 213 } 214 } 215 216 221 public final void addContainerSet(ContainerSet theContainerSet) 222 { 223 if (this.containerSet != null) 224 { 225 throw new BuildException( 226 "Only one nested containerset element supported"); 227 } 228 this.containerSet = theContainerSet; 229 } 230 231 238 public final void setEarFile(File theEarFile) 239 { 240 if (this.warFile != null) 241 { 242 throw new BuildException( 243 "You may only specify one of [earfile] and [warfile]"); 244 } 245 this.earFile = theEarFile; 246 } 247 248 254 public final void setWarFile(File theWarFile) 255 { 256 if (this.earFile != null) 257 { 258 throw new BuildException( 259 "You may only specify one of [earfile] and [warfile]"); 260 } 261 this.warFile = theWarFile; 262 } 263 264 268 public void addSysproperty(Environment.Variable theProperty) 269 { 270 addCactusServerProperty(theProperty); 271 super.addSysproperty(theProperty); 272 } 273 274 279 public void addConfiguredSysproperty(Environment.Variable theProperty) 280 { 281 addSysproperty(theProperty); 282 } 283 284 290 public void addConfiguredCactusproperty(PropertySet thePropertySet) 291 { 292 ResourceBundle bundle = thePropertySet.readProperties(); 294 Enumeration keys = bundle.getKeys(); 295 while (keys.hasMoreElements()) 296 { 297 String key = (String ) keys.nextElement(); 298 Variable var = new Variable(); 299 var.setKey(key); 300 var.setValue(bundle.getString(key)); 301 if (thePropertySet.isServer()) 302 { 303 addCactusServerProperty(var); 304 } 305 else 306 { 307 super.addSysproperty(var); 308 } 309 } 310 } 311 312 319 public Path createContainerClasspath() 320 { 321 if (this.containerClasspath == null) 322 { 323 this.containerClasspath = new Path(this.project); 324 } 325 326 return this.containerClasspath.createPath(); 327 } 328 329 331 337 private void addCactusClientProperty(String theKey, String theValue) 338 { 339 log("Adding Cactus client system property [" + theKey 340 + "] with value [" + theValue + "]", Project.MSG_VERBOSE); 341 Variable sysProperty = new Variable(); 342 sysProperty.setKey(theKey); 343 sysProperty.setValue(theValue); 344 super.addSysproperty(sysProperty); 345 } 346 347 352 private void addCactusServerProperty(Variable theProperty) 353 { 354 log("Adding Cactus server system property [" 355 + theProperty.getKey() + "] with value [" 356 + theProperty.getValue() + "]", Project.MSG_VERBOSE); 357 this.systemProperties.add(theProperty); 358 } 359 360 366 private void addCactusServerProperty(String theKey, String theValue) 367 { 368 Variable property = new Variable(); 369 property.setKey(theKey); 370 property.setValue(theValue); 371 addCactusServerProperty(property); 372 } 373 374 380 private void addRedirectorNameProperties(DeployableFile theFile) 381 { 382 String filterRedirectorMapping = 383 theFile.getFilterRedirectorMapping(); 384 if (filterRedirectorMapping != null) 385 { 386 addCactusClientProperty("cactus.filterRedirectorName", 387 filterRedirectorMapping.substring(1)); 388 } 389 else 390 { 391 log("No mapping of the filter redirector found", 392 Project.MSG_VERBOSE); 393 } 394 395 String jspRedirectorMapping = 396 theFile.getJspRedirectorMapping(); 397 if (jspRedirectorMapping != null) 398 { 399 addCactusClientProperty("cactus.jspRedirectorName", 400 jspRedirectorMapping.substring(1)); 401 } 402 else 403 { 404 log("No mapping of the JSP redirector found", 405 Project.MSG_VERBOSE); 406 } 407 408 String servletRedirectorMapping = 409 theFile.getServletRedirectorMapping(); 410 if (servletRedirectorMapping != null) 411 { 412 addCactusClientProperty("cactus.servletRedirectorName", 413 servletRedirectorMapping.substring(1)); 414 } 415 else 416 { 417 throw new BuildException("The WAR has not been cactified"); 418 } 419 } 420 421 427 private void executeInContainer(Container theContainer, 428 DeployableFile theFile) 429 { 430 log("Starting up container", Project.MSG_VERBOSE); 431 ContainerRunner runner = new ContainerRunner(theContainer); 432 runner.setLog(new AntLog(this)); 433 try 434 { 435 URL url = 436 new URL ("http", "localhost", theContainer.getPort(), "/" 437 + theFile.getTestContext() 438 + theFile.getServletRedirectorMapping() 439 + "?Cactus_Service=RUN_TEST"); 440 runner.setURL(url); 441 if (this.containerSet.getTimeout() > 0) 442 { 443 runner.setTimeout(this.containerSet.getTimeout()); 444 } 445 runner.startUpContainer(); 446 log("Server name retrieved from 'Server' HTTP header: [" 447 + runner.getServerName() + "]", Project.MSG_VERBOSE); 448 try 449 { 450 Enumeration tests = getIndividualTests(); 451 while (tests.hasMoreElements()) 452 { 453 JUnitTest test = (JUnitTest) tests.nextElement(); 454 if (test.shouldRun(getProject()) 455 && !theContainer.isExcluded(test.getName())) 456 { 457 if (theContainer.getToDir() != null) 458 { 459 test.setTodir(theContainer.getToDir()); 460 } 461 execute(test); 462 } 463 } 464 } 465 finally 466 { 467 log("Shutting down container", Project.MSG_VERBOSE); 468 runner.shutDownContainer(); 469 log("Container shut down", Project.MSG_VERBOSE); 470 } 471 } 472 catch (MalformedURLException mue) 473 { 474 throw new BuildException("Malformed test URL", mue); 475 } 476 } 477 } 478 | Popular Tags |