Coverage Report - org.codehaus.mojo.nbm.CreateUpdateSiteMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
CreateUpdateSiteMojo
0%
0/134
0%
0/62
12.5
 
 1  
 /* ==========================================================================
 2  
  * Copyright 2003-2004 Mevenide Team
 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  
  * =========================================================================
 16  
  */
 17  
 package org.codehaus.mojo.nbm;
 18  
 
 19  
 import java.io.File;
 20  
 import java.util.Iterator;
 21  
 import java.util.List;
 22  
 import java.util.Set;
 23  
 import java.util.regex.Matcher;
 24  
 import java.util.regex.Pattern;
 25  
 import org.apache.maven.artifact.Artifact;
 26  
 import org.apache.maven.artifact.factory.ArtifactFactory;
 27  
 import org.apache.maven.artifact.repository.ArtifactRepository;
 28  
 import org.apache.maven.artifact.repository.DefaultArtifactRepository;
 29  
 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
 30  
 import org.apache.maven.artifact.resolver.ArtifactResolver;
 31  
 import org.apache.maven.plugin.MojoExecutionException;
 32  
 import org.apache.maven.plugin.MojoFailureException;
 33  
 import org.apache.maven.plugin.logging.Log;
 34  
 import org.apache.maven.plugins.annotations.Component;
 35  
 import org.apache.maven.plugins.annotations.LifecyclePhase;
 36  
 import org.apache.maven.plugins.annotations.Mojo;
 37  
 import org.apache.maven.plugins.annotations.Parameter;
 38  
 import org.apache.maven.plugins.annotations.ResolutionScope;
 39  
 import org.apache.maven.project.MavenProject;
 40  
 import org.apache.maven.project.MavenProjectHelper;
 41  
 import org.apache.tools.ant.BuildException;
 42  
 import org.apache.tools.ant.Project;
 43  
 import org.apache.tools.ant.taskdefs.Copy;
 44  
 import org.apache.tools.ant.types.FileSet;
 45  
 import org.codehaus.plexus.PlexusConstants;
 46  
 import org.codehaus.plexus.PlexusContainer;
 47  
 import org.codehaus.plexus.archiver.gzip.GZipArchiver;
 48  
 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
 49  
 import org.codehaus.plexus.context.Context;
 50  
 import org.codehaus.plexus.context.ContextException;
 51  
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
 52  
 import org.netbeans.nbbuild.MakeUpdateDesc;
 53  
 
 54  
 /**
 55  
  * Create the NetBeans auto update site definition.
 56  
  * @author <a href="mailto:mkleint@codehaus.org">Milos Kleint</a>
 57  
  *
 58  
  */
 59  
 @Mojo(name="autoupdate", 
 60  
         defaultPhase= LifecyclePhase.PACKAGE, 
 61  
         aggregator=true, 
 62  
         requiresDependencyResolution= ResolutionScope.RUNTIME )
 63  0
 public class CreateUpdateSiteMojo
 64  
         extends AbstractNbmMojo
 65  
         implements Contextualizable
 66  
 {
 67  
 
 68  
     /**
 69  
      * output directory.
 70  
      */
 71  
     @Parameter(required=true, defaultValue="${project.build.directory}")
 72  
     protected File outputDirectory;
 73  
     /**
 74  
      * autoupdate site xml file name.
 75  
      */
 76  
     @Parameter( defaultValue="updates.xml", property="maven.nbm.updatesitexml")
 77  
     protected String fileName;
 78  
     /**
 79  
      * A custom distribution base for the nbms in the update site.
 80  
      * If NOT defined, the update site will use a simple relative URL, which is generally what you want.
 81  
      * Defining it as "auto" will pick up the distribution URL from each NBM, which is generally wrong. 
 82  
      * See <code>distributionUrl</code> in nbm mojo for what url will be used in that case.
 83  
      * <p/>
 84  
      * The value is either a direct http protocol based URL that points to
 85  
      * the location under which all nbm files are located, or
 86  
      * <p/>
 87  
      * allows to create an update site based on maven repository content.
 88  
      * The resulting autoupdate site document can be uploaded as tar.gz to repository as well
 89  
      * as attached artifact to the 'nbm-application' project.
 90  
      * <br/>
 91  
      * Format: id::layout::url same as in maven-deploy-plugin
 92  
      * <br/>
 93  
      * with the 'default' and 'legacy' layouts. (maven2 vs maven1 layout)
 94  
      * <br/>
 95  
      * If the value doesn't contain :: characters,
 96  
      * it's assumed to be the flat structure and the value is just the URL.
 97  
      * 
 98  
      * @since 3.0 it's also possible to add remote repository as base
 99  
      */
 100  
     @Parameter(defaultValue=".", property="maven.nbm.customDistBase")
 101  
     private String distBase;
 102  
 
 103  
     /**
 104  
      * The Maven Project.
 105  
      *
 106  
      */
 107  
     @Parameter(required=true, readonly=true, property="project")
 108  
     private MavenProject project;
 109  
 
 110  
     /**
 111  
      * If the executed project is a reactor project, this will contains the full list of projects in the reactor.
 112  
      */
 113  
     @Parameter(required=true, readonly=true, defaultValue="${reactorProjects}")
 114  
     private List reactorProjects;
 115  
     
 116  
     /**
 117  
      * List of Ant style patterns on artifact GA (groupID:artifactID) that should be included in the update site.
 118  
      * Eg. org.netbeans.* matches all artifacts with any groupID starting with 'org.netbeans.',
 119  
      * org.*:api will match any artifact with artifactId of 'api' and groupId starting with 'org.'
 120  
      * @since 3.14
 121  
      */
 122  
     @Parameter
 123  
     private List<String> updateSiteIncludes;
 124  
     
 125  
 
 126  
     // <editor-fold defaultstate="collapsed" desc="Component parameters">
 127  
 
 128  
     @Component
 129  
     private ArtifactFactory artifactFactory;
 130  
     /**
 131  
      * Contextualized.
 132  
      */
 133  
     private PlexusContainer container;
 134  
     /**
 135  
      * Used for attaching the artifact in the project
 136  
      *
 137  
      */
 138  
     @Component
 139  
     private MavenProjectHelper projectHelper;
 140  
 
 141  
     @Component
 142  
     private ArtifactResolver artifactResolver;
 143  
 
 144  
     /**
 145  
      * Local maven repository.
 146  
      *
 147  
      */
 148  
     @Parameter(readonly=true, required=true, defaultValue="${localRepository}")
 149  
     protected ArtifactRepository localRepository;
 150  
 
 151  
     // </editor-fold>
 152  
 
 153  
     public void execute()
 154  
         throws MojoExecutionException, MojoFailureException
 155  
     {
 156  0
         Project antProject = registerNbmAntTasks();
 157  0
         File nbmBuildDirFile = new File( outputDirectory, "netbeans_site" );
 158  0
         if ( !nbmBuildDirFile.exists() )
 159  
         {
 160  0
             nbmBuildDirFile.mkdirs();
 161  
         }
 162  
 
 163  0
         boolean isRepository = false;
 164  0
         if ( "auto".equals( distBase ) )
 165  
         {
 166  0
             distBase = null;
 167  
         }
 168  0
         ArtifactRepository distRepository = getDeploymentRepository( distBase, container, getLog() );
 169  0
         String oldDistBase = null;
 170  0
         if ( distRepository != null )
 171  
         {
 172  0
             isRepository = true;
 173  
         }
 174  
         else
 175  
         {
 176  0
             if ( distBase != null && !distBase.contains( "::" ) )
 177  
             {
 178  0
                 oldDistBase = distBase;
 179  
             }
 180  
         }
 181  
 
 182  0
         if ( "nbm-application".equals( project.getPackaging() ) )
 183  
         {
 184  
             @SuppressWarnings( "unchecked" )
 185  0
             Set<Artifact> artifacts = project.getArtifacts();
 186  0
             for ( Artifact art : artifacts )
 187  
             {
 188  0
                 if (!matchesIncludes(art)) {
 189  0
                     continue;
 190  
                 }
 191  0
                 ArtifactResult res =
 192  
                     turnJarToNbmFile( art, artifactFactory, artifactResolver, project, localRepository );
 193  0
                 if ( res.hasConvertedArtifact() )
 194  
                 {
 195  0
                     art = res.getConvertedArtifact();
 196  
                 }
 197  
 
 198  0
                 if ( art.getType().equals( "nbm-file" ) )
 199  
                 {
 200  0
                     Copy copyTask = (Copy) antProject.createTask( "copy" );
 201  0
                     copyTask.setOverwrite( true );
 202  0
                     copyTask.setFile( art.getFile() );
 203  0
                     if ( !isRepository )
 204  
                     {
 205  0
                         copyTask.setFlatten( true );
 206  0
                         copyTask.setTodir( nbmBuildDirFile );
 207  
                     }
 208  
                     else
 209  
                     {
 210  0
                         String path = distRepository.pathOf( art );
 211  0
                         File f = new File( nbmBuildDirFile, path.replace( '/', File.separatorChar ) );
 212  0
                         copyTask.setTofile( f );
 213  
                     }
 214  
                     try
 215  
                     {
 216  0
                         copyTask.execute();
 217  
                     }
 218  0
                     catch ( BuildException ex )
 219  
                     {
 220  0
                         throw new MojoExecutionException( "Cannot merge nbm files into autoupdate site", ex );
 221  0
                     }
 222  
 
 223  
                 }
 224  0
                 if ( res.isOSGiBundle() )
 225  
                 {
 226  
                     // TODO check for bundles
 227  
                 }
 228  0
             }
 229  0
             getLog().info( "Created NetBeans module cluster(s) at " + nbmBuildDirFile.getAbsoluteFile() );
 230  
 
 231  0
         }
 232  0
         else if ( reactorProjects != null && reactorProjects.size() > 0 )
 233  
         {
 234  
 
 235  0
             Iterator it = reactorProjects.iterator();
 236  0
             while ( it.hasNext() )
 237  
             {
 238  0
                 MavenProject proj = (MavenProject) it.next();
 239  
                 //TODO how to figure where the the buildDir/nbm directory is
 240  0
                 File moduleDir = proj.getFile().getParentFile();
 241  0
                 if ( moduleDir != null && moduleDir.exists() )
 242  
                 {
 243  0
                     Copy copyTask = (Copy) antProject.createTask( "copy" );
 244  0
                     if ( !isRepository )
 245  
                     {
 246  0
                         FileSet fs = new FileSet();
 247  0
                         fs.setDir( moduleDir );
 248  0
                         fs.createInclude().setName( "target/*.nbm" );
 249  0
                         copyTask.addFileset( fs );
 250  0
                         copyTask.setOverwrite( true );
 251  0
                         copyTask.setFlatten( true );
 252  0
                         copyTask.setTodir( nbmBuildDirFile );
 253  0
                     }
 254  
                     else
 255  
                     {
 256  0
                         File target = new File( moduleDir, "target" );
 257  0
                         boolean has = false;
 258  0
                         File[] fls = target.listFiles();
 259  0
                         if ( fls != null )
 260  
                         {
 261  0
                             for ( File fl : fls )
 262  
                             {
 263  0
                                 if ( fl.getName().endsWith( ".nbm" ) )
 264  
                                 {
 265  0
                                     copyTask.setFile( fl );
 266  0
                                     has = true;
 267  0
                                     break;
 268  
                                 }
 269  
                             }
 270  
                         }
 271  0
                         if ( !has )
 272  
                         {
 273  0
                             continue;
 274  
                         }
 275  0
                         Artifact art =
 276  
                             artifactFactory.createArtifact( proj.getGroupId(), proj.getArtifactId(), proj.getVersion(),
 277  
                                                             null, "nbm-file" );
 278  0
                         String path = distRepository.pathOf( art );
 279  0
                         File f = new File( nbmBuildDirFile, path.replace( '/', File.separatorChar ) );
 280  0
                         copyTask.setTofile( f );
 281  
                     }
 282  
                     try
 283  
                     {
 284  0
                         copyTask.execute();
 285  
                     }
 286  0
                     catch ( BuildException ex )
 287  
                     {
 288  0
                         throw new MojoExecutionException( "Cannot merge nbm files into autoupdate site", ex );
 289  0
                     }
 290  
                 }
 291  0
             }
 292  0
         }
 293  
         else
 294  
         {
 295  0
             throw new MojoExecutionException(
 296  
                     "This goal only makes sense on reactor projects or project with 'nbm-application' packaging." );
 297  
 
 298  
         }
 299  0
         MakeUpdateDesc descTask = (MakeUpdateDesc) antProject.createTask( "updatedist" );
 300  0
         File xmlFile = new File( nbmBuildDirFile, fileName );
 301  0
         descTask.setDesc( xmlFile );
 302  0
         if ( oldDistBase != null )
 303  
         {
 304  0
             descTask.setDistBase( oldDistBase );
 305  
         }
 306  0
         if ( distRepository != null )
 307  
         {
 308  0
             descTask.setDistBase( distRepository.getUrl() );
 309  
         }
 310  0
         FileSet fs = new FileSet();
 311  0
         fs.setDir( nbmBuildDirFile );
 312  0
         fs.createInclude().setName( "**/*.nbm" );
 313  0
         descTask.addFileset( fs );
 314  
         try
 315  
         {
 316  0
             descTask.execute();
 317  
         }
 318  0
         catch ( BuildException ex )
 319  
         {
 320  0
             throw new MojoExecutionException( "Cannot create autoupdate site xml file", ex );
 321  0
         }
 322  0
         getLog().info( "Generated autoupdate site content at " + nbmBuildDirFile.getAbsolutePath() );
 323  
 
 324  
         try
 325  
         {
 326  0
             GZipArchiver gz = new GZipArchiver();
 327  0
             gz.addFile( xmlFile, fileName );
 328  0
             File gzipped = new File( nbmBuildDirFile, fileName + ".gz" );
 329  0
             gz.setDestFile( gzipped );
 330  0
             gz.createArchive();
 331  0
             if ( "nbm-application".equals( project.getPackaging() ) )
 332  
             {
 333  0
                 projectHelper.attachArtifact( project, "xml.gz", "updatesite", gzipped );
 334  
             }
 335  
         }
 336  0
         catch ( Exception ex )
 337  
         {
 338  0
             throw new MojoExecutionException( "Cannot create gzipped version of the update site xml file.", ex );
 339  0
         }
 340  
 
 341  0
     }
 342  
 
 343  0
     private static final Pattern ALT_REPO_SYNTAX_PATTERN = Pattern.compile( "(.+)::(.+)::(.+)" );
 344  
 
 345  
     static ArtifactRepository getDeploymentRepository( String distBase, PlexusContainer container, Log log )
 346  
         throws MojoExecutionException, MojoFailureException
 347  
     {
 348  
 
 349  0
         ArtifactRepository repo = null;
 350  
 
 351  0
         if ( distBase != null )
 352  
         {
 353  
 
 354  0
             Matcher matcher = ALT_REPO_SYNTAX_PATTERN.matcher( distBase );
 355  
 
 356  0
             if ( !matcher.matches() )
 357  
             {
 358  0
                 if ( !distBase.contains( "::" ) )
 359  
                 {
 360  
                     //backward compatibility gag.
 361  0
                     return null;
 362  
                 }
 363  0
                 throw new MojoFailureException( distBase,
 364  
                         "Invalid syntax for repository.",
 365  
                         "Invalid syntax for alternative repository. Use \"id::layout::url\"." );
 366  
             }
 367  
             else
 368  
             {
 369  0
                 String id = matcher.group( 1 ).trim();
 370  0
                 String layout = matcher.group( 2 ).trim();
 371  0
                 String url = matcher.group( 3 ).trim();
 372  
 
 373  
                 ArtifactRepositoryLayout repoLayout;
 374  
                 try
 375  
                 {
 376  0
                     repoLayout = (ArtifactRepositoryLayout) container.lookup( ArtifactRepositoryLayout.ROLE, layout );
 377  
                 }
 378  0
                 catch ( ComponentLookupException e )
 379  
                 {
 380  0
                     throw new MojoExecutionException( "Cannot find repository layout: " + layout, e );
 381  0
                 }
 382  
 
 383  0
                 repo = new DefaultArtifactRepository( id, url, repoLayout );
 384  
             }
 385  
         }
 386  0
         return repo;
 387  
     }
 388  
 
 389  
     public void contextualize( Context context )
 390  
         throws ContextException
 391  
     {
 392  0
         this.container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
 393  0
     }
 394  
 
 395  
     private boolean matchesIncludes( Artifact art )
 396  
     {
 397  0
         if (updateSiteIncludes != null) {
 398  0
             String s = art.getGroupId() + ":" + art.getArtifactId();
 399  0
             for (String p : updateSiteIncludes) {
 400  
                 //TODO optimize and only do once per execution.
 401  0
                 p = p.replace(".", "\\.").replace( "*", ".*");
 402  0
                 Pattern patt = Pattern.compile( p );
 403  0
                 if (patt.matcher( s).matches()) {
 404  0
                     return true;
 405  
                 }
 406  0
             }
 407  0
             return false;    
 408  
         }
 409  0
         return true;
 410  
     }
 411  
 }