Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 379   Methods: 12
NCLOC: 180   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
JarLibManifestTask.java 0% 0% 0% 0%
 1   
 /*
 2   
  * The Apache Software License, Version 1.1
 3   
  *
 4   
  * Copyright (c) 2002 The Apache Software Foundation.  All rights
 5   
  * reserved.
 6   
  *
 7   
  * Redistribution and use in source and binary forms, with or without
 8   
  * modification, are permitted provided that the following conditions
 9   
  * are met:
 10   
  *
 11   
  * 1. Redistributions of source code must retain the above copyright
 12   
  *    notice, this list of conditions and the following disclaimer.
 13   
  *
 14   
  * 2. Redistributions in binary form must reproduce the above copyright
 15   
  *    notice, this list of conditions and the following disclaimer in
 16   
  *    the documentation and/or other materials provided with the
 17   
  *    distribution.
 18   
  *
 19   
  * 3. The end-user documentation included with the redistribution, if
 20   
  *    any, must include the following acknowlegement:
 21   
  *       "This product includes software developed by the
 22   
  *        Apache Software Foundation (http://www.apache.org/)."
 23   
  *    Alternately, this acknowlegement may appear in the software itself,
 24   
  *    if and wherever such third-party acknowlegements normally appear.
 25   
  *
 26   
  * 4. The names "Ant" and "Apache Software
 27   
  *    Foundation" must not be used to endorse or promote products derived
 28   
  *    from this software without prior written permission. For written
 29   
  *    permission, please contact apache@apache.org.
 30   
  *
 31   
  * 5. Products derived from this software may not be called "Apache"
 32   
  *    nor may "Apache" appear in their names without prior written
 33   
  *    permission of the Apache Group.
 34   
  *
 35   
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 36   
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 37   
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 38   
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 39   
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 40   
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 41   
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 42   
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 43   
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 44   
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 45   
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 46   
  * SUCH DAMAGE.
 47   
  * ====================================================================
 48   
  *
 49   
  * This software consists of voluntary contributions made by many
 50   
  * individuals on behalf of the Apache Software Foundation.  For more
 51   
  * information on the Apache Software Foundation, please see
 52   
  * <http://www.apache.org/>.
 53   
  */
 54   
 package org.apache.tools.ant.taskdefs.optional.extension;
 55   
 
 56   
 import java.io.File;
 57   
 import java.io.FileOutputStream;
 58   
 import java.io.IOException;
 59   
 import java.util.ArrayList;
 60   
 import java.util.Iterator;
 61   
 import java.util.jar.Attributes;
 62   
 import java.util.jar.Manifest;
 63   
 import org.apache.tools.ant.BuildException;
 64   
 import org.apache.tools.ant.Project;
 65   
 import org.apache.tools.ant.Task;
 66   
 
 67   
 /**
 68   
  * Generates a manifest that declares all the dependencies.
 69   
  * The dependencies are determined by looking in the
 70   
  * specified path and searching for Extension / "Optional Package"
 71   
  * specifications in the manifests of the jars.
 72   
  *
 73   
  * <p>Prior to JDK1.3, an "Optional Package" was known as an Extension.
 74   
  * The specification for this mechanism is available in the JDK1.3
 75   
  * documentation in the directory
 76   
  * $JDK_HOME/docs/guide/extensions/versioning.html. Alternatively it is
 77   
  * available online at <a href="http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html">
 78   
  * http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html</a>.</p>
 79   
  *
 80   
  * @author <a href="mailto:peter@apache.org">Peter Donald</a>
 81   
  * @ant.task name="jarlib-manifest"
 82   
  */
 83   
 public final class JarLibManifestTask
 84   
     extends Task
 85   
 {
 86   
     /**
 87   
      * Version of manifest spec that task generates.
 88   
      */
 89   
     private static final String MANIFEST_VERSION = "1.0";
 90   
 
 91   
     /**
 92   
      * "Created-By" string used when creating manifest.
 93   
      */
 94   
     private static final String CREATED_BY = "Created-By";
 95   
 
 96   
     /**
 97   
      * The library to display information about.
 98   
      */
 99   
     private File m_destfile;
 100   
 
 101   
     /**
 102   
      * The extension supported by this library (if any).
 103   
      */
 104   
     private Extension m_extension;
 105   
 
 106   
     /**
 107   
      * ExtensionAdapter objects representing
 108   
      * dependencies required by library.
 109   
      */
 110   
     private final ArrayList m_dependencies = new ArrayList();
 111   
 
 112   
     /**
 113   
      * ExtensionAdapter objects representing optional
 114   
      * dependencies required by library.
 115   
      */
 116   
     private final ArrayList m_optionals = new ArrayList();
 117   
 
 118   
     /**
 119   
      * Extra attributes the user specifies for main section
 120   
      * in manifest.
 121   
      */
 122   
     private final ArrayList m_extraAttributes = new ArrayList();
 123   
 
 124   
     /**
 125   
      * The location where generated manifest is placed.
 126   
      *
 127   
      * @param destfile The location where generated manifest is placed.
 128   
      */
 129  0
     public void setDestfile( final File destfile )
 130   
     {
 131  0
         m_destfile = destfile;
 132   
     }
 133   
 
 134   
     /**
 135   
      * Adds an extension that this library implements.
 136   
      *
 137   
      * @param extensionAdapter an extension that this library implements.
 138   
      */
 139  0
     public void addConfiguredExtension( final ExtensionAdapter extensionAdapter )
 140   
         throws BuildException
 141   
     {
 142  0
         if( null != m_extension )
 143   
         {
 144  0
             final String message =
 145   
                 "Can not have multiple extensions defined in one library.";
 146  0
             throw new BuildException( message );
 147   
         }
 148   
         else
 149   
         {
 150  0
             m_extension = extensionAdapter.toExtension();
 151   
         }
 152   
     }
 153   
 
 154   
     /**
 155   
      * Adds a set of extensions that this library requires.
 156   
      *
 157   
      * @param extensionSet a set of extensions that this library requires.
 158   
      */
 159  0
     public void addConfiguredDepends( final ExtensionSet extensionSet )
 160   
     {
 161  0
         m_dependencies.add( extensionSet );
 162   
     }
 163   
 
 164   
     /**
 165   
      * Adds a set of extensions that this library optionally requires.
 166   
      *
 167   
      * @param extensionSet a set of extensions that this library optionally requires.
 168   
      */
 169  0
     public void addConfiguredOptions( final ExtensionSet extensionSet )
 170   
     {
 171  0
         m_optionals.add( extensionSet );
 172   
     }
 173   
 
 174   
     /**
 175   
      * Adds an attribute that is to be put in main section of manifest.
 176   
      *
 177   
      * @param attribute an attribute that is to be put in main section of manifest.
 178   
      */
 179  0
     public void addConfiguredAttribute( final ExtraAttribute attribute )
 180   
     {
 181  0
         m_extraAttributes.add( attribute );
 182   
     }
 183   
 
 184  0
     public void execute()
 185   
         throws BuildException
 186   
     {
 187  0
         validate();
 188   
 
 189  0
         final Manifest manifest = new Manifest();
 190  0
         final Attributes attributes = manifest.getMainAttributes();
 191   
 
 192  0
         attributes.put( Attributes.Name.MANIFEST_VERSION, MANIFEST_VERSION );
 193  0
         final String createdBy = "Apache Ant " + getProject().getProperty( "ant.version" );
 194  0
         attributes.putValue( CREATED_BY, createdBy );
 195   
 
 196  0
         appendExtraAttributes( attributes );
 197   
 
 198  0
         if( null != m_extension )
 199   
         {
 200  0
             Extension.addExtension( m_extension, attributes );
 201   
         }
 202   
 
 203   
         //Add all the dependency data to manifest for dependencies
 204  0
         final ArrayList depends = toExtensions( m_dependencies );
 205  0
         appendExtensionList( attributes,
 206   
                              Extension.EXTENSION_LIST,
 207   
                              "lib",
 208   
                              depends.size() );
 209  0
         appendLibraryList( attributes, "lib", depends );
 210   
 
 211   
         //Add all the dependency data to manifest for "optional"
 212   
         //dependencies
 213  0
         final ArrayList option = toExtensions( m_optionals );
 214  0
         appendExtensionList( attributes,
 215   
                              Extension.OPTIONAL_EXTENSION_LIST,
 216   
                              "opt",
 217   
                              option.size() );
 218  0
         appendLibraryList( attributes, "opt", option );
 219   
 
 220  0
         try
 221   
         {
 222  0
             final String message = "Generating manifest " + m_destfile.getAbsoluteFile();
 223  0
             log( message, Project.MSG_INFO );
 224  0
             writeManifest( manifest );
 225   
         }
 226   
         catch( final IOException ioe )
 227   
         {
 228  0
             throw new BuildException( ioe.getMessage(), ioe );
 229   
         }
 230   
     }
 231   
 
 232   
     /**
 233   
      * Validate the tasks parameters.
 234   
      *
 235   
      * @throws BuildException if invalid parameters found
 236   
      */
 237  0
     private void validate()
 238   
         throws BuildException
 239   
     {
 240  0
         if( null == m_destfile )
 241   
         {
 242  0
             final String message = "Destfile attribute not specified.";
 243  0
             throw new BuildException( message );
 244   
         }
 245  0
         if( m_destfile.exists() && !m_destfile.isFile() )
 246   
         {
 247  0
             final String message = m_destfile + " is not a file.";
 248  0
             throw new BuildException( message );
 249   
         }
 250   
     }
 251   
 
 252   
     /**
 253   
      * Add any extra attributes to the manifest.
 254   
      *
 255   
      * @param attributes the manifest section to write
 256   
      *        attributes to
 257   
      */
 258  0
     private void appendExtraAttributes( final Attributes attributes )
 259   
     {
 260  0
         final Iterator iterator = m_extraAttributes.iterator();
 261  0
         while( iterator.hasNext() )
 262   
         {
 263  0
             final ExtraAttribute attribute =
 264   
                 (ExtraAttribute)iterator.next();
 265  0
             attributes.putValue( attribute.getName(),
 266   
                                  attribute.getValue() );
 267   
         }
 268   
     }
 269   
 
 270   
     /**
 271   
      * Write out manifest to destfile.
 272   
      *
 273   
      * @param manifest the manifest
 274   
      * @throws IOException if error writing file
 275   
      */
 276  0
     private void writeManifest( final Manifest manifest )
 277   
         throws IOException
 278   
     {
 279  0
         FileOutputStream output = null;
 280  0
         try
 281   
         {
 282  0
             output = new FileOutputStream( m_destfile );
 283  0
             manifest.write( output );
 284  0
             output.flush();
 285   
         }
 286   
         finally
 287   
         {
 288  0
             if( null != output )
 289   
             {
 290  0
                 try
 291   
                 {
 292  0
                     output.close();
 293   
                 }
 294   
                 catch( IOException e )
 295   
                 {
 296   
                 }
 297   
             }
 298   
         }
 299   
     }
 300   
 
 301   
     /**
 302   
      * Append specified extensions to specified attributes.
 303   
      * Use the extensionKey to list the extensions, usually "Extension-List:"
 304   
      * for required dependencies and "Optional-Extension-List:" for optional
 305   
      * dependencies. NOTE: "Optional" dependencies are not part of the
 306   
      * specification.
 307   
      *
 308   
      * @param attributes the attributes to add extensions to
 309   
      * @param extensions the list of extensions
 310   
      * @throws BuildException if an error occurs
 311   
      */
 312  0
     private void appendLibraryList( final Attributes attributes,
 313   
                                     final String listPrefix,
 314   
                                     final ArrayList extensions )
 315   
         throws BuildException
 316   
     {
 317  0
         final int size = extensions.size();
 318  0
         for( int i = 0; i < size; i++ )
 319   
         {
 320  0
             final Extension extension = (Extension)extensions.get( i );
 321  0
             final String prefix = listPrefix + i + "-";
 322  0
             Extension.addExtension( extension, prefix, attributes );
 323   
         }
 324   
     }
 325   
 
 326   
     /**
 327   
      * Append an attribute such as "Extension-List: lib0 lib1 lib2"
 328   
      * using specified prefix and counting up to specified size.
 329   
      * Also use specified extensionKey so that can generate list of
 330   
      * optional dependencies aswell.
 331   
      *
 332   
      * @param size the number of librarys to list
 333   
      * @param listPrefix the prefix for all librarys
 334   
      * @param attributes the attributes to add key-value to
 335   
      * @param extensionKey the key to use
 336   
      */
 337  0
     private void appendExtensionList( final Attributes attributes,
 338   
                                       final Attributes.Name extensionKey,
 339   
                                       final String listPrefix,
 340   
                                       final int size )
 341   
     {
 342  0
         final StringBuffer sb = new StringBuffer();
 343  0
         for( int i = 0; i < size; i++ )
 344   
         {
 345  0
             sb.append( listPrefix + i );
 346  0
             sb.append( ' ' );
 347   
         }
 348   
 
 349   
         //add in something like
 350   
         //"Extension-List: javahelp java3d"
 351  0
         attributes.put( extensionKey, sb.toString() );
 352   
     }
 353   
 
 354   
     /**
 355   
      * Convert a list of ExtensionSet objects to extensions.
 356   
      *
 357   
      * @param extensionSets the list of ExtensionSets to add to list
 358   
      * @throws BuildException if an error occurs
 359   
      */
 360  0
     private ArrayList toExtensions( final ArrayList extensionSets )
 361   
         throws BuildException
 362   
     {
 363  0
         final ArrayList results = new ArrayList();
 364   
 
 365  0
         final int size = extensionSets.size();
 366  0
         for( int i = 0; i < size; i++ )
 367   
         {
 368  0
             final ExtensionSet set = (ExtensionSet)extensionSets.get( i );
 369  0
             final Extension[] extensions = set.toExtensions( getProject() );
 370  0
             for( int j = 0; j < extensions.length; j++ )
 371   
             {
 372  0
                 results.add( extensions[ j ] );
 373   
             }
 374   
         }
 375   
 
 376  0
         return results;
 377   
     }
 378   
 }
 379