Coverage Report - org.apache.maven.plugin.eclipse.writers.EclipseOSGiManifestWriter
 
Classes in this File Line Coverage Branch Coverage Complexity
EclipseOSGiManifestWriter
15%
12/78
13%
5/38
7.5
 
 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.writers;
 20  
 
 21  
 import java.io.BufferedReader;
 22  
 import java.io.File;
 23  
 import java.io.FileInputStream;
 24  
 import java.io.FileNotFoundException;
 25  
 import java.io.FileOutputStream;
 26  
 import java.io.IOException;
 27  
 import java.io.InputStreamReader;
 28  
 import java.io.OutputStreamWriter;
 29  
 import java.io.Writer;
 30  
 
 31  
 import org.apache.maven.plugin.MojoExecutionException;
 32  
 import org.apache.maven.plugin.eclipse.Messages;
 33  
 import org.apache.maven.plugin.ide.IdeDependency;
 34  
 import org.codehaus.plexus.util.IOUtil;
 35  
 import org.codehaus.plexus.util.StringUtils;
 36  
 
 37  
 /**
 38  
  * The <code>EclipseOSGiManifestWriter</code> ensures that value of the "Bundle-Classpath" property in
 39  
  * META-INF/MANIFEST.MF is synchronized with the POM by adding all dependencies that don't have the scope provided.
 40  
  * 
 41  
  * @deprecated use <a href="http://cwiki.apache.org/FELIX/bundle-plugin-for-maven-bnd.html/">Maven Bundle plugin</a>
 42  
  *             from Felix
 43  
  */
 44  0
 public class EclipseOSGiManifestWriter
 45  
     extends AbstractEclipseWriter
 46  
 {
 47  
 
 48  
     /**
 49  
      * Constant used for newline.
 50  
      * 
 51  
      * @todo check if we should use system-dependent newlines or if eclipse prefers a common format
 52  
      */
 53  
     private static final String NEWLINE = "\n";
 54  
 
 55  
     /**
 56  
      * Bundle classpath: updated with the list of dependencies.
 57  
      */
 58  
     public final static String ENTRY_BUNDLE_CLASSPATH = "Bundle-ClassPath:";
 59  
 
 60  
     /**
 61  
      * Bundle name: updated with the project name.
 62  
      */
 63  
     public final static String ENTRY_BUNDLE_NAME = "Bundle-Name:";
 64  
 
 65  
     /**
 66  
      * Bundle symbolic name: updated with the artifact id.
 67  
      */
 68  
     public final static String ENTRY_BUNDLE_SYMBOLICNAME = "Bundle-SymbolicName:";
 69  
 
 70  
     /**
 71  
      * Bundle version: updated with the project version.
 72  
      */
 73  
     public final static String ENTRY_BUNDLE_VERSION = "Bundle-Version:";
 74  
 
 75  
     /**
 76  
      * Bundle vendor: updated with the organization name (if set in the POM).
 77  
      */
 78  
     public final static String ENTRY_BUNDLE_VENDOR = "Bundle-Vendor:";
 79  
 
 80  
     /**
 81  
      * @see org.apache.maven.plugin.eclipse.writers.EclipseWriter#write()
 82  
      */
 83  
     public void write()
 84  
         throws MojoExecutionException
 85  
     {
 86  
         // check for existence
 87  0
         if ( !config.getOSGIManifestFile().exists() )
 88  
         {
 89  0
             log.warn( Messages.getString( "EclipseOSGiManifestWriter.nomanifestfile",
 90  
                                           config.getOSGIManifestFile().getAbsolutePath() ) );
 91  0
             return;
 92  
         }
 93  
 
 94  0
         StringBuffer manifestSb = rewriteManifest( config.getOSGIManifestFile() );
 95  0
         Writer out = null;
 96  
         try
 97  
         {
 98  0
             out = new OutputStreamWriter( new FileOutputStream( config.getOSGIManifestFile() ), "UTF-8" );
 99  0
             out.write( manifestSb.toString() );
 100  
         }
 101  0
         catch ( FileNotFoundException e )
 102  
         {
 103  0
             throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantwritetofile",
 104  
                                                                   config.getOSGIManifestFile().getAbsolutePath() ) );
 105  
         }
 106  0
         catch ( IOException e )
 107  
         {
 108  0
             throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantwritetofile",
 109  
                                                                   config.getOSGIManifestFile().getAbsolutePath() ), e );
 110  
         }
 111  
         finally
 112  
         {
 113  0
             IOUtil.close( out );
 114  0
         }
 115  0
     }
 116  
 
 117  
     protected StringBuffer rewriteManifest( File manifestFile )
 118  
         throws MojoExecutionException
 119  
     {
 120  
 
 121  
         // warning: we read and rewrite the file line by line in order to preserve formatting
 122  0
         boolean inBundleClasspathEntry = false;
 123  0
         StringBuffer manifestSb = new StringBuffer();
 124  
         try
 125  
         {
 126  0
             BufferedReader in =
 127  
                 new BufferedReader( new InputStreamReader( new FileInputStream( manifestFile ), "UTF-8" ) );
 128  
             String line;
 129  0
             while ( ( line = in.readLine() ) != null )
 130  
             {
 131  0
                 if ( inBundleClasspathEntry && line.indexOf( ":" ) > -1 )
 132  
                 {
 133  0
                     inBundleClasspathEntry = false;
 134  
                 }
 135  0
                 else if ( inBundleClasspathEntry )
 136  
                 {
 137  
                     // skip it
 138  0
                     continue;
 139  
                 }
 140  
 
 141  
                 // Note that this could be the empty string, if we encounter
 142  
                 // a field that we weren't expecting to be multi-line.
 143  0
                 String name = line.substring( 0, line.indexOf( ":" ) + 1 );
 144  
 
 145  0
                 if ( name.equalsIgnoreCase( ENTRY_BUNDLE_CLASSPATH ) )
 146  
                 {
 147  0
                     inBundleClasspathEntry = true;
 148  
                 }
 149  0
                 else if ( name.equalsIgnoreCase( ENTRY_BUNDLE_NAME ) )
 150  
                 {
 151  0
                     manifestSb.append( ENTRY_BUNDLE_NAME );
 152  0
                     manifestSb.append( " " );
 153  0
                     manifestSb.append( config.getProject().getName() );
 154  0
                     manifestSb.append( NEWLINE );
 155  
                 }
 156  0
                 else if ( name.equalsIgnoreCase( ENTRY_BUNDLE_SYMBOLICNAME ) )
 157  
                 {
 158  0
                     manifestSb.append( ENTRY_BUNDLE_SYMBOLICNAME );
 159  0
                     manifestSb.append( " " );
 160  0
                     manifestSb.append( config.getEclipseProjectName() );
 161  0
                     manifestSb.append( ";singleton:=true" );
 162  0
                     manifestSb.append( NEWLINE );
 163  
                 }
 164  0
                 else if ( name.equalsIgnoreCase( ENTRY_BUNDLE_VERSION ) )
 165  
                 {
 166  0
                     manifestSb.append( ENTRY_BUNDLE_VERSION );
 167  0
                     manifestSb.append( " " );
 168  0
                     manifestSb.append( getNormalizedVersion( config.getProject().getVersion() ) );
 169  0
                     manifestSb.append( NEWLINE );
 170  
                 }
 171  0
                 else if ( name.equalsIgnoreCase( ENTRY_BUNDLE_VENDOR ) && config.getProject().getOrganization() != null )
 172  
                 {
 173  0
                     manifestSb.append( ENTRY_BUNDLE_VENDOR );
 174  0
                     manifestSb.append( " " );
 175  0
                     manifestSb.append( config.getProject().getOrganization().getName() );
 176  0
                     manifestSb.append( NEWLINE );
 177  
                 }
 178  
                 else
 179  
                 {
 180  0
                     manifestSb.append( line + NEWLINE );
 181  
                 }
 182  0
             }
 183  
 
 184  0
             IOUtil.close( in );
 185  
         }
 186  0
         catch ( IOException e )
 187  
         {
 188  0
             throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantreadfile",
 189  
                                                                   manifestFile.getAbsolutePath() ) );
 190  0
         }
 191  0
         manifestSb.append( addBundleClasspathEntries() );
 192  
 
 193  
         // OSGi manifest headers need to end with a line break
 194  0
         manifestSb.append( NEWLINE );
 195  0
         return manifestSb;
 196  
     }
 197  
 
 198  
     /**
 199  
      * Normalize a version number, by moving snapshot identifier to the 5th token (first 4 tokens must be numeric for
 200  
      * OSGI bundles)
 201  
      * 
 202  
      * @param version original version
 203  
      * @return a normalized version number
 204  
      */
 205  
     protected static String getNormalizedVersion( String version )
 206  
     {
 207  
 
 208  3
         if ( version.endsWith( "-SNAPSHOT" ) )
 209  
         {
 210  3
             String[] versionTokens = StringUtils.split( StringUtils.stripEnd( version, "-SNAPSHOT" ), "." );
 211  
 
 212  3
             int j = 0;
 213  3
             StringBuffer newVersion = new StringBuffer( 20 );
 214  21
             for ( ; j < versionTokens.length; j++ )
 215  
             {
 216  9
                 newVersion.append( versionTokens[j] );
 217  9
                 newVersion.append( "." );
 218  
             }
 219  5
             for ( ; j < 3; j++ )
 220  
             {
 221  1
                 newVersion.append( "0." );
 222  
             }
 223  
 
 224  3
             newVersion.append( "SNAPSHOT" );
 225  3
             version = newVersion.toString();
 226  
 
 227  
         }
 228  3
         return version;
 229  
     }
 230  
 
 231  
     /**
 232  
      * Add all libraries that don't have the scope "provided" to the "Bundle-Classpath".
 233  
      * 
 234  
      * @return complete "Bundle-ClassPath:" entry for manifest
 235  
      */
 236  
     protected String addBundleClasspathEntries()
 237  
     {
 238  0
         StringBuffer bundleClasspathSb = new StringBuffer( ENTRY_BUNDLE_CLASSPATH );
 239  
 
 240  
         // local classes, if the plugin is jarred
 241  
         // @todo handle expanded plugins
 242  0
         bundleClasspathSb.append( " ." );
 243  
 
 244  0
         IdeDependency[] deps = config.getDeps();
 245  
 
 246  0
         for ( int j = 0; j < deps.length; j++ )
 247  
         {
 248  0
             IdeDependency dep = deps[j];
 249  0
             if ( !dep.isProvided() && !dep.isReferencedProject() && !dep.isTestDependency() && !dep.isOsgiBundle() )
 250  
             {
 251  0
                 bundleClasspathSb.append( "," + NEWLINE );
 252  
 
 253  0
                 log.debug( "Adding artifact to manifest: " + dep.getArtifactId() );
 254  
 
 255  0
                 bundleClasspathSb.append( " " + dep.getFile().getName() );
 256  
             }
 257  
         }
 258  
         // only insert the name of the property if there are local libraries
 259  0
         return bundleClasspathSb.toString();
 260  
     }
 261  
 
 262  
 }