Search in sources :

Example 1 with ConnectionModel

use of com.liulishuo.filedownloader.model.ConnectionModel in project FileDownloader by lingochamp.

the class FileDownloadManager method start.

// synchronize for safe: check downloading, check resume, update data, execute runnable
public synchronized void start(final String url, final String path, final boolean pathAsDirectory, final int callbackProgressTimes, final int callbackProgressMinIntervalMillis, final int autoRetryTimes, final boolean forceReDownload, final FileDownloadHeader header, final boolean isWifiRequired) {
    if (FileDownloadLog.NEED_LOG) {
        FileDownloadLog.d(this, "request start the task with url(%s) path(%s) isDirectory(%B)", url, path, pathAsDirectory);
    }
    final int id = FileDownloadUtils.generateId(url, path, pathAsDirectory);
    FileDownloadModel model = mDatabase.find(id);
    List<ConnectionModel> dirConnectionModelList = null;
    if (!pathAsDirectory && model == null) {
        // try dir data.
        final int dirCaseId = FileDownloadUtils.generateId(url, FileDownloadUtils.getParent(path), true);
        model = mDatabase.find(dirCaseId);
        if (model != null && path.equals(model.getTargetFilePath())) {
            if (FileDownloadLog.NEED_LOG) {
                FileDownloadLog.d(this, "task[%d] find model by dirCaseId[%d]", id, dirCaseId);
            }
            dirConnectionModelList = mDatabase.findConnectionModel(dirCaseId);
        }
    }
    if (FileDownloadHelper.inspectAndInflowDownloading(id, model, this, true)) {
        if (FileDownloadLog.NEED_LOG) {
            FileDownloadLog.d(this, "has already started download %d", id);
        }
        return;
    }
    final String targetFilePath = model != null ? model.getTargetFilePath() : FileDownloadUtils.getTargetFilePath(path, pathAsDirectory, null);
    if (FileDownloadHelper.inspectAndInflowDownloaded(id, targetFilePath, forceReDownload, true)) {
        if (FileDownloadLog.NEED_LOG) {
            FileDownloadLog.d(this, "has already completed downloading %d", id);
        }
        return;
    }
    final long sofar = model != null ? model.getSoFar() : 0;
    final String tempFilePath = model != null ? model.getTempFilePath() : FileDownloadUtils.getTempPath(targetFilePath);
    if (FileDownloadHelper.inspectAndInflowConflictPath(id, sofar, tempFilePath, targetFilePath, this)) {
        if (FileDownloadLog.NEED_LOG) {
            FileDownloadLog.d(this, "there is an another task with the same target-file-path %d %s", id, targetFilePath);
        }
        // because of the file is dirty for this task.
        if (model != null) {
            mDatabase.remove(id);
            mDatabase.removeConnections(id);
        }
        return;
    }
    // real start
    // - create model
    boolean needUpdate2DB;
    if (model != null && (model.getStatus() == FileDownloadStatus.paused || model.getStatus() == FileDownloadStatus.error || model.getStatus() == FileDownloadStatus.pending || model.getStatus() == FileDownloadStatus.started || // FileDownloadRunnable
    model.getStatus() == FileDownloadStatus.connected)) // invoke #isBreakpointAvailable to determine whether it is really invalid.
    {
        if (model.getId() != id) {
            // in try dir case.
            mDatabase.remove(model.getId());
            mDatabase.removeConnections(model.getId());
            model.setId(id);
            model.setPath(path, pathAsDirectory);
            if (dirConnectionModelList != null) {
                for (ConnectionModel connectionModel : dirConnectionModelList) {
                    connectionModel.setId(id);
                    mDatabase.insertConnectionModel(connectionModel);
                }
            }
            needUpdate2DB = true;
        } else {
            if (!TextUtils.equals(url, model.getUrl())) {
                // for cover the case of reusing the downloaded processing with the different
                // url( using with idGenerator ).
                model.setUrl(url);
                needUpdate2DB = true;
            } else {
                needUpdate2DB = false;
            }
        }
    } else {
        if (model == null) {
            model = new FileDownloadModel();
        }
        model.setUrl(url);
        model.setPath(path, pathAsDirectory);
        model.setId(id);
        model.setSoFar(0);
        model.setTotal(0);
        model.setStatus(FileDownloadStatus.pending);
        model.setConnectionCount(1);
        needUpdate2DB = true;
    }
    // - update model to db
    if (needUpdate2DB) {
        mDatabase.update(model);
    }
    final DownloadLaunchRunnable.Builder builder = new DownloadLaunchRunnable.Builder();
    final DownloadLaunchRunnable runnable = builder.setModel(model).setHeader(header).setThreadPoolMonitor(this).setMinIntervalMillis(callbackProgressMinIntervalMillis).setCallbackProgressMaxCount(callbackProgressTimes).setForceReDownload(forceReDownload).setWifiRequired(isWifiRequired).setMaxRetryTimes(autoRetryTimes).build();
    // - execute
    mThreadPool.execute(runnable);
}
Also used : FileDownloadModel(com.liulishuo.filedownloader.model.FileDownloadModel) ConnectionModel(com.liulishuo.filedownloader.model.ConnectionModel) DownloadLaunchRunnable(com.liulishuo.filedownloader.download.DownloadLaunchRunnable)

