/** * Untar an input file into an output file. * * <p>The output file is created in the output folder, having the same name as the input file, * minus the '.tar' extension. * * @param archiveFile input TAR file * @param lastModified when collection has been last modified * @throws FileNotFoundException * @throws ArchiveException */ private static List<FileWithMeta> performUnTar( File archiveFile, IonConfig config, Collection collection, String lastModified, Context context) throws FileNotFoundException, IOException, ArchiveException { File collectionFolder = FilePaths.getCollectionFolderPath(config, context); File collectionFolderTemp = FilePaths.getTempFilePath(collectionFolder); final List<FileWithMeta> untaredFiles = new LinkedList<>(); InputStream is = null; TarArchiveInputStream debInputStream = null; try { IonLog.d( TAG, String.format( "Untaring %s to dir %s.", archiveFile.getPath(), collectionFolder.getPath())); is = new FileInputStream(archiveFile); debInputStream = (TarArchiveInputStream) new ArchiveStreamFactory().createArchiveInputStream("tar", is); TarArchiveEntry entry; List<ArchiveIndex> index = null; boolean indexHasBeenRead = false; while ((entry = (TarArchiveEntry) debInputStream.getNextEntry()) != null) { if (!indexHasBeenRead) { // get index.json InputStreamReader inputStreamReader = new InputStreamReader(debInputStream, "UTF-8"); index = Arrays.asList( GsonHolder.getInstance().fromJson(inputStreamReader, ArchiveIndex[].class)); indexHasBeenRead = true; continue; } // write the "content" files if (!entry.isDirectory()) { String archiveFileName = entry.getName(); ArchiveIndex fileInfo = ArchiveIndex.getByName(archiveFileName, index); if (fileInfo == null) { IonLog.w( TAG, "Skipping " + entry.getName() + " because it was not found in index.json."); continue; } IonLog.i(TAG, fileInfo.url); FileWithMeta fileWithMeta = getFilePath(fileInfo, collectionFolderTemp, config, context); File targetFile = fileWithMeta.file; FileUtils.createDir(targetFile.getParentFile()); targetFile = FileUtils.writeToFile(debInputStream, targetFile); if (targetFile != null) { untaredFiles.add(fileWithMeta); } } } } finally { // finished reading TAR archive if (is != null) { is.close(); } if (debInputStream != null) { debInputStream.close(); } if (archiveFile != null && archiveFile.exists()) { archiveFile.delete(); } } // if lastModified date was not passed, look if cache index entry exists for collection and // retrieve it from there if (collection != null && lastModified == null) { CollectionCacheIndex collectionCacheIndex = CollectionCacheIndex.retrieve(config, context); lastModified = collectionCacheIndex == null ? null : collectionCacheIndex.getLastModified(); IonLog.d(TAG, "Restoring last_modified from cache index: " + lastModified); } // delete old cache index entries of the collection in shared preferences and in memory cache CacheIndexStore.clearCollection(config, context); MemoryCache.clear(); // replace collection folder (containing json files) - deletes old file cache boolean jsonWriteSuccess = FileUtils.move(collectionFolderTemp, collectionFolder, true); if (!jsonWriteSuccess) { throw new IOException("JSON files could not be moved to final path."); } // replace media files in collection File mediaFolderTemp = FilePaths.getMediaFolderPath(config, context, true); File mediaFolder = FilePaths.getMediaFolderPath(config, context, false); if (mediaFolderTemp.exists()) { boolean mediaWriteSuccess = FileUtils.move(mediaFolderTemp, mediaFolder, true); if (!mediaWriteSuccess) { throw new IOException("Media files could not be moved to final path."); } } else { IonLog.w(TAG, "No media files were contained in archive."); } // add collection to file cache again if (collection != null) { MemoryCache.saveCollection(collection, config, context); try { saveCollectionToFileCache(config, collection, context); CollectionCacheIndex.save(config, context, lastModified); } catch (IOException e) { IonLog.e("ION Archive", "Collection could not be saved."); IonLog.ex(e); } } // cache index entries are not written yet at this point return untaredFiles; }
public static void e(String message) { e(defaultTag, message); }