blob: fbc0e5070b8f618e7bc1bdfe5ff4e6c9d4835b6e [file] [log] [blame]
package org.apache.netbeans.nbm;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.model.Developer;
import org.apache.maven.model.License;
import org.apache.maven.model.Organization;
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.MavenProjectHelper;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.util.FileUtils;
import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.context.Context;
import org.codehaus.plexus.context.ContextException;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
import org.netbeans.nbbuild.MakeNBM;
import org.netbeans.nbbuild.MakeNBM.Blurb;
import org.netbeans.nbbuild.MakeNBM.Signature;
/**
* Create the NetBeans module artifact (nbm file), part of "nbm" lifecycle/packaging.
*
*
* @author Milos Kleint
*/
@Mojo( name = "nbm",
requiresProject = true,
threadSafe = true,
requiresDependencyResolution = ResolutionScope.RUNTIME,
defaultPhase = LifecyclePhase.PACKAGE )
public class CreateNbmMojo
extends CreateNetBeansFileStructure
implements Contextualizable
{
/**
* keystore location for signing the nbm file
*/
@Parameter( property = "keystore" )
private String keystore;
/**
* keystore password
*/
@Parameter( property = "keystorepass" )
private String keystorepassword;
/**
* keystore alias
*/
@Parameter( property = "keystorealias" )
private String keystorealias;
/**
* Boolean parameter denoting if creation of NBM file shall be skipped or not.
* If skipped, just the expanded directory for cluster is created
* @since 3.0
*/
@Parameter( defaultValue = "false", property = "maven.nbm.skip" )
private boolean skipNbm;
/**
* if true, upon installing the NBM the platform app/IDE restart is requested. Not necessary in most cases.
* @since 3.8
*/
@Parameter( defaultValue = "false" )
private boolean requiresRestart;
/**
* Get homepage URL of the module. Is accessible from NetBeans
* UI upon installation, should point to place with additional
* information about the functionality.
* @since 3.8
*/
@Parameter( defaultValue = "${project.url}" )
private String homePageUrl;
/**
* Author of the module. Shown in the Module manager UI.
* @since 3.8
*/
@Parameter( defaultValue = "${project.organization.name}" )
private String author;
/**
* Distribution base URL for the NBM at runtime deployment time.
* Note: Usefulness of the parameter is questionable, it doesn't allow for mirrors and
* usually when downloading the nbm, one already knows the location anyway.
* Please note that the netbeans.org Ant scripts put a dummy url here.
* The actual correct value used when constructing update site is
* explicitly set there. The general assumption there is that all modules from one update
* center come from one base URL. Also see <code>distBase</code> parameter in auto-update mojo.
* <p/>
* The value is either a direct http protocol based URL that points to
* the location under which nbm file will be located, or
* <p/>
* it allows to create an update site based on maven repository content.
* The later created autoupdate site document can use this information and
* compose the application from one or multiple maven repositories.
* <br/>
* Format: id::layout::url same as in maven-deploy-plugin
* <br/>
* with the 'default' and 'legacy' layouts. (maven2 vs maven1 layout)
* <br/>
* If the value doesn't contain :: characters,
* it's assumed to be the flat structure and the value is just the URL.
*
*/
@Parameter( property = "maven.nbm.distributionURL" )
private String distributionUrl;
/**
* name of the license applicable to the NBM. The value should be equal across modules with the same license. If the user already agreed to the
* same license before, he/she won't be asked again to agree and for multiple one installed at the same time, just one license agreement is shown.
* When defined, <code>licenseFile</code> needs to be defined as well.
* @since 3.8
*/
@Parameter
private String licenseName;
/**
* path to the license agreement file that will be shown when installing the module. When defined, <code>licenseName</code> needs to be defined as well.
* @since 3.8
*/
@Parameter
private File licenseFile;
// <editor-fold defaultstate="collapsed" desc="Component parameters">
/**
* Contextualized.
*/
private PlexusContainer container;
@Component
private ArtifactFactory artifactFactory;
/**
* Used for attaching the artifact in the project
*/
@Component
private MavenProjectHelper projectHelper;
// end of component params custom code folding
// </editor-fold>
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat ( "yyyy/MM/dd" );
public void execute()
throws MojoExecutionException, MojoFailureException
{
if ( skipNbm )
{
getLog().info( "Skipping generation of NBM file." );
return;
}
if ( "pom".equals( project.getPackaging() ) )
{
getLog().info(
"Skipping " + project.getId() + ", no nbm:nbm execution for 'pom' packaging" );
return;
}
super.execute();
// 3. generate nbm
File nbmFile = new File( nbmBuildDir, finalName + ".nbm" );
MakeNBM nbmTask = (MakeNBM) antProject.createTask( "makenbm" );
nbmTask.setFile( nbmFile );
nbmTask.setProductDir( clusterDir );
nbmTask.setModule( "modules" + File.separator + moduleJarName + ".jar" );
boolean reqRestart = requiresRestart;
if ( !reqRestart && module.isRequiresRestart() )
{
reqRestart = module.isRequiresRestart();
getLog().warn( "Module descriptor's requiresRestart field is deprecated, use plugin's configuration in pom.xml" );
}
nbmTask.setNeedsrestart( Boolean.toString( reqRestart ) );
String moduleAuthor = author;
if ( module.getAuthor() != null )
{
moduleAuthor = module.getAuthor();
getLog().warn( "Module descriptor's requiresRestart field is deprecated, use plugin's configuration in pom.xml" );
}
nbmTask.setModuleauthor( moduleAuthor );
if ( keystore != null && keystorealias != null && keystorepassword != null )
{
File ks = new File( keystore );
if ( !ks.exists() )
{
getLog().warn( "Cannot find keystore file at " + ks.getAbsolutePath() );
}
else
{
Signature sig = nbmTask.createSignature();
sig.setKeystore( ks );
sig.setAlias( keystorealias );
sig.setStorepass( keystorepassword );
getLog().debug( "Setup the Ant task to sign the NBM file." );
}
}
else if ( keystore != null || keystorepassword != null || keystorealias != null )
{
getLog().warn(
"If you want to sign the nbm file, you need to define all three keystore related parameters." );
}
String licName = licenseName;
File licFile = licenseFile;
if ( module.getLicenseName() != null )
{
licName = module.getLicenseName();
getLog().warn( "Module descriptor's licenseName field is deprecated, use plugin's configuration in pom.xml" );
}
if ( module.getLicenseFile() != null )
{
File lf = new File( project.getBasedir(), module.getLicenseFile() );
licFile = lf;
getLog().warn( "Module descriptor's licenseFile field is deprecated, use plugin's configuration in pom.xml" );
}
if ( licName != null && licFile != null )
{
if ( !licFile.exists() || !licFile.isFile() )
{
getLog().warn( "Cannot find license file at " + licFile.getAbsolutePath() );
}
else
{
Blurb lb = nbmTask.createLicense();
lb.setFile( licFile );
lb.addText( licName );
}
}
else if ( licName != null || licFile != null )
{
getLog().warn(
"To set license for the nbm, you need to specify both licenseName and licenseFile parameters." );
}
else
{
Blurb lb = nbmTask.createLicense();
lb.addText( createDefaultLicenseHeader() );
lb.addText( createDefaultLicenseText() );
}
String hpUrl = homePageUrl;
if ( module.getHomepageUrl() != null )
{
getLog().warn( "Module descriptor's homePageUrl field is deprecated, use plugin's configuration in pom.xml" );
hpUrl = module.getHomepageUrl();
}
if ( hpUrl != null )
{
nbmTask.setHomepage( hpUrl );
}
String distribUrl = distributionUrl;
if ( module.getDistributionUrl() != null )
{
distribUrl = module.getDistributionUrl();
getLog().warn( "Module descriptor's distributionUrl field is deprecated, use plugin's configuration in pom.xml" );
}
if ( distribUrl != null )
{
ArtifactRepository distRepository = CreateUpdateSiteMojo.getDeploymentRepository(
distribUrl, container, getLog() );
String dist = null;
if ( distRepository == null )
{
if ( !distribUrl.contains( "::" ) )
{
dist =
distribUrl + ( distribUrl.endsWith( "/" ) ? "" : "/" )
+ nbmFile.getName();
}
}
else
{
Artifact art = artifactFactory.createArtifact(
project.getGroupId(), project.getArtifactId(),
project.getVersion(), null, "nbm-file" );
dist =
distRepository.getUrl() + ( distRepository.getUrl().endsWith( "/" ) ? "" : "/" )
+ distRepository.pathOf( art );
}
nbmTask.setDistribution( dist );
}
else
{
nbmTask.setDistribution( nbmFile.getName() );
}
if ( ! "extra".equals( cluster ) )
{
nbmTask.setTargetcluster( cluster );
}
//MNBMODULE-217 avoid using the static DATE_FORMAT variable in MavenNBM.java (in ant harness)
nbmTask.setReleasedate( DATE_FORMAT.format( new Date( System.currentTimeMillis() ) ) );
try
{
nbmTask.execute();
}
catch ( BuildException e )
{
throw new MojoExecutionException( "Cannot Generate nbm file:" + e.getMessage(), e );
}
try
{
File nbmfile = new File( buildDir, nbmFile.getName() );
FileUtils.getFileUtils().copyFile( nbmFile, nbmfile );
projectHelper.attachArtifact( project, "nbm-file", null, nbmfile );
}
catch ( IOException ex )
{
throw new MojoExecutionException( "Cannot copy nbm to build directory", ex );
}
}
@Override
public void contextualize( Context context )
throws ContextException
{
this.container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
}
private String createDefaultLicenseHeader()
{
String organization = "";
Organization org = project.getOrganization();
if ( org != null )
{
organization = org.getName();
}
if ( organization == null )
{
List devs = project.getDevelopers();
if ( devs.size() > 0 )
{
Iterator dvs = devs.iterator();
String devsString = "";
while ( dvs.hasNext() )
{
Developer d = ( Developer ) dvs.next();
devsString = devsString + "," + d.getName() != null ? d.getName() : d.getId();
}
organization = devsString.substring( 1 );
}
}
if ( organization == null )
{
organization = ""; //what's a good default value?
}
String date = "";
if ( project.getInceptionYear() != null )
{
date = project.getInceptionYear();
}
String year = Integer.toString( Calendar.getInstance().get( Calendar.YEAR ) );
if ( !year.equals( date ) )
{
date = date.length() == 0 ? year : date + "-" + year;
}
return "Copyright " + organization + " " + date;
}
private String createDefaultLicenseText()
{
String toRet = "License terms:\n";
List licenses = project.getLicenses();
if ( licenses != null && licenses.size() > 0 )
{
Iterator lic = licenses.iterator();
while ( lic.hasNext() )
{
License ll = ( License ) lic.next();
if ( ll.getName() != null )
{
toRet = toRet + ll.getName() + " - ";
}
if ( ll.getUrl() != null )
{
toRet = toRet + ll.getUrl();
}
if ( lic.hasNext() )
{
toRet = toRet + ",\n";
}
}
}
else
{
toRet = toRet + "Unknown";
}
return toRet;
}
}