@@ -9,6 +9,8 @@ import helpers = require("../common/helpers");
9
9
import fs = require( "fs" ) ;
10
10
import os = require( "os" ) ;
11
11
12
+ import androidProjectPropertiesManagerLib = require( "./android-project-properties-manager" ) ;
13
+
12
14
class AndroidProjectService implements IPlatformProjectService {
13
15
private static MIN_SUPPORTED_VERSION = 17 ;
14
16
private SUPPORTED_TARGETS = [ "android-17" , "android-18" , "android-19" , "android-21" , "android-22" ] ; // forbidden for now: "android-MNC"
@@ -21,6 +23,7 @@ class AndroidProjectService implements IPlatformProjectService {
21
23
22
24
23
25
private targetApi : string ;
26
+ private _androidProjectPropertiesManagers : IDictionary < IAndroidProjectPropertiesManager > ;
24
27
25
28
constructor ( private $androidEmulatorServices : Mobile . IEmulatorPlatformServices ,
26
29
private $childProcess : IChildProcess ,
@@ -30,7 +33,9 @@ class AndroidProjectService implements IPlatformProjectService {
30
33
private $projectData : IProjectData ,
31
34
private $propertiesParser : IPropertiesParser ,
32
35
private $options : IOptions ,
33
- private $hostInfo : IHostInfo ) {
36
+ private $hostInfo : IHostInfo ,
37
+ private $injector : IInjector ) {
38
+ this . _androidProjectPropertiesManagers = Object . create ( null ) ;
34
39
}
35
40
36
41
private _platformData : IPlatformData = null ;
@@ -185,79 +190,45 @@ class AndroidProjectService implements IPlatformProjectService {
185
190
return this . $fs . exists ( path . join ( projectRoot , "assets" , constants . APP_FOLDER_NAME ) ) ;
186
191
}
187
192
188
- private parseProjectProperties ( projDir : string , destDir : string ) : IFuture < void > {
193
+ private getProjectPropertiesManager ( filePath : string ) : IAndroidProjectPropertiesManager {
194
+ if ( ! this . _androidProjectPropertiesManagers [ filePath ] ) {
195
+ this . _androidProjectPropertiesManagers [ filePath ] = this . $injector . resolve ( androidProjectPropertiesManagerLib . AndroidProjectPropertiesManager , { directoryPath : filePath } ) ;
196
+ }
197
+
198
+ return this . _androidProjectPropertiesManagers [ filePath ] ;
199
+ }
200
+
201
+ private parseProjectProperties ( projDir : string , destDir : string ) : IFuture < void > { // projDir is libraryPath, targetPath is the path to lib folder
189
202
return ( ( ) => {
190
203
let projProp = path . join ( projDir , "project.properties" ) ;
191
-
192
204
if ( ! this . $fs . exists ( projProp ) . wait ( ) ) {
193
205
this . $logger . warn ( "Warning: File %s does not exist" , projProp ) ;
194
206
return ;
195
207
}
196
-
197
- let lines = this . $fs . readText ( projProp , "utf-8" ) . wait ( ) . split ( os . EOL ) ;
198
-
199
- let regEx = / a n d r o i d \. l i b r a r y \. r e f e r e n c e \. ( \d + ) = ( .* ) / ;
200
- lines . forEach ( elem => {
201
- let match = elem . match ( regEx ) ;
202
- if ( match ) {
203
- let libRef : ILibRef = { idx : parseInt ( match [ 1 ] ) , path : match [ 2 ] . trim ( ) } ;
204
- libRef . adjustedPath = this . $fs . isRelativePath ( libRef . path ) ? path . join ( projDir , libRef . path ) : libRef . path ;
205
- this . parseProjectProperties ( libRef . adjustedPath , destDir ) . wait ( ) ;
206
- }
208
+
209
+ let projectPropertiesManager = this . getProjectPropertiesManager ( projDir ) ;
210
+ let references = projectPropertiesManager . getProjectReferences ( ) . wait ( ) ;
211
+ _ . each ( references , reference => {
212
+ let adjustedPath = this . $fs . isRelativePath ( reference . path ) ? path . join ( projDir , reference . path ) : reference . path ;
213
+ this . parseProjectProperties ( adjustedPath , destDir ) . wait ( ) ;
207
214
} ) ;
208
215
209
216
this . $logger . info ( "Copying %s" , projDir ) ;
210
217
shell . cp ( "-Rf" , projDir , destDir ) ;
211
218
212
219
let targetDir = path . join ( destDir , path . basename ( projDir ) ) ;
213
- // TODO: parametrize targetSdk
214
- let targetSdk = "android-17" ;
220
+ let targetSdk = `android-${ this . $options . sdk || 17 } ` ;
215
221
this . $logger . info ( "Generate build.xml for %s" , targetDir ) ;
216
222
this . runAndroidUpdate ( targetDir , targetSdk ) . wait ( ) ;
217
223
} ) . future < void > ( ) ( ) ;
218
224
}
219
225
220
- private getProjectReferences ( projDir : string ) : ILibRef [ ] {
221
- let projProp = path . join ( projDir , "project.properties" ) ;
222
-
223
- let lines = this . $fs . readText ( projProp , "utf-8" ) . wait ( ) . split ( os . EOL ) ;
224
-
225
- let refs : ILibRef [ ] = [ ] ;
226
-
227
- let regEx = / a n d r o i d \. l i b r a r y \. r e f e r e n c e \. ( \d + ) = ( .* ) / ;
228
- lines . forEach ( elem => {
229
- let match = elem . match ( regEx ) ;
230
- if ( match ) {
231
- let libRef : ILibRef = { idx : parseInt ( match [ 1 ] ) , path : match [ 2 ] } ;
232
- libRef . adjustedPath = path . join ( projDir , libRef . path ) ;
233
- libRef . key = match [ 0 ] . split ( "=" ) [ 0 ] ;
234
- refs . push ( libRef ) ;
235
- }
236
- } ) ;
237
-
238
- return refs ;
239
- }
240
-
241
- private updateProjectReferences ( projDir : string , libraryPath : string ) : void {
242
- let refs = this . getProjectReferences ( projDir ) ;
243
- let maxIdx = refs . length > 0 ? _ . max ( refs , r => r . idx ) . idx : 0 ;
244
-
245
- let relLibDir = path . relative ( projDir , libraryPath ) . split ( "\\" ) . join ( "/" ) ;
246
-
247
- let libRefExists = _ . any ( refs , r => path . normalize ( r . path ) === path . normalize ( relLibDir ) ) ;
248
-
249
- if ( ! libRefExists ) {
250
- let projRef = util . format ( "%sandroid.library.reference.%d=%s" , os . EOL , maxIdx + 1 , relLibDir ) ;
251
- let projProp = path . join ( projDir , "project.properties" ) ;
252
- fs . appendFileSync ( projProp , projRef , { encoding : "utf-8" } ) ;
253
- }
254
- }
255
-
256
226
public addLibrary ( platformData : IPlatformData , libraryPath : string ) : IFuture < void > {
257
227
return ( ( ) => {
258
228
let name = path . basename ( libraryPath ) ;
259
- let projDir = this . $projectData . projectDir ;
260
- let targetPath = path . join ( projDir , "lib" , platformData . normalizedPlatformName ) ;
229
+ let targetLibPath = this . getLibraryPath ( name ) ;
230
+
231
+ let targetPath = path . dirname ( targetLibPath ) ;
261
232
this . $fs . ensureDirectoryExists ( targetPath ) . wait ( ) ;
262
233
263
234
this . parseProjectProperties ( libraryPath , targetPath ) . wait ( ) ;
@@ -267,11 +238,9 @@ class AndroidProjectService implements IPlatformProjectService {
267
238
this . $fs . ensureDirectoryExists ( projectLibsDir ) . wait ( ) ;
268
239
shell . cp ( "-f" , path . join ( libraryPath , "*.jar" ) , projectLibsDir ) ;
269
240
270
- let targetLibPath = path . join ( targetPath , path . basename ( libraryPath ) ) ;
271
-
272
241
let libProjProp = path . join ( libraryPath , "project.properties" ) ;
273
242
if ( this . $fs . exists ( libProjProp ) . wait ( ) ) {
274
- this . updateProjectReferences ( platformData . projectRoot , targetLibPath ) ;
243
+ this . updateProjectReferences ( platformData . projectRoot , targetLibPath ) . wait ( ) ;
275
244
}
276
245
} ) . future < void > ( ) ( ) ;
277
246
}
@@ -290,54 +259,61 @@ class AndroidProjectService implements IPlatformProjectService {
290
259
let libsFolderContents = this . $fs . readDirectory ( libsFolderPath ) . wait ( ) ;
291
260
_ ( libsFolderContents )
292
261
. filter ( libsFolderItem => path . extname ( libsFolderItem ) === ".jar" )
293
- . map ( jar => this . addLibrary ( this . platformData , path . join ( libsFolderPath , jar ) ) . wait ( ) ) ;
262
+ . map ( jar => this . addLibrary ( this . platformData , path . join ( libsFolderPath , jar ) ) . wait ( ) )
263
+ . value ( ) ;
294
264
}
295
265
296
266
// Handle android libraries
297
- let androidLibraries = this . getAllAndroidLibrariesForPlugin ( pluginData ) . wait ( ) ;
298
- _ . each ( androidLibraries , androidLibraryName => this . addLibrary ( this . platformData , path . join ( pluginPlatformsFolderPath , androidLibraryName ) ) . wait ( ) ) ;
299
-
267
+ let librarries = this . getAllLibrariesForPlugin ( pluginData ) . wait ( ) ;
268
+ _ . each ( librarries , libraryName => this . addLibrary ( this . platformData , path . join ( pluginPlatformsFolderPath , libraryName ) ) . wait ( ) ) ;
300
269
} ) . future < void > ( ) ( ) ;
301
270
}
302
271
303
272
public removePluginNativeCode ( pluginData : IPluginData ) : IFuture < void > {
304
273
return ( ( ) => {
305
- let projectReferences = this . getProjectReferences ( this . platformData . projectRoot ) ;
306
- let androidLibraries = this . getAllAndroidLibrariesForPlugin ( pluginData ) . wait ( ) ;
274
+ let projectPropertiesManager = this . getProjectPropertiesManager ( this . platformData . projectRoot ) ;
307
275
308
- let file = path . join ( this . platformData . projectRoot , "project.properties" ) ;
309
- let editor = this . $propertiesParser . createEditor ( file ) . wait ( ) ;
310
-
311
- _ . each ( androidLibraries , androidLibraryName => {
312
- // Remove library from project.properties
313
- let androidLibraryNameLowerCase = androidLibraryName . toLowerCase ( ) ;
314
- let projectReference = _ . find ( projectReferences , projectReference => _ . last ( projectReference . adjustedPath . split ( path . sep ) ) . toLowerCase ( ) === androidLibraryNameLowerCase ) ;
315
- if ( projectReference && projectReference . key ) {
316
- editor . unset ( projectReference . key ) ;
317
- }
318
-
319
- // Remove library from lib folder
320
- this . $fs . deleteDirectory ( path . join ( this . $projectData . projectDir , "lib" , this . platformData . normalizedPlatformName , androidLibraryName ) ) . wait ( ) ;
276
+ let libraries = this . getAllLibrariesForPlugin ( pluginData ) . wait ( ) ;
277
+ _ . each ( libraries , libraryName => {
278
+ let libPath = this . getLibraryRelativePath ( this . platformData . projectRoot , this . getLibraryPath ( libraryName ) ) ;
279
+ projectPropertiesManager . removeProjectReference ( path . relative ( this . platformData . projectRoot , libPath ) ) . wait ( ) ;
280
+ this . $fs . deleteDirectory ( libPath ) . wait ( ) ;
321
281
} ) ;
322
282
323
- this . $propertiesParser . saveEditor ( ) . wait ( ) ;
324
-
325
283
} ) . future < void > ( ) ( ) ;
326
284
}
327
285
328
286
private getPluginPlatformsFolderPath ( pluginData : IPluginData ) {
329
287
return pluginData . pluginPlatformsFolderPath ( AndroidProjectService . ANDROID_PLATFORM_NAME ) ;
330
288
}
331
289
332
- private getAllAndroidLibrariesForPlugin ( pluginData : IPluginData ) : IFuture < string [ ] > {
290
+ private getLibraryRelativePath ( basePath : string , libraryPath : string ) : string {
291
+ return path . relative ( basePath , libraryPath ) . split ( "\\" ) . join ( "/" ) ;
292
+ }
293
+
294
+ private getLibraryPath ( libraryName : string ) : string {
295
+ return path . join ( this . $projectData . projectDir , "lib" , this . platformData . normalizedPlatformName , libraryName ) ;
296
+ }
297
+
298
+ private updateProjectReferences ( projDir : string , libraryPath : string ) : IFuture < void > {
299
+ let relLibDir = this . getLibraryRelativePath ( projDir , libraryPath ) ;
300
+
301
+ let projectPropertiesManager = this . getProjectPropertiesManager ( projDir ) ;
302
+ return projectPropertiesManager . addProjectReference ( relLibDir ) ;
303
+ }
304
+
305
+ private getAllLibrariesForPlugin ( pluginData : IPluginData ) : IFuture < string [ ] > {
333
306
return ( ( ) => {
334
307
let pluginPlatformsFolderPath = this . getPluginPlatformsFolderPath ( pluginData ) ;
335
- let platformsContents = this . $fs . readDirectory ( pluginPlatformsFolderPath ) . wait ( ) ;
336
- return _ ( platformsContents )
337
- . filter ( platformItemName => platformItemName !== AndroidProjectService . LIBS_FOLDER_NAME &&
338
- this . $fs . exists ( path . join ( pluginPlatformsFolderPath , platformItemName , "project.properties" ) ) . wait ( ) )
339
- . map ( androidLibraryName => androidLibraryName )
340
- . value ( ) ;
308
+ if ( pluginPlatformsFolderPath && this . $fs . exists ( pluginPlatformsFolderPath ) . wait ( ) ) {
309
+ let platformsContents = this . $fs . readDirectory ( pluginPlatformsFolderPath ) . wait ( ) ;
310
+ return _ ( platformsContents )
311
+ . filter ( platformItemName => platformItemName !== AndroidProjectService . LIBS_FOLDER_NAME &&
312
+ this . $fs . exists ( path . join ( pluginPlatformsFolderPath , platformItemName , "project.properties" ) ) . wait ( ) )
313
+ . value ( ) ;
314
+ }
315
+
316
+ return [ ] ;
341
317
} ) . future < string [ ] > ( ) ( ) ;
342
318
}
343
319
0 commit comments