Coverage Report - org.codehaus.mojo.nbm.CreateWebstartAppMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
CreateWebstartAppMojo
0%
0/220
0%
0/72
3.2
CreateWebstartAppMojo$1
0%
0/9
N/A
3.2
CreateWebstartAppMojo$2
0%
0/9
N/A
3.2
 
 1  
 /*
 2  
  *  Copyright 2008 Johan Andrén.
 3  
  * 
 4  
  *  Licensed under the Apache License, Version 2.0 (the "License");
 5  
  *  you may not use this file except in compliance with the License.
 6  
  *  You may obtain a copy of the License at
 7  
  * 
 8  
  *       http://www.apache.org/licenses/LICENSE-2.0
 9  
  * 
 10  
  *  Unless required by applicable law or agreed to in writing, software
 11  
  *  distributed under the License is distributed on an "AS IS" BASIS,
 12  
  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  *  See the License for the specific language governing permissions and
 14  
  *  limitations under the License.
 15  
  *  under the License.
 16  
  */
 17  
 package org.codehaus.mojo.nbm;
 18  
 
 19  
 import java.io.BufferedReader;
 20  
 import java.io.ByteArrayInputStream;
 21  
 import java.io.File;
 22  
 import java.io.FileInputStream;
 23  
 import java.io.FileOutputStream;
 24  
 import java.io.IOException;
 25  
 import java.io.InputStream;
 26  
 import java.io.InputStreamReader;
 27  
 import java.io.OutputStreamWriter;
 28  
 import java.io.Reader;
 29  
 import java.io.Writer;
 30  
 import java.net.URL;
 31  
 import java.util.Properties;
 32  
 import java.util.StringTokenizer;
 33  
 import java.util.jar.JarFile;
 34  
 import org.apache.maven.plugin.MojoExecutionException;
 35  
 import org.apache.maven.plugin.MojoFailureException;
 36  
 import org.apache.maven.plugins.annotations.Component;
 37  
 import org.apache.maven.plugins.annotations.LifecyclePhase;
 38  
 import org.apache.maven.plugins.annotations.Mojo;
 39  
 import org.apache.maven.project.MavenProject;
 40  
 import org.apache.maven.project.MavenProjectHelper;
 41  
 import org.apache.tools.ant.Project;
 42  
 import org.apache.tools.ant.taskdefs.GenerateKey;
 43  
 import org.apache.tools.ant.taskdefs.SignJar;
 44  
 import org.apache.tools.ant.taskdefs.Taskdef;
 45  
 import org.apache.tools.ant.types.FileSet;
 46  
 import org.apache.tools.ant.types.Parameter;
 47  
 import org.apache.tools.ant.types.selectors.AndSelector;
 48  
 import org.apache.tools.ant.types.selectors.FilenameSelector;
 49  
 import org.apache.tools.ant.types.selectors.OrSelector;
 50  
 import org.codehaus.plexus.archiver.zip.ZipArchiver;
 51  
 import org.codehaus.plexus.components.io.resources.PlexusIoResource;
 52  
 import org.codehaus.plexus.util.DirectoryScanner;
 53  
 import org.codehaus.plexus.util.FileUtils;
 54  
 import org.codehaus.plexus.util.IOUtil;
 55  
 import org.codehaus.plexus.util.InterpolationFilterReader;
 56  
 import org.netbeans.nbbuild.MakeJNLP;
 57  
 import org.netbeans.nbbuild.ModuleSelector;
 58  
 import org.netbeans.nbbuild.VerifyJNLP;
 59  
 
 60  
 /**
 61  
  * Create webstartable binaries for a 'nbm-application'.
 62  
  * @author <a href="mailto:johan.andren@databyran.se">Johan Andrén</a>
 63  
  * @author <a href="mailto:mkleint@codehaus.org">Milos Kleint</a>
 64  
  * @since 3.0
 65  
  */
 66  
 @Mojo(name="webstart-app", defaultPhase= LifecyclePhase.PACKAGE )
 67  0
 public class CreateWebstartAppMojo
 68  
     extends AbstractNbmMojo
 69  
 {
 70  
 
 71  
     /**
 72  
      * The Maven project.
 73  
 
 74  
      */
 75  
     @org.apache.maven.plugins.annotations.Parameter(required=true, readonly=true, property="project")
 76  
     private MavenProject project;
 77  
 
 78  
     @Component
 79  
     protected MavenProjectHelper projectHelper;
 80  
 
 81  
     /**
 82  
      * The branding token for the application based on NetBeans platform.
 83  
      */
 84  
     @org.apache.maven.plugins.annotations.Parameter(required=true, property="netbeans.branding.token")
 85  
     protected String brandingToken;
 86  
 
 87  
     /**
 88  
      * output directory where the the NetBeans application will be created.
 89  
      */
 90  
     @org.apache.maven.plugins.annotations.Parameter(required=true, defaultValue="${project.build.directory}")
 91  
     private File outputDirectory;
 92  
 
 93  
     /**
 94  
      * Ready-to-deploy WAR containing application in JNLP packaging.
 95  
      * 
 96  
      */
 97  
     @org.apache.maven.plugins.annotations.Parameter(required=true, defaultValue="${project.build.directory}/${project.artifactId}-${project.version}-jnlp.war")
 98  
     private File destinationFile;
 99  
 
 100  
     /**
 101  
      * Artifact Classifier to use for the webstart distributable zip file.
 102  
      * @since 3.1
 103  
      */
 104  
     @org.apache.maven.plugins.annotations.Parameter(defaultValue="webstart", property="nbm.webstart.classifier")
 105  
     private String webstartClassifier;
 106  
 
 107  
     /**
 108  
      * Codebase value within *.jnlp files.
 109  
      * <strong>Defining this parameter is generally a bad idea.</strong>
 110  
      */
 111  
     @org.apache.maven.plugins.annotations.Parameter(property="nbm.webstart.codebase")
 112  
     private String codebase;
 113  
 
 114  
     /**
 115  
      * A custom master JNLP file. If not defined, the 
 116  
      * <a href="http://mojo.codehaus.org/nbm-maven-plugin/masterjnlp.txt">default one</a> is used.
 117  
      * The following expressions can be used within the file and will
 118  
      * be replaced when generating content.
 119  
      * <ul>
 120  
      * <li>${jnlp.resources}</li>
 121  
      * <li>${jnlp.codebase} - the 'codebase' parameter value is passed in.</li>
 122  
      * <li>${app.name}</li>
 123  
      * <li>${app.title}</li>
 124  
      * <li>${app.vendor}</li>
 125  
      * <li>${app.description}</li>
 126  
      * <li>${branding.token} - the 'brandingToken' parameter value is passed in.</li>
 127  
      * <li>${netbeans.jnlp.fixPolicy}</li>
 128  
      * </ul>
 129  
      */
 130  
     @org.apache.maven.plugins.annotations.Parameter
 131  
     private File masterJnlpFile;
 132  
     
 133  
     /**
 134  
      * The basename (minus .jnlp extension) of the master JNLP file in the output.
 135  
      * This file will be the entry point for javaws.
 136  
      * Defaults to the branding token.
 137  
      * @since 3.5
 138  
      */
 139  
     @org.apache.maven.plugins.annotations.Parameter(property="master.jnlp.file.name")
 140  
     private String masterJnlpFileName;
 141  
 
 142  
     /**
 143  
      * keystore location for signing the nbm file
 144  
      */
 145  
     @org.apache.maven.plugins.annotations.Parameter(property="keystore")
 146  
     private String keystore;
 147  
 
 148  
     /**
 149  
      * keystore password
 150  
      */
 151  
     @org.apache.maven.plugins.annotations.Parameter(property="keystorepass")
 152  
     private String keystorepassword;
 153  
 
 154  
     /**
 155  
      * keystore alias
 156  
      */
 157  
     @org.apache.maven.plugins.annotations.Parameter(property="keystorealias")
 158  
     private String keystorealias;
 159  
 
 160  
     /**
 161  
      * keystore type
 162  
      * @since 3.5
 163  
      */
 164  
     @org.apache.maven.plugins.annotations.Parameter(property="keystoretype")
 165  
     private String keystoretype;
 166  
 
 167  
     /**
 168  
      * If set true, build-jnlp target creates versioning info in jnlp descriptors and version.xml files.
 169  
      * This allows for incremental updates of Webstart applications, but requires download via
 170  
      * JnlpDownloadServlet
 171  
      * Defaults to false, which means versioning
 172  
      * info is not generated (see
 173  
      * http://java.sun.com/j2se/1.5.0/docs/guide/javaws/developersguide/downloadservletguide.html#resources).
 174  
      *
 175  
      */
 176  
     @org.apache.maven.plugins.annotations.Parameter(defaultValue="false", property="nbm.webstart.versions")
 177  
     private boolean processJarVersions;
 178  
     /**
 179  
      * additional command line arguments. Eg.
 180  
      * -J-Xdebug -J-Xnoagent -J-Xrunjdwp:transport=dt_socket,suspend=n,server=n,address=8888
 181  
      * can be used to debug the IDE.
 182  
      */
 183  
     @org.apache.maven.plugins.annotations.Parameter(property="netbeans.run.params")
 184  
     private String additionalArguments;
 185  
 
 186  
     /**
 187  
      * 
 188  
      * @throws org.apache.maven.plugin.MojoExecutionException 
 189  
      * @throws org.apache.maven.plugin.MojoFailureException 
 190  
      */
 191  
     @Override
 192  
     public void execute()
 193  
         throws MojoExecutionException, MojoFailureException
 194  
     {
 195  0
         if ( !"nbm-application".equals( project.getPackaging() ) )
 196  
         {
 197  0
             throw new MojoExecutionException(
 198  
                 "This goal only makes sense on project with nbm-application packaging." );
 199  
         }
 200  0
         Project antProject = antProject();
 201  
         
 202  0
         getLog().warn( "WARNING: Unsigned and self-signed WebStart applications are deprecated from JDK7u21 onwards. To ensure future correct functionality please use trusted certificate.");
 203  
 
 204  0
         if ( keystore != null && keystorealias != null && keystorepassword != null )
 205  
         {
 206  0
             File ks = new File( keystore );
 207  0
             if ( !ks.exists() )
 208  
             {
 209  0
                 throw new MojoFailureException( "Cannot find keystore file at " + ks.getAbsolutePath() );
 210  
             }
 211  
             else
 212  
             {
 213  
                 //proceed..
 214  
             }
 215  0
         }
 216  0
         else if ( keystore != null || keystorepassword != null || keystorealias != null )
 217  
         {
 218  0
             throw new MojoFailureException(
 219  
                 "If you want to sign the jnlp application, you need to define all three keystore related parameters." );
 220  
         }
 221  
         else
 222  
         {
 223  0
             File generatedKeystore = new File( outputDirectory, "generated.keystore" );
 224  0
             if ( ! generatedKeystore.exists() )
 225  
             {
 226  0
                 getLog().warn( "Keystore related parameters not set, generating a default keystore." );
 227  0
                 GenerateKey genTask = (GenerateKey) antProject.createTask( "genkey" );
 228  0
                 genTask.setAlias( "jnlp" );
 229  0
                 genTask.setStorepass( "netbeans" );
 230  0
                 genTask.setDname( "CN=" + System.getProperty( "user.name" ) );
 231  0
                 genTask.setKeystore( generatedKeystore.getAbsolutePath() );
 232  0
                 genTask.execute();
 233  
             }
 234  0
             keystore = generatedKeystore.getAbsolutePath();
 235  0
             keystorepassword = "netbeans";
 236  0
             keystorealias = "jnlp";
 237  
         }
 238  
 
 239  0
         Taskdef taskdef = (Taskdef) antProject.createTask( "taskdef" );
 240  0
         taskdef.setClassname( "org.netbeans.nbbuild.MakeJNLP" );
 241  0
         taskdef.setName( "makejnlp" );
 242  0
         taskdef.execute();
 243  
 
 244  0
         taskdef = (Taskdef) antProject.createTask( "taskdef" );
 245  0
         taskdef.setClassname( "org.netbeans.nbbuild.VerifyJNLP" );
 246  0
         taskdef.setName( "verifyjnlp" );
 247  0
         taskdef.execute();
 248  
 
 249  
 
 250  
         try
 251  
         {
 252  0
             File webstartBuildDir = new File(
 253  
                 outputDirectory + File.separator + "webstart" + File.separator + brandingToken );
 254  0
             if ( webstartBuildDir.exists() )
 255  
             {
 256  0
                 FileUtils.deleteDirectory( webstartBuildDir );
 257  
             }
 258  0
             webstartBuildDir.mkdirs();
 259  0
             final String localCodebase = codebase != null ? codebase : webstartBuildDir.toURI().toString();
 260  0
             getLog().info( "Generating webstartable binaries at " + webstartBuildDir.getAbsolutePath() );
 261  
 
 262  0
             File nbmBuildDirFile = new File( outputDirectory, brandingToken );
 263  
 
 264  
 //            FileUtils.copyDirectoryStructureIfModified( nbmBuildDirFile, webstartBuildDir );
 265  
 
 266  0
             MakeJNLP jnlpTask = (MakeJNLP) antProject.createTask( "makejnlp" );
 267  0
             jnlpTask.setDir( webstartBuildDir );
 268  0
             jnlpTask.setCodebase( localCodebase );
 269  
             //TODO, how to figure verify excludes..
 270  0
             jnlpTask.setVerify( false );
 271  0
             jnlpTask.setPermissions( "<security><all-permissions/></security>" );
 272  0
             jnlpTask.setSignJars( true );
 273  
 
 274  0
             jnlpTask.setAlias( keystorealias );
 275  0
             jnlpTask.setKeystore( keystore );
 276  0
             jnlpTask.setStorePass( keystorepassword );
 277  0
             if ( keystoretype != null )
 278  
             {
 279  0
                 jnlpTask.setStoreType( keystoretype );
 280  
             }
 281  0
             jnlpTask.setProcessJarVersions( processJarVersions );
 282  
 
 283  0
             FileSet fs = jnlpTask.createModules();
 284  0
             fs.setDir( nbmBuildDirFile );
 285  0
             OrSelector or = new OrSelector();
 286  0
             AndSelector and = new AndSelector();
 287  0
             FilenameSelector inc = new FilenameSelector();
 288  0
             inc.setName( "*/modules/**/*.jar" );
 289  0
             or.addFilename( inc );
 290  0
             inc = new FilenameSelector();
 291  0
             inc.setName( "*/lib/**/*.jar" );
 292  0
             or.addFilename( inc );
 293  0
             inc = new FilenameSelector();
 294  0
             inc.setName( "*/core/**/*.jar" );
 295  0
             or.addFilename( inc );
 296  
 
 297  0
             ModuleSelector ms = new ModuleSelector();
 298  0
             Parameter included = new Parameter();
 299  0
             included.setName( "includeClusters" );
 300  0
             included.setValue( "" );
 301  0
             Parameter excluded = new Parameter();
 302  0
             excluded.setName( "excludeClusters" );
 303  0
             excluded.setValue( "" );
 304  0
             Parameter exModules = new Parameter();
 305  0
             exModules.setName( "excludeModules" );
 306  0
             exModules.setValue( "" );
 307  0
             ms.setParameters( new Parameter[]
 308  
                 {
 309  
                     included,
 310  
                     excluded,
 311  
                     exModules
 312  
                 } );
 313  0
             and.add( or );
 314  0
             and.add( ms );
 315  0
             fs.addAnd( and );
 316  0
             jnlpTask.execute();
 317  
 
 318  
             //TODO is it really netbeans/
 319  0
             String extSnippet = generateExtensions( fs, antProject, "" ); // "netbeans/"
 320  
 
 321  0
             if ( masterJnlpFileName == null )
 322  
             {
 323  0
                masterJnlpFileName = brandingToken;
 324  
             }
 325  
 
 326  0
             Properties props = new Properties();
 327  0
             props.setProperty( "jnlp.codebase", localCodebase );
 328  0
             props.setProperty( "app.name", brandingToken );
 329  0
             props.setProperty( "app.title", project.getName() );
 330  0
             if ( project.getOrganization() != null )
 331  
             {
 332  0
                 props.setProperty( "app.vendor", project.getOrganization().getName() );
 333  
             }
 334  
             else
 335  
             {
 336  0
                 props.setProperty( "app.vendor", "Nobody" );
 337  
             }
 338  0
             String description = project.getDescription() != null ? project.getDescription() : "No Project Description";
 339  0
             props.setProperty( "app.description", description );
 340  0
             props.setProperty( "branding.token", brandingToken );
 341  0
             props.setProperty( "master.jnlp.file.name", masterJnlpFileName );
 342  0
             props.setProperty( "netbeans.jnlp.fixPolicy", "false" );
 343  
 
 344  0
             StringBuilder stBuilder = new StringBuilder();
 345  0
             if ( additionalArguments != null )
 346  
             {
 347  0
                 StringTokenizer st = new StringTokenizer( additionalArguments );
 348  0
                 while ( st.hasMoreTokens() )
 349  
                 {
 350  0
                     String arg = st.nextToken();
 351  0
                     if ( arg.startsWith( "-J" ) )
 352  
                     {
 353  0
                         if ( stBuilder.length() > 0 )
 354  
                         {
 355  0
                             stBuilder.append( ' ' );
 356  
                         }
 357  0
                         stBuilder.append( arg.substring( 2 ) );
 358  
                     }
 359  0
                 }
 360  
             }
 361  0
             props.setProperty( "netbeans.run.params", stBuilder.toString() );
 362  
 
 363  0
             File masterJnlp = new File(
 364  
                 webstartBuildDir.getAbsolutePath() + File.separator + masterJnlpFileName + ".jnlp" );
 365  0
             filterCopy( masterJnlpFile, "master.jnlp", masterJnlp, props );
 366  
 
 367  
 
 368  0
             File startup = copyLauncher( outputDirectory, nbmBuildDirFile );
 369  0
             File jnlpDestination = new File(
 370  
                 webstartBuildDir.getAbsolutePath() + File.separator + "startup.jar" );
 371  
 
 372  0
             SignJar signTask = (SignJar) antProject.createTask( "signjar" );
 373  0
             signTask.setKeystore( keystore );
 374  0
             signTask.setStorepass( keystorepassword );
 375  0
             signTask.setAlias( keystorealias );
 376  0
             if ( keystoretype != null )
 377  
             {
 378  0
                 signTask.setStoretype( keystoretype );
 379  
             }
 380  0
             signTask.setSignedjar( jnlpDestination );
 381  0
             signTask.setJar( startup );
 382  0
             signTask.execute();
 383  
 
 384  
             //branding
 385  0
             DirectoryScanner ds = new DirectoryScanner();
 386  0
             ds.setBasedir( nbmBuildDirFile );
 387  0
             ds.setIncludes( new String[]
 388  
                 {
 389  
                     "**/locale/*.jar"
 390  
                 } );
 391  0
             ds.scan();
 392  0
             String[] includes = ds.getIncludedFiles();
 393  0
             StringBuilder brandRefs = new StringBuilder();
 394  0
             if ( includes != null && includes.length > 0 )
 395  
             {
 396  0
                 File brandingDir = new File( webstartBuildDir, "branding" );
 397  0
                 brandingDir.mkdirs();
 398  0
                 for ( String incBran : includes )
 399  
                 {
 400  0
                     File source = new File( nbmBuildDirFile, incBran );
 401  0
                     File dest = new File( brandingDir, source.getName() );
 402  0
                     FileUtils.copyFile( source, dest );
 403  0
                     brandRefs.append( "    <jar href=\'branding/" ).append( dest.getName() ).append( "\'/>\n" );
 404  
                 }
 405  
 
 406  0
                 signTask = (SignJar) antProject.createTask( "signjar" );
 407  0
                 signTask.setKeystore( keystore );
 408  0
                 signTask.setStorepass( keystorepassword );
 409  0
                 signTask.setAlias( keystorealias );
 410  0
                 if ( keystoretype != null )
 411  
                 {
 412  0
                     signTask.setStoretype( keystoretype );
 413  
                 }
 414  
                 
 415  0
                 FileSet set = new FileSet();
 416  0
                 set.setDir( brandingDir );
 417  0
                 set.setIncludes( "*.jar" );
 418  0
                 signTask.addFileset( set );
 419  0
                 signTask.execute();
 420  
             }
 421  
 
 422  0
             File modulesJnlp = new File(
 423  
                 webstartBuildDir.getAbsolutePath() + File.separator + "modules.jnlp" );
 424  0
             props.setProperty( "jnlp.branding.jars", brandRefs.toString() );
 425  0
             props.setProperty( "jnlp.resources", extSnippet );
 426  0
             filterCopy( null, /* filename is historical */"branding.jnlp", modulesJnlp, props );
 427  
 
 428  0
             getLog().info( "Verifying generated webstartable content." );
 429  0
             VerifyJNLP verifyTask = (VerifyJNLP) antProject.createTask( "verifyjnlp" );
 430  0
             FileSet verify = new FileSet();
 431  0
             verify.setFile( masterJnlp );
 432  0
             verifyTask.addConfiguredFileset( verify );
 433  0
             verifyTask.execute();
 434  
 
 435  
 
 436  
             // create zip archive
 437  0
             if ( destinationFile.exists() )
 438  
             {
 439  0
                 destinationFile.delete();
 440  
             }
 441  0
             ZipArchiver archiver = new ZipArchiver();
 442  0
             if ( codebase != null )
 443  
             {
 444  0
                 getLog().warn( "Defining <codebase>/${nbm.webstart.codebase} is generally unnecessary" );
 445  0
                 archiver.addDirectory( webstartBuildDir );
 446  
             }
 447  
             else
 448  
             {
 449  0
                 archiver.addDirectory( webstartBuildDir, null, new String[] { "**/*.jnlp" } );
 450  0
                 for ( final File jnlp : webstartBuildDir.listFiles() )
 451  
                 {
 452  0
                     if ( !jnlp.getName().endsWith( ".jnlp" ) )
 453  
                     {
 454  0
                         continue;
 455  
                     }
 456  0
                     archiver.addResource( new PlexusIoResource() {
 457  
                         public @Override InputStream getContents() throws IOException
 458  
                         {
 459  0
                             return new ByteArrayInputStream( FileUtils.fileRead( jnlp, "UTF-8" ).replace( localCodebase, "$$codebase" ).getBytes( "UTF-8" ) );
 460  
                         }
 461  
                         public @Override long getLastModified()
 462  
                         {
 463  0
                             return jnlp.lastModified();
 464  
                         }
 465  
                         public @Override boolean isExisting()
 466  
                         {
 467  0
                             return true;
 468  
                         }
 469  
                         public @Override long getSize()
 470  
                         {
 471  0
                             return UNKNOWN_RESOURCE_SIZE;
 472  
                         }
 473  
                         public @Override URL getURL() throws IOException
 474  
                         {
 475  0
                             return null;
 476  
                         }
 477  
                         public @Override String getName()
 478  
                         {
 479  0
                             return jnlp.getAbsolutePath();
 480  
                         }
 481  
                         public @Override boolean isFile()
 482  
                         {
 483  0
                             return true;
 484  
                         }
 485  
                         public @Override boolean isDirectory()
 486  
                         {
 487  0
                             return false;
 488  
                         }
 489  
                     }, jnlp.getName(), archiver.getDefaultFileMode() );
 490  
                 }
 491  
             }
 492  0
             File jdkhome = new File( System.getProperty( "java.home" ) );
 493  0
             File servlet = new File( jdkhome, "sample/jnlp/servlet/jnlp-servlet.jar" );
 494  0
             if ( ! servlet.isFile() )
 495  
             {
 496  0
                 servlet = new File( jdkhome.getParentFile(), "sample/jnlp/servlet/jnlp-servlet.jar" );
 497  
             }
 498  0
             if ( servlet.isFile() )
 499  
             {
 500  0
                 archiver.addFile( servlet, "WEB-INF/lib/jnlp-servlet.jar" );
 501  0
                 archiver.addResource( new PlexusIoResource() {
 502  
                     public @Override InputStream getContents() throws IOException
 503  
                     {
 504  0
                         return new ByteArrayInputStream( ( "" +
 505  
                             "<web-app>\n" +
 506  
                             "    <servlet>\n" +
 507  
                             "        <servlet-name>JnlpDownloadServlet</servlet-name>\n" +
 508  
                             "        <servlet-class>jnlp.sample.servlet.JnlpDownloadServlet</servlet-class>\n" +
 509  
                             "    </servlet>\n" +
 510  
                             "    <servlet-mapping>\n" +
 511  
                             "        <servlet-name>JnlpDownloadServlet</servlet-name>\n" +
 512  
                             "        <url-pattern>*.jnlp</url-pattern>\n" +
 513  
                             "    </servlet-mapping>\n" +
 514  
                             "</web-app>\n" ).getBytes() );
 515  
                     }
 516  
                     public @Override long getLastModified()
 517  
                     {
 518  0
                         return UNKNOWN_MODIFICATION_DATE;
 519  
                     }
 520  
                     public @Override boolean isExisting()
 521  
                     {
 522  0
                         return true;
 523  
                     }
 524  
                     public @Override long getSize()
 525  
                     {
 526  0
                         return UNKNOWN_RESOURCE_SIZE;
 527  
                     }
 528  
                     public @Override URL getURL() throws IOException
 529  
                     {
 530  0
                         return null;
 531  
                     }
 532  
                     public @Override String getName()
 533  
                     {
 534  0
                         return "web.xml";
 535  
                     }
 536  
                     public @Override boolean isFile()
 537  
                     {
 538  0
                         return true;
 539  
                     }
 540  
                     public @Override boolean isDirectory()
 541  
                     {
 542  0
                         return false;
 543  
                     }
 544  
                 }, "WEB-INF/web.xml", archiver.getDefaultFileMode() );
 545  
             }
 546  0
             archiver.setDestFile( destinationFile );
 547  0
             archiver.createArchive();
 548  
 
 549  
             // attach standalone so that it gets installed/deployed
 550  0
             projectHelper.attachArtifact( project, "war", webstartClassifier, destinationFile );
 551  
 
 552  
         }
 553  0
         catch ( Exception ex )
 554  
         {
 555  0
             throw new MojoExecutionException( "Error creating webstartable binary.", ex );
 556  0
         }
 557  0
     }
 558  
 
 559  
     /**
 560  
      * @param standaloneBuildDir
 561  
      * @return The name of the jnlp-launcher jarfile in the build directory
 562  
      */
 563  
     private File copyLauncher( File standaloneBuildDir, File builtInstallation )
 564  
         throws IOException
 565  
     {
 566  0
         File jnlpStarter =
 567  
             new File( builtInstallation.getAbsolutePath() + File.separator + "harness" + File.separator + "jnlp"
 568  
                 + File.separator + "jnlp-launcher.jar" );
 569  
         // buffer so it isn't reading a byte at a time!
 570  0
         InputStream source = null;
 571  0
         FileOutputStream outstream = null;
 572  
         try
 573  
         {
 574  0
             if ( !jnlpStarter.exists() )
 575  
             {
 576  0
                 source = getClass().getClassLoader().getResourceAsStream(
 577  
                     "harness/jnlp/jnlp-launcher.jar" );
 578  
             }
 579  
             else
 580  
             {
 581  0
                 source = new FileInputStream( jnlpStarter );
 582  
             }
 583  0
             File jnlpDestination = new File(
 584  
                 standaloneBuildDir.getAbsolutePath() + File.separator + "jnlp-launcher.jar" );
 585  
 
 586  0
             outstream = new FileOutputStream( jnlpDestination );
 587  0
             IOUtil.copy( source, outstream );
 588  0
             return jnlpDestination;
 589  
         }
 590  
         finally
 591  
         {
 592  0
             IOUtil.close( source );
 593  0
             IOUtil.close( outstream );
 594  
         }
 595  
     }
 596  
 
 597  
     private void filterCopy( File sourceFile, String resourcePath, File destinationFile, Properties filterProperties )
 598  
         throws IOException
 599  
     {
 600  
         // buffer so it isn't reading a byte at a time!
 601  0
         Reader source = null;
 602  0
         Writer destination = null;
 603  
         try
 604  
         {
 605  
             InputStream instream;
 606  0
             if ( sourceFile != null )
 607  
             {
 608  0
                 instream = new FileInputStream( sourceFile );
 609  
             }
 610  
             else
 611  
             {
 612  0
                 instream = getClass().getClassLoader().getResourceAsStream( resourcePath );
 613  
             }
 614  0
             FileOutputStream outstream = new FileOutputStream( destinationFile );
 615  
 
 616  0
             source = new BufferedReader( new InputStreamReader( instream, "UTF-8" ) );
 617  0
             destination = new OutputStreamWriter( outstream, "UTF-8" );
 618  
 
 619  
             // support ${token}
 620  0
             Reader reader = new InterpolationFilterReader( source, filterProperties, "${", "}" );
 621  
 
 622  0
             IOUtil.copy( reader, destination );
 623  
         }
 624  
         finally
 625  
         {
 626  0
             IOUtil.close( source );
 627  0
             IOUtil.close( destination );
 628  0
         }
 629  0
     }
 630  
 
 631  
     /**
 632  
      * copied from MakeMasterJNLP ant task.
 633  
      * @param files
 634  
      * @param antProject
 635  
      * @param masterPrefix
 636  
      * @return
 637  
      * @throws java.io.IOException
 638  
      */
 639  
     private String generateExtensions( FileSet files, Project antProject, String masterPrefix )
 640  
         throws IOException
 641  
     {
 642  0
         StringBuilder buff = new StringBuilder();
 643  0
         for ( String nm : files.getDirectoryScanner( antProject ).getIncludedFiles() )
 644  
         {
 645  0
             File jar = new File( files.getDir( antProject ), nm );
 646  
 
 647  0
             if ( !jar.canRead() )
 648  
             {
 649  0
                 throw new IOException( "Cannot read file: " + jar );
 650  
             }
 651  
 
 652  0
             JarFile theJar = new JarFile( jar );
 653  0
             String codenamebase = theJar.getManifest().getMainAttributes().getValue( "OpenIDE-Module" );
 654  0
             if ( codenamebase == null )
 655  
             {
 656  0
                 throw new IOException( "Not a NetBeans Module: " + jar );
 657  
             }
 658  
             {
 659  0
                 int slash = codenamebase.indexOf( '/' );
 660  0
                 if ( slash >= 0 )
 661  
                 {
 662  0
                     codenamebase = codenamebase.substring( 0, slash );
 663  
                 }
 664  
             }
 665  0
             String dashcnb = codenamebase.replace( '.', '-' );
 666  
 
 667  0
             buff.append( "    <extension name='" ).append( codenamebase ).append( "' href='" ).append( masterPrefix ).append( dashcnb ).append( ".jnlp' />\n" );
 668  0
             theJar.close();
 669  
         }
 670  0
         return buff.toString();
 671  
 
 672  
     }
 673  
 }