Coverage Report - org.apache.maven.plugin.eclipse.EclipseToMavenMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
EclipseToMavenMojo
26%
51/199
30%
21/70
4.706
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements.  See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership.  The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License.  You may obtain a copy of the License at
 9  
  *
 10  
  *   http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied.  See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package org.apache.maven.plugin.eclipse;
 20  
 
 21  
 import java.io.File;
 22  
 import java.io.FileOutputStream;
 23  
 import java.io.IOException;
 24  
 import java.io.OutputStreamWriter;
 25  
 import java.io.Writer;
 26  
 import java.util.ArrayList;
 27  
 import java.util.HashMap;
 28  
 import java.util.Iterator;
 29  
 import java.util.List;
 30  
 import java.util.Map;
 31  
 import java.util.regex.Matcher;
 32  
 import java.util.regex.Pattern;
 33  
 
 34  
 import aQute.lib.osgi.Analyzer;
 35  
 
 36  
 import org.apache.maven.artifact.Artifact;
 37  
 import org.apache.maven.artifact.deployer.ArtifactDeployer;
 38  
 import org.apache.maven.artifact.deployer.ArtifactDeploymentException;
 39  
 import org.apache.maven.artifact.factory.ArtifactFactory;
 40  
 import org.apache.maven.artifact.installer.ArtifactInstallationException;
 41  
 import org.apache.maven.artifact.installer.ArtifactInstaller;
 42  
 import org.apache.maven.artifact.metadata.ArtifactMetadata;
 43  
 import org.apache.maven.artifact.repository.ArtifactRepository;
 44  
 import org.apache.maven.artifact.repository.DefaultArtifactRepository;
 45  
 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
 46  
 import org.apache.maven.model.Dependency;
 47  
 import org.apache.maven.model.License;
 48  
 import org.apache.maven.model.Model;
 49  
 import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
 50  
 import org.apache.maven.plugin.AbstractMojo;
 51  
 import org.apache.maven.plugin.MojoExecutionException;
 52  
 import org.apache.maven.plugin.MojoFailureException;
 53  
 import org.apache.maven.plugin.eclipse.osgiplugin.EclipseOsgiPlugin;
 54  
 import org.apache.maven.plugin.eclipse.osgiplugin.ExplodedPlugin;
 55  
 import org.apache.maven.plugin.eclipse.osgiplugin.PackagedPlugin;
 56  
 import org.apache.maven.project.artifact.ProjectArtifactMetadata;
 57  
 import org.codehaus.plexus.PlexusConstants;
 58  
 import org.codehaus.plexus.PlexusContainer;
 59  
 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
 60  
 import org.codehaus.plexus.components.interactivity.InputHandler;
 61  
 import org.codehaus.plexus.context.Context;
 62  
 import org.codehaus.plexus.context.ContextException;
 63  
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
 64  
 import org.codehaus.plexus.util.IOUtil;
 65  
 import org.codehaus.plexus.util.StringUtils;
 66  
 
 67  
 /**
 68  
  * Add eclipse artifacts from an eclipse installation to the local repo. This mojo automatically analize the eclipse
 69  
  * directory, copy plugins jars to the local maven repo, and generates appropriate poms. This is the official central
 70  
  * repository builder for Eclipse plugins, so it has the necessary default values. For customized repositories see
 71  
  * {@link MakeArtifactsMojo} Typical usage:
 72  
  * <code>mvn eclipse:to-maven -DdeployTo=maven.org::default::scpexe://repo1.maven.org/home/maven/repository-staging/to-ibiblio/eclipse-staging -DeclipseDir=.</code>
 73  
  * 
 74  
  * @author Fabrizio Giustina
 75  
  * @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
 76  
  * @version $Id: EclipseToMavenMojo.java 618464 2008-02-04 22:12:32Z aheritier $
 77  
  * @goal to-maven
 78  
  * @requiresProject false
 79  
  */
 80  30
 public class EclipseToMavenMojo
 81  
     extends AbstractMojo
 82  
     implements Contextualizable
 83  
 {
 84  
 
 85  
     /**
 86  
      * A pattern the <code>deployTo</code> param should match.
 87  
      */
 88  2
     private static final Pattern DEPLOYTO_PATTERN = Pattern.compile( "(.+)::(.+)::(.+)" );
 89  
 
 90  
     /**
 91  
      * A pattern for a 4 digit osgi version number.
 92  
      */
 93  2
     private static final Pattern VERSION_PATTERN = Pattern.compile( "(([0-9]+\\.)+[0-9]+)" );
 94  
 
 95  
     /**
 96  
      * Plexus container, needed to manually lookup components for deploy of artifacts.
 97  
      */
 98  
     private PlexusContainer container;
 99  
 
 100  
     /**
 101  
      * Local maven repository.
 102  
      * 
 103  
      * @parameter expression="${localRepository}"
 104  
      * @required
 105  
      * @readonly
 106  
      */
 107  
     private ArtifactRepository localRepository;
 108  
 
 109  
     /**
 110  
      * ArtifactFactory component.
 111  
      * 
 112  
      * @component
 113  
      */
 114  
     private ArtifactFactory artifactFactory;
 115  
 
 116  
     /**
 117  
      * ArtifactInstaller component.
 118  
      * 
 119  
      * @component
 120  
      */
 121  
     protected ArtifactInstaller installer;
 122  
 
 123  
     /**
 124  
      * ArtifactDeployer component.
 125  
      * 
 126  
      * @component
 127  
      */
 128  
     private ArtifactDeployer deployer;
 129  
 
 130  
     /**
 131  
      * Eclipse installation dir. If not set, a value for this parameter will be asked on the command line.
 132  
      * 
 133  
      * @parameter expression="${eclipseDir}"
 134  
      */
 135  
     private File eclipseDir;
 136  
 
 137  
     /**
 138  
      * Input handler, needed for comand line handling.
 139  
      * 
 140  
      * @component
 141  
      */
 142  
     protected InputHandler inputHandler;
 143  
 
 144  
     /**
 145  
      * Specifies a remote repository to which generated artifacts should be deployed to. If this property is specified,
 146  
      * artifacts are also deployed to the remote repo. The format for this parameter is <code>id::layout::url</code>
 147  
      * 
 148  
      * @parameter expression="${deployTo}"
 149  
      */
 150  
     private String deployTo;
 151  
 
 152  
     /**
 153  
      * @see org.apache.maven.plugin.Mojo#execute()
 154  
      */
 155  
     public void execute()
 156  
         throws MojoExecutionException, MojoFailureException
 157  
     {
 158  0
         if ( eclipseDir == null )
 159  
         {
 160  0
             getLog().info( "Eclipse directory? " );
 161  
 
 162  
             String eclipseDirString;
 163  
             try
 164  
             {
 165  0
                 eclipseDirString = inputHandler.readLine();
 166  
             }
 167  0
             catch ( IOException e )
 168  
             {
 169  0
                 throw new MojoFailureException( "Unable to read from standard input" );
 170  0
             }
 171  0
             eclipseDir = new File( eclipseDirString );
 172  
         }
 173  
 
 174  0
         if ( !eclipseDir.isDirectory() )
 175  
         {
 176  0
             throw new MojoFailureException( "Directory " + eclipseDir.getAbsolutePath() + " doesn't exists" );
 177  
         }
 178  
 
 179  0
         File pluginDir = new File( eclipseDir, "plugins" );
 180  
 
 181  0
         if ( !pluginDir.isDirectory() )
 182  
         {
 183  0
             throw new MojoFailureException( "Plugin directory " + pluginDir.getAbsolutePath() + " doesn't exists" );
 184  
         }
 185  
 
 186  0
         File[] files = pluginDir.listFiles();
 187  
 
 188  0
         ArtifactRepository remoteRepo = resolveRemoteRepo();
 189  
 
 190  0
         if ( remoteRepo != null )
 191  
         {
 192  0
             getLog().info( "Will deploy artifacts to remote repository " + deployTo );
 193  
         }
 194  
 
 195  0
         Map plugins = new HashMap();
 196  0
         Map models = new HashMap();
 197  
 
 198  0
         for ( int j = 0; j < files.length; j++ )
 199  
         {
 200  0
             File file = files[j];
 201  
 
 202  0
             getLog().info( "Processing file " + file.getAbsolutePath() );
 203  
 
 204  0
             processFile( file, plugins, models );
 205  
         }
 206  
 
 207  0
         int i = 1;
 208  0
         for ( Iterator it = plugins.keySet().iterator(); it.hasNext(); )
 209  
         {
 210  0
             getLog().info( "Processing " + ( i++ ) + " of " + plugins.keySet().size() );
 211  0
             String key = (String) it.next();
 212  0
             EclipseOsgiPlugin plugin = (EclipseOsgiPlugin) plugins.get( key );
 213  0
             Model model = (Model) models.get( key );
 214  0
             writeArtifact( plugin, model, remoteRepo );
 215  0
         }
 216  0
     }
 217  
 
 218  
     protected void processFile( File file, Map plugins, Map models )
 219  
         throws MojoExecutionException, MojoFailureException
 220  
     {
 221  0
         EclipseOsgiPlugin plugin = getEclipsePlugin( file );
 222  
 
 223  0
         if ( plugin == null )
 224  
         {
 225  0
             getLog().warn( "Skipping file " + file.getAbsolutePath() );
 226  0
             return;
 227  
         }
 228  
 
 229  0
         Model model = createModel( plugin );
 230  
 
 231  0
         if ( model == null )
 232  
         {
 233  0
             return;
 234  
         }
 235  
 
 236  0
         processPlugin( plugin, model, plugins, models );
 237  0
     }
 238  
 
 239  
     protected void processPlugin( EclipseOsgiPlugin plugin, Model model, Map plugins, Map models )
 240  
         throws MojoExecutionException, MojoFailureException
 241  
     {
 242  0
         plugins.put( getKey( model ), plugin );
 243  0
         models.put( getKey( model ), model );
 244  0
     }
 245  
 
 246  
     protected String getKey( Model model )
 247  
     {
 248  0
         return model.getGroupId() + "." + model.getArtifactId();
 249  
     }
 250  
 
 251  
     private String getKey( Dependency dependency )
 252  
     {
 253  0
         return dependency.getGroupId() + "." + dependency.getArtifactId();
 254  
     }
 255  
 
 256  
     /**
 257  
      * Resolve version ranges in the model provided, overriding version ranges with versions from the dependency in the
 258  
      * provided map of models. TODO doesn't check if the version is in range, it just overwrites it
 259  
      * 
 260  
      * @param model
 261  
      * @param models
 262  
      * @throws MojoFailureException
 263  
      */
 264  
     protected void resolveVersionRanges( Model model, Map models )
 265  
         throws MojoFailureException
 266  
     {
 267  0
         for ( Iterator it = model.getDependencies().iterator(); it.hasNext(); )
 268  
         {
 269  0
             Dependency dep = (Dependency) it.next();
 270  0
             if ( dep.getVersion().indexOf( "[" ) > -1 || dep.getVersion().indexOf( "(" ) > -1 )
 271  
             {
 272  0
                 String key = getKey( model );
 273  0
                 Model dependencyModel = (Model) models.get( getKey( dep ) );
 274  0
                 if ( dependencyModel != null )
 275  
                 {
 276  0
                     dep.setVersion( dependencyModel.getVersion() );
 277  
                 }
 278  
                 else
 279  
                 {
 280  0
                     throw new MojoFailureException( "Unable to resolve version range for dependency " + dep +
 281  
                         " in project " + key );
 282  
                 }
 283  
             }
 284  0
         }
 285  0
     }
 286  
 
 287  
     /**
 288  
      * Get a {@link EclipseOsgiPlugin} object from a plugin jar/dir found in the target dir.
 289  
      * 
 290  
      * @param file plugin jar or dir
 291  
      * @throws MojoExecutionException if anything bad happens while parsing files
 292  
      */
 293  
     private EclipseOsgiPlugin getEclipsePlugin( File file )
 294  
         throws MojoExecutionException
 295  
     {
 296  0
         if ( file.isDirectory() )
 297  
         {
 298  0
             return new ExplodedPlugin( file );
 299  
         }
 300  0
         else if ( file.getName().endsWith( ".jar" ) )
 301  
         {
 302  
             try
 303  
             {
 304  0
                 return new PackagedPlugin( file );
 305  
             }
 306  0
             catch ( IOException e )
 307  
             {
 308  0
                 throw new MojoExecutionException( "Unable to access jar " + file.getAbsolutePath(), e );
 309  
             }
 310  
         }
 311  
 
 312  0
         return null;
 313  
     }
 314  
 
 315  
     /**
 316  
      * Create the {@link Model} from a plugin manifest
 317  
      * 
 318  
      * @param plugin Eclipse plugin jar or dir
 319  
      * @throws MojoExecutionException if anything bad happens while parsing files
 320  
      */
 321  
     private Model createModel( EclipseOsgiPlugin plugin )
 322  
         throws MojoExecutionException
 323  
     {
 324  
 
 325  
         String name, bundleName, version, groupId, artifactId, requireBundle;
 326  
 
 327  
         try
 328  
         {
 329  0
             if ( !plugin.hasManifest() )
 330  
             {
 331  0
                 getLog().warn( "Plugin " + plugin + " does not have a manifest; skipping.." );
 332  0
                 return null;
 333  
             }
 334  
 
 335  0
             Analyzer analyzer = new Analyzer();
 336  
 
 337  0
             Map bundleSymbolicNameHeader =
 338  
                 analyzer.parseHeader( plugin.getManifestAttribute( Analyzer.BUNDLE_SYMBOLICNAME ) );
 339  0
             bundleName = (String) bundleSymbolicNameHeader.keySet().iterator().next();
 340  0
             version = plugin.getManifestAttribute( Analyzer.BUNDLE_VERSION );
 341  
 
 342  0
             if ( bundleName == null || version == null )
 343  
             {
 344  0
                 getLog().error( "Unable to read bundle name/version from manifest, skipping..." );
 345  0
                 return null;
 346  
             }
 347  
 
 348  0
             version = osgiVersionToMavenVersion( version );
 349  
 
 350  0
             name = plugin.getManifestAttribute( Analyzer.BUNDLE_NAME );
 351  
 
 352  0
             requireBundle = plugin.getManifestAttribute( Analyzer.REQUIRE_BUNDLE );
 353  
 
 354  
         }
 355  0
         catch ( IOException e )
 356  
         {
 357  0
             throw new MojoExecutionException( "Error processing plugin " + plugin, e );
 358  0
         }
 359  
 
 360  0
         Dependency[] deps = parseDependencies( requireBundle );
 361  
 
 362  0
         groupId = createGroupId( bundleName );
 363  0
         artifactId = createArtifactId( bundleName );
 364  
 
 365  0
         Model model = new Model();
 366  0
         model.setModelVersion( "4.0.0" );
 367  0
         model.setGroupId( groupId );
 368  0
         model.setArtifactId( artifactId );
 369  0
         model.setName( name );
 370  0
         model.setVersion( version );
 371  
 
 372  0
         model.setProperties( plugin.getPomProperties() );
 373  
 
 374  0
         if ( groupId.startsWith( "org.eclipse" ) )
 375  
         {
 376  
             // why do we need a parent?
 377  
 
 378  
             // Parent parent = new Parent();
 379  
             // parent.setGroupId( "org.eclipse" );
 380  
             // parent.setArtifactId( "eclipse" );
 381  
             // parent.setVersion( "1" );
 382  
             // model.setParent( parent );
 383  
 
 384  
             // infer license for know projects, everything at eclipse is licensed under EPL
 385  
             // maybe too simplicistic, but better than nothing
 386  0
             License license = new License();
 387  0
             license.setName( "Eclipse Public License - v 1.0" );
 388  0
             license.setUrl( "http://www.eclipse.org/org/documents/epl-v10.html" );
 389  0
             model.addLicense( license );
 390  
         }
 391  
 
 392  0
         if ( deps.length > 0 )
 393  
         {
 394  0
             for ( int k = 0; k < deps.length; k++ )
 395  
             {
 396  0
                 model.getDependencies().add( deps[k] );
 397  
             }
 398  
 
 399  
         }
 400  
 
 401  0
         return model;
 402  
     }
 403  
 
 404  
     /**
 405  
      * Writes the artifact to the repo
 406  
      * 
 407  
      * @param model
 408  
      * @param remoteRepo remote repository (if set)
 409  
      * @throws MojoExecutionException
 410  
      */
 411  
     private void writeArtifact( EclipseOsgiPlugin plugin, Model model, ArtifactRepository remoteRepo )
 412  
         throws MojoExecutionException
 413  
     {
 414  0
         Writer fw = null;
 415  0
         ArtifactMetadata metadata = null;
 416  0
         File pomFile = null;
 417  0
         Artifact pomArtifact =
 418  
             artifactFactory.createArtifact( model.getGroupId(), model.getArtifactId(), model.getVersion(), null, "pom" );
 419  0
         Artifact artifact =
 420  
             artifactFactory.createArtifact( model.getGroupId(), model.getArtifactId(), model.getVersion(), null,
 421  
                                             Constants.PROJECT_PACKAGING_JAR );
 422  
         try
 423  
         {
 424  0
             pomFile = File.createTempFile( "pom-", ".xml" );
 425  
 
 426  
             // TODO use WriterFactory.newXmlWriter() when plexus-utils is upgraded to 1.4.5+
 427  0
             fw = new OutputStreamWriter( new FileOutputStream( pomFile ), "UTF-8" );
 428  0
             model.setModelEncoding( "UTF-8" ); // to be removed when encoding is detected instead of forced to UTF-8
 429  0
             pomFile.deleteOnExit();
 430  0
             new MavenXpp3Writer().write( fw, model );
 431  0
             metadata = new ProjectArtifactMetadata( pomArtifact, pomFile );
 432  0
             pomArtifact.addMetadata( metadata );
 433  
         }
 434  0
         catch ( IOException e )
 435  
         {
 436  0
             throw new MojoExecutionException( "Error writing temporary pom file: " + e.getMessage(), e );
 437  
         }
 438  
         finally
 439  
         {
 440  0
             IOUtil.close( fw );
 441  0
         }
 442  
 
 443  
         try
 444  
         {
 445  0
             File jarFile = plugin.getJarFile();
 446  
 
 447  0
             if ( remoteRepo != null )
 448  
             {
 449  0
                 deployer.deploy( pomFile, pomArtifact, remoteRepo, localRepository );
 450  0
                 deployer.deploy( jarFile, artifact, remoteRepo, localRepository );
 451  
             }
 452  
             else
 453  
             {
 454  0
                 installer.install( pomFile, pomArtifact, localRepository );
 455  0
                 installer.install( jarFile, artifact, localRepository );
 456  
             }
 457  
         }
 458  0
         catch ( ArtifactDeploymentException e )
 459  
         {
 460  0
             throw new MojoExecutionException( "Unable to deploy artifact to repository.", e );
 461  
         }
 462  0
         catch ( ArtifactInstallationException e )
 463  
         {
 464  0
             throw new MojoExecutionException( "Unable to install artifact to repository.", e );
 465  
         }
 466  0
         catch ( IOException e )
 467  
         {
 468  0
             throw new MojoExecutionException( "Error getting the jar file for plugin " + plugin, e );
 469  
         }
 470  
         finally
 471  
         {
 472  0
             pomFile.delete();
 473  0
         }
 474  
 
 475  0
     }
 476  
 
 477  
     protected String osgiVersionToMavenVersion( String version )
 478  
     {
 479  0
         return osgiVersionToMavenVersion( version, null, false );
 480  
     }
 481  
 
 482  
     /**
 483  
      * The 4th (build) token MUST be separed with "-" and not with "." in maven. A version with 4 dots is not parsed,
 484  
      * and the whole string is considered a qualifier. See tests in DefaultArtifactVersion for reference.
 485  
      * 
 486  
      * @param version initial version
 487  
      * @param forcedQualifier build number
 488  
      * @param stripQualifier always remove 4th token in version
 489  
      * @return converted version
 490  
      */
 491  
     protected String osgiVersionToMavenVersion( String version, String forcedQualifier, boolean stripQualifier )
 492  
     {
 493  32
         if ( stripQualifier && StringUtils.countMatches( version, "." ) > 2 )
 494  
         {
 495  8
             version = StringUtils.substring( version, 0, version.lastIndexOf( "." ) );
 496  
         }
 497  24
         else if ( StringUtils.countMatches( version, "." ) > 2 )
 498  
         {
 499  8
             int lastDot = version.lastIndexOf( "." );
 500  8
             if ( StringUtils.isNotEmpty( forcedQualifier ) )
 501  
             {
 502  4
                 version = StringUtils.substring( version, 0, lastDot ) + "-" + forcedQualifier;
 503  
             }
 504  
             else
 505  
             {
 506  4
                 version =
 507  
                     StringUtils.substring( version, 0, lastDot ) + "-" +
 508  
                         StringUtils.substring( version, lastDot + 1, version.length() );
 509  
             }
 510  
         }
 511  32
         return version;
 512  
     }
 513  
 
 514  
     /**
 515  
      * Resolves the deploy<code>deployTo</code> parameter to an <code>ArtifactRepository</code> instance (if set).
 516  
      * 
 517  
      * @throws MojoFailureException
 518  
      * @throws MojoExecutionException
 519  
      * @return ArtifactRepository instance of null if <code>deployTo</code> is not set.
 520  
      */
 521  
     private ArtifactRepository resolveRemoteRepo()
 522  
         throws MojoFailureException, MojoExecutionException
 523  
     {
 524  0
         if ( deployTo != null )
 525  
         {
 526  0
             Matcher matcher = DEPLOYTO_PATTERN.matcher( deployTo );
 527  
 
 528  0
             if ( !matcher.matches() )
 529  
             {
 530  0
                 throw new MojoFailureException( deployTo, "Invalid syntax for repository.",
 531  
                                                 "Invalid syntax for remote repository. Use \"id::layout::url\"." );
 532  
             }
 533  
             else
 534  
             {
 535  0
                 String id = matcher.group( 1 ).trim();
 536  0
                 String layout = matcher.group( 2 ).trim();
 537  0
                 String url = matcher.group( 3 ).trim();
 538  
 
 539  
                 ArtifactRepositoryLayout repoLayout;
 540  
                 try
 541  
                 {
 542  0
                     repoLayout = (ArtifactRepositoryLayout) container.lookup( ArtifactRepositoryLayout.ROLE, layout );
 543  
                 }
 544  0
                 catch ( ComponentLookupException e )
 545  
                 {
 546  0
                     throw new MojoExecutionException( "Cannot find repository layout: " + layout, e );
 547  0
                 }
 548  
 
 549  0
                 return new DefaultArtifactRepository( id, url, repoLayout );
 550  
             }
 551  
         }
 552  0
         return null;
 553  
     }
 554  
 
 555  
     /**
 556  
      * {@inheritDoc}
 557  
      */
 558  
     public void contextualize( Context context )
 559  
         throws ContextException
 560  
     {
 561  0
         this.container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
 562  0
     }
 563  
 
 564  
     /**
 565  
      * Get the group id as the tokens until last dot e.g. <code>org.eclipse.jdt</code> -> <code>org.eclipse</code>
 566  
      * 
 567  
      * @param bundleName bundle name
 568  
      * @return group id
 569  
      */
 570  
     protected String createGroupId( String bundleName )
 571  
     {
 572  26
         int i = bundleName.lastIndexOf( "." );
 573  26
         if ( i > 0 )
 574  
         {
 575  24
             return bundleName.substring( 0, i );
 576  
         }
 577  
         else
 578  2
             return bundleName;
 579  
     }
 580  
 
 581  
     /**
 582  
      * Get the artifact id as the tokens after last dot e.g. <code>org.eclipse.jdt</code> -> <code>jdt</code>
 583  
      * 
 584  
      * @param bundleName bundle name
 585  
      * @return artifact id
 586  
      */
 587  
     protected String createArtifactId( String bundleName )
 588  
     {
 589  26
         int i = bundleName.lastIndexOf( "." );
 590  26
         if ( i > 0 )
 591  
         {
 592  24
             return bundleName.substring( i + 1 );
 593  
         }
 594  
         else
 595  2
             return bundleName;
 596  
     }
 597  
 
 598  
     /**
 599  
      * Parses the "Require-Bundle" and convert it to a list of dependencies.
 600  
      * 
 601  
      * @param requireBundle "Require-Bundle" entry
 602  
      * @return an array of <code>Dependency</code>
 603  
      */
 604  
     protected Dependency[] parseDependencies( String requireBundle )
 605  
     {
 606  8
         if ( requireBundle == null )
 607  
         {
 608  0
             return new Dependency[0];
 609  
         }
 610  
 
 611  8
         List dependencies = new ArrayList();
 612  
 
 613  8
         Analyzer analyzer = new Analyzer();
 614  
 
 615  8
         Map requireBundleHeader = analyzer.parseHeader( requireBundle );
 616  
 
 617  
         // now iterates on bundles and extract dependencies
 618  8
         for ( Iterator iter = requireBundleHeader.entrySet().iterator(); iter.hasNext(); )
 619  
         {
 620  32
             Map.Entry entry = (Map.Entry) iter.next();
 621  32
             String bundleName = (String) entry.getKey();
 622  32
             Map attributes = (Map) entry.getValue();
 623  
 
 624  32
             String version = (String) attributes.get( Analyzer.BUNDLE_VERSION.toLowerCase() );
 625  32
             boolean optional = "optional".equals( attributes.get( "resolution:" ) );
 626  
 
 627  32
             if ( version == null )
 628  
             {
 629  0
                 getLog().info( "Missing version for bundle " + bundleName + ", assuming any version > 0" );
 630  0
                 version = "[0,)";
 631  
             }
 632  
 
 633  32
             version = fixBuildNumberSeparator( version );
 634  
 
 635  32
             Dependency dep = new Dependency();
 636  32
             dep.setGroupId( createGroupId( bundleName ) );
 637  32
             dep.setArtifactId( createArtifactId( bundleName ) );
 638  32
             dep.setVersion( version );
 639  32
             dep.setOptional( optional );
 640  
 
 641  32
             dependencies.add( dep );
 642  
 
 643  32
         }
 644  
 
 645  8
         return (Dependency[]) dependencies.toArray( new Dependency[dependencies.size()] );
 646  
 
 647  
     }
 648  
 
 649  
     /**
 650  
      * Fix the separator for the 4th token in a versions. In maven this must be "-", in OSGI it's "."
 651  
      * 
 652  
      * @param versionRange input range
 653  
      * @return modified version range
 654  
      */
 655  
     protected String fixBuildNumberSeparator( String versionRange )
 656  
     {
 657  
         // should not be called with a null versionRange, but a check doesn't hurt...
 658  32
         if ( versionRange == null )
 659  
         {
 660  0
             return null;
 661  
         }
 662  
 
 663  32
         StringBuffer newVersionRange = new StringBuffer();
 664  
 
 665  32
         Matcher matcher = VERSION_PATTERN.matcher( versionRange );
 666  
 
 667  96
         while ( matcher.find() )
 668  
         {
 669  64
             String group = matcher.group();
 670  
 
 671  64
             if ( StringUtils.countMatches( group, "." ) > 2 )
 672  
             {
 673  
                 // build number found, fix it
 674  32
                 int lastDot = group.lastIndexOf( "." );
 675  32
                 group =
 676  
                     StringUtils.substring( group, 0, lastDot ) + "-" +
 677  
                         StringUtils.substring( group, lastDot + 1, group.length() );
 678  
             }
 679  64
             matcher.appendReplacement( newVersionRange, group );
 680  64
         }
 681  
 
 682  32
         matcher.appendTail( newVersionRange );
 683  
 
 684  32
         return newVersionRange.toString();
 685  
     }
 686  
 
 687  
 }