Clover coverage report - Cactus 1.5 for J2EE API 1.3
Coverage timestamp: Wed Feb 18 2004 09:09:13 EST
file stats: LOC: 487   Methods: 24
NCLOC: 199   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
AbstractContainer.java 0% 25.4% 12.5% 18%
coverage coverage
 1   
 /*
 2   
  * ====================================================================
 3   
  *
 4   
  * The Apache Software License, Version 1.1
 5   
  *
 6   
  * Copyright (c) 2003 The Apache Software Foundation.  All rights
 7   
  * reserved.
 8   
  *
 9   
  * Redistribution and use in source and binary forms, with or without
 10   
  * modification, are permitted provided that the following conditions
 11   
  * are met:
 12   
  *
 13   
  * 1. Redistributions of source code must retain the above copyright
 14   
  *    notice, this list of conditions and the following disclaimer.
 15   
  *
 16   
  * 2. Redistributions in binary form must reproduce the above copyright
 17   
  *    notice, this list of conditions and the following disclaimer in
 18   
  *    the documentation and/or other materials provided with the
 19   
  *    distribution.
 20   
  *
 21   
  * 3. The end-user documentation included with the redistribution, if
 22   
  *    any, must include the following acknowlegement:
 23   
  *       "This product includes software developed by the
 24   
  *        Apache Software Foundation (http://www.apache.org/)."
 25   
  *    Alternately, this acknowlegement may appear in the software itself,
 26   
  *    if and wherever such third-party acknowlegements normally appear.
 27   
  *
 28   
  * 4. The names "The Jakarta Project", "Cactus" and "Apache Software
 29   
  *    Foundation" must not be used to endorse or promote products
 30   
  *    derived from this software without prior written permission. For
 31   
  *    written permission, please contact apache@apache.org.
 32   
  *
 33   
  * 5. Products derived from this software may not be called "Apache"
 34   
  *    nor may "Apache" appear in their names without prior written
 35   
  *    permission of the Apache Group.
 36   
  *
 37   
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 38   
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 39   
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 40   
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 41   
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 42   
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 43   
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 44   
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 45   
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 46   
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 47   
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 48   
  * SUCH DAMAGE.
 49   
  * ====================================================================
 50   
  *
 51   
  * This software consists of voluntary contributions made by many
 52   
  * individuals on behalf of the Apache Software Foundation.  For more
 53   
  * information on the Apache Software Foundation, please see
 54   
  * <http://www.apache.org/>.
 55   
  *
 56   
  */
 57   
 package org.apache.cactus.integration.ant.container;
 58   
 
 59   
 import java.io.File;
 60   
 import java.io.IOException;
 61   
 
 62   
 import org.apache.cactus.integration.ant.util.AntLog;
 63   
 import org.apache.cactus.integration.ant.util.AntTaskFactory;
 64   
 import org.apache.commons.logging.Log;
 65   
 import org.apache.tools.ant.BuildException;
 66   
 import org.apache.tools.ant.ProjectComponent;
 67   
 import org.apache.tools.ant.Task;
 68   
 import org.apache.tools.ant.filters.ReplaceTokens;
 69   
 import org.apache.tools.ant.taskdefs.Delete;
 70   
 import org.apache.tools.ant.types.FileSet;
 71   
 import org.apache.tools.ant.types.FilterChain;
 72   
 import org.apache.tools.ant.types.PatternSet;
 73   
 import org.apache.tools.ant.types.Environment.Variable;
 74   
 import org.apache.tools.ant.types.selectors.SelectorUtils;
 75   
 
 76   
 /**
 77   
  * Abstract base class for supporting specific containers as nested elements in
 78   
  * the {@link org.apache.cactus.integration.ant.CactusTask}.
 79   
  * 
 80   
  * @author <a href="mailto:cmlenz@apache.org">Christopher Lenz</a>
 81   
  *
 82   
  * @version $Id: AbstractContainer.java,v 1.6.2.3 2003/10/23 18:20:43 vmassol Exp $
 83   
  */
 84   
 public abstract class AbstractContainer extends ProjectComponent
 85   
     implements Container
 86   
 {
 87   
     // Constants ---------------------------------------------------------------
 88   
 
 89   
     /**
 90   
      * The path under which the container resources are stored in the JAR.
 91   
      */
 92   
     protected static final String RESOURCE_PATH =
 93   
         "/org/apache/cactus/integration/ant/container/resources/";
 94   
 
 95   
     // Instance Variables ------------------------------------------------------
 96   
 
 97   
     /**
 98   
      * The WAR or EAR that should be deployed to the container.
 99   
      */
 100   
     private DeployableFile deployableFile;
 101   
 
 102   
     /**
 103   
      * A pattern set which lists patterns for names of test cases that are to be
 104   
      * excluded from a specific container.
 105   
      */
 106   
     private PatternSet patternSet = new PatternSet();
 107   
 
 108   
     /**
 109   
      * The directory to which the test reports should be written.
 110   
      */
 111   
     private File toDir;
 112   
 
 113   
     /**
 114   
      * Name of a property that must exist in the project if tests are to be run
 115   
      * on the container. 
 116   
      */
 117   
     private String ifCondition;
 118   
 
 119   
     /**
 120   
      * Name of a property that must not exist in the project if tests are to be
 121   
      * run on the container. 
 122   
      */
 123   
     private String unlessCondition;
 124   
 
 125   
     /**
 126   
      * The factory for creating ant tasks.
 127   
      */
 128   
     private AntTaskFactory antTaskFactory;
 129   
 
 130   
     /**
 131   
      * The log to use.
 132   
      */
 133   
     private Log log = AntLog.NULL;
 134   
 
 135   
     /**
 136   
      * List of system properties to set in the container JVM. 
 137   
      */
 138   
     private Variable[] systemProperties;
 139   
 
 140   
     /**
 141   
      * The time to sleep after the container has started up. 
 142   
      */
 143   
     private long startUpWait = 1000;
 144   
 
 145   
     // Public Methods ----------------------------------------------------------
 146   
 
 147   
     /**
 148   
      * Sets the time to wait after the container has been started up.
 149   
      * 
 150   
      * The default time is 1 second.
 151   
      * 
 152   
      * Note: This is a hack while waiting for container specific solutions
 153   
      * that tell exactly when the server is started or not. ATM, the only known
 154   
      * issue is with JBoss, where the servlet engine is started before the full
 155   
      * JBoss is started and thus it may happen that we try to shutdown JBoss 
 156   
      * before it has finished starting, leading to an exception.
 157   
      * 
 158   
      * @param theStartUpWait The time to wait in milliseconds
 159   
      */
 160  0
     public void setStartUpWait(long theStartUpWait)
 161   
     {
 162  0
         this.startUpWait = theStartUpWait;
 163   
     }
 164   
 
 165   
     /**
 166   
      * Creates a nested exclude element that is added to the pattern set.
 167   
      * 
 168   
      * @return The created exclude element
 169   
      */
 170  0
     public final PatternSet.NameEntry createExclude()
 171   
     {
 172  0
         return this.patternSet.createExclude();
 173   
     }
 174   
 
 175   
     /**
 176   
      * Returns the exclude patterns.
 177   
      * 
 178   
      * @return The exclude patterns 
 179   
      */
 180  0
     public final String[] getExcludePatterns()
 181   
     {
 182  0
         return this.patternSet.getExcludePatterns(getProject());
 183   
     }
 184   
 
 185   
     /**
 186   
      * Sets the name of a property that must exist in the project if tests are 
 187   
      * to be run on the container.
 188   
      * 
 189   
      * @param theIfCondition The property name to set
 190   
      */
 191  0
     public final void setIf(String theIfCondition)
 192   
     {
 193  0
         this.ifCondition = theIfCondition;
 194   
     }
 195   
 
 196   
     /**
 197   
      * Sets the directory to which the test reports should be written.
 198   
      * 
 199   
      * @param theToDir The output directory to set
 200   
      */
 201  0
     public final void setToDir(File theToDir)
 202   
     {
 203  0
         this.toDir = theToDir;
 204   
     }
 205   
 
 206   
     /**
 207   
      * Sets the name of a property that must not exist in the project if tests
 208   
      * are to be run on the container.
 209   
      * 
 210   
      * @param theUnlessCondition The property name to set
 211   
      */
 212  0
     public final void setUnless(String theUnlessCondition)
 213   
     {
 214  0
         this.unlessCondition = theUnlessCondition;
 215   
     }
 216   
 
 217   
     // Container Implementation ------------------------------------------------
 218   
 
 219   
     /**
 220   
      * @see Container#getStartUpWait 
 221   
      */
 222  0
     public long getStartUpWait()
 223   
     {
 224  0
         return this.startUpWait;
 225   
     }
 226   
 
 227   
     /**
 228   
      * @see Container#getToDir
 229   
      */
 230  0
     public final File getToDir()
 231   
     {
 232  0
         return this.toDir;
 233   
     }
 234   
 
 235   
     /**
 236   
      * The default implementation does nothing.
 237   
      * 
 238   
      * @see Container#init
 239   
      */
 240  0
     public void init()
 241   
     {
 242   
         // The default implementation doesn nothing
 243   
     }
 244   
 
 245   
     /**
 246   
      * @see Container#isEnabled
 247   
      */
 248  0
     public final boolean isEnabled()
 249   
     {
 250  0
         return (testIfCondition() && testUnlessCondition());
 251   
     }
 252   
 
 253   
     /**
 254   
      * @see Container#isExcluded
 255   
      */
 256  0
     public final boolean isExcluded(String theTestName)
 257   
     {
 258  0
         String[] excludePatterns =
 259   
             this.patternSet.getExcludePatterns(getProject());
 260  0
         if (excludePatterns != null)
 261   
         {
 262  0
             String testPath = theTestName.replace('.', '/');
 263  0
             for (int i = 0; i < excludePatterns.length; i++)
 264   
             {
 265  0
                 String excludePattern = excludePatterns[i];
 266  0
                 if (excludePattern.endsWith(".java")
 267   
                  || excludePattern.endsWith(".class"))
 268   
                 {
 269  0
                     excludePattern = excludePattern.substring(
 270   
                         0, excludePattern.lastIndexOf('.'));
 271   
                 }
 272  0
                 if (SelectorUtils.matchPath(excludePattern, testPath))
 273   
                 {
 274  0
                     return true;
 275   
                 }
 276   
             }
 277   
         }
 278  0
         return false;
 279   
     }
 280   
 
 281   
     /**
 282   
      * @see Container#setAntTaskFactory
 283   
      */
 284  0
     public final void setAntTaskFactory(AntTaskFactory theFactory)
 285   
     {
 286  0
         this.antTaskFactory = theFactory;
 287   
     }
 288   
 
 289   
     /**
 290   
      * @see Container#setDeployableFile
 291   
      */
 292  1
     public final void setDeployableFile(DeployableFile theDeployableFile)
 293   
     {
 294  1
         this.deployableFile = theDeployableFile;
 295   
     }
 296   
 
 297   
     /**
 298   
      * @see Container#setLog
 299   
      */
 300  0
     public final void setLog(Log theLog)
 301   
     {
 302  0
         this.log = theLog;
 303   
     }
 304   
 
 305   
     /**
 306   
      * @see Container#setSystemProperties
 307   
      */
 308  0
     public void setSystemProperties(Variable[] theProperties)
 309   
     {
 310  0
         this.systemProperties = theProperties;
 311   
     }
 312   
 
 313   
     /**
 314   
      * @see Container#getSystemProperties
 315   
      */
 316  0
     public Variable[] getSystemProperties()
 317   
     {
 318  0
         return this.systemProperties;
 319   
     }
 320   
     
 321   
     // Protected Methods -------------------------------------------------------
 322   
 
 323   
     /**
 324   
      * Creates and returns a new instance of the Ant task mapped to the
 325   
      * specified logical name using the
 326   
      * {@link org.apache.cactus.integration.ant.util.AntTaskFactory} set.
 327   
      * 
 328   
      * @param theName The logical name of the task to create
 329   
      * @return A new isntance of the task
 330   
      * @see AntTaskFactory#createTask
 331   
      */
 332  0
     protected final Task createAntTask(String theName)
 333   
     {
 334  0
         return this.antTaskFactory.createTask(theName);
 335   
     }
 336   
 
 337   
     /**
 338   
      * Convenience method for creating a new directory inside another one.
 339   
      * 
 340   
      * @param theParentDir The directory in which the new directory should be
 341   
      *        created
 342   
      * @param theName The name of the directory to create
 343   
      * @return The new directory
 344   
      * @throws IOException If the directory could not be created
 345   
      */
 346  0
     protected final File createDirectory(File theParentDir, String theName)
 347   
         throws IOException
 348   
     {
 349  0
         File dir = new File(theParentDir, theName);
 350  0
         dir.mkdirs();
 351  0
         if (!dir.isDirectory())
 352   
         {
 353  0
             throw new IOException(
 354   
                 "Couldn't create directory " + dir.getAbsolutePath());
 355   
         }
 356  0
         return dir;
 357   
     }
 358   
 
 359   
     /**
 360   
      * Creates the default filter chain that should be applied while copying
 361   
      * container configuration files to the temporary directory from which the
 362   
      * container is started. The default filter chain replaces all occurences
 363   
      * of @cactus.port@ with the TCP port of the container, and all occurences
 364   
      * of @cactus.context@ with the web-application's context path (if the
 365   
      * deployable file is a web-app).
 366   
      * 
 367   
      * @return The default filter chain
 368   
      */
 369  1
     protected final FilterChain createFilterChain()
 370   
     {
 371  1
         ReplaceTokens.Token token = null;
 372  1
         FilterChain filterChain = new FilterChain();
 373   
 
 374   
         // Token for the cactus port
 375  1
         ReplaceTokens replacePort = new ReplaceTokens();
 376  1
         token = new ReplaceTokens.Token();
 377  1
         token.setKey("cactus.port");
 378  1
         token.setValue(String.valueOf(getPort()));
 379  1
         replacePort.addConfiguredToken(token);
 380  1
         filterChain.addReplaceTokens(replacePort);
 381   
 
 382   
         // Token for the cactus webapp context 
 383  1
         ReplaceTokens replaceContext = new ReplaceTokens();
 384  1
         token = new ReplaceTokens.Token();
 385  1
         token.setKey("cactus.context");
 386  1
         token.setValue(getDeployableFile().getTestContext());
 387  1
         replaceContext.addConfiguredToken(token);
 388  1
         filterChain.addReplaceTokens(replaceContext);
 389   
 
 390  1
         return filterChain;
 391   
     }
 392   
 
 393   
     /**
 394   
      * Convenience method that creates a temporary directory.
 395   
      * 
 396   
      * @param theName The name of the directory relative to the system specific
 397   
      *        temporary directory
 398   
      * @return The temporary directory
 399   
      */
 400  0
     protected final File createTempDirectory(String theName)
 401   
     {
 402  0
         File tmpDir = new File(System.getProperty("java.io.tmpdir"), theName);
 403  0
         if (!tmpDir.exists())
 404   
         {
 405  0
             if (!tmpDir.mkdirs())
 406   
             {
 407  0
                 throw new BuildException("Could not create temporary "
 408   
                     + "directory " + tmpDir);
 409   
             }
 410   
         }
 411   
         else
 412   
         {
 413   
             // Clean up stuff previously put in the temporary directory
 414  0
             Delete delete = (Delete) createAntTask("delete");
 415  0
             FileSet fileSet = new FileSet();
 416  0
             fileSet.setDir(tmpDir);
 417  0
             fileSet.createInclude().setName("**/*");
 418  0
             delete.addFileset(fileSet);
 419  0
             delete.setIncludeEmptyDirs(true);
 420  0
             delete.execute();
 421   
         }
 422   
         // make sure we're returning a directory
 423  0
         if (!tmpDir.isDirectory())
 424   
         {
 425  0
             throw new BuildException(tmpDir + " is not a directory");
 426   
         }
 427  0
         return tmpDir;
 428   
     }
 429   
 
 430   
     /**
 431   
      * Returns the log to use.
 432   
      * 
 433   
      * @return The log
 434   
      */
 435  0
     protected final Log getLog()
 436   
     {
 437  0
         return this.log;
 438   
     }
 439   
 
 440   
     /**
 441   
      * Returns the web-application archive that is to be deployed to the
 442   
      * container.
 443   
      * 
 444   
      * @return The WAR file  
 445   
      */
 446  1
     protected final DeployableFile getDeployableFile()
 447   
     {
 448  1
         return this.deployableFile;
 449   
     }
 450   
 
 451   
     // Private Methods ---------------------------------------------------------
 452   
 
 453   
     /**
 454   
      * Tests whether the property necessary to run the tests in the container 
 455   
      * has been set.
 456   
      * 
 457   
      * @return <code>true</code> if the tests should be run in the container,
 458   
      *         <code>false</code> otherwise
 459   
      */
 460  0
     private boolean testIfCondition()
 461   
     {
 462  0
         if (ifCondition == null || ifCondition.length() == 0)
 463   
         {
 464  0
             return true;
 465   
         }
 466   
         
 467  0
         return (getProject().getProperty(ifCondition) != null);
 468   
     }
 469   
 
 470   
     /**
 471   
      * Tests whether the property specified as the 'unless' condition has not
 472   
      * been set.
 473   
      * 
 474   
      * @return <code>true</code> if the tests should be run in the container,
 475   
      *         <code>false</code> otherwise
 476   
      */
 477  0
     private boolean testUnlessCondition()
 478   
     {
 479  0
         if (unlessCondition == null || unlessCondition.length() == 0)
 480   
         {
 481  0
             return true;
 482   
         }
 483  0
         return (getProject().getProperty(unlessCondition) == null);
 484   
     }
 485   
 
 486   
 }
 487