1
2
3
4
5
6
7
8
9
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
30
31 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
41 private final File unpackedLibsDirectory;
42
43 public UnpackedLibHelper ( ArtifactResolverHelper artifactResolverHelper, MavenProject project, Logger log,
44 File unpackedLibsFolder )
45 {
46 this.artifactResolverHelper = artifactResolverHelper;
47 if ( unpackedLibsFolder != null )
48 {
49
50
51 this.unpackedLibsDirectory = unpackedLibsFolder.isAbsolute()
52 ? unpackedLibsFolder
53 : new File ( project.getBasedir(), unpackedLibsFolder.getPath() );
54 }
55 else
56 {
57
58 final File targetFolder = new File ( project.getBuild().getDirectory() );
59 this.unpackedLibsDirectory = new File ( targetFolder, "unpacked-libs" );
60 }
61 this.log = log;
62 }
63
64 public void extractApklib( Artifact apklibArtifact ) throws MojoExecutionException
65 {
66 final File apkLibFile = artifactResolverHelper.resolveArtifactToFile( apklibArtifact );
67 if ( apkLibFile.isDirectory() )
68 {
69 log.warn(
70 "The apklib artifact points to '" + apkLibFile + "' which is a directory; skipping unpacking it." );
71 return;
72 }
73
74 final UnArchiver unArchiver = new ZipUnArchiver ( apkLibFile )
75 {
76 @Override
77 protected Logger getLogger()
78 {
79 return new ConsoleLogger( log.getThreshold(), "dependencies-unarchiver" );
80 }
81 };
82
83 final File apklibDirectory = getUnpackedLibFolder( apklibArtifact );
84 apklibDirectory.mkdirs();
85 unArchiver.setDestDirectory( apklibDirectory );
86 log.debug( "Extracting APKLIB to " + apklibDirectory );
87 try
88 {
89 unArchiver.extract();
90 }
91 catch ( ArchiverException e )
92 {
93 throw new MojoExecutionException ( "ArchiverException while extracting " + apklibDirectory
94 + ". Message: " + e.getLocalizedMessage(), e );
95 }
96 }
97
98 public void extractAarLib( Artifact aarArtifact ) throws MojoExecutionException
99 {
100 final File aarFile = artifactResolverHelper.resolveArtifactToFile( aarArtifact );
101 if ( aarFile.isDirectory() )
102 {
103 log.warn(
104 "The aar artifact points to '" + aarFile + "' which is a directory; skipping unpacking it." );
105 return;
106 }
107
108 final UnArchiver unArchiver = new ZipUnArchiver ( aarFile )
109 {
110 @Override
111 protected Logger getLogger()
112 {
113 return new ConsoleLogger( log.getThreshold(), "dependencies-unarchiver" );
114 }
115 };
116
117 final File aarDirectory = getUnpackedLibFolder( aarArtifact );
118 aarDirectory.mkdirs();
119 unArchiver.setDestDirectory( aarDirectory );
120 log.debug( "Extracting AAR to " + aarDirectory );
121 try
122 {
123 unArchiver.extract();
124 }
125 catch ( ArchiverException e )
126 {
127 throw new MojoExecutionException ( "ArchiverException while extracting " + aarDirectory.getAbsolutePath()
128 + ". Message: " + e.getLocalizedMessage(), e );
129 }
130
131
132
133 final File jniFolder = new File ( aarDirectory, UnpackedLibHelper.AAR_NATIVE_LIBRARIES_FOLDER );
134 final File libsFolder = new File ( aarDirectory, UnpackedLibHelper.APKLIB_NATIVE_LIBRARIES_FOLDER );
135 if ( !jniFolder.exists() && libsFolder.isDirectory() && libsFolder.exists() )
136 {
137 String[] natives = libsFolder.list( new PatternFilenameFilter( "^.*(?<!(?i)\\.jar)$" ) );
138 if ( natives.length > 0 )
139 {
140 log.debug( "Moving AAR native libraries from libs to jni folder" );
141 for ( String nativeLibPath : natives )
142 {
143 try
144 {
145 FileUtils.moveToDirectory( new File ( libsFolder, nativeLibPath ), jniFolder, true );
146 }
147 catch ( IOException e )
148 {
149 throw new MojoExecutionException (
150 "Could not move native libraries from " + libsFolder, e );
151 }
152 }
153 }
154 }
155 }
156
157 public File getArtifactToFile( Artifact artifact ) throws MojoExecutionException
158 {
159 final File artifactFile = artifactResolverHelper.resolveArtifactToFile( artifact );
160 return artifactFile;
161 }
162
163 public File getUnpackedLibsFolder()
164 {
165 return unpackedLibsDirectory;
166 }
167
168 public File getUnpackedLibFolder( Artifact artifact )
169 {
170 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 return new File ( getUnpackedLibFolder( artifact ), SdkConstants.FN_CLASSES_JAR );
182 }
183
184 public File getUnpackedApkLibSourceFolder( Artifact artifact )
185 {
186 return new File ( getUnpackedLibFolder( artifact ), "src" );
187 }
188
189 public File getUnpackedLibResourceFolder( Artifact artifact )
190 {
191 return new File ( getUnpackedLibFolder( artifact ), "res" );
192 }
193
194 public File getUnpackedLibAssetsFolder( Artifact artifact )
195 {
196 return new File ( getUnpackedLibFolder( artifact ), "assets" );
197 }
198
199
200
201
202
203
204 public File getUnpackedLibNativesFolder( Artifact artifact )
205 {
206 if ( AndroidExtension.AAR.equals( artifact.getType() ) )
207 {
208 return new File ( getUnpackedLibFolder( artifact ), UnpackedLibHelper.AAR_NATIVE_LIBRARIES_FOLDER );
209 }
210 else
211 {
212 return new File ( getUnpackedLibFolder( artifact ), UnpackedLibHelper.APKLIB_NATIVE_LIBRARIES_FOLDER );
213 }
214 }
215
216 public File getJarFileForApk( Artifact artifact )
217 {
218 final String fileName = artifact.getFile().getName();
219 final String modifiedFileName = fileName.substring( 0, fileName.lastIndexOf( "." ) ) + ".jar";
220 return new File ( artifact.getFile().getParentFile(), modifiedFileName );
221 }
222
223
224
225
226
227
228 private String getShortenedGroupId( String groupId )
229 {
230 final String[] parts = groupId.split( "\\." );
231 final StringBuilder sb = new StringBuilder ();
232 for ( final String part : parts )
233 {
234 sb.append( part.charAt( 0 ) );
235 }
236 return sb.toString();
237 }
238
239
240
241
242 public boolean isAPKBuild( MavenProject project )
243 {
244 return AndroidExtension.APK.equals( project.getPackaging() );
245 }
246 }