commit
50ed36a470
@ -0,0 +1,64 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.arialyy.aria.core.delegate; |
||||
|
||||
import android.text.TextUtils; |
||||
import com.arialyy.aria.core.inf.AbsEntity; |
||||
import com.arialyy.aria.core.inf.AbsTaskEntity; |
||||
import com.arialyy.aria.core.inf.IFtpTarget; |
||||
import com.arialyy.aria.core.inf.ITarget; |
||||
import com.arialyy.aria.util.ALog; |
||||
|
||||
/** |
||||
* Created by laoyuyu on 2018/3/9. |
||||
* ftp 委托 |
||||
*/ |
||||
public class FtpDelegate<TARGET extends ITarget, ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>> |
||||
implements IFtpTarget<TARGET> { |
||||
private static final String TAG = "FtpDelegate"; |
||||
private ENTITY mEntity; |
||||
private TASK_ENTITY mTaskEntity; |
||||
|
||||
public FtpDelegate(TASK_ENTITY mTaskEntity) { |
||||
this.mTaskEntity = mTaskEntity; |
||||
mEntity = mTaskEntity.getEntity(); |
||||
} |
||||
|
||||
@Override public TARGET charSet(String charSet) { |
||||
if (TextUtils.isEmpty(charSet)) return (TARGET) this; |
||||
mTaskEntity.charSet = charSet; |
||||
return (TARGET) this; |
||||
} |
||||
|
||||
@Override public TARGET login(String userName, String password) { |
||||
return login(userName, password, null); |
||||
} |
||||
|
||||
@Override public TARGET login(String userName, String password, String account) { |
||||
if (TextUtils.isEmpty(userName)) { |
||||
ALog.e(TAG, "用户名不能为null"); |
||||
return (TARGET) this; |
||||
} else if (TextUtils.isEmpty(password)) { |
||||
ALog.e(TAG, "密码不能为null"); |
||||
return (TARGET) this; |
||||
} |
||||
mTaskEntity.urlEntity.needLogin = true; |
||||
mTaskEntity.urlEntity.user = userName; |
||||
mTaskEntity.urlEntity.password = password; |
||||
mTaskEntity.urlEntity.account = account; |
||||
return (TARGET) this; |
||||
} |
||||
} |
@ -0,0 +1,202 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.arialyy.aria.core.delegate; |
||||
|
||||
import android.support.annotation.NonNull; |
||||
import android.text.TextUtils; |
||||
import com.arialyy.aria.core.common.RequestEnum; |
||||
import com.arialyy.aria.core.download.DownloadEntity; |
||||
import com.arialyy.aria.core.inf.AbsEntity; |
||||
import com.arialyy.aria.core.inf.AbsTaskEntity; |
||||
import com.arialyy.aria.core.inf.IHttpHeaderTarget; |
||||
import com.arialyy.aria.core.inf.ITarget; |
||||
import com.arialyy.aria.util.ALog; |
||||
import java.util.Collection; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* Created by laoyuyu on 2018/3/9. |
||||
* HTTP header参数设置委托类 |
||||
*/ |
||||
public class HttpHeaderDelegate<TARGET extends ITarget, ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>> |
||||
implements IHttpHeaderTarget<TARGET> { |
||||
private static final String TAG = "HttpHeaderDelegate"; |
||||
private ENTITY mEntity; |
||||
private TASK_ENTITY mTaskEntity; |
||||
|
||||
public HttpHeaderDelegate(TASK_ENTITY mTaskEntity) { |
||||
this.mTaskEntity = mTaskEntity; |
||||
mEntity = mTaskEntity.getEntity(); |
||||
} |
||||
|
||||
/** |
||||
* 给url请求添加Header数据 |
||||
* 如果新的header数据和数据保存的不一致,则更新数据库中对应的header数据 |
||||
* |
||||
* @param key header对应的key |
||||
* @param value header对应的value |
||||
*/ |
||||
@Override |
||||
public TARGET addHeader(@NonNull String key, @NonNull String value) { |
||||
if (TextUtils.isEmpty(key)) { |
||||
ALog.w(TAG, "设置header失败,header对应的key不能为null"); |
||||
return (TARGET) this; |
||||
} else if (TextUtils.isEmpty(value)) { |
||||
ALog.w(TAG, "设置header失败,header对应的value不能为null"); |
||||
return (TARGET) this; |
||||
} |
||||
if (mTaskEntity.headers.get(key) == null) { |
||||
mTaskEntity.headers.put(key, value); |
||||
mTaskEntity.update(); |
||||
} else if (!mTaskEntity.headers.get(key).equals(value)) { |
||||
mTaskEntity.headers.put(key, value); |
||||
mTaskEntity.update(); |
||||
} |
||||
return (TARGET) this; |
||||
} |
||||
|
||||
/** |
||||
* 给url请求添加一组header数据 |
||||
* 如果新的header数据和数据保存的不一致,则更新数据库中对应的header数据 |
||||
* |
||||
* @param headers 一组http header数据 |
||||
*/ |
||||
@Override |
||||
public TARGET addHeaders(@NonNull Map<String, String> headers) { |
||||
if (headers.size() == 0) { |
||||
ALog.w(TAG, "设置header失败,map没有header数据"); |
||||
return (TARGET) this; |
||||
} |
||||
/* |
||||
两个map比较逻辑 |
||||
1、比对key是否相同 |
||||
2、如果key相同,比对value是否相同 |
||||
3、只有当上面两个步骤中key 和 value都相同时才能任务两个map数据一致 |
||||
*/ |
||||
boolean mapEquals = false; |
||||
if (mTaskEntity.headers.size() == headers.size()) { |
||||
int i = 0; |
||||
Set<String> keys = mTaskEntity.headers.keySet(); |
||||
for (String key : keys) { |
||||
if (headers.containsKey(key)) { |
||||
i++; |
||||
} else { |
||||
break; |
||||
} |
||||
} |
||||
if (i == mTaskEntity.headers.size()) { |
||||
int j = 0; |
||||
Collection<String> values = mTaskEntity.headers.values(); |
||||
for (String value : values) { |
||||
if (headers.containsValue(value)) { |
||||
j++; |
||||
} else { |
||||
break; |
||||
} |
||||
} |
||||
if (j == mTaskEntity.headers.size()) { |
||||
mapEquals = true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (!mapEquals) { |
||||
mTaskEntity.headers.clear(); |
||||
Set<String> keys = headers.keySet(); |
||||
for (String key : keys) { |
||||
mTaskEntity.headers.put(key, headers.get(key)); |
||||
} |
||||
mTaskEntity.update(); |
||||
} |
||||
|
||||
return (TARGET) this; |
||||
} |
||||
|
||||
/** |
||||
* 设置请求类型,POST或GET,默认为在GET |
||||
* 只试用于HTTP请求 |
||||
* |
||||
* @param requestEnum {@link RequestEnum} |
||||
*/ |
||||
@Override |
||||
public TARGET setRequestMode(RequestEnum requestEnum) { |
||||
mTaskEntity.requestEnum = requestEnum; |
||||
return (TARGET) this; |
||||
} |
||||
|
||||
/** |
||||
* 如果你的下载链接的header中含有md5码信息,那么你可以通过设置key,来获取从header获取该md5码信息。 |
||||
* key默认值为:Content-MD5 |
||||
* 获取md5信息:{@link DownloadEntity#getMd5Code()} |
||||
*/ |
||||
@Override |
||||
public TARGET setHeaderMd5Key(String md5Key) { |
||||
if (TextUtils.isEmpty(md5Key)) return (TARGET) this; |
||||
mTaskEntity.md5Key = md5Key; |
||||
if (TextUtils.isEmpty(mTaskEntity.md5Key) || !mTaskEntity.md5Key.equals(md5Key)) { |
||||
mTaskEntity.update(); |
||||
} |
||||
return (TARGET) this; |
||||
} |
||||
|
||||
/** |
||||
* 如果你的文件长度是放在header中,那么你需要配置key来让Aria知道正确的文件长度 |
||||
* key默认值为:Content-Length |
||||
*/ |
||||
@Override |
||||
public TARGET setHeaderContentLengthKey(String contentLength) { |
||||
if (TextUtils.isEmpty(contentLength)) return (TARGET) this; |
||||
mTaskEntity.contentLength = contentLength; |
||||
if (TextUtils.isEmpty(mTaskEntity.contentLength) || !mTaskEntity.contentLength.equals( |
||||
contentLength)) { |
||||
mTaskEntity.update(); |
||||
} |
||||
return (TARGET) this; |
||||
} |
||||
|
||||
/** |
||||
* 如果你的下载链接的header中含有文件描述信息,那么你可以通过设置key,来获取从header获取该文件描述信息。 |
||||
* key默认值为:Content-Disposition |
||||
* 获取文件描述信息:{@link DownloadEntity#getDisposition()} |
||||
*/ |
||||
@Override |
||||
public TARGET setHeaderDispositionKey(String dispositionKey) { |
||||
if (TextUtils.isEmpty(dispositionKey)) return (TARGET) this; |
||||
mTaskEntity.dispositionKey = dispositionKey; |
||||
if (TextUtils.isEmpty(mTaskEntity.dispositionKey) || !mTaskEntity.dispositionKey.equals( |
||||
dispositionKey)) { |
||||
mTaskEntity.update(); |
||||
} |
||||
return (TARGET) this; |
||||
} |
||||
|
||||
/** |
||||
* 从文件描述信息{@link #setHeaderDispositionKey(String)}中含有文件名信息,你可以通过设置key来获取header中的文件名 |
||||
* key默认值为:attachment;filename |
||||
* 获取文件名信息:{@link DownloadEntity#getServerFileName()} |
||||
*/ |
||||
@Override |
||||
public TARGET setHeaderDispositionFileKey(String dispositionFileKey) { |
||||
if (TextUtils.isEmpty(dispositionFileKey)) return (TARGET) this; |
||||
mTaskEntity.dispositionFileKey = dispositionFileKey; |
||||
if (TextUtils.isEmpty(mTaskEntity.dispositionFileKey) || !mTaskEntity.dispositionFileKey.equals( |
||||
dispositionFileKey)) { |
||||
mTaskEntity.update(); |
||||
} |
||||
return (TARGET) this; |
||||
} |
||||
} |
@ -0,0 +1,110 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.arialyy.aria.core.download; |
||||
|
||||
import android.text.TextUtils; |
||||
import com.arialyy.aria.core.AriaManager; |
||||
import com.arialyy.aria.core.command.normal.NormalCmdFactory; |
||||
import com.arialyy.aria.core.inf.AbsEntity; |
||||
import com.arialyy.aria.core.inf.AbsTarget; |
||||
import com.arialyy.aria.core.inf.AbsTaskEntity; |
||||
import com.arialyy.aria.util.ALog; |
||||
import com.arialyy.aria.util.CommonUtil; |
||||
|
||||
/** |
||||
* Created by lyy on 2017/2/28. |
||||
*/ |
||||
abstract class AbsDownloadTarget<TARGET extends AbsTarget, ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity> |
||||
extends AbsTarget<TARGET, ENTITY, TASK_ENTITY> { |
||||
|
||||
static final int HTTP = 1; |
||||
static final int FTP = 2; |
||||
//HTTP任务组
|
||||
static final int GROUP_HTTP = 3; |
||||
//FTP文件夹
|
||||
static final int GROUP_FTP_DIR = 4; |
||||
|
||||
/** |
||||
* 设置的文件保存路径的临时变量 |
||||
*/ |
||||
String mTempFilePath; |
||||
|
||||
/** |
||||
* 将任务设置为最高优先级任务,最高优先级任务有以下特点: |
||||
* 1、在下载队列中,有且只有一个最高优先级任务 |
||||
* 2、最高优先级任务会一直存在,直到用户手动暂停或任务完成 |
||||
* 3、任务调度器不会暂停最高优先级任务 |
||||
* 4、用户手动暂停或任务完成后,第二次重新执行该任务,该命令将失效 |
||||
* 5、如果下载队列中已经满了,则会停止队尾的任务,当高优先级任务完成后,该队尾任务将自动执行 |
||||
* 6、把任务设置为最高优先级任务后,将自动执行任务,不需要重新调用start()启动任务 |
||||
*/ |
||||
protected void setHighestPriority() { |
||||
if (checkEntity()) { |
||||
AriaManager.getInstance(AriaManager.APP) |
||||
.setCmd(CommonUtil.createNormalCmd(mTargetName, mTaskEntity, |
||||
NormalCmdFactory.TASK_HIGHEST_PRIORITY, checkTaskType())) |
||||
.exe(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 添加任务 |
||||
*/ |
||||
public void add() { |
||||
if (checkEntity()) { |
||||
AriaManager.getInstance(AriaManager.APP) |
||||
.setCmd(CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_CREATE, |
||||
checkTaskType())) |
||||
.exe(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 重定向后,新url的key,默认为location |
||||
*/ |
||||
public void setRedirectUrlKey(String redirectUrlKey) { |
||||
if (TextUtils.isEmpty(redirectUrlKey)) { |
||||
ALog.e("AbsDownloadTarget", "重定向后,新url的key不能为null"); |
||||
return; |
||||
} |
||||
mTaskEntity.redirectUrlKey = redirectUrlKey; |
||||
} |
||||
|
||||
/** |
||||
* 获取任务文件大小 |
||||
* |
||||
* @return 文件大小 |
||||
*/ |
||||
public long getFileSize() { |
||||
return getSize(); |
||||
} |
||||
|
||||
/** |
||||
* 获取单位转换后的文件大小 |
||||
* |
||||
* @return 文件大小{@code xxx mb} |
||||
*/ |
||||
public String getConvertFileSize() { |
||||
return getConvertSize(); |
||||
} |
||||
|
||||
/** |
||||
* 设置target类型 |
||||
* |
||||
* @return {@link #HTTP}、{@link #FTP}、{@link #GROUP_HTTP}、{@link #GROUP_FTP_DIR} |
||||
*/ |
||||
protected abstract int getTargetType(); |
||||
} |
@ -0,0 +1,200 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.arialyy.aria.core.download; |
||||
|
||||
import android.text.TextUtils; |
||||
import com.arialyy.aria.core.manager.TEManager; |
||||
import com.arialyy.aria.core.queue.DownloadTaskQueue; |
||||
import com.arialyy.aria.orm.DbEntity; |
||||
import com.arialyy.aria.util.ALog; |
||||
import com.arialyy.aria.util.CommonUtil; |
||||
import java.io.File; |
||||
|
||||
/** |
||||
* Created by Aria.Lao on 2017/7/26. |
||||
*/ |
||||
abstract class BaseNormalTarget<TARGET extends BaseNormalTarget> |
||||
extends AbsDownloadTarget<TARGET, DownloadEntity, DownloadTaskEntity> { |
||||
|
||||
private static final String TAG = "BaseNormalTarget"; |
||||
/** |
||||
* 资源地址 |
||||
*/ |
||||
protected String url; |
||||
|
||||
/** |
||||
* 通过实体初始化target |
||||
*/ |
||||
void initTarget(DownloadEntity entity, String targetName, boolean refreshInfo) { |
||||
this.url = entity.getUrl(); |
||||
mTargetName = targetName; |
||||
mTaskEntity = TEManager.getInstance().getTEntity(DownloadTaskEntity.class, url); |
||||
if (mTaskEntity == null) { |
||||
mTaskEntity = TEManager.getInstance().createTEntity(DownloadTaskEntity.class, entity); |
||||
} |
||||
mEntity = mTaskEntity.entity; |
||||
mTaskEntity.refreshInfo = refreshInfo; |
||||
} |
||||
|
||||
/** |
||||
* 通过地址初始化target |
||||
*/ |
||||
void initTarget(String url, String targetName, boolean refreshInfo) { |
||||
this.url = url; |
||||
mTargetName = targetName; |
||||
mTaskEntity = TEManager.getInstance().getTEntity(DownloadTaskEntity.class, url); |
||||
if (mTaskEntity == null) { |
||||
mTaskEntity = TEManager.getInstance().createTEntity(DownloadTaskEntity.class, url); |
||||
} |
||||
mEntity = mTaskEntity.entity; |
||||
mTaskEntity.refreshInfo = refreshInfo; |
||||
} |
||||
|
||||
/** |
||||
* 将任务设置为最高优先级任务,最高优先级任务有以下特点: |
||||
* 1、在下载队列中,有且只有一个最高优先级任务 |
||||
* 2、最高优先级任务会一直存在,直到用户手动暂停或任务完成 |
||||
* 3、任务调度器不会暂停最高优先级任务 |
||||
* 4、用户手动暂停或任务完成后,第二次重新执行该任务,该命令将失效 |
||||
* 5、如果下载队列中已经满了,则会停止队尾的任务,当高优先级任务完成后,该队尾任务将自动执行 |
||||
* 6、把任务设置为最高优先级任务后,将自动执行任务,不需要重新调用start()启动任务 |
||||
*/ |
||||
@Override public void setHighestPriority() { |
||||
super.setHighestPriority(); |
||||
} |
||||
|
||||
/** |
||||
* 下载任务是否存在 |
||||
* |
||||
* @return {@code true}任务存在 |
||||
*/ |
||||
@Override public boolean taskExists() { |
||||
return DownloadTaskQueue.getInstance().getTask(mEntity.getUrl()) != null; |
||||
} |
||||
|
||||
/** |
||||
* 获取下载实体 |
||||
*/ |
||||
public DownloadEntity getDownloadEntity() { |
||||
return mEntity; |
||||
} |
||||
|
||||
/** |
||||
* 是否在下载,该api后续版本会删除 |
||||
* |
||||
* @deprecated {@link #isRunning()} |
||||
*/ |
||||
@Deprecated |
||||
public boolean isDownloading() { |
||||
return isRunning(); |
||||
} |
||||
|
||||
/** |
||||
* 是否在下载 |
||||
* |
||||
* @return {@code true}任务正在下载 |
||||
*/ |
||||
@Override public boolean isRunning() { |
||||
DownloadTask task = DownloadTaskQueue.getInstance().getTask(mEntity.getKey()); |
||||
return task != null && task.isRunning(); |
||||
} |
||||
|
||||
/** |
||||
* 检查下载实体,判断实体是否合法 |
||||
* 合法标准为: |
||||
* 1、下载路径不为null,并且下载路径是正常的http或ftp路径 |
||||
* 2、保存路径不为null,并且保存路径是android文件系统路径 |
||||
* 3、保存路径不能重复 |
||||
* |
||||
* @return {@code true}合法 |
||||
*/ |
||||
@Override |
||||
protected boolean checkEntity() { |
||||
return getTargetType() < GROUP_HTTP && checkUrl() && checkFilePath(); |
||||
} |
||||
|
||||
/** |
||||
* 检查并设置普通任务的文件保存路径 |
||||
* |
||||
* @return {@code true}保存路径合法 |
||||
*/ |
||||
private boolean checkFilePath() { |
||||
String filePath = mTempFilePath; |
||||
if (TextUtils.isEmpty(filePath)) { |
||||
ALog.e(TAG, "下载失败,文件保存路径为null"); |
||||
return false; |
||||
} else if (!filePath.startsWith("/")) { |
||||
ALog.e(TAG, "下载失败,文件保存路径【" + filePath + "】错误"); |
||||
return false; |
||||
} |
||||
File file = new File(filePath); |
||||
if (file.isDirectory()) { |
||||
if (getTargetType() == HTTP) { |
||||
ALog.e(TAG, "保存路径【" + filePath + "】不能为文件夹,路径需要是完整的文件路径,如:/mnt/sdcard/game.zip"); |
||||
return false; |
||||
} else if (getTargetType() == FTP) { |
||||
filePath += mEntity.getFileName(); |
||||
} |
||||
} |
||||
//设置文件保存路径,如果新文件路径和就文件路径不同,则修改路径
|
||||
if (!filePath.equals(mEntity.getDownloadPath())) { |
||||
if (!mTaskEntity.refreshInfo && DbEntity.checkDataExist(DownloadEntity.class, |
||||
"downloadPath=?", filePath)) { |
||||
ALog.e(TAG, "保存路径【" + filePath + "】已经被其它任务占用,请设置其它保存路径"); |
||||
return false; |
||||
} |
||||
File oldFile = new File(mEntity.getDownloadPath()); |
||||
File newFile = new File(filePath); |
||||
if (TextUtils.isEmpty(mEntity.getDownloadPath()) || oldFile.renameTo(newFile)) { |
||||
mEntity.setDownloadPath(filePath); |
||||
mEntity.setFileName(newFile.getName()); |
||||
mTaskEntity.key = filePath; |
||||
mTaskEntity.update(); |
||||
CommonUtil.renameDownloadConfig(oldFile.getName(), newFile.getName()); |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* 检查普通任务的下载地址 |
||||
* |
||||
* @return {@code true}地址合法 |
||||
*/ |
||||
private boolean checkUrl() { |
||||
final String url = mEntity.getUrl(); |
||||
if (TextUtils.isEmpty(url)) { |
||||
ALog.e(TAG, "下载失败,url为null"); |
||||
return false; |
||||
} else if (!url.startsWith("http") && !url.startsWith("ftp")) { |
||||
ALog.e(TAG, "下载失败,url【" + url + "】错误"); |
||||
return false; |
||||
} |
||||
int index = url.indexOf("://"); |
||||
if (index == -1) { |
||||
ALog.e(TAG, "下载失败,url【" + url + "】不合法"); |
||||
return false; |
||||
} |
||||
String temp = url.substring(index + 3, url.length()); |
||||
if (temp.contains("//")) { |
||||
temp = url.substring(0, index + 3) + temp.replaceAll("//", "/"); |
||||
ALog.w(TAG, "url中含有//,//将转换为/,转换后的url为:" + temp); |
||||
mEntity.setUrl(temp); |
||||
mEntity.update(); |
||||
} |
||||
return true; |
||||
} |
||||
} |
@ -1,151 +0,0 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.arialyy.aria.core.inf; |
||||
|
||||
import android.text.TextUtils; |
||||
import com.arialyy.aria.core.AriaManager; |
||||
import com.arialyy.aria.core.command.normal.NormalCmdFactory; |
||||
import com.arialyy.aria.core.download.DownloadEntity; |
||||
import com.arialyy.aria.util.ALog; |
||||
import com.arialyy.aria.util.CommonUtil; |
||||
|
||||
/** |
||||
* Created by lyy on 2017/2/28. |
||||
*/ |
||||
public abstract class AbsDownloadTarget<TARGET extends AbsTarget, ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity> |
||||
extends AbsTarget<TARGET, ENTITY, TASK_ENTITY> { |
||||
|
||||
/** |
||||
* 如果你的下载链接的header中含有md5码信息,那么你可以通过设置key,来获取从header获取该md5码信息。 |
||||
* key默认值为:Content-MD5 |
||||
* 获取md5信息:{@link DownloadEntity#getMd5Code()} |
||||
*/ |
||||
public TARGET setHeaderMd5Key(String md5Key) { |
||||
if (TextUtils.isEmpty(md5Key)) return (TARGET) this; |
||||
mTaskEntity.md5Key = md5Key; |
||||
if (TextUtils.isEmpty(mTaskEntity.md5Key) || !mTaskEntity.md5Key.equals(md5Key)) { |
||||
mTaskEntity.update(); |
||||
} |
||||
return (TARGET) this; |
||||
} |
||||
|
||||
/** |
||||
* 如果你的文件长度是放在header中,那么你需要配置key来让Aria知道正确的文件长度 |
||||
* key默认值为:Content-Length |
||||
*/ |
||||
public TARGET setHeaderContentLengthKey(String contentLength) { |
||||
if (TextUtils.isEmpty(contentLength)) return (TARGET) this; |
||||
mTaskEntity.contentLength = contentLength; |
||||
if (TextUtils.isEmpty(mTaskEntity.contentLength) || !mTaskEntity.contentLength.equals( |
||||
contentLength)) { |
||||
mTaskEntity.update(); |
||||
} |
||||
return (TARGET) this; |
||||
} |
||||
|
||||
/** |
||||
* 如果你的下载链接的header中含有文件描述信息,那么你可以通过设置key,来获取从header获取该文件描述信息。 |
||||
* key默认值为:Content-Disposition |
||||
* 获取文件描述信息:{@link DownloadEntity#getDisposition()} |
||||
*/ |
||||
public TARGET setHeaderDispositionKey(String dispositionKey) { |
||||
if (TextUtils.isEmpty(dispositionKey)) return (TARGET) this; |
||||
mTaskEntity.dispositionKey = dispositionKey; |
||||
if (TextUtils.isEmpty(mTaskEntity.dispositionKey) || !mTaskEntity.dispositionKey.equals( |
||||
dispositionKey)) { |
||||
mTaskEntity.save(); |
||||
} |
||||
return (TARGET) this; |
||||
} |
||||
|
||||
/** |
||||
* 从文件描述信息{@link #setHeaderDispositionKey(String)}中含有文件名信息,你可以通过设置key来获取header中的文件名 |
||||
* key默认值为:attachment;filename |
||||
* 获取文件名信息:{@link DownloadEntity#getServerFileName()} |
||||
*/ |
||||
public TARGET setHeaderDispositionFileKey(String dispositionFileKey) { |
||||
if (TextUtils.isEmpty(dispositionFileKey)) return (TARGET) this; |
||||
mTaskEntity.dispositionFileKey = dispositionFileKey; |
||||
if (TextUtils.isEmpty(mTaskEntity.dispositionFileKey) || !mTaskEntity.dispositionFileKey.equals( |
||||
dispositionFileKey)) { |
||||
mTaskEntity.save(); |
||||
} |
||||
return (TARGET) this; |
||||
} |
||||
|
||||
/** |
||||
* 将任务设置为最高优先级任务,最高优先级任务有以下特点: |
||||
* 1、在下载队列中,有且只有一个最高优先级任务 |
||||
* 2、最高优先级任务会一直存在,直到用户手动暂停或任务完成 |
||||
* 3、任务调度器不会暂停最高优先级任务 |
||||
* 4、用户手动暂停或任务完成后,第二次重新执行该任务,该命令将失效 |
||||
* 5、如果下载队列中已经满了,则会停止队尾的任务,当高优先级任务完成后,该队尾任务将自动执行 |
||||
* 6、把任务设置为最高优先级任务后,将自动执行任务,不需要重新调用start()启动任务 |
||||
*/ |
||||
protected void setHighestPriority() { |
||||
AriaManager.getInstance(AriaManager.APP) |
||||
.setCmd(CommonUtil.createNormalCmd(mTargetName, mTaskEntity, |
||||
NormalCmdFactory.TASK_HIGHEST_PRIORITY, checkTaskType())) |
||||
.exe(); |
||||
} |
||||
|
||||
/** |
||||
* 重定向后,新url的key,默认为location |
||||
*/ |
||||
public void setRedirectUrlKey(String redirectUrlKey) { |
||||
if (TextUtils.isEmpty(redirectUrlKey)) { |
||||
ALog.e("AbsDownloadTarget", "重定向后,新url的key不能为null"); |
||||
return; |
||||
} |
||||
mTaskEntity.redirectUrlKey = redirectUrlKey; |
||||
} |
||||
|
||||
/** |
||||
* 获取任务文件大小 |
||||
* |
||||
* @return 文件大小 |
||||
*/ |
||||
public long getFileSize() { |
||||
return getSize(); |
||||
} |
||||
|
||||
/** |
||||
* 获取单位转换后的文件大小 |
||||
* |
||||
* @return 文件大小{@code xxx mb} |
||||
*/ |
||||
public String getConvertFileSize() { |
||||
return getConvertSize(); |
||||
} |
||||
|
||||
/** |
||||
* 添加任务 |
||||
*/ |
||||
public void add() { |
||||
AriaManager.getInstance(AriaManager.APP) |
||||
.setCmd(CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_CREATE, |
||||
checkTaskType())) |
||||
.exe(); |
||||
} |
||||
|
||||
/** |
||||
* 重新下载 |
||||
*/ |
||||
public void reStart() { |
||||
cancel(); |
||||
start(); |
||||
} |
||||
} |
@ -1,65 +0,0 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.arialyy.aria.core.inf; |
||||
|
||||
import android.support.annotation.NonNull; |
||||
import com.arialyy.aria.core.queue.UploadTaskQueue; |
||||
import com.arialyy.aria.core.upload.UploadEntity; |
||||
import com.arialyy.aria.core.upload.UploadTask; |
||||
import com.arialyy.aria.core.upload.UploadTaskEntity; |
||||
import com.arialyy.aria.util.CheckUtil; |
||||
|
||||
/** |
||||
* Created by AriaL on 2017/6/29. |
||||
* 任务组超类 |
||||
*/ |
||||
public abstract class AbsUploadTarget<TARGET extends AbsUploadTarget, ENTITY extends UploadEntity, TASK_ENTITY extends UploadTaskEntity> |
||||
extends AbsTarget<TARGET, ENTITY, TASK_ENTITY> { |
||||
|
||||
/** |
||||
* 设置上传路径 |
||||
* |
||||
* @param uploadUrl 上传路径 |
||||
*/ |
||||
public TARGET setUploadUrl(@NonNull String uploadUrl) { |
||||
uploadUrl = CheckUtil.checkUrl(uploadUrl); |
||||
if (mEntity.getUrl().equals(uploadUrl)) return (TARGET) this; |
||||
mEntity.setUrl(uploadUrl); |
||||
mEntity.update(); |
||||
return (TARGET) this; |
||||
} |
||||
|
||||
/** |
||||
* 下载任务是否存在 |
||||
*/ |
||||
@Override public boolean taskExists() { |
||||
return UploadTaskQueue.getInstance().getTask(mEntity.getFilePath()) != null; |
||||
} |
||||
|
||||
/** |
||||
* 是否在下载 |
||||
* |
||||
* @deprecated {@link #isRunning()} |
||||
*/ |
||||
public boolean isUploading() { |
||||
return isRunning(); |
||||
} |
||||
|
||||
@Override public boolean isRunning() { |
||||
UploadTask task = UploadTaskQueue.getInstance().getTask(mEntity.getKey()); |
||||
return task != null && task.isRunning(); |
||||
} |
||||
} |
@ -0,0 +1,45 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.arialyy.aria.core.inf; |
||||
|
||||
/** |
||||
* Created by laoyuyu on 2018/3/9. |
||||
*/ |
||||
public interface IFtpTarget<TARGET extends ITarget> { |
||||
/** |
||||
* 设置字符编码 |
||||
*/ |
||||
TARGET charSet(String charSet); |
||||
|
||||
/** |
||||
* ftp 用户登录信。 |
||||
* 设置登录信息需要在设置上传链接之后{@link #setUploadUrl(String)} |
||||
* |
||||
* @param userName ftp用户名 |
||||
* @param password ftp用户密码 |
||||
*/ |
||||
TARGET login(String userName, String password); |
||||
|
||||
/** |
||||
* ftp 用户登录信息 |
||||
* 设置登录信息需要在设置上传链接之后{@link #setUploadUrl(String)} |
||||
* |
||||
* @param userName ftp用户名 |
||||
* @param password ftp用户密码 |
||||
* @param account ftp账号 |
||||
*/ |
||||
TARGET login(String userName, String password, String account); |
||||
} |
@ -0,0 +1,79 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.arialyy.aria.core.inf; |
||||
|
||||
import android.support.annotation.NonNull; |
||||
import com.arialyy.aria.core.common.RequestEnum; |
||||
import com.arialyy.aria.core.download.DownloadEntity; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* Created by laoyuyu on 2018/3/9. |
||||
* HTTP Header功能接口 |
||||
*/ |
||||
public interface IHttpHeaderTarget<TARGET extends ITarget> { |
||||
|
||||
/** |
||||
* 给url请求添加Header数据 |
||||
* 如果新的header数据和数据保存的不一致,则更新数据库中对应的header数据 |
||||
* |
||||
* @param key header对应的key |
||||
* @param value header对应的value |
||||
*/ |
||||
TARGET addHeader(@NonNull String key, @NonNull String value); |
||||
|
||||
/** |
||||
* 给url请求添加一组header数据 |
||||
* 如果新的header数据和数据保存的不一致,则更新数据库中对应的header数据 |
||||
* |
||||
* @param headers 一组http header数据 |
||||
*/ |
||||
TARGET addHeaders(Map<String, String> headers); |
||||
|
||||
/** |
||||
* 设置HTTP请求类型 |
||||
* |
||||
* @param requestEnum {@link RequestEnum} |
||||
*/ |
||||
TARGET setRequestMode(RequestEnum requestEnum); |
||||
|
||||
/** |
||||
* 如果你的下载链接的header中含有md5码信息,那么你可以通过设置key,来获取从header获取该md5码信息。 |
||||
* key默认值为:Content-MD5 |
||||
* 获取md5信息:{@link DownloadEntity#getMd5Code()} |
||||
*/ |
||||
TARGET setHeaderMd5Key(String md5Key); |
||||
|
||||
/** |
||||
* 如果你的文件长度是放在header中,那么你需要配置key来让Aria知道正确的文件长度 |
||||
* key默认值为:Content-Length |
||||
*/ |
||||
TARGET setHeaderContentLengthKey(String contentLength); |
||||
|
||||
/** |
||||
* 如果你的下载链接的header中含有文件描述信息,那么你可以通过设置key,来获取从header获取该文件描述信息。 |
||||
* key默认值为:Content-Disposition |
||||
* 获取文件描述信息:{@link DownloadEntity#getDisposition()} |
||||
*/ |
||||
TARGET setHeaderDispositionKey(String dispositionKey); |
||||
|
||||
/** |
||||
* 从文件描述信息{@link #setHeaderDispositionKey(String)}中含有文件名信息,你可以通过设置key来获取header中的文件名 |
||||
* key默认值为:attachment;filename |
||||
* 获取文件名信息:{@link DownloadEntity#getServerFileName()} |
||||
*/ |
||||
TARGET setHeaderDispositionFileKey(String dispositionFileKey); |
||||
} |
@ -0,0 +1,28 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.arialyy.aria.core.upload; |
||||
|
||||
import com.arialyy.aria.core.inf.AbsEntity; |
||||
import com.arialyy.aria.core.inf.AbsTarget; |
||||
import com.arialyy.aria.core.inf.AbsTaskEntity; |
||||
|
||||
/** |
||||
* Created by AriaL on 2017/6/29. |
||||
*/ |
||||
abstract class AbsUploadTarget<TARGET extends AbsUploadTarget, ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity> |
||||
extends AbsTarget<TARGET, ENTITY, TASK_ENTITY> { |
||||
|
||||
} |
@ -0,0 +1,139 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.arialyy.aria.core.upload; |
||||
|
||||
import android.support.annotation.NonNull; |
||||
import android.text.TextUtils; |
||||
import com.arialyy.aria.core.manager.TEManager; |
||||
import com.arialyy.aria.core.queue.UploadTaskQueue; |
||||
import com.arialyy.aria.util.ALog; |
||||
import java.io.File; |
||||
|
||||
/** |
||||
* Created by AriaL on 2018/3/9. |
||||
*/ |
||||
abstract class BaseNormalTarget<TARGET extends AbsUploadTarget> |
||||
extends AbsUploadTarget<TARGET, UploadEntity, UploadTaskEntity> { |
||||
private static final String TAG = "BaseNormalTarget"; |
||||
|
||||
protected void initTarget(String filePath) { |
||||
mTaskEntity = TEManager.getInstance().getTEntity(UploadTaskEntity.class, filePath); |
||||
if (mTaskEntity == null) { |
||||
mTaskEntity = TEManager.getInstance().createTEntity(UploadTaskEntity.class, filePath); |
||||
} |
||||
mEntity = mTaskEntity.entity; |
||||
File file = new File(filePath); |
||||
mEntity.setFileName(file.getName()); |
||||
mEntity.setFileSize(file.length()); |
||||
} |
||||
|
||||
/** |
||||
* 设置上传路径 |
||||
* |
||||
* @param uploadUrl 上传路径 |
||||
*/ |
||||
public abstract TARGET setUploadUrl(@NonNull String uploadUrl); |
||||
|
||||
/** |
||||
* 上传任务是否存在 |
||||
* |
||||
* @return {@code true}存在 |
||||
*/ |
||||
@Override public boolean taskExists() { |
||||
return UploadTaskQueue.getInstance().getTask(mEntity.getFilePath()) != null; |
||||
} |
||||
|
||||
/** |
||||
* 是否在上传 |
||||
* |
||||
* @deprecated {@link #isRunning()} |
||||
*/ |
||||
public boolean isUploading() { |
||||
return isRunning(); |
||||
} |
||||
|
||||
@Override public boolean isRunning() { |
||||
UploadTask task = UploadTaskQueue.getInstance().getTask(mEntity.getKey()); |
||||
return task != null && task.isRunning(); |
||||
} |
||||
|
||||
@Override protected boolean checkEntity() { |
||||
return checkUrl() && checkFilePath(); |
||||
} |
||||
|
||||
/** |
||||
* 检查上传文件路径是否合法 |
||||
* |
||||
* @return {@code true} 合法 |
||||
*/ |
||||
private boolean checkFilePath() { |
||||
String filePath = mEntity.getFilePath(); |
||||
if (TextUtils.isEmpty(filePath)) { |
||||
ALog.e(TAG, "上传失败,文件路径为null"); |
||||
return false; |
||||
} else if (!filePath.startsWith("/")) { |
||||
ALog.e(TAG, "上传失败,文件路径【" + filePath + "】不合法"); |
||||
return false; |
||||
} |
||||
|
||||
File file = new File(mEntity.getFilePath()); |
||||
if (!file.exists()) { |
||||
ALog.e(TAG, "上传失败,文件【" + filePath + "】不存在"); |
||||
return false; |
||||
} |
||||
if (file.isDirectory()) { |
||||
ALog.e(TAG, "上传失败,文件【" + filePath + "】不能死文件夹"); |
||||
return false; |
||||
} |
||||
|
||||
if (filePath.contains("//")) { |
||||
filePath = filePath.replaceAll("//", "/"); |
||||
ALog.w(TAG, "url中含有//,//将转换为/,转换后的url为:" + filePath); |
||||
mEntity.setFilePath(filePath); |
||||
mEntity.update(); |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* 检查普通任务的下载地址 |
||||
* |
||||
* @return {@code true}地址合法 |
||||
*/ |
||||
private boolean checkUrl() { |
||||
final String url = mEntity.getUrl(); |
||||
if (TextUtils.isEmpty(url)) { |
||||
ALog.e(TAG, "上传失败,url为null"); |
||||
return false; |
||||
} else if (!url.startsWith("http") && !url.startsWith("ftp")) { |
||||
ALog.e(TAG, "上传失败,url【" + url + "】错误"); |
||||
return false; |
||||
} |
||||
int index = url.indexOf("://"); |
||||
if (index == -1) { |
||||
ALog.e(TAG, "上传失败,url【" + url + "】不合法"); |
||||
return false; |
||||
} |
||||
String temp = url.substring(index + 3, url.length()); |
||||
if (temp.contains("//")) { |
||||
temp = url.substring(0, index + 3) + temp.replaceAll("//", "/"); |
||||
ALog.w(TAG, "url中含有//,//将转换为/,转换后的url为:" + temp); |
||||
mEntity.setUrl(temp); |
||||
mEntity.update(); |
||||
} |
||||
return true; |
||||
} |
||||
} |
Loading…
Reference in new issue