package com.stardust.scriptdroid.script; import android.os.Environment; import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.R; import com.stardust.util.FileSorter; import com.stardust.util.LimitedHashMap; import org.greenrobot.eventbus.EventBus; import java.util.Map; /** * Created by Stardust on 2017/3/31. */ public class StorageScriptProvider { public static class DirectoryChangeEvent { public ScriptFile directory; public DirectoryChangeEvent(ScriptFile directory) { this.directory = directory; } } public static final String DEFAULT_DIRECTORY_PATH = Environment.getExternalStorageDirectory() + App.getApp().getString(R.string.folder_name); public static final ScriptFile DEFAULT_DIRECTORY = new ScriptFile(DEFAULT_DIRECTORY_PATH); private static StorageScriptProvider defaultProvider = new StorageScriptProvider(); public static StorageScriptProvider getDefault() { return defaultProvider; } private static StorageScriptProvider externalStorageProvider; public static StorageScriptProvider getExternalStorageProvider() { if (externalStorageProvider == null) { externalStorageProvider = new StorageScriptProvider(Environment.getExternalStorageDirectory().getPath(), 5); } return externalStorageProvider; } private EventBus mDirectoryEventBus = new EventBus(); private LimitedHashMap<String, ScriptFile[]> mScriptFileCache; private ScriptFile mInitialDirectory; private ScriptFile[] mInitialDirectoryScriptFiles; public StorageScriptProvider(String path, int cacheSize) { this(new ScriptFile(path), cacheSize); } public StorageScriptProvider(ScriptFile initialDirectory, int cacheSize) { mInitialDirectory = initialDirectory; mScriptFileCache = new LimitedHashMap<>(cacheSize); } public StorageScriptProvider() { this(DEFAULT_DIRECTORY, 10); } public void notifyDirectoryChanged(ScriptFile directory) { if (directory.equals(mInitialDirectory)) { mInitialDirectoryScriptFiles = getInitialDirectoryScriptFilesInner(); } else { clearCache(directory); } mDirectoryEventBus.post(new DirectoryChangeEvent(directory)); } public void notifyStoragePermissionGranted() { mScriptFileCache.clear(); mInitialDirectoryScriptFiles = null; mDirectoryEventBus.post(new DirectoryChangeEvent(mInitialDirectory)); } @SuppressWarnings("unchecked") public void refreshAll() { Map<String, ScriptFile> files = (Map<String, ScriptFile>) mScriptFileCache.clone(); mScriptFileCache.clear(); mInitialDirectoryScriptFiles = null; mDirectoryEventBus.post(new DirectoryChangeEvent(mInitialDirectory)); for (Map.Entry<String, ScriptFile> file : files.entrySet()) { mDirectoryEventBus.post(new DirectoryChangeEvent(new ScriptFile(file.getKey()))); } } public ScriptFile getInitialDirectory() { return mInitialDirectory; } public ScriptFile[] getInitialDirectoryScriptFiles() { if (mInitialDirectoryScriptFiles == null) { mInitialDirectoryScriptFiles = getInitialDirectoryScriptFilesInner(); } return mInitialDirectoryScriptFiles; } private ScriptFile[] getInitialDirectoryScriptFilesInner() { return listAndSortFiles(mInitialDirectory); } public ScriptFile[] getDirectoryScriptFiles(ScriptFile directory) { if (directory.equals(mInitialDirectory)) { return getInitialDirectoryScriptFiles(); } ScriptFile[] scriptFiles = getScriptFilesFromCache(directory); if (scriptFiles == null) { scriptFiles = getScriptFiles(directory); } return scriptFiles; } public void clearCacheExceptInitialDirectory() { mScriptFileCache.clear(); } private void clearCache(ScriptFile directory) { mScriptFileCache.remove(directory.getPath()); } private ScriptFile[] getScriptFiles(ScriptFile directory) { ScriptFile[] scriptFiles = listAndSortFiles(directory); mScriptFileCache.put(directory.getPath(), scriptFiles); return scriptFiles; } private ScriptFile[] listAndSortFiles(ScriptFile directory) { ScriptFile[] scriptFiles = directory.listFiles(); if (scriptFiles == null) scriptFiles = new ScriptFile[0]; else FileSorter.sort(scriptFiles); return scriptFiles; } private ScriptFile[] getScriptFilesFromCache(ScriptFile directory) { return mScriptFileCache.get(directory.getPath()); } public void registerDirectoryChangeListener(Object subscriber) { if (!mDirectoryEventBus.isRegistered(subscriber)) mDirectoryEventBus.register(subscriber); } public void unregisterDirectoryChangeListener(Object subscriber) { mDirectoryEventBus.unregister(subscriber); } }