All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.mojo.nbm.CreateWebstartAppMojo Maven / Gradle / Ivy

Go to download

Maven plugin for creating NetBeans modules. It defines a custom lifecycle called "nbm". During packaging, the module JAR is enhanced with NetBeans-specific manifest entries and, along with other required files, packed into a *.nbm file, ready for distribution. Additionally the plugin provides aggregator goals to create an update site or cluster for your module projects.

The newest version!
/*
 *  Copyright 2008 Johan Andrén.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */
package org.codehaus.mojo.nbm;

import static org.bitstrings.maven.nbm.utils.JarUtils.*;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.jar.Attributes;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.jar.JarFile;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.collections.CollectionUtils;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.apache.maven.shared.filtering.MavenResourcesExecution;
import org.apache.maven.shared.filtering.MavenResourcesFiltering;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.GenerateKey;
import org.apache.tools.ant.taskdefs.Jar;
import org.apache.tools.ant.taskdefs.Jar.FilesetManifestConfig;
import org.apache.tools.ant.taskdefs.Property;
import org.apache.tools.ant.taskdefs.SignJar;
import org.apache.tools.ant.taskdefs.Taskdef;
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Parameter;
import org.apache.tools.ant.types.ZipFileSet;
import org.apache.tools.ant.types.selectors.AndSelector;
import org.apache.tools.ant.types.selectors.FilenameSelector;
import org.apache.tools.ant.types.selectors.OrSelector;
import org.bitstrings.maven.nbm.utils.JnlpUtils;
import org.codehaus.mojo.nbm.JarsConfig.ManifestEntries;
import org.codehaus.plexus.archiver.manager.ArchiverManager;
import org.codehaus.plexus.archiver.zip.ZipArchiver;
import org.codehaus.plexus.components.io.resources.PlexusIoResource;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.InterpolationFilterReader;
import org.netbeans.nbbuild.MakeJnlp2;
import org.netbeans.nbbuild.ModuleSelector;
import org.netbeans.nbbuild.VerifyJNLP;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.io.ByteSink;
import com.google.common.io.FileWriteMode;
import com.google.common.io.Files;

/**
 * Create webstartable binaries for a 'nbm-application'.
 * @author Johan Andrén
 * @author Milos Kleint
 * @author Pino Silvaggio
 * @since 3.0
 */
