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

org.codehaus.mojo.nbm.BuildInstallersMojo 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.

There is a newer version: 4.1
Show newest version
/*
 * Copyright 2012 Frantisek Mantlik .
 *
 * 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 java.io.*;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
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.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
import org.apache.tools.ant.util.StringUtils;

/**
 * Build installers for Mavenized NetBeans application.
 * Creates installers for supported operating systems
 * and packages each installer as a deployable artifact.
 * 

See a how-to on customizing the installer. * @author Frantisek Mantlik */ @Mojo(name="build-installers", requiresProject=true, requiresDependencyResolution=ResolutionScope.RUNTIME, defaultPhase=LifecyclePhase.PACKAGE ) public class BuildInstallersMojo extends AbstractNbmMojo { /** * output directory. */ @Parameter(defaultValue="${project.build.directory}", required=true) protected File outputDirectory; /** * The branding token for the application based on NetBeans platform. */ @Parameter(property="netbeans.branding.token", required=true) protected String brandingToken; /** * Installation directory name at the destination system */ @Parameter(property="netbeans.branding.token") protected String installDirName; /** * Prefix of all generated installers files */ @Parameter(defaultValue="${project.build.finalName}") private String installersFilePrefix; /** * Create installer for Windows */ @Parameter(defaultValue="true") private boolean installerOsWindows; /** * Create installer for Solaris */ @Parameter(defaultValue="true") private boolean installerOsSolaris; /** * Create installer for Linux */ @Parameter(defaultValue="true") private boolean installerOsLinux; /** * Create installer for MacOSx */ @Parameter(defaultValue="true") private boolean installerOsMacosx; /** * Enable Pack200 compression */ @Parameter(defaultValue="true") private boolean installerPack200Enable; /** * License file */ @Parameter(defaultValue="${basedir}/license.txt") private File installerLicenseFile; /** * Custom installer template. * This file, if provided, will replace default template from * <NetBeansInstallation>/harness/nbi/stub/template.xml */ @Parameter private File templateFile; /** * Parameters passed to templateFile * or to installer/nbi/stub/template.xml * to customize generated installers. * */ @Parameter private Map userSettings; /** * Name of the zip artifact used to produce installers from (without .zip extension) */ @Parameter(defaultValue="${project.build.finalName}") private String finalName; // /** * Used for attaching the artifact in the project */ @Component private MavenProjectHelper projectHelper; @Parameter(readonly=true, required=true, property="basedir") private File basedir; /** * The Maven Project. */ @Parameter(required=true, readonly=true, property="project") private MavenProject project; // @Override public void execute() throws MojoExecutionException, MojoFailureException { Project antProject = antProject(); if ( !"nbm-application".equals( project.getPackaging() ) ) { throw new MojoExecutionException( "This goal only makes sense on project with 'nbm-application' packaging." ); } String zipName = finalName + ".zip"; File zipFile = new File( outputDirectory, zipName ); getLog().info( String.format( "Running Build Installers action for (existing=%2$s) zip file %1$s", zipFile, zipFile.exists() ) ); File appIconIcnsFile; // Copy Netbeans Installer resources FileUrlUtils fu = new FileUrlUtils(); File harnessDir = new File( outputDirectory, "installer" ); fu.copyResourcesRecursively( getClass().getClassLoader().getResource( "harness" ), harnessDir ); // Overwrite template file with modified version to accept branded images etc. if ( templateFile != null ) { File template = new File( harnessDir, "nbi/stub/template.xml" ); fu.copyFile( templateFile, template ); } appIconIcnsFile = new File( harnessDir, "etc" + File.separatorChar + "applicationIcon.icns" ); getLog().info( "Application icon:" + appIconIcnsFile.getAbsolutePath() ); Map props = new HashMap (); props.put( "suite.location", basedir.getAbsolutePath().replace( "\\", "/" ) ); props.put( "suite.props.app.name", brandingToken); props.put( "suite.dist.zip", zipFile.getAbsolutePath().replace( "\\", "/" ) ); props.put( "suite.dist.directory", outputDirectory.getAbsolutePath().replace( "\\", "/" ) ); props.put( "installer.build.dir", new File( outputDirectory, "installerbuild" ).getAbsolutePath().replace( "\\", "/" ) ); props.put( "installers.file.prefix", installersFilePrefix ); props.put( "install.dir.name", installDirName ); //mkleint: this is a flawed pattern! cannot make any assumption on multimodule layout String appName = project.getParent().getArtifactId().replace( ".", "" ).replace( "-", "" ).replace( "_", "" ).replaceAll( "[0-9]+", "" ); props.put( "suite.nbi.product.uid", appName.toLowerCase( Locale.ENGLISH ) ); props.put( "suite.props.app.title", ( project.getName() + " " + project.getVersion() ).replaceAll( "-SNAPSHOT", "" ) ); String appVersion = project.getVersion().replaceAll( "-SNAPSHOT", "" ); props.put( "suite.nbi.product.version.short", appVersion ); while ( appVersion.split( "\\." ).length < 5 ) { appVersion += ".0"; } props.put( "suite.nbi.product.version", appVersion ); props.put( "nbi.stub.location", new File( harnessDir, "nbi/stub" ).getAbsolutePath().replace( "\\", "/" ) ); props.put( "nbi.stub.common.location", new File( harnessDir, "nbi/.common" ).getAbsolutePath().replace( "\\", "/" ) ); props.put( "nbi.ant.tasks.jar", new File( harnessDir, "modules/ext/nbi-ant-tasks.jar" ).getAbsolutePath().replace( "\\", "/" ) ); props.put( "nbi.registries.management.jar", new File( harnessDir, "modules/ext/nbi-registries-management.jar" ).getAbsolutePath().replace( "\\", "/" ) ); props.put( "nbi.engine.jar", new File( harnessDir, "modules/ext/nbi-engine.jar" ).getAbsolutePath().replace( "\\", "/" ) ); if ( installerLicenseFile != null ) { getLog().info( String.format( "License file is at %1s, exist = %2$s", installerLicenseFile, installerLicenseFile.exists() ) ); props.put( "nbi.license.file", installerLicenseFile.getAbsolutePath() ); //mkleint: no path replacement here?? } List platforms = new ArrayList(); if ( this.installerOsLinux ) { platforms.add( "linux" ); File linuxFile = new File( outputDirectory, installersFilePrefix + "-linux.sh" ); projectHelper.attachArtifact( project, "sh", "linux", linuxFile ); } if ( this.installerOsSolaris ) { platforms.add( "solaris" ); File solarisFile = new File( outputDirectory, installersFilePrefix + "-solaris.sh" ); projectHelper.attachArtifact( project, "sh", "solaris", solarisFile ); } if ( this.installerOsWindows ) { platforms.add( "windows" ); File windowsFile = new File( outputDirectory, installersFilePrefix + "-windows.exe" ); projectHelper.attachArtifact( project, "exe", "windows", windowsFile ); } if ( this.installerOsMacosx ) { platforms.add( "macosx" ); File macosxFile = new File( outputDirectory, installersFilePrefix + "-macosx.tgz" ); projectHelper.attachArtifact( project, "tgz", "macosx", macosxFile ); } StringBuilder sb = new StringBuilder(); for ( int i = 0; i < platforms.size(); i++ ) { if ( i != 0 ) { sb.append( " " ); } sb.append( platforms.get( i ) ); } if ( sb.length() == 0 ) { //nothing to build getLog().warn( "Nothing to build." ); } props.put( "generate.installer.for.platforms", sb.toString() ); File javaHome = new File( System.getProperty( "java.home" ) ); if ( new File( javaHome, "lib/rt.jar" ).exists() && javaHome.getName().equals( "jre" ) ) //mkleint: does this work on mac? no rt.jar there { javaHome = javaHome.getParentFile(); } props.put( "generator-jdk-location-forward-slashes", javaHome.getAbsolutePath().replace( "\\", "/" ) ); props.put( "pack200.enabled", "" + installerPack200Enable ); if ( appIconIcnsFile != null ) { props.put( "nbi.dock.icon.file", appIconIcnsFile.getAbsolutePath() ); } try { antProject.setUserProperty( "ant.file", new File( harnessDir, "nbi/stub/template.xml" ).getAbsolutePath().replace( "\\", "/" ) ); ProjectHelper helper = ProjectHelper.getProjectHelper(); antProject.addReference( "ant.projectHelper", helper ); helper.parse( antProject, new File( harnessDir, "nbi/stub/template.xml" ) ); for ( Map.Entry e : props.entrySet() ) { antProject.setProperty( e.getKey(), e.getValue() ); } if ( userSettings != null ) { for ( Map.Entry e : userSettings.entrySet() ) { antProject.setProperty( e.getKey(), e.getValue() ); } } antProject.executeTarget( "build" ); } catch ( Exception ex ) { throw new MojoExecutionException( "Installers creation failed: " + ex, ex ); } } //mkleint: could this be replaced by something from plexus-utils? private class FileUrlUtils { boolean copyFile( final File toCopy, final File destFile ) throws MojoExecutionException { try { return copyStream( new FileInputStream( toCopy ), new FileOutputStream( destFile ) ); } catch ( final FileNotFoundException e ) { throw new MojoExecutionException( "Installers creation failed: " + e, e ); } } boolean copyFilesRecusively( final File toCopy, final File destDir ) throws MojoExecutionException { assert destDir.isDirectory(); if ( !toCopy.isDirectory() ) { return copyFile( toCopy, new File( destDir, toCopy.getName() ) ); } else { final File newDestDir = new File( destDir, toCopy.getName() ); if ( !newDestDir.exists() && !newDestDir.mkdir() ) { return false; } for ( final File child : toCopy.listFiles() ) { if ( !copyFilesRecusively( child, newDestDir ) ) { return false; } } } return true; } boolean copyJarResourcesRecursively( final File destDir, final JarURLConnection jarConnection ) throws IOException, MojoExecutionException { final JarFile jarFile = jarConnection.getJarFile(); for ( final Enumeration e = jarFile.entries(); e.hasMoreElements(); ) { final JarEntry entry = e.nextElement(); if ( entry.getName().startsWith( jarConnection.getEntryName() ) ) { final String filename = StringUtils.removePrefix( entry.getName(), // jarConnection.getEntryName() ); final File f = new File( destDir, filename ); if ( !entry.isDirectory() ) { final InputStream entryInputStream = jarFile.getInputStream( entry ); if ( !copyStream( entryInputStream, f ) ) { return false; } entryInputStream.close(); } else { if ( !ensureDirectoryExists( f ) ) { throw new IOException( "Could not create directory: " + f.getAbsolutePath() ); } } } } return true; } boolean copyResourcesRecursively( final URL originUrl, final File destination ) throws MojoExecutionException { try { final URLConnection urlConnection = originUrl.openConnection(); if ( urlConnection instanceof JarURLConnection ) { return copyJarResourcesRecursively( destination, (JarURLConnection) urlConnection ); } else { return copyFilesRecusively( new File( originUrl.getPath() ), destination ); } } catch ( final IOException e ) { throw new MojoExecutionException( "Installers creation failed: " + e, e ); } } boolean copyStream( final InputStream is, final File f ) throws MojoExecutionException { try { return copyStream( is, new FileOutputStream( f ) ); } catch ( final FileNotFoundException e ) { throw new MojoExecutionException( "Installers creation failed: " + e, e ); } } boolean copyStream( final InputStream is, final OutputStream os ) throws MojoExecutionException { try { final byte[] buf = new byte[1024]; int len; while ( ( len = is.read( buf ) ) > 0 ) { os.write( buf, 0, len ); } is.close(); os.close(); return true; } catch ( final IOException e ) { throw new MojoExecutionException( "Installers creation failed: " + e, e ); } } boolean ensureDirectoryExists( final File f ) { return f.exists() || f.mkdir(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy