3838import java .util .logging .Level ;
3939import java .util .logging .Logger ;
4040import java .lang .UnsatisfiedLinkError ;
41- import electrostatic .snaploader .filesystem .ExtractionListener ;
41+ import electrostatic .snaploader .filesystem .FileExtractionListener ;
4242import electrostatic .snaploader .filesystem .FileExtractor ;
43+ import electrostatic .snaploader .filesystem .FileLocalizingListener ;
4344import electrostatic .snaploader .filesystem .FileLocator ;
4445import electrostatic .snaploader .library .LibraryExtractor ;
46+ import electrostatic .snaploader .library .LibraryLocator ;
4547import electrostatic .snaploader .platform .NativeDynamicLibrary ;
4648import electrostatic .snaploader .platform .util .NativeVariant ;
4749
@@ -66,6 +68,10 @@ public class NativeBinaryLoader {
6668
6769 protected SystemDetectionListener systemDetectionListener ;
6870
71+ protected FileLocalizingListener libraryLocalizingListener ;
72+
73+ protected FileExtractionListener libraryExtractionListener ;
74+
6975 /**
7076 * An Output stream concrete provider for library extraction.
7177 */
@@ -221,14 +227,30 @@ public NativeBinaryLoadingListener getNativeBinaryLoadingListener() {
221227 return nativeBinaryLoadingListener ;
222228 }
223229
224- public void setSystemFoundListener (SystemDetectionListener systemDetectionListener ) {
230+ public void setSystemDetectionListener (SystemDetectionListener systemDetectionListener ) {
225231 this .systemDetectionListener = systemDetectionListener ;
226232 }
227233
228- public SystemDetectionListener getSystemFoundListener () {
234+ public SystemDetectionListener getSystemDetectionListener () {
229235 return systemDetectionListener ;
230236 }
231237
238+ public void setLibraryExtractionListener (FileExtractionListener libraryExtractionListener ) {
239+ this .libraryExtractionListener = libraryExtractionListener ;
240+ }
241+
242+ public FileExtractionListener getLibraryExtractionListener () {
243+ return libraryExtractionListener ;
244+ }
245+
246+ public void setLibraryLocalizingListener (FileLocalizingListener libraryLocalizingListener ) {
247+ this .libraryLocalizingListener = libraryLocalizingListener ;
248+ }
249+
250+ public FileLocalizingListener getLibraryLocalizingListener () {
251+ return libraryLocalizingListener ;
252+ }
253+
232254 /**
233255 * Loads a native binary using the platform dependent object, for android,
234256 * the library is loaded by its basename (variant is managed internally by the android sdk).
@@ -272,24 +294,39 @@ protected void loadBinary(NativeDynamicLibrary library) throws IOException {
272294 */
273295 protected void cleanExtractBinary (NativeDynamicLibrary library ) throws IOException {
274296 libraryExtractor = initializeLibraryExtractor (library );
297+ log (Level .INFO , "cleanExtractBinary" , "File extractor handler initialized!" , null );
275298 /* CLEAR RESOURCES AND RESET OBJECTS ON-EXTRACTION */
276- libraryExtractor .setExtractionListener (new ExtractionListener () {
299+ libraryExtractor .setExtractionListener (new FileExtractionListener () {
277300 @ Override
278301 public void onExtractionCompleted (FileExtractor fileExtractor ) {
279302 try {
303+ // free resources
304+ // removes file locks on some OS
280305 libraryExtractor .getFileLocator ().close ();
281306 libraryExtractor .close ();
282307 libraryExtractor = null ;
283308 log (Level .INFO , "cleanExtractBinary" , "Extracted successfully to " + library .getExtractedLibrary (), null );
309+ log (Level .INFO , "cleanExtractBinary" , "Filesystem Resources closed!" , null );
310+ // load the native binary
284311 loadBinary (library );
285312 } catch (Exception e ) {
286313 log (Level .SEVERE , "cleanExtractBinary" , "Error while loading the binary!" , e );
287314 }
315+
316+ // bind the extraction lifecycle to the user application
317+ if (libraryExtractionListener != null ) {
318+ libraryExtractionListener .onExtractionCompleted (fileExtractor );
319+ }
288320 }
289321
290322 @ Override
291323 public void onExtractionFailure (FileExtractor fileExtractor , Throwable throwable ) {
292324 log (Level .SEVERE , "cleanExtractBinary" , "Extraction has failed!" , throwable );
325+
326+ // bind the extraction lifecycle to the user application
327+ if (libraryExtractionListener != null ) {
328+ libraryExtractionListener .onExtractionFailure (fileExtractor , throwable );
329+ }
293330 }
294331
295332 @ Override
@@ -298,31 +335,76 @@ public void onExtractionFinalization(FileExtractor fileExtractor, FileLocator fi
298335 if (fileLocator != null &&
299336 fileLocator .getFileInputStream () != null ) {
300337 fileLocator .close ();
338+ log (Level .INFO , "cleanExtractBinary" , "File locator Resources closed!" , null );
301339 }
302340 if (fileExtractor != null &&
303341 fileExtractor .getFileOutputStream () != null ) {
304342 fileExtractor .close ();
343+ log (Level .INFO , "cleanExtractBinary" , "File extractor Resources closed!" , null );
305344 }
306345 } catch (IOException e ) {
307346 log (Level .SEVERE , "cleanExtractBinary" , "Error while closing the resources!" , e );
308347 }
348+
349+ // bind the extraction lifecycle to the user application
350+ if (libraryExtractionListener != null ) {
351+ libraryExtractionListener .onExtractionFinalization (fileExtractor , fileLocator );
352+ }
309353 }
310354 });
311355 libraryExtractor .extract ();
312356 }
313357
314358 /**
315- * Initializes a filesystem extrator object if the filesystem extractor object associated with this loader isnot defined.
359+ * Initializes a filesystem extractor object
360+ * if the filesystem extractor object associated with this loader isn't defined.
316361 *
317362 * @param library the native dynamic library to load
318363 * @return a new FileExtractor object that represents an output stream provider
319364 * @throws IOException if the jar filesystem to be located is not found, or if the extraction destination is not found
320365 */
321366 protected FileExtractor initializeLibraryExtractor (NativeDynamicLibrary library ) throws IOException {
367+ FileExtractor extractor ;
322368 if (library .getJarPath () != null ) {
323- return new LibraryExtractor (library .getJarPath (), library .getCompressedLibrary (), library .getExtractedLibrary ());
369+ extractor = new LibraryExtractor (library .getJarPath (), library .getCompressedLibrary (), library .getExtractedLibrary ());
370+ } else {
371+ extractor = new LibraryExtractor (library .getCompressedLibrary (), library .getExtractedLibrary ());
324372 }
325- return new LibraryExtractor (library .getCompressedLibrary (), library .getExtractedLibrary ());
373+ final LibraryLocator fileLocator = preInitLibraryLocator (extractor );
374+ fileLocator .initializeLocator ();
375+ return extractor ;
376+ }
377+
378+ protected LibraryLocator preInitLibraryLocator (FileExtractor extractor ) {
379+ extractor .getFileLocator ().setFileLocalizingListener (new FileLocalizingListener () {
380+ @ Override
381+ public void onFileLocalizationSuccess (FileLocator locator ) {
382+ log (Level .INFO , "initializeLibraryExtractor" , "Locating native libraries has succeeded!" , null );
383+
384+ // bind the library locator lifecycle to the user application
385+ if (libraryLocalizingListener != null ) {
386+ libraryLocalizingListener .onFileLocalizationSuccess (locator );
387+ }
388+ }
389+
390+ @ Override
391+ public void onFileLocalizationFailure (FileLocator locator , Throwable throwable ) {
392+ log (Level .SEVERE , "initializeLibraryExtractor" , "Locating native libraries has failed!" , throwable );
393+ try {
394+ extractor .close ();
395+ locator .close ();
396+ log (Level .INFO , "initializeLibraryExtractor" , "Filesystem resources closed!" , null );
397+ } catch (IOException e ) {
398+ log (Level .SEVERE , "initializeLibraryExtractor" , "File locator closure failed!" , e );
399+ }
400+
401+ // bind the library locator lifecycle to the user application
402+ if (libraryLocalizingListener != null ) {
403+ libraryLocalizingListener .onFileLocalizationFailure (locator , throwable );
404+ }
405+ }
406+ });
407+ return (LibraryLocator ) extractor .getFileLocator ();
326408 }
327409
328410 /**
0 commit comments