Coverage Report - com.simpligility.maven.plugins.androidndk.common.UnpackedLibHelper
 
Classes in this File Line Coverage Branch Coverage Complexity
UnpackedLibHelper
0%
0/68
0%
0/22
2.25
UnpackedLibHelper$1
0%
0/2
N/A
2.25
UnpackedLibHelper$2
0%
0/2
N/A
2.25
 
 1  
 /*******************************************************************************
 2  
  * Copyright (c) 2008, 2011 Sonatype Inc. and others.
 3  
  * All rights reserved. This program and the accompanying materials
 4  
  * are made available under the terms of the Eclipse Public License v1.0
 5  
  * which accompanies this distribution, and is available at
 6  
  * http://www.eclipse.org/legal/epl-v10.html
 7  
  *
 8  
  * Contributors:
 9  
  *    Sonatype Inc. - initial API and implementation
 10  
  *******************************************************************************/
 11  
 package com.simpligility.maven.plugins.androidndk.common;
 12  
 
 13  
 import java.io.File;
 14  
 import java.io.IOException;
 15  
 
 16  
 import com.android.SdkConstants;
 17  
 import com.google.common.io.PatternFilenameFilter;
 18  
 import org.apache.commons.io.FileUtils;
 19  
 import org.apache.maven.artifact.Artifact;
 20  
 import org.apache.maven.plugin.MojoExecutionException;
 21  
 import org.apache.maven.project.MavenProject;
 22  
 import org.codehaus.plexus.archiver.ArchiverException;
 23  
 import org.codehaus.plexus.archiver.UnArchiver;
 24  
 import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
 25  
 import org.codehaus.plexus.logging.Logger;
 26  
 import org.codehaus.plexus.logging.console.ConsoleLogger;
 27  
 
 28  
 /**
 29  
  * Provides convenience methods for unpacking Android libraries so that their contents can be used in the build.
 30  
  */
 31  0
 public final class UnpackedLibHelper
 32  
 {
 33  
     private final ArtifactResolverHelper artifactResolverHelper;
 34  
     private final Logger log;
 35  
 
 36  
     public static final String AAR_NATIVE_LIBRARIES_FOLDER = "jni";
 37  
     public static final String APKLIB_NATIVE_LIBRARIES_FOLDER = "libs";
 38  
 
 39  
 
 40  
     // ${project.build.directory}/unpacked-libs
 41  
     private final File unpackedLibsDirectory;
 42  
 
 43  
     public UnpackedLibHelper ( ArtifactResolverHelper artifactResolverHelper, MavenProject project, Logger log,
 44  
                                File unpackedLibsFolder )
 45  0
     {
 46  0
         this.artifactResolverHelper = artifactResolverHelper;
 47  0
         if ( unpackedLibsFolder != null )
 48  
         {
 49  
             // if absolute then use it.
 50  
             // if relative then make it relative to the basedir of the project.
 51  0
             this.unpackedLibsDirectory = unpackedLibsFolder.isAbsolute()
 52  
                     ? unpackedLibsFolder
 53  
                     : new File ( project.getBasedir(), unpackedLibsFolder.getPath() );
 54  
         }
 55  
         else
 56  
         {
 57  
             // If not specified then default to target/unpacked-libs
 58  0
             final File targetFolder = new File ( project.getBuild().getDirectory() );
 59  0
             this.unpackedLibsDirectory = new File ( targetFolder, "unpacked-libs" );
 60  
         }
 61  0
         this.log = log;
 62  0
     }
 63  
 
 64  
     public void extractApklib( Artifact apklibArtifact ) throws MojoExecutionException
 65  
     {
 66  0
         final File apkLibFile = artifactResolverHelper.resolveArtifactToFile( apklibArtifact );
 67  0
         if ( apkLibFile.isDirectory() )
 68  
         {
 69  0
             log.warn(
 70  
                     "The apklib artifact points to '" + apkLibFile + "' which is a directory; skipping unpacking it." );
 71  0
             return;
 72  
         }
 73  
 
 74  0
         final UnArchiver unArchiver = new ZipUnArchiver ( apkLibFile )
 75  0
         {
 76  
             @Override
 77  
             protected Logger getLogger()
 78  
             {
 79  0
                 return new ConsoleLogger( log.getThreshold(), "dependencies-unarchiver" );
 80  
             }
 81  
         };
 82  
 
 83  0
         final File apklibDirectory = getUnpackedLibFolder( apklibArtifact );
 84  0
         apklibDirectory.mkdirs();
 85  0
         unArchiver.setDestDirectory( apklibDirectory );
 86  0
         log.debug( "Extracting APKLIB to " + apklibDirectory );
 87  
         try
 88  
         {
 89  0
             unArchiver.extract();
 90  
         }
 91  0
         catch ( ArchiverException e )
 92  
         {
 93  0
             throw new MojoExecutionException ( "ArchiverException while extracting " + apklibDirectory
 94  
                     + ". Message: " + e.getLocalizedMessage(), e );
 95  0
         }
 96  0
     }
 97  
 
 98  
     public void extractAarLib( Artifact aarArtifact ) throws MojoExecutionException
 99  
     {
 100  0
         final File aarFile = artifactResolverHelper.resolveArtifactToFile( aarArtifact );
 101  0
         if ( aarFile.isDirectory() )
 102  
         {
 103  0
             log.warn(
 104  
                     "The aar artifact points to '" + aarFile + "' which is a directory; skipping unpacking it." );
 105  0
             return;
 106  
         }
 107  
 
 108  0
         final UnArchiver unArchiver = new ZipUnArchiver ( aarFile )
 109  0
         {
 110  
             @Override
 111  
             protected Logger getLogger()
 112  
             {
 113  0
                 return new ConsoleLogger( log.getThreshold(), "dependencies-unarchiver" );
 114  
             }
 115  
         };
 116  
 
 117  0
         final File aarDirectory = getUnpackedLibFolder( aarArtifact );
 118  0
         aarDirectory.mkdirs();
 119  0
         unArchiver.setDestDirectory( aarDirectory );
 120  0
         log.debug( "Extracting AAR to " + aarDirectory );
 121  
         try
 122  
         {
 123  0
             unArchiver.extract();
 124  
         }
 125  0
         catch ( ArchiverException e )
 126  
         {
 127  0
             throw new MojoExecutionException ( "ArchiverException while extracting " + aarDirectory.getAbsolutePath()
 128  
                     + ". Message: " + e.getLocalizedMessage(), e );
 129  0
         }
 130  
 
 131  
         // Move native libraries from libs to jni folder for legacy AARs.
 132  
         // This ensures backward compatibility with older AARs where libs are in "libs" folder.
 133  0
         final File jniFolder = new File ( aarDirectory, UnpackedLibHelper.AAR_NATIVE_LIBRARIES_FOLDER );
 134  0
         final File libsFolder = new File ( aarDirectory, UnpackedLibHelper.APKLIB_NATIVE_LIBRARIES_FOLDER );
 135  0
         if ( !jniFolder.exists() && libsFolder.isDirectory() && libsFolder.exists() )
 136  
         {
 137  0
             String[] natives = libsFolder.list( new PatternFilenameFilter( "^.*(?<!(?i)\\.jar)$" ) );
 138  0
             if ( natives.length > 0 )
 139  
             {
 140  0
                 log.debug( "Moving AAR native libraries from libs to jni folder" );
 141  0
                 for ( String nativeLibPath : natives )
 142  
                 {
 143  
                     try
 144  
                     {
 145  0
                         FileUtils.moveToDirectory( new File ( libsFolder, nativeLibPath ), jniFolder, true );
 146  
                     }
 147  0
                     catch ( IOException e )
 148  
                     {
 149  0
                         throw new MojoExecutionException (
 150  
                                 "Could not move native libraries from " + libsFolder, e );
 151  0
                     }
 152  
                 }
 153  
             }
 154  
         }
 155  0
     }
 156  
 
 157  
     public File getArtifactToFile( Artifact artifact ) throws MojoExecutionException
 158  
     {
 159  0
         final File artifactFile = artifactResolverHelper.resolveArtifactToFile( artifact );
 160  0
         return artifactFile;
 161  
     }
 162  
 
 163  
     public File getUnpackedLibsFolder()
 164  
     {
 165  0
         return unpackedLibsDirectory;
 166  
     }
 167  
 
 168  
     public File getUnpackedLibFolder( Artifact artifact )
 169  
     {
 170  0
         return new File ( unpackedLibsDirectory.getAbsolutePath(),
 171  
                 getShortenedGroupId( artifact.getGroupId() )
 172  
                 + "_"
 173  
                 + artifact.getArtifactId()
 174  
                 + "_"
 175  
                 + artifact.getBaseVersion()
 176  
         );
 177  
     }
 178  
 
 179  
     public File getUnpackedClassesJar( Artifact artifact )
 180  
     {
 181  0
         return new File ( getUnpackedLibFolder( artifact ), SdkConstants.FN_CLASSES_JAR );
 182  
     }
 183  
 
 184  
     public File getUnpackedApkLibSourceFolder( Artifact artifact )
 185  
     {
 186  0
         return new File ( getUnpackedLibFolder( artifact ), "src" );
 187  
     }
 188  
 
 189  
     public File getUnpackedLibResourceFolder( Artifact artifact )
 190  
     {
 191  0
         return new File ( getUnpackedLibFolder( artifact ), "res" );
 192  
     }
 193  
 
 194  
     public File getUnpackedLibAssetsFolder( Artifact artifact )
 195  
     {
 196  0
         return new File ( getUnpackedLibFolder( artifact ), "assets" );
 197  
     }
 198  
 
 199  
     /**
 200  
      * @param artifact  Android dependency that is being referenced.
 201  
      * @return Folder where the unpacked native libraries are located.
 202  
      * @see http://tools.android.com/tech-docs/new-build-system/aar-format
 203  
      */
 204  
     public File getUnpackedLibNativesFolder( Artifact artifact )
 205  
     {
 206  0
         if ( AndroidExtension.AAR.equals( artifact.getType() ) )
 207  
         {
 208  0
             return new File ( getUnpackedLibFolder( artifact ), UnpackedLibHelper.AAR_NATIVE_LIBRARIES_FOLDER );
 209  
         }
 210  
         else
 211  
         {
 212  0
             return new File ( getUnpackedLibFolder( artifact ), UnpackedLibHelper.APKLIB_NATIVE_LIBRARIES_FOLDER );
 213  
         }
 214  
     }
 215  
 
 216  
     public File getJarFileForApk( Artifact artifact )
 217  
     {
 218  0
         final String fileName = artifact.getFile().getName();
 219  0
         final String modifiedFileName = fileName.substring( 0, fileName.lastIndexOf( "." ) ) + ".jar";
 220  0
         return new File ( artifact.getFile().getParentFile(), modifiedFileName );
 221  
     }
 222  
 
 223  
     /**
 224  
      * @param groupId   An a dot separated groupId (eg org.apache.maven)
 225  
      * @return A shortened (and potentially non-unique) version of the groupId, that consists of the first letter
 226  
      *      of each part of the groupId. Eg oam for org.apache.maven
 227  
      */
 228  
     private String getShortenedGroupId( String groupId )
 229  
     {
 230  0
         final String[] parts = groupId.split( "\\." );
 231  0
         final StringBuilder sb = new StringBuilder ();
 232  0
         for ( final String part : parts )
 233  
         {
 234  0
             sb.append( part.charAt( 0 ) );
 235  
         }
 236  0
         return sb.toString();
 237  
     }
 238  
 
 239  
     /**
 240  
      * @return True if this project constructs an APK as opposed to an AAR or APKLIB.
 241  
      */
 242  
     public boolean isAPKBuild( MavenProject project )
 243  
     {
 244  0
         return AndroidExtension.APK.equals( project.getPackaging() );
 245  
     }
 246  
 }