Example 2 with ConnectionModel

use of com.liulishuo.filedownloader.model.ConnectionModel in project FileDownloader by lingochamp.

the class FileDownloadManager method getSoFar.

public long getSoFar(final int id) {
    final FileDownloadModel model = mDatabase.find(id);
    if (model == null) {
        return 0;
    }
    final int connectionCount = model.getConnectionCount();
    if (connectionCount <= 1) {
        return model.getSoFar();
    } else {
        final List<ConnectionModel> modelList = mDatabase.findConnectionModel(id);
        if (modelList == null || modelList.size() != connectionCount) {
            return 0;
        } else {
            return ConnectionModel.getTotalOffset(modelList);
        }
    }
}
Also used : FileDownloadModel(com.liulishuo.filedownloader.model.FileDownloadModel) ConnectionModel(com.liulishuo.filedownloader.model.ConnectionModel)

Example 3 with ConnectionModel

use of com.liulishuo.filedownloader.model.ConnectionModel in project FileDownloader by lingochamp.

the class RemitDatabase method syncCacheToDB.

private void syncCacheToDB(int id) {
    if (FileDownloadLog.NEED_LOG) {
        FileDownloadLog.d(this, "sync cache to db %d", id);
    }
    // need to attention that the `sofar` in `FileDownloadModel` database will
    // be updated even through this is a multiple connections task. But the
    // multi-connections task only concern about the `ConnectionModel` database,
    // so it doesn't matter in current.
    realDatabase.update(cachedDatabase.find(id));
    final List<ConnectionModel> modelList = cachedDatabase.findConnectionModel(id);
    realDatabase.removeConnections(id);
    for (ConnectionModel connectionModel : modelList) {
        realDatabase.insertConnectionModel(connectionModel);
    }
}
Also used : ConnectionModel(com.liulishuo.filedownloader.model.ConnectionModel)

Example 4 with ConnectionModel

use of com.liulishuo.filedownloader.model.ConnectionModel in project FileDownloader by lingochamp.

the class SqliteDatabaseImpl method findConnectionModel.