//
// +p
// this crap should be refactored
//
@Mojo(name="webstart-app", defaultPhase= LifecyclePhase.PACKAGE )
public class CreateWebstartAppMojo
    extends AbstractNbmMojo
{
    /**
     * The Maven project.
     */
    @org.apache.maven.plugins.annotations.Parameter(required=true, readonly=true, property="project")
    private MavenProject project;

    @Component
    protected MavenProjectHelper projectHelper;

    /**
     * The branding token for the application based on NetBeans platform.
     */
    @org.apache.maven.plugins.annotations.Parameter(required=true, property="netbeans.branding.token")
    protected String brandingToken;

    /**
     * output directory where the the NetBeans application will be created.
     */
    @org.apache.maven.plugins.annotations.Parameter(required=true, defaultValue="${project.build.directory}")
    private File outputDirectory;

    /**
     * Ready-to-deploy WAR containing application in JNLP packaging.
     *
     */
    @org.apache.maven.plugins.annotations.Parameter(required=true, defaultValue="${project.build.directory}/${project.artifactId}-${project.version}-jnlp.war")
    private File destinationFile;

    /**
     * Artifact Classifier to use for the webstart distributable zip file.
     * @since 3.1
     */
    @org.apache.maven.plugins.annotations.Parameter(defaultValue="webstart", property="nbm.webstart.classifier")
    private String webstartClassifier;

    /**
     * Codebase value within *.jnlp files.
     * Defining this parameter is generally a bad idea.
     */
    @org.apache.maven.plugins.annotations.Parameter(property="nbm.webstart.codebase")
    private String codebase;

    /**
     * A custom master JNLP file. If not defined, the
     * default one is used.
     * The following expressions can be used within the file and will
     * be replaced when generating content.
     * 
    *
  • ${jnlp.resources}
  • *
  • ${jnlp.codebase} - the 'codebase' parameter value is passed in.
  • *
  • ${app.name}
  • *
  • ${app.title}
  • *
  • ${app.vendor}
  • *
  • ${app.description}
  • *
  • ${branding.token} - the 'brandingToken' parameter value is passed in.
  • *
  • ${netbeans.jnlp.fixPolicy}
  • *
*/ @org.apache.maven.plugins.annotations.Parameter private File masterJnlpFile; /** * The basename (minus .jnlp extension) of the master JNLP file in the output. * This file will be the entry point for javaws. * Defaults to the branding token. * @since 3.5 */ @org.apache.maven.plugins.annotations.Parameter(property="master.jnlp.file.name") private String masterJnlpFileName; /** * keystore location for signing the nbm file */ @org.apache.maven.plugins.annotations.Parameter(property="keystore") private String keystore; /** * keystore password */ @org.apache.maven.plugins.annotations.Parameter(property="keystorepass") private String keystorepassword; /** * keystore alias */ @org.apache.maven.plugins.annotations.Parameter(property="keystorealias") private String keystorealias; /** * keystore type * @since 3.5 */ @org.apache.maven.plugins.annotations.Parameter(property="keystoretype") private String keystoretype; /** * If set true, build-jnlp target creates versioning info in jnlp descriptors and version.xml files. * This allows for incremental updates of Webstart applications, but requires download via * JnlpDownloadServlet * Defaults to false, which means versioning * info is not generated (see * http://java.sun.com/j2se/1.5.0/docs/guide/javaws/developersguide/downloadservletguide.html#resources). * */ @org.apache.maven.plugins.annotations.Parameter(defaultValue="false", property="nbm.webstart.versions") private boolean processJarVersions; // +p @org.apache.maven.plugins.annotations.Parameter( defaultValue="false", property="nbm.webstart.signWar" ) private boolean signWar; // +p @org.apache.maven.plugins.annotations.Parameter( defaultValue="false", property="nbm.webstart.generateJnlpApplicationTemplate" ) private boolean generateJnlpApplicationTemplate; /** * additional command line arguments. Eg. * -J-Xdebug -J-Xnoagent -J-Xrunjdwp:transport=dt_socket,suspend=n,server=n,address=8888 * can be used to debug the IDE. */ // +p @org.apache.maven.plugins.annotations.Parameter( property="netbeans.run.params" ) private String additionalArguments; // +p @org.apache.maven.plugins.annotations.Parameter( property="nbm.signing.threads", defaultValue="0" ) private int signingThreads; // +p @org.apache.maven.plugins.annotations.Parameter( property="nbm.signing.maximumthreads", defaultValue="0" ) private int signingMaximumThreads; // +p @org.apache.maven.plugins.annotations.Parameter( property="nbm.signing.force", defaultValue="true" ) private boolean signingForce; // +p @org.apache.maven.plugins.annotations.Parameter( property="nbm.signing.tsacert" ) private String signingTsaCert; // +p @org.apache.maven.plugins.annotations.Parameter( property="nbm.signing.tsaurl" ) private String signingTsaUrl; // +p @org.apache.maven.plugins.annotations.Parameter( property="nbm.signing.removeExistingSignatures", defaultValue="false") private boolean signingRemoveExistingSignatures; // +p @org.apache.maven.plugins.annotations.Parameter( property="nbm.signing.maxMemory" ) private String signingMaxMemory = "96m"; // +p @org.apache.maven.plugins.annotations.Parameter( property="nbm.signing.retryCount", defaultValue="5") private int signingRetryCount; @org.apache.maven.plugins.annotations.Parameter( property="encoding", defaultValue="${project.build.sourceEncoding}" ) private String encoding; @org.apache.maven.plugins.annotations.Parameter( property="session", readonly=true, required=true ) private MavenSession session; // +p @Component private MavenResourcesFiltering mavenResourcesFiltering; // +p @org.apache.maven.plugins.annotations.Parameter( defaultValue="true" ) private boolean autoManifestSecurityEntries = true; // +p @org.apache.maven.plugins.annotations.Parameter private List jarsConfigs; // +p @org.apache.maven.plugins.annotations.Parameter private List webappResources; // +p @org.apache.maven.plugins.annotations.Parameter private String applicationName; // +p @org.apache.maven.plugins.annotations.Parameter( defaultValue="false" ) private boolean pack200 = false; // +p @org.apache.maven.plugins.annotations.Parameter private Integer pack200Effort = null; // +p @org.apache.maven.plugins.annotations.Parameter( defaultValue="false" ) private boolean generateJnlpTimestamp; // +p @org.apache.maven.plugins.annotations.Parameter( defaultValue="true" ) private boolean verifyJnlp = true; @org.apache.maven.plugins.annotations.Parameter( defaultValue="true" ) private boolean validateJnlpDtd = true; @org.apache.maven.plugins.annotations.Parameter( defaultValue="*" ) private String includeLocales; // +p private String jarPermissions; private String jarCodebase; private String jnlpSecurity; // +p @org.apache.maven.plugins.annotations.Parameter( defaultValue="false" ) private boolean optimize; @Component protected ArchiverManager archiverManager; /** * * @throws org.apache.maven.plugin.MojoExecutionException * @throws org.apache.maven.plugin.MojoFailureException */ @Override public void execute() throws MojoExecutionException, MojoFailureException { if ( "none".equalsIgnoreCase( includeLocales ) ) { includeLocales = ""; } if ( signingThreads < 1 ) { signingThreads = Runtime.getRuntime().availableProcessors(); } if ( ( signingMaximumThreads > 0 ) && ( signingThreads > signingMaximumThreads ) ) { signingThreads = signingMaximumThreads; } getLog().info( "Using " + signingThreads + " signing threads." ); if ( !"nbm-application".equals( project.getPackaging() ) ) { throw new MojoExecutionException( "This goal only makes sense on project with nbm-application packaging." ); } final Project antProject = antProject(); getLog().warn( "WARNING: Unsigned and self-signed WebStart applications are deprecated from JDK7u21 onwards. To ensure future correct functionality please use trusted certificate."); if ( keystore != null && keystorealias != null && keystorepassword != null ) { File ks = new File( keystore ); if ( !ks.exists() ) { throw new MojoFailureException( "Cannot find keystore file at " + ks.getAbsolutePath() ); } else { //proceed.. } } else if ( keystore != null || keystorepassword != null || keystorealias != null ) { throw new MojoFailureException( "If you want to sign the jnlp application, you need to define all three keystore related parameters." ); } else { File generatedKeystore = new File( outputDirectory, "generated.keystore" ); if ( ! generatedKeystore.exists() ) { getLog().warn( "Keystore related parameters not set, generating a default keystore." ); GenerateKey genTask = (GenerateKey) antProject.createTask( "genkey" ); genTask.setAlias( "jnlp" ); genTask.setStorepass( "netbeans" ); genTask.setDname( "CN=" + System.getProperty( "user.name" ) ); genTask.setKeystore( generatedKeystore.getAbsolutePath() ); genTask.execute(); } keystore = generatedKeystore.getAbsolutePath(); keystorepassword = "netbeans"; keystorealias = "jnlp"; } Taskdef taskdef = (Taskdef) antProject.createTask( "taskdef" ); taskdef.setClassname( MakeJnlp2.class.getName() ); taskdef.setName( "makejnlp" ); taskdef.execute(); taskdef = (Taskdef) antProject.createTask( "taskdef" ); taskdef.setClassname( Jar.class.getName() ); taskdef.setName( "jar" ); taskdef.execute(); taskdef = (Taskdef) antProject.createTask( "taskdef" ); taskdef.setClassname( VerifyJNLP.class.getName() ); taskdef.setName( "verifyjnlp" ); taskdef.execute(); // +p try { final File webstartBuildDir = new File( outputDirectory + File.separator + "webstart" + File.separator + brandingToken ); if ( webstartBuildDir.exists() ) { FileUtils.deleteDirectory( webstartBuildDir ); } webstartBuildDir.mkdirs(); // P: copy webappResources --[ MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution( webappResources, webstartBuildDir, project, encoding, Collections.EMPTY_LIST, Collections.EMPTY_LIST, session ); mavenResourcesExecution.setEscapeWindowsPaths( true ); mavenResourcesFiltering.filterResources( mavenResourcesExecution ); // ]-- final String localCodebase = codebase != null ? codebase : webstartBuildDir.toURI().toString(); getLog().info( "Generating webstartable binaries at " + webstartBuildDir.getAbsolutePath() ); final File nbmBuildDirFile = new File( outputDirectory, brandingToken ); // +p (needs to be before make jnlp) //TODO is it really netbeans/ if ( masterJnlpFileName == null ) { masterJnlpFileName = brandingToken; } Properties props = new Properties(); props.setProperty( "jnlp.codebase", localCodebase ); props.setProperty( "app.name", brandingToken ); props.setProperty( "app.title", project.getName() ); if ( project.getOrganization() != null ) { props.setProperty( "app.vendor", project.getOrganization().getName() ); } else { props.setProperty( "app.vendor", "Nobody" ); } String description = project.getDescription() != null ? project.getDescription() : "No Project Description"; props.setProperty( "app.description", description ); props.setProperty( "branding.token", brandingToken ); props.setProperty( "master.jnlp.file.name", masterJnlpFileName ); props.setProperty( "netbeans.jnlp.fixPolicy", "false" ); StringBuilder stBuilder = new StringBuilder(); if ( additionalArguments != null ) { StringTokenizer st = new StringTokenizer( additionalArguments ); while ( st.hasMoreTokens() ) { String arg = st.nextToken(); if ( arg.startsWith( "-J" ) ) { if ( stBuilder.length() > 0 ) { stBuilder.append( ' ' ); } stBuilder.append( arg.substring( 2 ) ); } } } props.setProperty( "netbeans.run.params", stBuilder.toString() ); final File masterJnlp = new File( webstartBuildDir, masterJnlpFileName + ".jnlp" ); filterCopy( masterJnlpFile, "master.jnlp", masterJnlp, props ); if ( generateJnlpTimestamp ) // \/\/\/\/ bad bad bad \/\/\/\/ { final File masterJnlpFileTmp = File.createTempFile( masterJnlpFileName + "_", "" ); Files.append( JnlpUtils.getCurrentJnlpTimestamp() + "\n", masterJnlpFileTmp, Charset.forName( "UTF-8" ) ); ByteSink sink = Files.asByteSink( masterJnlpFileTmp, FileWriteMode.APPEND ); sink.write( Files.toByteArray(masterJnlp) ); Files.copy( masterJnlpFileTmp, masterJnlp ); } File startup = copyLauncher( outputDirectory, nbmBuildDirFile ); String masterJnlpStr = FileUtils.fileRead( masterJnlp ); // P: JNLP-INF/APPLICATION_TEMPLATE.JNLP support --[ // this can be done better and will // ashamed if ( generateJnlpApplicationTemplate ) { File jnlpInfDir = new File( outputDirectory, "JNLP-INF" ); getLog().info( "Generate JNLP application template under: " + jnlpInfDir ); jnlpInfDir.mkdirs(); File jnlpTemplate = new File( jnlpInfDir, "APPLICATION_TEMPLATE.JNLP" ); masterJnlpStr = masterJnlpStr .replaceAll( "("; } startupManifestEntries.setPermissions( jarPermissions ); if ( applicationName == null ) { String jnlpApplicationTitle = (String) xpath.evaluate( "/jnlp/information/title", doc, XPathConstants.STRING ); applicationName = jnlpApplicationTitle == null ? brandingToken : jnlpApplicationTitle; } startupManifestEntries.setApplicationName( applicationName ); // +p if ( autoManifestSecurityEntries ) { if ( jarsConfigs == null ) { jarsConfigs = new ArrayList(); } jarsConfigs.add( 0, startupConfig ); } final List signJarJarsConfigs = buildSignJarJarsConfigs( jarsConfigs ); File jnlpDestination = new File( webstartBuildDir.getAbsolutePath() + File.separator + "startup.jar" ); SignJar signTask = (SignJar) antProject.createTask( "signjar" ); signTask.setKeystore( keystore ); signTask.setStorepass( keystorepassword ); signTask.setAlias( keystorealias ); if ( keystoretype != null ) { signTask.setStoretype( keystoretype ); } signTask.setForce( signingForce ); signTask.setTsacert( signingTsaCert ); signTask.setTsaurl( signingTsaUrl ); signTask.setMaxmemory( signingMaxMemory ); signTask.setRetryCount( signingRetryCount ); signTask.setUnsignFirst( signingRemoveExistingSignatures ); signTask.setJarsConfigs( buildSignJarJarsConfigs( Collections.singletonList( startupConfig ) ) ); signTask.setBasedir( nbmBuildDirFile ); signTask.setSignedjar( jnlpDestination ); signTask.setJar( startup ); signTask.setPack200( pack200 ); signTask.setPack200Effort( pack200Effort ); signTask.execute(); // <-- all of this will be refactored soon ]-- // FileUtils.copyDirectoryStructureIfModified( nbmBuildDirFile, webstartBuildDir ); MakeJnlp2 jnlpTask = (MakeJnlp2) antProject.createTask( "makejnlp" ); jnlpTask.setOptimize(optimize); jnlpTask.setIncludelocales(includeLocales); jnlpTask.setDir( webstartBuildDir ); jnlpTask.setCodebase( localCodebase ); //TODO, how to figure verify excludes.. jnlpTask.setVerify( false ); jnlpTask.setPermissions( jnlpSecurity ); jnlpTask.setSignJars( true ); jnlpTask.setAlias( keystorealias ); jnlpTask.setKeystore( keystore ); jnlpTask.setStorePass( keystorepassword ); if ( keystoretype != null ) { jnlpTask.setStoreType( keystoretype ); } jnlpTask.setSigningForce( signingForce ); jnlpTask.setSigningTsaCert( signingTsaCert ); jnlpTask.setSigningTsaUrl( signingTsaUrl ); jnlpTask.setUnsignFirst( signingRemoveExistingSignatures ); jnlpTask.setJarsConfigs( signJarJarsConfigs ); jnlpTask.setSigningMaxMemory( signingMaxMemory ); jnlpTask.setSigningRetryCount( signingRetryCount ); jnlpTask.setBasedir( nbmBuildDirFile ); jnlpTask.setNbThreads( signingThreads ); jnlpTask.setProcessJarVersions( processJarVersions ); jnlpTask.setPack200( pack200 ); jnlpTask.setPack200Effort( pack200Effort ); FileSet fs = jnlpTask.createModules(); fs.setDir( nbmBuildDirFile ); OrSelector or = new OrSelector(); AndSelector and = new AndSelector(); FilenameSelector inc = new FilenameSelector(); inc.setName( "*/modules/**/*.jar" ); or.addFilename( inc ); inc = new FilenameSelector(); inc.setName( "*/lib/**/*.jar" ); or.addFilename( inc ); inc = new FilenameSelector(); inc.setName( "*/core/**/*.jar" ); or.addFilename( inc ); ModuleSelector ms = new ModuleSelector(); Parameter included = new Parameter(); included.setName( "includeClusters" ); included.setValue( "" ); Parameter excluded = new Parameter(); excluded.setName( "excludeClusters" ); excluded.setValue( "" ); Parameter exModules = new Parameter(); exModules.setName( "excludeModules" ); exModules.setValue( "" ); ms.setParameters( new Parameter[] { included, excluded, exModules } ); and.add( or ); and.add( ms ); fs.addAnd( and ); jnlpTask.execute(); Set locales = jnlpTask.getExecutedLocales(); String extSnippet = generateExtensions( fs, antProject, "" ); // "netbeans/" //branding DirectoryScanner ds = new DirectoryScanner(); ds.setBasedir( nbmBuildDirFile ); final List localeIncludes = new ArrayList(); final List localeExcludes = new ArrayList(); localeIncludes.add( "**/locale/*.jar" ); if ( includeLocales != null ) { List excludes = Lists.newArrayList( Splitter.on(',').trimResults().omitEmptyStrings().split(includeLocales) ); for ( String exclude : (Collection) CollectionUtils.subtract( locales, excludes ) ) { localeExcludes.add( "**/locale/*_" + exclude + ".jar" ); } } ds.setIncludes( localeIncludes.toArray( new String[localeIncludes.size()] ) ); ds.setExcludes( localeExcludes.toArray( new String[localeExcludes.size()] ) ); ds.scan(); String[] includes = ds.getIncludedFiles(); StringBuilder brandRefs = new StringBuilder( "\n" ); if ( includes != null && includes.length > 0 ) { final File brandingDir = new File( webstartBuildDir, "branding" ); brandingDir.mkdirs(); for ( String incBran : includes ) { File source = new File( nbmBuildDirFile, incBran ); File dest = new File( brandingDir, source.getName() ); brandRefs.append( " \n" ); } final ExecutorService executorService = Executors.newFixedThreadPool( signingThreads ); final List threadException = new ArrayList(); for (final String toSign : includes) { executorService.execute( new Runnable() { @Override public void run() { try { File toSignFile = new File( nbmBuildDirFile, toSign ); SignJar signTask = (SignJar) antProject.createTask( "signjar" ); if ( keystoretype != null ) { signTask.setStoretype( keystoretype ); } signTask.setKeystore( keystore ); signTask.setStorepass( keystorepassword ); signTask.setAlias( keystorealias ); signTask.setForce( signingForce ); signTask.setTsacert( signingTsaCert ); signTask.setTsaurl( signingTsaUrl ); signTask.setMaxmemory( signingMaxMemory ); signTask.setRetryCount( signingRetryCount ); signTask.setUnsignFirst( signingRemoveExistingSignatures ); signTask.setJarsConfigs( signJarJarsConfigs ); signTask.setJar( toSignFile ); signTask.setDestDir( brandingDir ); signTask.setBasedir( nbmBuildDirFile ); signTask.setDestFlatten( true ); signTask.setPack200( pack200 ); signTask.setPack200Effort( pack200Effort ); signTask.execute(); } catch ( Exception e ) { threadException.add( e ); } } } ); } executorService.shutdown(); executorService.awaitTermination( Long.MAX_VALUE, TimeUnit.NANOSECONDS ); if ( !threadException.isEmpty() ) { throw threadException.get( 0 ); } } File modulesJnlp = new File( webstartBuildDir.getAbsolutePath() + File.separator + "modules.jnlp" ); props.setProperty( "jnlp.branding.jars", brandRefs.toString() ); props.setProperty( "jnlp.resources", extSnippet ); filterCopy( null, /* filename is historical */"branding.jnlp", modulesJnlp, props ); if ( verifyJnlp ) { getLog().info( "Verifying generated webstartable content." ); VerifyJNLP verifyTask = ( VerifyJNLP ) antProject.createTask( "verifyjnlp" ); FileSet verify = new FileSet(); verify.setFile( masterJnlp ); verifyTask.addConfiguredFileset( verify ); verifyTask.execute(); } // create zip archive if ( destinationFile.exists() ) { destinationFile.delete(); } ZipArchiver archiver = new ZipArchiver(); if ( codebase != null ) { getLog().warn( "Defining /${nbm.webstart.codebase} is generally unnecessary" ); archiver.addDirectory( webstartBuildDir ); } else { archiver.addDirectory( webstartBuildDir, null, new String[] { "**/*.jnlp" } ); for ( final File jnlp : webstartBuildDir.listFiles() ) { if ( !jnlp.getName().endsWith( ".jnlp" ) ) { continue; } archiver.addResource( new PlexusIoResource() { public @Override InputStream getContents() throws IOException { return new ByteArrayInputStream( FileUtils.fileRead( jnlp, "UTF-8" ).replace( localCodebase, "$$codebase" ).getBytes( "UTF-8" ) ); } public @Override long getLastModified() { return jnlp.lastModified(); } public @Override boolean isExisting() { return true; } public @Override long getSize() { return UNKNOWN_RESOURCE_SIZE; } public @Override URL getURL() throws IOException { return null; } public @Override String getName() { return jnlp.getAbsolutePath(); } public @Override boolean isFile() { return true; } public @Override boolean isDirectory() { return false; } @Override public boolean isSymbolicLink() { return false; } }, jnlp.getName(), archiver.getDefaultFileMode() ); } } File jdkhome = new File( System.getProperty( "java.home" ) ); File servlet = new File( jdkhome, "sample/jnlp/servlet/jnlp-servlet.jar" ); if ( ! servlet.exists() ) { servlet = new File( jdkhome.getParentFile(), "sample/jnlp/servlet/jnlp-servlet.jar" ); if ( !servlet.exists() ) { servlet = File.createTempFile( "nbm_", "jnlp-servlet.jar" ); FileUtils.copyURLToFile( Thread.currentThread().getContextClassLoader() .getResource( "jnlp-servlet.jar" ), servlet ); } } if ( servlet.exists() ) { File servletDir = new File( webstartBuildDir, "WEB-INF/lib" ); servletDir.mkdirs(); signTask = (SignJar) antProject.createTask( "signjar" ); signTask.setKeystore( keystore ); signTask.setStorepass( keystorepassword ); signTask.setAlias( keystorealias ); signTask.setForce( signingForce ); signTask.setTsacert( signingTsaCert ); signTask.setTsaurl( signingTsaUrl ); signTask.setMaxmemory( signingMaxMemory ); signTask.setRetryCount( signingRetryCount ); signTask.setJar( servlet ); signTask.setSignedjar( new File( servletDir, "jnlp-servlet.jar" ) ); signTask.execute(); //archiver.addFile( servlet, "WEB-INF/lib/jnlp-servlet.jar" ); archiver.addResource( new PlexusIoResource() { public @Override InputStream getContents() throws IOException { return new ByteArrayInputStream( ( "" + "\n" + " \n" + " JnlpDownloadServlet\n" + " jnlp.sample.servlet.JnlpDownloadServlet\n" + " \n" + " \n" + " JnlpDownloadServlet\n" + " *.jnlp\n" + " \n" + " \n" + " JnlpDownloadServlet\n" + " *.jar\n" + " \n" + " \n" + " jnlp\n" + " application/x-java-jnlp-file\n" + " \n" + "\n" ).getBytes() ); } public @Override long getLastModified() { return UNKNOWN_MODIFICATION_DATE; } public @Override boolean isExisting() { return true; } public @Override long getSize() { return UNKNOWN_RESOURCE_SIZE; } public @Override URL getURL() throws IOException { return null; } public @Override String getName() { return "web.xml"; } public @Override boolean isFile() { return true; } public @Override boolean isDirectory() { return false; } @Override public boolean isSymbolicLink() { return false; } }, "WEB-INF/web.xml", archiver.getDefaultFileMode() ); } archiver.setDestFile( destinationFile ); archiver.createArchive(); if (signWar) { signTask = (SignJar) antProject.createTask( "signjar" ); signTask.setKeystore( keystore ); signTask.setStorepass( keystorepassword ); signTask.setAlias( keystorealias ); signTask.setForce( signingForce ); signTask.setTsacert( signingTsaCert ); signTask.setTsaurl( signingTsaUrl ); signTask.setMaxmemory( signingMaxMemory ); signTask.setRetryCount( signingRetryCount ); signTask.setJar( destinationFile ); signTask.execute(); } // attach standalone so that it gets installed/deployed projectHelper.attachArtifact( project, "war", webstartClassifier, destinationFile ); } catch ( Exception ex ) { throw new MojoExecutionException( "Error creating webstartable binary.", ex ); } } /** * @param standaloneBuildDir * @return The name of the jnlp-launcher jarfile in the build directory */ private File copyLauncher( File standaloneBuildDir, File builtInstallation ) throws IOException { File jnlpStarter = new File( builtInstallation.getAbsolutePath() + File.separator + "harness" + File.separator + "jnlp" + File.separator + "jnlp-launcher.jar" ); // buffer so it isn't reading a byte at a time! InputStream source = null; FileOutputStream outstream = null; try { if ( !jnlpStarter.exists() ) { source = getClass().getClassLoader().getResourceAsStream( "harness/jnlp/jnlp-launcher.jar" ); } else { source = new FileInputStream( jnlpStarter ); } File jnlpDestination = new File( standaloneBuildDir.getAbsolutePath() + File.separator + "jnlp-launcher.jar" ); outstream = new FileOutputStream( jnlpDestination ); IOUtil.copy( source, outstream ); return jnlpDestination; } finally { IOUtil.close( source ); IOUtil.close( outstream ); } } private void filterCopy( File sourceFile, String resourcePath, File destinationFile, Properties filterProperties ) throws IOException { // buffer so it isn't reading a byte at a time! Reader source = null; Writer destination = null; try { InputStream instream; if ( sourceFile != null ) { instream = new FileInputStream( sourceFile ); } else { instream = getClass().getClassLoader().getResourceAsStream( resourcePath ); } FileOutputStream outstream = new FileOutputStream( destinationFile ); source = new BufferedReader( new InputStreamReader( instream, "UTF-8" ) ); destination = new OutputStreamWriter( outstream, "UTF-8" ); // support ${token} Reader reader = new InterpolationFilterReader( source, filterProperties, "${", "}" ); IOUtil.copy( reader, destination ); } finally { IOUtil.close( source ); IOUtil.close( destination ); } } /** * copied from MakeMasterJNLP ant task. * @param files * @param antProject * @param masterPrefix * @return * @throws java.io.IOException */ private String generateExtensions( FileSet files, Project antProject, String masterPrefix ) throws IOException { StringBuilder buff = new StringBuilder(); for ( String nm : files.getDirectoryScanner( antProject ).getIncludedFiles() ) { File jar = new File( files.getDir( antProject ), nm ); if ( !jar.canRead() ) { throw new IOException( "Cannot read file: " + jar ); } try ( JarFile theJar = new JarFile( jar ) ) { Attributes attr = theJar.getManifest().getMainAttributes(); String codenamebase = attr.getValue( "OpenIDE-Module" ); if ( codenamebase == null ) { codenamebase = attr.getValue("Bundle-SymbolicName"); } if ( codenamebase == null ) { throw new IOException( "Not a NetBeans Module: " + jar ); } // see http://hg.netbeans.org/main-silver/rev/87823abb86d9 if (codenamebase.equals("org.objectweb.asm.all") && jar.getParentFile().getName().equals("core") && jar.getParentFile().getParentFile().getName().startsWith("platform")) { continue; } { int slash = codenamebase.indexOf( '/' ); if ( slash >= 0 ) { codenamebase = codenamebase.substring( 0, slash ); } } String dashcnb = codenamebase.replace( '.', '-' ); buff.append( " \n" ); } } return buff.toString(); } private List buildSignJarJarsConfigs( List jarsConfigs ) { List signJarJarsConfigs = new ArrayList(); if ( jarsConfigs != null ) { for ( JarsConfig jarsConfig : jarsConfigs ) { SignJar.JarsConfig signJarJarsConfig = new SignJar.JarsConfig(); if ( jarsConfig.getJarSet() != null ) { signJarJarsConfig.setIncludes( Joiner.on(',').join( jarsConfig.getJarSet().getIncludes() ) ); signJarJarsConfig.setExcludes( Joiner.on(',').join( jarsConfig.getJarSet().getExcludes() ) ); } signJarJarsConfig.setUnsignFirst( jarsConfig.getRemoveExistingSignatures() ); List signJarManifestAttributes = new ArrayList(); JarsConfig.ManifestEntries manifestEntries = jarsConfig.getManifestEntries(); if ( manifestEntries != null ) { if ( manifestEntries.getTrustedOnly() != null ) { signJarManifestAttributes .add( createAntProperty( MANIFEST_ATTR_TRUSTED_ONLY, manifestEntries.getTrustedOnly().toString() ) ); } if ( manifestEntries.getTrustedLibrary() != null ) { signJarManifestAttributes .add( createAntProperty( MANIFEST_ATTR_TRUSTED_LIBRARY, manifestEntries.getTrustedLibrary().toString() ) ); } if ( manifestEntries.getPermissions() != null ) { signJarManifestAttributes .add( createAntProperty( MANIFEST_ATTR_PERMISSIONS, manifestEntries.getPermissions() ) ); } if ( manifestEntries.getCodebase() != null ) { signJarManifestAttributes .add( createAntProperty( MANIFEST_ATTR_CODEBASE, manifestEntries.getCodebase() ) ); } if ( manifestEntries.getApplicationName() != null ) { signJarManifestAttributes .add( createAntProperty( MANIFEST_ATTR_APPLICATION_NAME, manifestEntries.getApplicationName() ) ); } if ( manifestEntries.getApplicationLibraryAllowableCodebase() != null ) { signJarManifestAttributes .add( createAntProperty( MANIFEST_ATTR_APPLICATION_LIBRARY_ALLOWABLE_CODEBASE, manifestEntries.getApplicationLibraryAllowableCodebase() ) ); } if ( manifestEntries.getCallerAllowableCodebase() != null ) { signJarManifestAttributes .add( createAntProperty( MANIFEST_ATTR_CALLER_ALLOWABLE_CODEBASE, manifestEntries.getCallerAllowableCodebase() ) ); } Map jarsConfigManifestAttributes = manifestEntries.getExtraAttributes(); if ( jarsConfigManifestAttributes != null ) { for ( Map.Entry entry : jarsConfigManifestAttributes.entrySet() ) { signJarManifestAttributes.add( createAntProperty( entry.getKey(), entry.getValue() ) ); } } List jarsConfigRemoveAttributes = manifestEntries.getRemoveAttributes(); if ( jarsConfigRemoveAttributes == null ) { manifestEntries.setRemoveAttributes( jarsConfigRemoveAttributes = new ArrayList() ); } if ( ( manifestEntries.getRemoveClassPath() == null ) || manifestEntries.getRemoveClassPath().equals( true ) ) { jarsConfigRemoveAttributes.add( MANIFEST_ATTR_CLASS_PATH ); } signJarJarsConfig.setRemoveAttributes(jarsConfigRemoveAttributes); } if ( autoManifestSecurityEntries ) { if ( manifestEntries == null ) { manifestEntries = new ManifestEntries(); } if ( manifestEntries.getPermissions() == null ) { signJarManifestAttributes .add( createAntProperty( MANIFEST_ATTR_PERMISSIONS, jarPermissions ) ); } if ( manifestEntries.getCodebase() == null ) { signJarManifestAttributes .add( createAntProperty( MANIFEST_ATTR_CODEBASE, jarCodebase ) ); } if ( manifestEntries.getApplicationName() == null ) { signJarManifestAttributes .add( createAntProperty( MANIFEST_ATTR_APPLICATION_NAME, applicationName ) ); } if ( manifestEntries.getTrustedLibrary() == null ) { signJarManifestAttributes .add( createAntProperty( MANIFEST_ATTR_TRUSTED_LIBRARY, "true" ) ); } } signJarJarsConfig.setExtraManifestAttributes( signJarManifestAttributes ); signJarJarsConfigs.add( signJarJarsConfig ); } } return signJarJarsConfigs; } private Property createAntProperty( String name, String value ) { Property property = new Property(); property.setProject( antProject() ); property.setName( name ); property.setValue( value ); property.execute(); return property; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy