3434
3535import electrostatic4j .snaploader .throwable .FilesystemResourceInitializationException ;
3636import electrostatic4j .snaploader .util .SnapLoaderLogger ;
37-
3837import java .io .*;
3938import java .util .logging .Level ;
4039import java .util .zip .ZipEntry ;
4645 *
4746 * @author pavl_g
4847 */
49- public class FileLocator implements InputStreamProvider {
48+ public class FileLocator implements ZipStreamProvider {
5049
5150 /**
5251 * The input stream associated with the located filesystem.
@@ -59,27 +58,39 @@ public class FileLocator implements InputStreamProvider {
5958 */
6059 protected FileLocalizingListener fileLocalizingListener ;
6160
62- protected String directory ;
61+ protected ZipFile compression ;
62+
63+ protected String compressionPath ;
6364
6465 protected String filePath ;
6566
6667 protected ZipCompressionType compressionType ;
6768
69+ /**
70+ * Locates the library inside the stock jar filesystem.
71+ * This object leaks an input stream.
72+ *
73+ * @param filePath the path to the dynamic native library inside that jar filesystem
74+ */
75+ public FileLocator (String filePath ) {
76+ this .filePath = filePath ;
77+ }
78+
6879 /**
6980 * Locates a filesystem inside an external zip compression, the zip filesystem is defined as a {@link ZipFile} object and
7081 * the locatable filesystem is defined as a {@link ZipEntry} object.
7182 * <p>
7283 * Warning: This object leaks a buffered stream, either use try-with-resources, or handle your
7384 * memory manually!
7485 *
75- * @param directory the absolute path for the external jar filesystem
86+ * @param compressionPath the absolute path for the external jar filesystem
7687 * @param filePath the path to the filesystem to be extracted
7788 * @param compressionType the type of the zip compression, ZIP or JAR
7889 *
7990 * @throws IOException if the jar to be located is not found or an interrupted I/O exception has occured
8091 */
81- public FileLocator (String directory , String filePath , ZipCompressionType compressionType ) throws IOException {
82- this .directory = directory ;
92+ public FileLocator (String compressionPath , String filePath , ZipCompressionType compressionType ) throws IOException {
93+ this .compressionPath = compressionPath ;
8394 this .filePath = filePath ;
8495 this .compressionType = compressionType ;
8596 }
@@ -94,53 +105,54 @@ protected FileLocator() {
94105 @ Override
95106 public void initialize (int size ) throws IOException {
96107 // 1) sanity-check for double initializing
97- // 2) sanity-check for pre-initialization using other routines
98- // (e.g., classpath resources stream).
99108 if (this .fileInputStream != null ) {
100109 SnapLoaderLogger .log (Level .INFO , getClass ().getName (), "initialize(int)" ,
101110 "File locator already initialized using external routines with hash key #" + getHashKey ());
102111 return ;
103112 }
104113 try {
105- final ZipFile compression = compressionType .createNewCompressionObject (directory );
106- final ZipEntry zipEntry = compression .getEntry (filePath );
107- validateFileLocalization (zipEntry );
108- if (size > 0 ) {
109- this .fileInputStream = new BufferedInputStream (compression .getInputStream (zipEntry ), size );
110- SnapLoaderLogger .log (Level .INFO , getClass ().getName (), "initialize(int)" ,
111- "File locator initialized with hash key #" + getHashKey ());
112- return ;
114+
115+ // 2) sanity-check for initialization routines
116+ // (e.g., classpath resources stream v.s. external compression).
117+ if (compressionPath == null || compressionType == null ) {
118+ classPathRoutine ();
119+ } else {
120+ externalCompressionRoutine (size );
121+ }
122+
123+ // fire the success listener if the file localization has passed!
124+ if (fileLocalizingListener != null ) {
125+ fileLocalizingListener .onFileLocalizationSuccess (this );
113126 }
114- this .fileInputStream = compression .getInputStream (zipEntry );
115- SnapLoaderLogger .log (Level .INFO , getClass ().getName (), "initialize(int)" ,
116- "File locator initialized with hash key #" + getHashKey ());
117127 } catch (Exception e ) {
118128 close ();
119- throw new FilesystemResourceInitializationException (
129+ final FilesystemResourceInitializationException exception = new FilesystemResourceInitializationException (
120130 "Failed to initialize the file locator handler #" + getHashKey (), e );
131+ // fire the failure listener when file localization fails and pass
132+ // the causative exception
133+ if (fileLocalizingListener != null ) {
134+ fileLocalizingListener .onFileLocalizationFailure (this , exception );
135+ }
136+ throw exception ;
121137 }
122138 }
123139
124- /**
125- * Validates the file localization process inside the compression.
126- *
127- * @throws FileNotFoundException if the localization of the file inside
128- * the specified compression has failed.
129- */
130- protected void validateFileLocalization (final ZipEntry zipEntry ) throws FileNotFoundException {
131- if (zipEntry != null ) {
132- if (fileLocalizingListener != null ) {
133- fileLocalizingListener .onFileLocalizationSuccess (this );
134- }
135- } else {
136- final FileNotFoundException fileNotFoundException =
137- new FileNotFoundException ("File locator has failed to locate the file inside the compression!" );
140+ protected void classPathRoutine () {
141+ SnapLoaderLogger .log (Level .INFO , getClass ().getName (), "initialize(int)" ,
142+ "File locator initialized using classpath routine with hash key #" + getHashKey ());
143+ this .fileInputStream = getClass ().getResourceAsStream (filePath );
144+ }
138145
139- if (fileLocalizingListener != null ) {
140- fileLocalizingListener .onFileLocalizationFailure (this , fileNotFoundException );
141- }
142- throw fileNotFoundException ;
146+ protected void externalCompressionRoutine (int size ) throws IOException {
147+ this .compression = compressionType .createNewCompressionObject (compressionPath );
148+ final ZipEntry zipEntry = compression .getEntry (filePath );
149+ if (size > 0 ) {
150+ this .fileInputStream = new BufferedInputStream (compression .getInputStream (zipEntry ), size );
151+ } else {
152+ this .fileInputStream = compression .getInputStream (zipEntry );
143153 }
154+ SnapLoaderLogger .log (Level .INFO , getClass ().getName (), "initialize(int)" ,
155+ "File locator initialized using external compression routine with hash key #" + getHashKey ());
144156 }
145157
146158 @ Override
@@ -150,10 +162,24 @@ public InputStream getFileInputStream() {
150162
151163 @ Override
152164 public void close () throws IOException {
165+ // this is executed in all routines
166+ // it updates the CleanableResource object
167+ // for the Compression Routines
153168 if (fileInputStream != null ) {
154169 fileInputStream .close ();
155170 fileInputStream = null ;
156171 }
172+
173+ // this will be bypassed in the case of using other non-compression routines to
174+ // initialize the file streams (e.g., the classpath routines).
175+ if (compression != null ) {
176+ // this closes all the streams associated with it (if they are not closed)
177+ // aka.
178+ // the file entries stream
179+ // and the native resources for this object
180+ compression .close ();
181+ compression = null ;
182+ }
157183 SnapLoaderLogger .log (Level .INFO , getClass ().getName (),
158184 "close" , "File locator #" + getHashKey () + " resources closed!" );
159185 }
@@ -162,4 +188,9 @@ public void close() throws IOException {
162188 public void setFileLocalizingListener (FileLocalizingListener fileLocalizingListener ) {
163189 this .fileLocalizingListener = fileLocalizingListener ;
164190 }
191+
192+ @ Override
193+ public ZipFile getCompression () {
194+ return compression ;
195+ }
165196}
0 commit comments