@Override
public List<ConnectionModel> findConnectionModel(int id) {
    final List<ConnectionModel> resultList = new ArrayList<>();
    Cursor c = null;
    try {
        c = db.rawQuery(FileDownloadUtils.formatString("SELECT * FROM %s WHERE %s = ?", CONNECTION_TABLE_NAME, ConnectionModel.ID), new String[] { Integer.toString(id) });
        while (c.moveToNext()) {
            final ConnectionModel model = new ConnectionModel();
            model.setId(id);
            model.setIndex(c.getInt(c.getColumnIndex(ConnectionModel.INDEX)));
            model.setStartOffset(c.getLong(c.getColumnIndex(ConnectionModel.START_OFFSET)));
            model.setCurrentOffset(c.getLong(c.getColumnIndex(ConnectionModel.CURRENT_OFFSET)));
            model.setEndOffset(c.getLong(c.getColumnIndex(ConnectionModel.END_OFFSET)));
            resultList.add(model);
        }
    } finally {
        if (c != null)
            c.close();
    }
    return resultList;
}
Also used : ArrayList(java.util.ArrayList) ConnectionModel(com.liulishuo.filedownloader.model.ConnectionModel) Cursor(android.database.Cursor)

Example 5 with ConnectionModel

use of com.liulishuo.filedownloader.model.ConnectionModel in project FileDownloader by lingochamp.

the class DownloadLaunchRunnable method checkupAfterGetFilename.

private void checkupAfterGetFilename() throws RetryDirectly, DiscardSafely {
    final int id = model.getId();
    if (model.isPathAsDirectory()) {
        // this scope for caring about the case of there is another task is provided
        // the same path to store file and the same url.
        final String targetFilePath = model.getTargetFilePath();
        // get the ID after got the filename.
        final int fileCaseId = FileDownloadUtils.generateId(model.getUrl(), targetFilePath);
        // whether the file with the filename has been existed.
        if (FileDownloadHelper.inspectAndInflowDownloaded(id, targetFilePath, isForceReDownload, false)) {
            database.remove(id);
            database.removeConnections(id);
            throw new DiscardSafely();
        }
        final FileDownloadModel fileCaseModel = database.find(fileCaseId);
        if (fileCaseModel != null) {
            // whether the another task with the same file and url is downloading.
            if (FileDownloadHelper.inspectAndInflowDownloading(id, fileCaseModel, threadPoolMonitor, false)) {
                // it has been post to upper layer the 'warn' message, so the current
                // task no need to continue download.
                database.remove(id);
                database.removeConnections(id);
                throw new DiscardSafely();
            }
            final List<ConnectionModel> connectionModelList = database.findConnectionModel(fileCaseId);
            // the another task with the same file name and url is paused
            database.remove(fileCaseId);
            database.removeConnections(fileCaseId);
            FileDownloadUtils.deleteTargetFile(model.getTargetFilePath());
            if (FileDownloadUtils.isBreakpointAvailable(fileCaseId, fileCaseModel)) {
                model.setSoFar(fileCaseModel.getSoFar());
                model.setTotal(fileCaseModel.getTotal());
                model.setETag(fileCaseModel.getETag());
                model.setConnectionCount(fileCaseModel.getConnectionCount());
                database.update(model);
                // re connect to resume from breakpoint.
                if (connectionModelList != null) {
                    for (ConnectionModel connectionModel : connectionModelList) {
                        connectionModel.setId(id);
                        database.insertConnectionModel(connectionModel);
                    }
                }
                // retry
                throw new RetryDirectly();
            }
        }
        // whether there is an another running task with the same target-file-path.
        if (FileDownloadHelper.inspectAndInflowConflictPath(id, model.getSoFar(), model.getTempFilePath(), targetFilePath, threadPoolMonitor)) {
            database.remove(id);
            database.removeConnections(id);
            throw new DiscardSafely();
        }
    }
}
Also used : FileDownloadModel(com.liulishuo.filedownloader.model.FileDownloadModel) ConnectionModel(com.liulishuo.filedownloader.model.ConnectionModel)

Aggregations

ConnectionModel (com.liulishuo.filedownloader.model.ConnectionModel)7 FileDownloadModel (com.liulishuo.filedownloader.model.FileDownloadModel)3 ArrayList (java.util.ArrayList)3 Cursor (android.database.Cursor)1 DownloadLaunchRunnable (com.liulishuo.filedownloader.download.DownloadLaunchRunnable)1 Callable (java.util.concurrent.Callable)1 Future (java.util.concurrent.Future)1