diff --git a/Aria/build.gradle b/Aria/build.gradle index 025b23bb..247d08ee 100644 --- a/Aria/build.gradle +++ b/Aria/build.gradle @@ -26,7 +26,7 @@ dependencies { testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.1.1' compile project(':AriaAnnotations') - compile 'com.arialyy.aria:aria-ftp-plug:1.0.3' + compile 'com.arialyy.aria:aria-ftp-plug:1.0.4' // compile project(':AriaFtpPlug') } diff --git a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java index 940b05cf..ba810bb9 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java +++ b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java @@ -26,7 +26,6 @@ import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.support.v4.app.Fragment; import android.widget.PopupWindow; -import android.widget.Toast; import com.arialyy.aria.core.command.ICmd; import com.arialyy.aria.core.common.QueueMod; import com.arialyy.aria.core.download.DownloadEntity; @@ -71,7 +70,6 @@ import org.xml.sax.SAXException; * activity 和其Dialog、Fragment的映射表 */ private Map> mSubClass = new ConcurrentHashMap<>(); - private List mActivityCount = new ArrayList<>(); public static Context APP; private List mCommands = new ArrayList<>(); private Configuration.DownloadConfig mDConfig; @@ -470,9 +468,6 @@ import org.xml.sax.SAXException; private class LifeCallback implements Application.ActivityLifecycleCallbacks { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { - mActivityCount.add( - String.format("%s_%s", activity.getClass().getName(), activity.hashCode())); - ALog.w(TAG, "size = " + mActivityCount.size()); } @Override public void onActivityStarted(Activity activity) { @@ -497,13 +492,6 @@ import org.xml.sax.SAXException; @Override public void onActivityDestroyed(Activity activity) { removeReceiver(activity); - mActivityCount.remove( - String.format("%s_%s", activity.getClass().getName(), activity.hashCode())); - ALog.w(TAG, "size = " + mActivityCount.size()); - if (mActivityCount.size() == 0) { - ALog.e(TAG, "gggg"); - //Toast.makeText(activity, "destroy", Toast.LENGTH_SHORT).show(); - } } } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/ConfigHelper.java b/Aria/src/main/java/com/arialyy/aria/core/ConfigHelper.java index 0d26d978..e8dda5b6 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/ConfigHelper.java +++ b/Aria/src/main/java/com/arialyy/aria/core/ConfigHelper.java @@ -184,6 +184,9 @@ class ConfigHelper extends DefaultHandler { if (mType == ConfigType.DOWNLOAD) { mDownloadConfig.maxSpeed = maxSpeed; } + if (mType == ConfigType.UPLOAD) { + mUploadConfig.maxSpeed = maxSpeed; + } } private void loadConvertSpeed(String value) { diff --git a/Aria/src/main/java/com/arialyy/aria/core/FtpUrlEntity.java b/Aria/src/main/java/com/arialyy/aria/core/FtpUrlEntity.java index da821979..8d4df9e5 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/FtpUrlEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/FtpUrlEntity.java @@ -17,6 +17,8 @@ */ package com.arialyy.aria.core; +import com.arialyy.aria.core.common.ProtocolType; +import com.arialyy.aria.orm.annotation.Ignore; import java.net.InetAddress; /** @@ -32,6 +34,12 @@ public class FtpUrlEntity implements Cloneable { public String account; + /** + * 是否是ftps + * {@code true}ftps协议的地址,{@code false}不是ftps协议的地址 + */ + public boolean isFtps = false; + /** * 原始url */ @@ -40,15 +48,17 @@ public class FtpUrlEntity implements Cloneable { /** * ftp协议:ftp */ - public String protocol; + public String scheme; /** * 登录的用户名 */ public String user; + /** * 密码 */ + @Ignore public String password; /** @@ -71,6 +81,28 @@ public class FtpUrlEntity implements Cloneable { */ public InetAddress validAddr; + /** + * 证书路径 + */ + public String storePath; + + /** + * 证书密码 + */ + public String storePass; + + /** + * 连接协议 + * {@link ProtocolType} + */ + @ProtocolType + public String protocol; + + /** + * 私钥别名 + */ + public String keyAlias; + @Override public FtpUrlEntity clone() { FtpUrlEntity entity = null; try { diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmd.java index 34c80642..5e0f9ec3 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmd.java @@ -26,7 +26,6 @@ public abstract class AbsCmd implements ICmd { protected ITaskQueue mQueue; protected T mTaskEntity; protected String TAG; - protected String mTargetName; /** * 是否是下载任务的命令 diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmdFactory.java b/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmdFactory.java index d0def907..4783fd91 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmdFactory.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmdFactory.java @@ -24,10 +24,9 @@ import com.arialyy.aria.core.inf.AbsTaskEntity; public abstract class AbsCmdFactory { /** - * @param target 创建任务的对象 * @param entity 下载实体 * @param taskType {@link ICmd#TASK_TYPE_DOWNLOAD}、{@link ICmd#TASK_TYPE_DOWNLOAD_GROUP}、{@link * ICmd#TASK_TYPE_UPLOAD} */ - public abstract CMD createCmd(String target, TASK_ENTITY entity, int type, int taskType); + public abstract CMD createCmd(TASK_ENTITY entity, int type, int taskType); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/group/AbsGroupCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/group/AbsGroupCmd.java index 0246b207..6f0cd071 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/group/AbsGroupCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/group/AbsGroupCmd.java @@ -36,11 +36,7 @@ public abstract class AbsGroupCmd extends AbsCmd extends AbsCmd extends AbsGroupCmd { - /** - * @param targetName 创建任务的对象名 - */ - GroupCancelCmd(String targetName, T entity) { - super(targetName, entity); + GroupCancelCmd(T entity) { + super(entity); } @Override public void executeCmd() { diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupCmdFactory.java b/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupCmdFactory.java index 8af60348..e96a9437 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupCmdFactory.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupCmdFactory.java @@ -62,13 +62,13 @@ public class GroupCmdFactory { AbsGroupCmd cmd = null; switch (type) { case SUB_TASK_START: - cmd = new GroupStartCmd<>(target, entity); + cmd = new GroupStartCmd<>(entity); break; case SUB_TASK_STOP: - cmd = new GroupStopCmd<>(target, entity); + cmd = new GroupStopCmd<>(entity); break; case SUB_TASK_CANCEL: - cmd = new GroupCancelCmd<>(target, entity); + cmd = new GroupCancelCmd<>(entity); } if (cmd != null) { cmd.childUrl = childUrl; diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStartCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStartCmd.java index 747e794c..be661ebc 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStartCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStartCmd.java @@ -22,11 +22,8 @@ import com.arialyy.aria.core.inf.AbsGroupTaskEntity; * 任务组开始命令,该命令负责处理任务组子任务的开始\恢复等工作 */ class GroupStartCmd extends AbsGroupCmd { - /** - * @param targetName 创建任务的对象名 - */ - GroupStartCmd(String targetName, T entity) { - super(targetName, entity); + GroupStartCmd( T entity) { + super( entity); } @Override public void executeCmd() { diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStopCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStopCmd.java index 483a7608..009a8e90 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStopCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStopCmd.java @@ -22,11 +22,8 @@ import com.arialyy.aria.core.inf.AbsGroupTaskEntity; * 停止任务组的命令 */ class GroupStopCmd extends AbsGroupCmd { - /** - * @param targetName 创建任务的对象名 - */ - GroupStopCmd(String targetName, T entity) { - super(targetName, entity); + GroupStopCmd(T entity) { + super(entity); } @Override public void executeCmd() { diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/AbsNormalCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/AbsNormalCmd.java index 7e6a996a..3ef585b1 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/AbsNormalCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/AbsNormalCmd.java @@ -46,13 +46,11 @@ public abstract class AbsNormalCmd extends AbsCmd { int taskType; /** - * @param targetName 产生任务的对象名 * @param taskType 下载任务类型{@link ICmd#TASK_TYPE_DOWNLOAD}、{@link ICmd#TASK_TYPE_DOWNLOAD_GROUP}、{@link * ICmd#TASK_TYPE_UPLOAD} */ - AbsNormalCmd(String targetName, T entity, int taskType) { + AbsNormalCmd(T entity, int taskType) { this.taskType = taskType; - mTargetName = targetName; mTaskEntity = entity; TAG = CommonUtil.getClassName(this); if (taskType == ICmd.TASK_TYPE_DOWNLOAD) { @@ -126,7 +124,7 @@ public abstract class AbsNormalCmd extends AbsCmd { */ void removeTask(AbsTaskEntity taskEntity) { AbsTask tempTask = getTask(taskEntity.getEntity()); - if (tempTask == null){ + if (tempTask == null) { tempTask = createTask(taskEntity); } mQueue.cancelTask(tempTask); @@ -181,7 +179,7 @@ public abstract class AbsNormalCmd extends AbsCmd { * @return 创建的任务 */ AbsTask createTask() { - tempTask = mQueue.createTask(mTargetName, mTaskEntity); + tempTask = mQueue.createTask(mTaskEntity); return tempTask; } @@ -193,6 +191,6 @@ public abstract class AbsNormalCmd extends AbsCmd { */ AbsTask createTask(AbsTaskEntity taskEntity) { TEManager.getInstance().addTEntity(taskEntity); - return mQueue.createTask(mTargetName, taskEntity); + return mQueue.createTask(taskEntity); } } \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/AddCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/AddCmd.java index 554e9c74..a34d385f 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/AddCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/AddCmd.java @@ -27,8 +27,8 @@ import com.arialyy.aria.util.ALog; */ class AddCmd extends AbsNormalCmd { - AddCmd(String targetName, T entity, int taskType) { - super(targetName, entity, taskType); + AddCmd(T entity, int taskType) { + super(entity, taskType); } @Override public void executeCmd() { diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java index dd47032e..e8e0f16e 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java @@ -42,11 +42,8 @@ public class CancelAllCmd extends AbsNormalCmd { */ public boolean removeFile = false; - /** - * @param targetName 产生任务的对象名 - */ - CancelAllCmd(String targetName, T entity, int taskType) { - super(targetName, entity, taskType); + CancelAllCmd(T entity, int taskType) { + super(entity, taskType); } @Override public void executeCmd() { diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelCmd.java index 57ab73d1..f0a80cdf 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelCmd.java @@ -16,7 +16,6 @@ package com.arialyy.aria.core.command.normal; -import android.text.TextUtils; import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsTaskEntity; @@ -31,8 +30,8 @@ public class CancelCmd extends AbsNormalCmd { */ public boolean removeFile = false; - CancelCmd(String targetName, T entity, int taskType) { - super(targetName, entity, taskType); + CancelCmd(T entity, int taskType) { + super(entity, taskType); } @Override public void executeCmd() { @@ -43,9 +42,6 @@ public class CancelCmd extends AbsNormalCmd { } if (task != null) { mTaskEntity.setRemoveFile(removeFile); - if (!TextUtils.isEmpty(mTargetName)) { - task.setTargetName(mTargetName); - } removeTask(); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/HighestPriorityCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/HighestPriorityCmd.java index ac3570d1..a033a145 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/HighestPriorityCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/HighestPriorityCmd.java @@ -36,11 +36,8 @@ import com.arialyy.aria.util.NetUtils; * 目前只只支持单下载任务的最高优先级任务 */ final class HighestPriorityCmd extends AbsNormalCmd { - /** - * @param targetName 产生任务的对象名 - */ - HighestPriorityCmd(String targetName, T entity, int taskType) { - super(targetName, entity, taskType); + HighestPriorityCmd(T entity, int taskType) { + super(entity, taskType); } @Override public void executeCmd() { @@ -54,9 +51,6 @@ final class HighestPriorityCmd extends AbsNormalCmd task = (DownloadTask) createTask(); } if (task != null) { - if (!TextUtils.isEmpty(mTargetName)) { - task.setTargetName(mTargetName); - } ((DownloadTaskQueue) mQueue).setTaskHighestPriority(task); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/NormalCmdFactory.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/NormalCmdFactory.java index 005e31b0..837d01a3 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/NormalCmdFactory.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/NormalCmdFactory.java @@ -78,32 +78,31 @@ public class NormalCmdFactory extends AbsCmdFactory } /** - * @param target 创建任务的对象 * @param entity 下载实体 * @param type 命令类型{@link #TASK_CREATE}、{@link #TASK_START}、{@link #TASK_CANCEL}、{@link * #TASK_STOP}、{@link #TASK_HIGHEST_PRIORITY}、{@link #TASK_STOP_ALL}、{@link #TASK_RESUME_ALL} * @param taskType {@link ICmd#TASK_TYPE_DOWNLOAD}、{@link ICmd#TASK_TYPE_DOWNLOAD_GROUP}、{@link * ICmd#TASK_TYPE_UPLOAD} */ - public AbsNormalCmd createCmd(String target, AbsTaskEntity entity, int type, int taskType) { + public AbsNormalCmd createCmd(AbsTaskEntity entity, int type, int taskType) { switch (type) { case TASK_CREATE: - return new AddCmd<>(target, entity, taskType); + return new AddCmd<>(entity, taskType); case TASK_RESUME: case TASK_START: - return new StartCmd<>(target, entity, taskType); + return new StartCmd<>(entity, taskType); case TASK_CANCEL: - return new CancelCmd<>(target, entity, taskType); + return new CancelCmd<>(entity, taskType); case TASK_STOP: - return new StopCmd<>(target, entity, taskType); + return new StopCmd<>(entity, taskType); case TASK_HIGHEST_PRIORITY: - return new HighestPriorityCmd<>(target, entity, taskType); + return new HighestPriorityCmd<>(entity, taskType); case TASK_STOP_ALL: - return new StopAllCmd<>(target, entity, taskType); + return new StopAllCmd<>(entity, taskType); case TASK_RESUME_ALL: - return new ResumeAllCmd<>(target, entity, taskType); + return new ResumeAllCmd<>(entity, taskType); case TASK_CANCEL_ALL: - return new CancelAllCmd<>(target, entity, taskType); + return new CancelAllCmd<>(entity, taskType); default: return null; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/ResumeAllCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/ResumeAllCmd.java index 76a80536..cb4c0eba 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/ResumeAllCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/ResumeAllCmd.java @@ -1,5 +1,6 @@ package com.arialyy.aria.core.command.normal; +import android.text.TextUtils; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadGroupEntity; @@ -32,11 +33,8 @@ import java.util.List; final class ResumeAllCmd extends AbsNormalCmd { private List mWaitList = new ArrayList<>(); - /** - * @param targetName 产生任务的对象名 - */ - ResumeAllCmd(String targetName, T entity, int taskType) { - super(targetName, entity, taskType); + ResumeAllCmd(T entity, int taskType) { + super(entity, taskType); } @Override public void executeCmd() { @@ -65,6 +63,9 @@ final class ResumeAllCmd extends AbsNormalCmd { "isGroupChild=? AND state!=? ORDER BY stopTime DESC", "false", "1"); if (entities != null && !entities.isEmpty()) { for (DownloadEntity entity : entities) { + //if (TextUtils.isEmpty(entity.getDownloadPath())){ + // continue; + //} resumeTask(TEManager.getInstance().getTEntity(DownloadTaskEntity.class, entity.getKey())); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/StartCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/StartCmd.java index eaaf57d0..511c8d10 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/StartCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/StartCmd.java @@ -16,7 +16,6 @@ package com.arialyy.aria.core.command.normal; -import android.text.TextUtils; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.common.QueueMod; import com.arialyy.aria.core.download.DownloadGroupTaskEntity; @@ -45,8 +44,8 @@ import java.util.List; */ class StartCmd extends AbsNormalCmd { - StartCmd(String targetName, T entity, int taskType) { - super(targetName, entity, taskType); + StartCmd(T entity, int taskType) { + super(entity, taskType); } @Override public void executeCmd() { @@ -67,9 +66,6 @@ class StartCmd extends AbsNormalCmd { AbsTask task = getTask(); if (task == null) { task = createTask(); - if (!TextUtils.isEmpty(mTargetName)) { - task.setTargetName(mTargetName); - } // 任务不存在时,根据配置不同,对任务执行操作 if (mod.equals(QueueMod.NOW.getTag())) { startTask(); @@ -82,14 +78,14 @@ class StartCmd extends AbsNormalCmd { || task.getState() == IEntity.STATE_COMPLETE) { resumeTask(); } else { - sendWaitState(); + sendWaitState(task); } } } else { //任务没执行并且执行队列中没有该任务,才认为任务没有运行中 if (!task.isRunning() && !mQueue.taskIsRunning(task.getKey())) { resumeTask(); - }else { + } else { ALog.w(TAG, String.format("任务【%s】已经在运行", task.getTaskName())); } } @@ -152,7 +148,8 @@ class StartCmd extends AbsNormalCmd { AbsTask task = getTask(te.getEntity()); if (task != null) continue; if (te instanceof DownloadTaskEntity) { - if (te.getRequestType() == AbsTaskEntity.D_FTP || te.getRequestType() == AbsTaskEntity.U_FTP) { + if (te.getRequestType() == AbsTaskEntity.D_FTP + || te.getRequestType() == AbsTaskEntity.U_FTP) { te.setUrlEntity(CommonUtil.getFtpUrlInfo(te.getEntity().getKey())); } mQueue = DownloadTaskQueue.getInstance(); diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/StopAllCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/StopAllCmd.java index 7f55e573..ff15dc92 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/StopAllCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/StopAllCmd.java @@ -7,11 +7,8 @@ import com.arialyy.aria.core.inf.AbsTaskEntity; * 停止所有任务的命令,并清空所有等待队列 */ final class StopAllCmd extends AbsNormalCmd { - /** - * @param targetName 产生任务的对象名 - */ - StopAllCmd(String targetName, T entity, int taskType) { - super(targetName, entity, taskType); + StopAllCmd(T entity, int taskType) { + super(entity, taskType); } @Override public void executeCmd() { diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/StopCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/StopCmd.java index 15a9479b..396cd389 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/StopCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/StopCmd.java @@ -16,10 +16,9 @@ package com.arialyy.aria.core.command.normal; -import android.text.TextUtils; import com.arialyy.aria.core.inf.AbsTask; -import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.AbsTaskEntity; +import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.util.ALog; /** @@ -28,8 +27,8 @@ import com.arialyy.aria.util.ALog; */ class StopCmd extends AbsNormalCmd { - StopCmd(String targetName, T entity, int taskType) { - super(targetName, entity, taskType); + StopCmd(T entity, int taskType) { + super(entity, taskType); } @Override public void executeCmd() { @@ -42,9 +41,6 @@ class StopCmd extends AbsNormalCmd { ALog.w(TAG, "停止命令执行失败,【调度器中没有该任务】"); } } else { - if (!TextUtils.isEmpty(mTargetName)) { - task.setTargetName(mTargetName); - } stopTask(); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadListener.java b/Aria/src/main/java/com/arialyy/aria/core/common/AEvent.java similarity index 57% rename from Aria/src/main/java/com/arialyy/aria/core/download/DownloadListener.java rename to Aria/src/main/java/com/arialyy/aria/core/common/AEvent.java index 78cf1d9f..f5852b92 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadListener.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/AEvent.java @@ -13,23 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.arialyy.aria.core.download; - -import android.os.Handler; -import com.arialyy.aria.core.inf.IDownloadListener; +package com.arialyy.aria.core.common; /** - * Created by Aria.Lao on 2017/7/20. - * 普通任务下载的事件监听器 + * Aria事件总线 */ -class DownloadListener extends BaseDListener - implements IDownloadListener { - DownloadListener(DownloadTask task, Handler outHandler) { - super(task, outHandler); - } +public class AEvent { + private static final Object LOCK = new Object(); + private static volatile AEvent INSTANCE = null; - @Override public void supportBreakpoint(boolean support) { + private AEvent() { } + public static AEvent getInstance() { + if (INSTANCE == null) { + synchronized (LOCK) { + INSTANCE = new AEvent(); + } + } + return INSTANCE; + } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java b/Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java index 5680a83d..33f8cf56 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java @@ -16,36 +16,33 @@ package com.arialyy.aria.core.common; import android.content.Context; +import android.util.SparseArray; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.inf.AbsNormalEntity; import com.arialyy.aria.core.inf.AbsTaskEntity; -import com.arialyy.aria.core.inf.IDownloadListener; import com.arialyy.aria.core.inf.IEventListener; +import com.arialyy.aria.core.manager.ThreadTaskManager; import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.DbHelper; import java.io.File; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Properties; import java.util.Set; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; /** * Created by AriaL on 2017/7/1. * 任务处理器 */ public abstract class AbsFileer> - implements Runnable, IUtil { + implements Runnable { private static final String STATE = "_state_"; private static final String RECORD = "_record_"; /** @@ -64,16 +61,13 @@ public abstract class AbsFileer mTask = new HashMap<>(); + private SparseArray mTask = new SparseArray<>(); - private Timer mTimer; + private ScheduledThreadPoolExecutor mTimer; @Deprecated private File mConfigFile; /** * 进度刷新间隔 @@ -93,7 +87,12 @@ public abstract class AbsFileer mEntity.getFileSize()) { + ALog.i(TAG, String.format("文件【%s】错误,任务重新开始", file.getPath())); + file.delete(); + tr.startLocation = 0; + tr.isComplete = false; + tr.endLocation = mEntity.getFileSize(); + } else if (file.length() == mEntity.getFileSize()) { + tr.isComplete = true; + mCompleteThreadNum++; + } else { + if (file.length() != tr.startLocation) { + ALog.i(TAG, String.format("修正【%s】的进度记录为:%s", file.getPath(), file.length())); + tr.startLocation = file.length(); + tr.isComplete = false; + } + } + } else { + for (ThreadRecord tr : mRecord.threadRecords) { + if (tr.isComplete) { + mCompleteThreadNum++; + } + } + } + mTotalThreadNum = mRecord.threadRecords.size(); + mTaskEntity.setNewTask(false); + } + + /** + * 处理分块任务的记录 + */ + private void handleBlockRecord() { + final int threadNum = mRecord.threadRecords.size(); + final long blockLen = mEntity.getFileSize() / threadNum; + int i = 0; + for (ThreadRecord tr : mRecord.threadRecords) { + File temp = new File(String.format(SUB_PATH, mRecord.filePath, tr.threadId)); + if (!temp.exists()) { + ALog.i(TAG, String.format("分块文件【%s】不存在,该分块将重新开始", temp.getPath())); + tr.isComplete = false; + tr.startLocation = -1; + } else { + if (tr.isComplete) { + mCompleteThreadNum++; + } else { + long realLocation = i * blockLen + temp.length(); + ALog.i(TAG, String.format( + "startLocation = %s; endLocation = %s; block = %s; tempLen = %s; i = %s", + tr.startLocation, tr.endLocation, blockLen, temp.length(), i)); + if (tr.endLocation == realLocation) { + ALog.d(TAG, String.format("分块【%s】已完成,更新记录", temp.getPath())); + tr.startLocation = realLocation; + tr.isComplete = true; + mCompleteThreadNum++; + } else { + tr.isComplete = false; + if (realLocation != tr.startLocation) { + ALog.i(TAG, String.format("修正分块【%s】的进度记录为:%s", temp.getPath(), realLocation)); + tr.startLocation = realLocation; + } else if (realLocation > tr.endLocation) { + ALog.i(TAG, String.format("分块【%s】错误,将重新开始该分块", temp.getPath())); + temp.delete(); + tr.startLocation = i * blockLen; } } - mTotalThreadNum = mRecord.threadRecords.size(); - mTaskEntity.setNewTask(false); } } + i++; } + mTotalThreadNum = mRecord.threadRecords.size(); + mTaskEntity.setNewTask(false); } /** @@ -342,7 +457,6 @@ public abstract class AbsFileer 0 ? temp : 0; @@ -418,7 +532,7 @@ public abstract class AbsFileer config = new SubThreadConfig<>(); - config.FILE_SIZE = fileLength; + config.TOTAL_FILE_SIZE = fileLength; config.URL = mEntity.isRedirect() ? mEntity.getRedirectUrl() : mEntity.getUrl(); config.TEMP_FILE = mRecord.isBlock ? new File(String.format(SUB_PATH, mTempFile.getPath(), i)) : mTempFile; @@ -456,28 +570,35 @@ public abstract class AbsFileer= 0) { - Long r = tr.startLocation; + if (tr.startLocation > 0) { + long r = tr.startLocation; //记录的位置需要在线程区间中 - if (startL < r && r < (i == (mTotalThreadNum - 1) ? fileLength : endL)) { + if (startL < r && r <= (i == (mTotalThreadNum - 1) ? fileLength : endL)) { mConstance.CURRENT_LOCATION += r - startL; startL = r; } ALog.d(TAG, String.format("任务【%s】线程__%s__恢复任务", mEntity.getFileName(), i)); + } else { + tr.startLocation = startL; } //最后一个线程的结束位置即为文件的总长度 if (i == (mTotalThreadNum - 1)) { endL = fileLength; } - // 更新记录 - tr.startLocation = startL; - tr.endLocation = endL; + if (tr.endLocation <= 0) { + tr.endLocation = endL; + } if (isNewTr) { mRecord.threadRecords.add(tr); } @@ -508,45 +629,18 @@ public abstract class AbsFileer keys = mTask.keySet(); - for (Integer key : keys) { - AbsThreadTask task = mTask.get(key); - if (task != null && !task.isThreadComplete()) { - task.getConfig().START_LOCATION = task.getConfig().THREAD_RECORD.startLocation; - mConstance.resetState(); - startTimer(); - ALog.d(TAG, String.format("任务【%s】开始重试,线程__%s__【开始位置:%s,结束位置:%s】", mEntity.getFileName(), - key, task.getConfig().START_LOCATION, task.getConfig().END_LOCATION)); - if (!mFixedThreadPool.isShutdown()) { - mFixedThreadPool.execute(task); - } else { - ALog.w(TAG, "线程池已关闭"); - mListener.onFail(true); - } - } - } + public void retryTask() { + ALog.w(TAG, String.format("任务【%s】开始重试", mEntity.getFileName())); + startFlow(); } /** @@ -561,24 +655,23 @@ public abstract class AbsFileer config = new SubThreadConfig<>(); - config.FILE_SIZE = mEntity.getFileSize(); + config.TOTAL_FILE_SIZE = mEntity.getFileSize(); config.URL = mEntity.isRedirect() ? mEntity.getRedirectUrl() : mEntity.getUrl(); config.TEMP_FILE = mTempFile; config.THREAD_ID = 0; config.START_LOCATION = 0; - config.END_LOCATION = config.FILE_SIZE; + config.END_LOCATION = config.TOTAL_FILE_SIZE; config.SUPPORT_BP = mTaskEntity.isSupportBP(); config.TASK_ENTITY = mTaskEntity; ThreadRecord record = new ThreadRecord(); record.startLocation = 0; - record.endLocation = config.FILE_SIZE; + record.endLocation = config.TOTAL_FILE_SIZE; record.key = mTempFile.getPath(); config.THREAD_RECORD = record; AbsThreadTask task = selectThreadTask(config); if (task == null) return; mTask.put(0, task); - mFixedThreadPool = Executors.newFixedThreadPool(1); - mFixedThreadPool.execute(task); + ThreadTaskManager.getInstance().startThread(mTaskEntity.getKey(), task); mListener.onStart(0); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/AbsThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/common/AbsThreadTask.java index c776b047..0214c09d 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/AbsThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/AbsThreadTask.java @@ -15,22 +15,24 @@ */ package com.arialyy.aria.core.common; -import android.os.Build; +import android.os.Process; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.inf.AbsNormalEntity; import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.IEventListener; +import com.arialyy.aria.core.manager.ThreadTaskManager; import com.arialyy.aria.core.upload.UploadEntity; +import com.arialyy.aria.exception.BaseException; +import com.arialyy.aria.exception.FileException; +import com.arialyy.aria.exception.TaskException; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ErrorHelp; import com.arialyy.aria.util.FileUtil; import com.arialyy.aria.util.NetUtils; import java.io.File; -import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; -import java.util.Timer; -import java.util.TimerTask; +import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -39,20 +41,17 @@ import java.util.concurrent.Executors; * 任务线程 */ public abstract class AbsThreadTask> - implements Runnable { + implements Callable { /** * 线程重试次数 */ private final int RETRY_NUM = 2; - /** - * 线程重试间隔 - */ - private final int RETRY_INTERVAL = 5000; + private final String TAG = "AbsThreadTask"; /** * 当前子线程的下载位置 */ - protected long mChildCurrentLocation = 0, mSleepTime = 0; + protected long mChildCurrentLocation = 0; protected int mBufSize; protected IEventListener mListener; protected StateConstance STATE; @@ -60,16 +59,23 @@ public abstract class AbsThreadTask 0) { + mSpeedBandUtil = new BandwidthLimiter(getMaxSpeed(), mThreadNum); + } } - protected void setMaxSpeed(double maxSpeed) { - if (-0.9999 < maxSpeed && maxSpeed < 0.00001) { - mSleepTime = 0; - } else { - BigDecimal db = new BigDecimal( - ((mBufSize / 1024) * (filterVersion() ? 1 : STATE.START_THREAD_NUM) / maxSpeed) * 1000); - mSleepTime = db.setScale(0, BigDecimal.ROUND_HALF_UP).longValue(); - } + /** + * 设置线程是否中断 + * + * @param isInterrupted {@code true} 中断 + */ + public void setInterrupted(boolean isInterrupted) { + this.isInterrupted = isInterrupted; + } + + /** + * 线程是否存活 + * + * @return {@code true}存活 + */ + protected boolean isLive() { + Thread t = Thread.currentThread(); + return !t.isInterrupted() && !isInterrupted; } /** @@ -104,6 +124,74 @@ public abstract class AbsThreadTask= Build.VERSION_CODES.LOLLIPOP; - } - @Override protected void finalize() throws Throwable { super.finalize(); if (mConfigThreadPool != null) { @@ -188,10 +272,11 @@ public abstract class AbsThreadTask mEntity.getFileSize()) { - ALog.d(TAG, String.format("currentLocation=%s, fileSize=%s", STATE.CURRENT_LOCATION, - mEntity.getFileSize())); + String errorMsg = + String.format("下载失败,下载长度超出文件大;currentLocation=%s, fileSize=%s", STATE.CURRENT_LOCATION, + mEntity.getFileSize()); taskBreak = true; - fail(mChildCurrentLocation, "下载失败,下载长度超出文件大小", null, false); + fail(mChildCurrentLocation, new FileException(TAG, errorMsg), false); return; } mChildCurrentLocation += len; @@ -235,11 +320,10 @@ public abstract class AbsThreadTask tr.endLocation) { + ALog.i(TAG, String.format("分块【%s】错误,将重新下载该分块", file.getPath())); + boolean b = file.delete(); + ALog.w(TAG, "删除:" + b); + tr.startLocation = block * tr.threadId; + tr.isComplete = false; + mConfig.START_LOCATION = tr.startLocation; + } else if (file.length() == tr.endLocation) { + STATE.COMPLETE_THREAD_NUM++; + tr.isComplete = true; + } else { + tr.startLocation = block * tr.threadId + file.length(); + mConfig.START_LOCATION = tr.startLocation; + tr.isComplete = false; + STATE.CURRENT_LOCATION = getBlockRealTotalSize(); + ALog.i(TAG, String.format("修正分块【%s】进度,开始位置:%s,当前进度:%s", file.getPath(), tr.startLocation, + STATE.CURRENT_LOCATION)); + } + } else { + mConfig.START_LOCATION = mChildCurrentLocation == 0 ? mConfig.START_LOCATION + : mConfig.THREAD_RECORD.startLocation; + } + } + + /** + * 获取分块任务真实的进度 + * + * @return 进度 + */ + private long getBlockRealTotalSize() { + long size = 0; + for (int i = 0, len = getTaskRecord().threadRecords.size(); i < len; i++) { + File temp = new File(String.format(AbsFileer.SUB_PATH, getTaskRecord().filePath, i)); + if (temp.exists()) { + size += temp.length(); + } + } + return size; + } + /** * 处理失败状态 * @@ -313,8 +429,9 @@ public abstract class AbsThreadTask 1) { + maxRate = maxRate / threadNum; + } + this.setMaxRate(maxRate); + } + + /** + * Set the max upload or download rate in KB/s. maxRate must be grater than + * 0. If maxRate is zero, it means there is no bandwidth limit. + * + * @param maxRate If maxRate is zero, it means there is no bandwidth limit. + * @throws IllegalArgumentException + */ + public synchronized void setMaxRate(int maxRate) + throws IllegalArgumentException { + if (maxRate < 0) { + throw new IllegalArgumentException("maxRate can not less than 0"); + } + this.maxRate = maxRate; + if (maxRate == 0) { + this.timeCostPerChunk = 0; + } else { + this.timeCostPerChunk = (1000000000L * CHUNK_LENGTH) + / (this.maxRate * KB); + } + } + + /** + * Next 1 byte should do bandwidth limit. + */ + public synchronized void limitNextBytes() { + this.limitNextBytes(1); + } + + /** + * Next len bytes should do bandwidth limit + */ + public synchronized void limitNextBytes(int len) { + this.bytesWillBeSentOrReceive += len; + + /* We have sent CHUNK_LENGTH bytes */ + while (!Thread.currentThread().isInterrupted() && this.bytesWillBeSentOrReceive > CHUNK_LENGTH) { + long nowTick = System.nanoTime(); + long missedTime = this.timeCostPerChunk + - (nowTick - this.lastPieceSentOrReceiveTick); + if (missedTime > 0) { + try { + Thread.currentThread().sleep(missedTime / 1000000, + (int) (missedTime % 1000000)); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + this.bytesWillBeSentOrReceive -= CHUNK_LENGTH; + this.lastPieceSentOrReceiveTick = nowTick + + (missedTime > 0 ? missedTime : 0); + } + } +} \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/BaseListener.java b/Aria/src/main/java/com/arialyy/aria/core/common/BaseListener.java new file mode 100644 index 00000000..d6fde579 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/common/BaseListener.java @@ -0,0 +1,145 @@ +/* + * 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.common; + +import android.os.Handler; +import com.arialyy.aria.core.AriaManager; +import com.arialyy.aria.core.inf.AbsEntity; +import com.arialyy.aria.core.inf.AbsTask; +import com.arialyy.aria.core.inf.AbsTaskEntity; +import com.arialyy.aria.core.inf.IEntity; +import com.arialyy.aria.core.inf.IEventListener; +import com.arialyy.aria.core.inf.TaskSchedulerType; +import com.arialyy.aria.core.scheduler.ISchedulers; +import com.arialyy.aria.exception.BaseException; +import com.arialyy.aria.util.ALog; +import com.arialyy.aria.util.CommonUtil; +import com.arialyy.aria.util.ErrorHelp; +import java.lang.ref.WeakReference; + +public abstract class BaseListener, TASK extends AbsTask> + implements IEventListener { + private static final String TAG = "BaseListener"; + protected WeakReference outHandler; + private int RUN_SAVE_INTERVAL = 5 * 1000; //5s保存一次下载中的进度 + private long mLastLen; //上一次发送长度 + private boolean isFirst = true; + private TASK mTask; + private long mLastSaveTime; + protected ENTITY mEntity; + protected TASK_ENTITY mTaskEntity; + protected boolean isConvertSpeed; + protected long mUpdateInterval; + protected AriaManager manager; + + protected BaseListener(TASK task, Handler outHandler) { + this.outHandler = new WeakReference<>(outHandler); + this.mTask = new WeakReference<>(task).get(); + this.mEntity = mTask.getTaskEntity().getEntity(); + this.mTaskEntity = mTask.getTaskEntity(); + manager = AriaManager.getInstance(AriaManager.APP); + mLastLen = mEntity.getCurrentProgress(); + mLastSaveTime = System.currentTimeMillis(); + } + + @Override public void onPre() { + saveData(IEntity.STATE_PRE, -1); + sendInState2Target(ISchedulers.PRE); + } + + @Override public void onStart(long startLocation) { + saveData(IEntity.STATE_RUNNING, startLocation); + sendInState2Target(ISchedulers.START); + } + + @Override public void onResume(long resumeLocation) { + saveData(IEntity.STATE_RUNNING, resumeLocation); + sendInState2Target(ISchedulers.RESUME); + } + + @Override public void onProgress(long currentLocation) { + mEntity.setCurrentProgress(currentLocation); + long speed = currentLocation - mLastLen; + if (isFirst) { + speed = 0; + isFirst = false; + } + handleSpeed(speed); + sendInState2Target(ISchedulers.RUNNING); + if (System.currentTimeMillis() - mLastSaveTime >= RUN_SAVE_INTERVAL) { + saveData(IEntity.STATE_RUNNING, currentLocation); + mLastSaveTime = System.currentTimeMillis(); + } + + mLastLen = currentLocation; + } + + @Override public void onStop(long stopLocation) { + saveData(mTask.getSchedulerType() == TaskSchedulerType.TYPE_STOP_AND_WAIT ? IEntity.STATE_WAIT + : IEntity.STATE_STOP, stopLocation); + handleSpeed(0); + sendInState2Target(ISchedulers.STOP); + } + + @Override public void onComplete() { + saveData(IEntity.STATE_COMPLETE, mEntity.getFileSize()); + handleSpeed(0); + sendInState2Target(ISchedulers.COMPLETE); + } + + @Override public void onCancel() { + saveData(IEntity.STATE_CANCEL, -1); + handleSpeed(0); + sendInState2Target(ISchedulers.CANCEL); + } + + @Override public void onFail(boolean needRetry, BaseException e) { + mEntity.setFailNum(mEntity.getFailNum() + 1); + saveData(IEntity.STATE_FAIL, mEntity.getCurrentProgress()); + handleSpeed(0); + mTask.needRetry = needRetry; + mTask.putExpand(AbsTask.ERROR_INFO_KEY, e); + sendInState2Target(ISchedulers.FAIL); + e.printStackTrace(); + ErrorHelp.saveError(e.getTag(), "", ALog.getExceptionString(e)); + } + + private void handleSpeed(long speed) { + if (mUpdateInterval != 1000) { + speed = speed * 1000 / mUpdateInterval; + } + if (isConvertSpeed) { + mEntity.setConvertSpeed(CommonUtil.formatFileSize(speed < 0 ? 0 : speed) + "/s"); + } + mEntity.setSpeed(speed < 0 ? 0 : speed); + + mEntity.setPercent((int) (mEntity.getFileSize() <= 0 ? 0 + : mEntity.getCurrentProgress() * 100 / mEntity.getFileSize())); + } + + /** + * 将任务状态发送给下载器 + * + * @param state {@link ISchedulers#START} + */ + protected void sendInState2Target(int state) { + if (outHandler.get() != null) { + outHandler.get().obtainMessage(state, mTask).sendToTarget(); + } + } + + protected abstract void saveData(int state, long location); +} diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/IUtil.java b/Aria/src/main/java/com/arialyy/aria/core/common/IUtil.java index 17698d8f..f7354574 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/IUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/IUtil.java @@ -60,7 +60,9 @@ public interface IUtil { void resume(); /** - * 设置最大速度 + * 设置最大下载/上传速度 + * + * @param speed 单位:kb */ - void setMaxSpeed(double maxSpeed); + void setMaxSpeed(int speed); } \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/OnFileInfoCallback.java b/Aria/src/main/java/com/arialyy/aria/core/common/OnFileInfoCallback.java index 0a12f5f1..82ed853f 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/OnFileInfoCallback.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/OnFileInfoCallback.java @@ -15,6 +15,8 @@ */ package com.arialyy.aria.core.common; +import com.arialyy.aria.exception.BaseException; + public interface OnFileInfoCallback { /** * 处理完成 @@ -26,7 +28,7 @@ public interface OnFileInfoCallback { /** * 请求失败 * - * @param errorMsg 错误信息 + * @param e 错误信息 */ - void onFail(String url, String errorMsg, boolean needRetry); + void onFail(String url, BaseException e, boolean needRetry); } \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/ProtocolType.java b/Aria/src/main/java/com/arialyy/aria/core/common/ProtocolType.java new file mode 100644 index 00000000..8a80e123 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/common/ProtocolType.java @@ -0,0 +1,39 @@ +/* + * 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.common; + +import android.support.annotation.StringDef; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@StringDef({ + ProtocolType.Default, + ProtocolType.SSL, + ProtocolType.SSLv3, + ProtocolType.TLS, + ProtocolType.TLSv1, + ProtocolType.TLSv1_1, + ProtocolType.TLSv1_2 +}) +@Retention(RetentionPolicy.SOURCE) public @interface ProtocolType { + String Default = "TLS"; + String SSL = "SSL"; + String SSLv3 = "SSLv3"; + String TLS = "TLS"; + String TLSv1 = "TLSv1"; + String TLSv1_1 = "TLSv1.1"; + String TLSv1_2 = "TLSv1.2"; +} diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/ProxyHelper.java b/Aria/src/main/java/com/arialyy/aria/core/common/ProxyHelper.java index c5e59eb4..a1d64f23 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/ProxyHelper.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/ProxyHelper.java @@ -15,26 +15,47 @@ */ package com.arialyy.aria.core.common; +import android.os.Build; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.util.CommonUtil; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; /** * Created by Aria.Lao on 2017/7/10. * 代理参数获取 */ public class ProxyHelper { + /** + * 普通下载任务类型 + */ + public static int PROXY_TYPE_DOWNLOAD = 0x01; + /** + * 组合下载任务类型 + */ + public static int PROXY_TYPE_DOWNLOAD_GROUP = 0x02; + ///** + // * 组合任务子任务类型 + // */ + //public static int PROXY_TYPE_DOWNLOAD_GROUP_SUB = 0x03; + /** + * 普通上传任务类型 + */ + public static int PROXY_TYPE_UPLOAD = 0x04; public Set downloadCounter = new HashSet<>(), uploadCounter = new HashSet<>(), downloadGroupCounter = new HashSet<>(), downloadGroupSubCounter = new HashSet<>(); + public Map> mProxyCache = new ConcurrentHashMap<>(); public static volatile ProxyHelper INSTANCE = null; + private boolean canLoadClass = false; private ProxyHelper() { - init(); + //init(); } public static ProxyHelper getInstance() { @@ -46,14 +67,75 @@ public class ProxyHelper { return INSTANCE; } + /** + * @since 3.4.6 版本开始,已经在ElementHandler中关闭了ProxyClassCounter对象的生成 + */ + @Deprecated private void init() { - List classes = CommonUtil.getClassName(AriaManager.APP, + List classes = CommonUtil.getPkgClassNames(AriaManager.APP, "com.arialyy.aria.ProxyClassCounter"); - for (String className : classes) { - count(className); + canLoadClass = classes != null + && !classes.isEmpty() + && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; + if (canLoadClass) { + for (String className : classes) { + count(className); + } + } + } + + /** + * 是否能读取到代理计数文件 + * + * @return {@code true} 可以读取,{@code false} 不能读取 + */ + public boolean isCanLoadCountClass() { + return canLoadClass; + } + + /** + * 检查观察者对象的代理文件类型 + * + * @param clazz 观察者对象 + * @return {@link #PROXY_TYPE_DOWNLOAD},如果没有实体对象则返回空的list + */ + public Set checkProxyType(Class clazz) { + final String className = clazz.getName(); + Set result = mProxyCache.get(clazz.getName()); + if (result != null) { + return result; + } + result = new HashSet<>(); + try { + if (Class.forName(className.concat("$$DownloadGroupListenerProxy")) != null) { + result.add(PROXY_TYPE_DOWNLOAD_GROUP); + } + } catch (ClassNotFoundException e) { + //e.printStackTrace(); + } + try { + if (Class.forName(className.concat("$$DownloadListenerProxy")) != null) { + result.add(PROXY_TYPE_DOWNLOAD); + } + } catch (ClassNotFoundException e) { + //e.printStackTrace(); + } + + try { + if (Class.forName(className.concat("$$UploadListenerProxy")) != null) { + result.add(PROXY_TYPE_UPLOAD); + } + } catch (ClassNotFoundException e) { + //e.printStackTrace(); + } + + if (!result.isEmpty()) { + mProxyCache.put(clazz.getName(), result); } + return result; } + @Deprecated private void count(String className) { try { Class clazz = Class.forName(className); diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/StateConstance.java b/Aria/src/main/java/com/arialyy/aria/core/common/StateConstance.java index b3cae98b..5ccc8274 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/StateConstance.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/StateConstance.java @@ -40,24 +40,29 @@ public class StateConstance { public void resetState() { isCancel = false; isStop = false; - isRunning = true; + isRunning = false; CANCEL_NUM = 0; STOP_NUM = 0; FAIL_NUM = 0; + COMPLETE_THREAD_NUM = 0; + START_THREAD_NUM = 0; + CURRENT_LOCATION = 0; } /** * 所有子线程是否都已经停止 */ public boolean isStop() { - return STOP_NUM == START_THREAD_NUM; + //ALog.d(TAG, String.format("stop_num=%s; start_thread_num=%s; complete_num=%s", STOP_NUM, + // START_THREAD_NUM, COMPLETE_THREAD_NUM)); + return STOP_NUM == START_THREAD_NUM || STOP_NUM + COMPLETE_THREAD_NUM == START_THREAD_NUM; } /** * 所有子线程是否都已经失败 */ public boolean isFail() { - ALog.d(TAG, String.format("fail_num=%s; start_thread_num=%s, complete_num=%s", FAIL_NUM, + ALog.d(TAG, String.format("fail_num=%s; start_thread_num=%s; complete_num=%s", FAIL_NUM, START_THREAD_NUM, COMPLETE_THREAD_NUM)); return COMPLETE_THREAD_NUM != START_THREAD_NUM && (FAIL_NUM == START_THREAD_NUM || FAIL_NUM + COMPLETE_THREAD_NUM == START_THREAD_NUM); diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/SubThreadConfig.java b/Aria/src/main/java/com/arialyy/aria/core/common/SubThreadConfig.java index 2dc5b647..02859b08 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/SubThreadConfig.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/SubThreadConfig.java @@ -9,8 +9,8 @@ import java.io.File; public class SubThreadConfig { //线程Id public int THREAD_ID; - //下载文件大小 - public long FILE_SIZE; + //文件总长度 + public long TOTAL_FILE_SIZE; //子线程启动下载位置 public long START_LOCATION; //子线程结束下载位置 diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/ThreadRecord.java b/Aria/src/main/java/com/arialyy/aria/core/common/ThreadRecord.java index 29632e51..c9c7cb80 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/ThreadRecord.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/ThreadRecord.java @@ -47,4 +47,9 @@ public class ThreadRecord extends DbEntity { * 线程id */ public int threadId = -1; + + /** + * 分块长度 + */ + public long blockLen = 0; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/ThreadTaskManager.java b/Aria/src/main/java/com/arialyy/aria/core/common/ThreadTaskManager.java deleted file mode 100644 index 8893d6df..00000000 --- a/Aria/src/main/java/com/arialyy/aria/core/common/ThreadTaskManager.java +++ /dev/null @@ -1,78 +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.common; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * 线程任务管理器 - */ -class ThreadTaskManager { - private static volatile ThreadTaskManager INSTANCE = null; - private Map> mThreadTasks = new ConcurrentHashMap<>(); - - private ThreadTaskManager() { - - } - - public static ThreadTaskManager getInstance() { - if (INSTANCE == null) { - synchronized (ThreadTaskManager.class) { - INSTANCE = new ThreadTaskManager(); - } - } - return INSTANCE; - } - - /** - * 添加单条线程记录 - * - * @param key 任务对应的key - * @param threadTask 线程任务 - */ - public void addTask(String key, AbsThreadTask threadTask) { - if (mThreadTasks.get(key) == null) { - mThreadTasks.put(key, new ArrayList()); - } - mThreadTasks.get(key).add(threadTask); - } - - /** - * 删除对应的任务的线程记录 - * - * @param key 任务对应的key - */ - public void removeTask(String key) { - for (Iterator>> iter = mThreadTasks.entrySet().iterator(); - iter.hasNext(); ) { - Map.Entry> entry = iter.next(); - if (key.equals(entry.getKey())) { - List list = mThreadTasks.get(key); - if (list != null && !list.isEmpty()) { - list.clear(); - } - iter.remove(); - } - } - } - - - -} diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/AbsFtpInfoThread.java b/Aria/src/main/java/com/arialyy/aria/core/common/ftp/AbsFtpInfoThread.java similarity index 68% rename from Aria/src/main/java/com/arialyy/aria/core/common/AbsFtpInfoThread.java rename to Aria/src/main/java/com/arialyy/aria/core/common/ftp/AbsFtpInfoThread.java index c2b649ec..32910485 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/AbsFtpInfoThread.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/ftp/AbsFtpInfoThread.java @@ -13,26 +13,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.arialyy.aria.core.common; +package com.arialyy.aria.core.common.ftp; +import android.os.Process; import android.text.TextUtils; +import aria.apache.commons.net.ftp.FTP; +import aria.apache.commons.net.ftp.FTPClient; +import aria.apache.commons.net.ftp.FTPFile; +import aria.apache.commons.net.ftp.FTPReply; +import aria.apache.commons.net.ftp.FTPSClient; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.FtpUrlEntity; +import com.arialyy.aria.core.common.OnFileInfoCallback; +import com.arialyy.aria.core.common.ProtocolType; import com.arialyy.aria.core.inf.AbsEntity; import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.upload.UploadEntity; +import com.arialyy.aria.exception.AriaIOException; +import com.arialyy.aria.exception.BaseException; +import com.arialyy.aria.exception.FileException; +import com.arialyy.aria.exception.TaskException; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.Regular; +import com.arialyy.aria.util.SSLContextUtil; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.apache.commons.net.ftp.FTP; -import org.apache.commons.net.ftp.FTPClient; -import org.apache.commons.net.ftp.FTPFile; -import org.apache.commons.net.ftp.FTPReply; +import javax.net.ssl.SSLContext; /** * Created by Aria.Lao on 2017/7/25. @@ -69,6 +79,7 @@ public abstract class AbsFtpInfoThread 0) { - client = new FTPClient(); + client = newInstanceClient(urlEntity); InetAddress ip = InetAddress.getByName(urlEntity.hostName); client.setConnectTimeout(mConnectTimeOut); // 连接10s超时 client.connect(ip, Integer.parseInt(urlEntity.port)); @@ -182,11 +192,18 @@ public abstract class AbsFtpInfoThread> extends AbsThreadTask { private final String TAG = "AbsFtpThreadTask"; - protected String charSet, port; + protected String charSet; /** * D_FTP 服务器编码 */ @@ -55,7 +62,7 @@ public abstract class AbsFtpThreadTask= ips.length) { diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/ftp/FTPSConfig.java b/Aria/src/main/java/com/arialyy/aria/core/common/ftp/FTPSConfig.java new file mode 100644 index 00000000..95c826ba --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/common/ftp/FTPSConfig.java @@ -0,0 +1,104 @@ +/* + * 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.common.ftp; + +import android.text.TextUtils; +import com.arialyy.aria.core.FtpUrlEntity; +import com.arialyy.aria.core.common.ProtocolType; +import com.arialyy.aria.core.inf.AbsTarget; +import com.arialyy.aria.core.inf.ITarget; + +/** + * FTP SSL/TSL配置 + */ +public class FTPSConfig implements ITarget { + private final String TAG = "FTPSConfig"; + private TARGET mTarget; + private FtpUrlEntity mUrlEntity; + + public FTPSConfig(TARGET target) { + mTarget = target; + mUrlEntity = mTarget.getTaskEntity().getUrlEntity(); + } + + /** + * 设置协议类型 + * + * @param protocol {@link ProtocolType} + */ + public FTPSConfig setProtocol(@ProtocolType String protocol) { + if (TextUtils.isEmpty(protocol)) { + throw new NullPointerException("协议为空"); + } + mUrlEntity.protocol = protocol; + return this; + } + + /** + * 设置证书别名 + * + * @param keyAlias 别名 + */ + public FTPSConfig setAlias(String keyAlias) { + if (TextUtils.isEmpty(keyAlias)) { + throw new NullPointerException("别名为空"); + } + mUrlEntity.keyAlias = keyAlias; + return this; + } + + /** + * 设置证书密码 + * + * @param storePass 私钥密码 + */ + public FTPSConfig setStorePass(String storePass) { + if (TextUtils.isEmpty(storePass)) { + throw new NullPointerException("证书密码为空"); + } + mUrlEntity.storePass = storePass; + return this; + } + + /** + * 设置证书路径 + * + * @param storePath 证书路径 + */ + public FTPSConfig setStorePath(String storePath) { + if (TextUtils.isEmpty(storePath)) { + throw new NullPointerException("证书路径为空"); + } + mUrlEntity.storePath = storePath; + return this; + } + + @Override public void start() { + mTarget.start(); + } + + @Override public void stop() { + mTarget.stop(); + } + + @Override public void resume() { + mTarget.resume(); + } + + @Override public void cancel() { + mTarget.cancel(); + } +} diff --git a/Aria/src/main/java/com/arialyy/aria/core/delegate/FtpDelegate.java b/Aria/src/main/java/com/arialyy/aria/core/common/ftp/FtpDelegate.java similarity index 63% rename from Aria/src/main/java/com/arialyy/aria/core/delegate/FtpDelegate.java rename to Aria/src/main/java/com/arialyy/aria/core/common/ftp/FtpDelegate.java index 736a53c8..04f2792d 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/delegate/FtpDelegate.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/ftp/FtpDelegate.java @@ -13,35 +13,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.arialyy.aria.core.delegate; +package com.arialyy.aria.core.common.ftp; import android.text.TextUtils; -import com.arialyy.aria.core.inf.AbsEntity; -import com.arialyy.aria.core.inf.AbsTaskEntity; +import com.arialyy.aria.core.FtpUrlEntity; +import com.arialyy.aria.core.inf.AbsTarget; import com.arialyy.aria.core.inf.IFtpTarget; -import com.arialyy.aria.core.inf.ITarget; import com.arialyy.aria.util.ALog; +import java.net.Proxy; /** * Created by laoyuyu on 2018/3/9. * ftp 委托 */ -public class FtpDelegate> - implements IFtpTarget { +public class FtpDelegate implements IFtpTarget { private static final String TAG = "FtpDelegate"; - private ENTITY mEntity; - private TASK_ENTITY mTaskEntity; + private FtpUrlEntity mUrlEntity; private TARGET mTarget; - public FtpDelegate(TARGET target, TASK_ENTITY taskEntity) { + public FtpDelegate(TARGET target) { mTarget = target; - mTaskEntity = taskEntity; - mEntity = mTaskEntity.getEntity(); + mUrlEntity = target.getTaskEntity().getUrlEntity(); } @Override public TARGET charSet(String charSet) { - if (TextUtils.isEmpty(charSet)) return mTarget; - mTaskEntity.setCharSet(charSet); + if (TextUtils.isEmpty(charSet)) { + throw new NullPointerException("字符编码为空"); + } + mTarget.getTaskEntity().setCharSet(charSet); return mTarget; } @@ -57,10 +56,15 @@ public class FtpDelegate> - implements IHttpHeaderTarget { +public class HttpHeaderDelegate + implements IHttpHeaderDelegate { private static final String TAG = "HttpHeaderDelegate"; - private ENTITY mEntity; - private TASK_ENTITY mTaskEntity; private TARGET mTarget; - public HttpHeaderDelegate(TARGET target, TASK_ENTITY taskEntity) { + public HttpHeaderDelegate(TARGET target) { mTarget = target; - mTaskEntity = taskEntity; - - mEntity = mTaskEntity.getEntity(); } /** @@ -61,7 +55,7 @@ public class HttpHeaderDelegate headers) { /* 两个map比较逻辑 diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/http/PostDelegate.java b/Aria/src/main/java/com/arialyy/aria/core/common/http/PostDelegate.java new file mode 100644 index 00000000..f06f3ae9 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/common/http/PostDelegate.java @@ -0,0 +1,86 @@ +/* + * 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.common.http; + +import android.text.TextUtils; +import com.arialyy.aria.core.common.RequestEnum; +import com.arialyy.aria.core.download.DownloadGroupTarget; +import com.arialyy.aria.core.download.DownloadGroupTaskEntity; +import com.arialyy.aria.core.download.DownloadTaskEntity; +import com.arialyy.aria.core.inf.AbsTarget; +import com.arialyy.aria.core.inf.IPostDelegate; +import com.arialyy.aria.core.inf.ITarget; +import com.arialyy.aria.util.ALog; +import java.util.HashMap; +import java.util.Map; + +/** + * post处理委托类 + */ +public class PostDelegate implements IPostDelegate, ITarget { + private static final String TAG = "PostDelegate"; + private TARGET mTarget; + + public PostDelegate(TARGET target) { + mTarget = target; + mTarget.getTaskEntity().setRequestEnum(RequestEnum.POST); + } + + @Override public TARGET setParams(Map params) { + mTarget.getTaskEntity().setParams(params); + if (mTarget instanceof DownloadGroupTarget) { + for (DownloadTaskEntity subTask : ((DownloadGroupTaskEntity) mTarget.getTaskEntity()).getSubTaskEntities()) { + subTask.setParams(params); + } + } + return mTarget; + } + + @Override public TARGET setParam(String key, String value) { + if (TextUtils.isEmpty(key) || TextUtils.isEmpty(value)) { + ALog.d(TAG, "key 或value 为空"); + return mTarget; + } + Map params = mTarget.getTaskEntity().getParams(); + if (params == null) { + params = new HashMap<>(); + mTarget.getTaskEntity().setParams(params); + } + params.put(key, value); + if (mTarget instanceof DownloadGroupTarget) { + for (DownloadTaskEntity subTask : ((DownloadGroupTaskEntity) mTarget.getTaskEntity()).getSubTaskEntities()) { + subTask.setParams(params); + } + } + return mTarget; + } + + @Override public void start() { + mTarget.start(); + } + + @Override public void stop() { + mTarget.stop(); + } + + @Override public void resume() { + mTarget.resume(); + } + + @Override public void cancel() { + mTarget.cancel(); + } +} diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/AbsDownloadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/AbsDownloadTarget.java index c48943e3..4662be8d 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/AbsDownloadTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/AbsDownloadTarget.java @@ -40,6 +40,11 @@ abstract class AbsDownloadTarget, TASK extends AbsTask> +class BaseDListener extends BaseListener implements IDownloadListener { private static final String TAG = "BaseDListener"; - WeakReference outHandler; - private int RUN_SAVE_INTERVAL = 5 * 1000; //5s保存一次下载中的进度 - private long mLastLen = 0; //上一次发送长度 - private boolean isFirst = true; - protected ENTITY mEntity; - protected TASK_ENTITY mTaskEntity; - private TASK mTask; - private boolean isConvertSpeed = false; - boolean isWait = false; - private long mLastSaveTime; - private long mUpdateInterval; - BaseDListener(TASK task, Handler outHandler) { - this.outHandler = new WeakReference<>(outHandler); - this.mTask = new WeakReference<>(task).get(); - this.mEntity = mTask.getTaskEntity().getEntity(); - this.mTaskEntity = mTask.getTaskEntity(); - final AriaManager manager = AriaManager.getInstance(AriaManager.APP); + BaseDListener(DownloadTask task, Handler outHandler) { + super(task, outHandler); isConvertSpeed = manager.getDownloadConfig().isConvertSpeed(); - mLastLen = mEntity.getCurrentProgress(); - mLastSaveTime = System.currentTimeMillis(); mUpdateInterval = manager.getDownloadConfig().getUpdateInterval(); } - @Override public void onPre() { - saveData(IEntity.STATE_PRE, -1); - sendInState2Target(ISchedulers.PRE); - } - @Override public void onPostPre(long fileSize) { mEntity.setFileSize(fileSize); mEntity.setConvertFileSize(CommonUtil.formatFileSize(fileSize)); @@ -74,84 +48,8 @@ class BaseDListener= RUN_SAVE_INTERVAL) { - saveData(IEntity.STATE_RUNNING, currentLocation); - mLastSaveTime = System.currentTimeMillis(); - } - - mLastLen = currentLocation; - } - - @Override public void onStop(long stopLocation) { - saveData(isWait ? IEntity.STATE_WAIT : IEntity.STATE_STOP, stopLocation); - handleSpeed(0); - sendInState2Target(ISchedulers.STOP); - } - - @Override public void onCancel() { - saveData(IEntity.STATE_CANCEL, -1); - handleSpeed(0); - sendInState2Target(ISchedulers.CANCEL); - } - - @Override public void onComplete() { - saveData(IEntity.STATE_COMPLETE, mEntity.getFileSize()); - handleSpeed(0); - sendInState2Target(ISchedulers.COMPLETE); - } - - @Override public void onFail(boolean needRetry) { - mEntity.setFailNum(mEntity.getFailNum() + 1); - saveData(IEntity.STATE_FAIL, mEntity.getCurrentProgress()); - handleSpeed(0); - mTask.needRetry = needRetry; - sendInState2Target(ISchedulers.FAIL); - } - - private void handleSpeed(long speed) { - if (mUpdateInterval != 1000) { - speed = speed * 1000 / mUpdateInterval; - } - if (isConvertSpeed) { - mEntity.setConvertSpeed(CommonUtil.formatFileSize(speed < 0 ? 0 : speed) + "/s"); - } - mEntity.setSpeed(speed < 0 ? 0 : speed); - - mEntity.setPercent((int) (mEntity.getFileSize() <= 0 ? 0 - : mEntity.getCurrentProgress() * 100 / mEntity.getFileSize())); - } - - /** - * 将任务状态发送给下载器 - * - * @param state {@link ISchedulers#START} - */ - private void sendInState2Target(int state) { - if (outHandler.get() != null) { - outHandler.get().obtainMessage(state, mTask).sendToTarget(); - } - } - - private void saveData(int state, long location) { + @Override + protected void saveData(int state, long location) { mTaskEntity.setState(state); mEntity.setState(state); mEntity.setComplete(state == IEntity.STATE_COMPLETE); @@ -160,14 +58,11 @@ class BaseDListener extends AbsDownloadTarget { diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/BaseNormalTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/BaseNormalTarget.java index 5bc9abdc..538de167 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/BaseNormalTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/BaseNormalTarget.java @@ -86,7 +86,7 @@ abstract class BaseNormalTarget * @return {@code true}任务存在 */ @Override public boolean taskExists() { - return DownloadTaskQueue.getInstance().getTask(mEntity.getUrl()) != null; + return DownloadTaskQueue.getInstance().getTask(mEntity.getKey()) != null; } /** @@ -162,11 +162,17 @@ abstract class BaseNormalTarget } } - //设置文件保存路径,如果新文件路径和就文件路径不同,则修改路径 + //设置文件保存路径,如果新文件路径和旧文件路径不同,则修改路径 if (!filePath.equals(mEntity.getDownloadPath())) { if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=?", filePath)) { - ALog.e(TAG, "下载失败,保存路径【" + filePath + "】已经被其它任务占用,请设置其它保存路径"); - return false; + if (!forceDownload) { + ALog.e(TAG, "下载失败,保存路径【" + filePath + "】已经被其它任务占用,请设置其它保存路径"); + return false; + }else { + ALog.d(TAG, "保存路径【" + filePath + "】已经被其它任务占用,当前任务将覆盖该路径的文件"); + DbEntity.deleteData(DownloadEntity.class, "downloadPath=?", filePath); + mTaskEntity = TEManager.getInstance().getTEntity(DownloadTaskEntity.class, url); + } } File oldFile = new File(mEntity.getDownloadPath()); File newFile = new File(filePath); @@ -200,7 +206,7 @@ abstract class BaseNormalTarget ALog.e(TAG, "下载失败,url【" + url + "】不合法"); return false; } - if (!TextUtils.isEmpty(newUrl)){ + if (!TextUtils.isEmpty(newUrl)) { mEntity.setUrl(newUrl); mTaskEntity.setUrl(newUrl); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupListener.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupListener.java index d029b959..6b417a03 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupListener.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupListener.java @@ -16,17 +16,22 @@ package com.arialyy.aria.core.download; import android.os.Handler; +import com.arialyy.aria.core.common.BaseListener; import com.arialyy.aria.core.download.downloader.IDownloadGroupListener; import com.arialyy.aria.core.inf.GroupSendParams; +import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.scheduler.ISchedulers; +import com.arialyy.aria.exception.BaseException; import com.arialyy.aria.util.ALog; +import com.arialyy.aria.util.CommonUtil; +import com.arialyy.aria.util.ErrorHelp; /** * Created by Aria.Lao on 2017/7/20. * 任务组下载事件 */ class DownloadGroupListener - extends BaseDListener + extends BaseListener implements IDownloadGroupListener { private final String TAG = "DownloadGroupListener"; private GroupSendParams mSeedEntity; @@ -35,6 +40,8 @@ class DownloadGroupListener super(task, outHandler); mSeedEntity = new GroupSendParams<>(); mSeedEntity.groupTask = task; + isConvertSpeed = manager.getDownloadConfig().isConvertSpeed(); + mUpdateInterval = manager.getDownloadConfig().getUpdateInterval(); } @Override public void onSubPre(DownloadEntity subEntity) { @@ -59,9 +66,11 @@ class DownloadGroupListener sendInState2Target(ISchedulers.SUB_COMPLETE, subEntity); } - @Override public void onSubFail(DownloadEntity subEntity) { + @Override public void onSubFail(DownloadEntity subEntity, BaseException e) { saveCurrentLocation(); sendInState2Target(ISchedulers.SUB_FAIL, subEntity); + e.printStackTrace(); + ErrorHelp.saveError(e.getTag(), "", ALog.getExceptionString(e)); } @Override public void onSubCancel(DownloadEntity subEntity) { @@ -100,4 +109,36 @@ class DownloadGroupListener mEntity.setCurrentProgress(location); mEntity.update(); } + + @Override public void onPostPre(long fileSize) { + mEntity.setFileSize(fileSize); + mEntity.setConvertFileSize(CommonUtil.formatFileSize(fileSize)); + saveData(IEntity.STATE_POST_PRE, -1); + sendInState2Target(ISchedulers.POST_PRE); + } + + @Override public void supportBreakpoint(boolean support) { + + } + + @Override protected void saveData(int state, long location) { + mTaskEntity.setState(state); + mEntity.setState(state); + mEntity.setComplete(state == IEntity.STATE_COMPLETE); + if (state == IEntity.STATE_CANCEL) { + if (mEntity instanceof DownloadGroupEntity) { + CommonUtil.delGroupTaskRecord(mTaskEntity.isRemoveFile(), mEntity); + } + return; + } else if (state == IEntity.STATE_STOP) { + mEntity.setStopTime(System.currentTimeMillis()); + } else if (mEntity.isComplete()) { + mEntity.setCompleteTime(System.currentTimeMillis()); + mEntity.setCurrentProgress(mEntity.getFileSize()); + } + if (location > 0) { + mEntity.setCurrentProgress(location); + } + mTaskEntity.update(); + } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java index 85100747..2380f54f 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java @@ -19,12 +19,15 @@ import android.support.annotation.CheckResult; import android.support.annotation.NonNull; import android.text.TextUtils; import com.arialyy.aria.core.common.RequestEnum; -import com.arialyy.aria.core.delegate.HttpHeaderDelegate; -import com.arialyy.aria.core.inf.IHttpHeaderTarget; +import com.arialyy.aria.core.common.http.HttpHeaderDelegate; +import com.arialyy.aria.core.common.http.PostDelegate; +import com.arialyy.aria.core.inf.IHttpHeaderDelegate; import com.arialyy.aria.core.manager.TEManager; +import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.CommonUtil; import java.io.File; +import java.net.Proxy; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -36,9 +39,8 @@ import java.util.Set; * 下载任务组 */ public class DownloadGroupTarget extends BaseGroupTarget implements - IHttpHeaderTarget { - private HttpHeaderDelegate - mDelegate; + IHttpHeaderDelegate { + private HttpHeaderDelegate mDelegate; /** * 子任务下载地址, */ @@ -67,11 +69,45 @@ public class DownloadGroupTarget extends BaseGroupTarget im mGroupName = CommonUtil.getMd5Code(mUrls); mTaskEntity = TEManager.getInstance().getGTEntity(DownloadGroupTaskEntity.class, mUrls); mEntity = mTaskEntity.getEntity(); - if (mEntity != null) { mDirPathTemp = mEntity.getDirPath(); } - mDelegate = new HttpHeaderDelegate<>(this, mTaskEntity); + mDelegate = new HttpHeaderDelegate<>(this); + } + + /** + * Post处理 + */ + public PostDelegate asPost() { + return new PostDelegate<>(this); + } + + /** + * 更新组合任务下载地址 + * + * @param urls 新的组合任务下载地址列表 + */ + @CheckResult + public DownloadGroupTarget updateUrls(List urls) { + if (urls == null || urls.isEmpty()) { + throw new NullPointerException("下载地址列表为空"); + } + if (urls.size() != mUrls.size()) { + throw new IllegalArgumentException("新下载地址数量和旧下载地址数量不一致"); + } + mUrls.clear(); + mUrls.addAll(urls); + mGroupName = CommonUtil.getMd5Code(urls); + mEntity.setGroupName(mGroupName); + mTaskEntity.setKey(mGroupName); + mEntity.update(); + if (mEntity.getSubEntities() != null && !mEntity.getSubEntities().isEmpty()) { + for (DownloadEntity de : mEntity.getSubEntities()) { + de.setGroupName(mGroupName); + de.update(); + } + } + return this; } /** @@ -150,6 +186,12 @@ public class DownloadGroupTarget extends BaseGroupTarget im return false; } + if (mTaskEntity.getRequestEnum() == RequestEnum.POST) { + for (DownloadTaskEntity subTask : mTaskEntity.getSubTaskEntities()) { + subTask.setRequestEnum(RequestEnum.POST); + } + } + mEntity.save(); mTaskEntity.save(); @@ -234,10 +276,17 @@ public class DownloadGroupTarget extends BaseGroupTarget im if (!newName.equals(entity.getFileName())) { String oldPath = mEntity.getDirPath() + "/" + entity.getFileName(); String newPath = mEntity.getDirPath() + "/" + newName; + if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=? or isComplete='true'", + newPath)) { + ALog.w(TAG, String.format("更新文件名失败,路径【%s】已存在或文件已下载", newPath)); + return; + } + File oldFile = new File(oldPath); if (oldFile.exists()) { oldFile.renameTo(new File(newPath)); } + CommonUtil.modifyTaskRecord(oldFile.getPath(), newPath); entity.setDownloadPath(newPath); taskEntity.setKey(newPath); @@ -263,6 +312,7 @@ public class DownloadGroupTarget extends BaseGroupTarget im return true; } + @CheckResult @Override public DownloadGroupTarget addHeader(@NonNull String key, @NonNull String value) { for (DownloadTaskEntity subTask : mTaskEntity.getSubTaskEntities()) { mDelegate.addHeader(subTask, key, value); @@ -270,6 +320,7 @@ public class DownloadGroupTarget extends BaseGroupTarget im return mDelegate.addHeader(key, value); } + @CheckResult @Override public DownloadGroupTarget addHeaders(Map headers) { for (DownloadTaskEntity subTask : mTaskEntity.getSubTaskEntities()) { mDelegate.addHeaders(subTask, headers); @@ -277,10 +328,8 @@ public class DownloadGroupTarget extends BaseGroupTarget im return mDelegate.addHeaders(headers); } - @Override public DownloadGroupTarget setRequestMode(RequestEnum requestEnum) { - for (DownloadTaskEntity subTask : mTaskEntity.getSubTaskEntities()) { - subTask.setRequestEnum(requestEnum); - } - return mDelegate.setRequestMode(requestEnum); + @CheckResult + @Override public DownloadGroupTarget setUrlProxy(Proxy proxy) { + return mDelegate.setUrlProxy(proxy); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java index 78cd6e7b..855ab3e9 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java @@ -18,23 +18,20 @@ package com.arialyy.aria.core.download; import android.os.Handler; import android.os.Looper; import android.text.TextUtils; -import android.util.Log; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.download.downloader.DownloadGroupUtil; import com.arialyy.aria.core.download.downloader.FtpDirDownloadUtil; +import com.arialyy.aria.core.download.downloader.IDownloadGroupListener; import com.arialyy.aria.core.inf.AbsGroupTask; import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.scheduler.ISchedulers; -import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.CheckUtil; /** * Created by AriaL on 2017/6/27. * 任务组任务 */ -public class DownloadGroupTask extends AbsGroupTask { - private final String TAG = "DownloadGroupTask"; - private DownloadGroupListener mListener; +public class DownloadGroupTask extends AbsGroupTask { private DownloadGroupTask(DownloadGroupTaskEntity taskEntity, Handler outHandler) { mTaskEntity = taskEntity; @@ -43,49 +40,18 @@ public class DownloadGroupTask extends AbsGroupTask { mListener = new DownloadGroupListener(this, mOutHandler); switch (taskEntity.getRequestType()) { case AbsTaskEntity.D_HTTP: - mUtil = new DownloadGroupUtil(mListener, mTaskEntity); + mUtil = new DownloadGroupUtil((IDownloadGroupListener) mListener, mTaskEntity); break; case AbsTaskEntity.D_FTP_DIR: - mUtil = new FtpDirDownloadUtil(mListener, mTaskEntity); + mUtil = new FtpDirDownloadUtil((IDownloadGroupListener) mListener, mTaskEntity); break; } - Log.d(TAG, "FTP_TASK_MD5:" + mTaskEntity.hashCode()); - } - - @Override public boolean isRunning() { - return mUtil.isRunning(); } public DownloadGroupEntity getEntity() { return mTaskEntity.getEntity(); } - @Override public void start() { - if (mUtil.isRunning()) { - ALog.d(TAG, "任务正在下载"); - } else { - mUtil.start(); - } - } - - @Override public void stop() { - super.stop(); - if (!mUtil.isRunning()) { - mListener.onStop(getCurrentProgress()); - } else { - mUtil.stop(); - } - } - - @Override public void cancel() { - super.cancel(); - if (!mUtil.isRunning()) { - mListener.onCancel(); - } else { - mUtil.cancel(); - } - } - @Override public String getTaskName() { return "任务组->" + (TextUtils.isEmpty(mTaskEntity.getEntity().getAlias()) ? mTaskEntity.getEntity().getGroupName() : mTaskEntity.getEntity().getAlias()); @@ -94,11 +60,9 @@ public class DownloadGroupTask extends AbsGroupTask { public static class Builder { DownloadGroupTaskEntity taskEntity; Handler outHandler; - String targetName; - public Builder(String targetName, DownloadGroupTaskEntity taskEntity) { + public Builder(DownloadGroupTaskEntity taskEntity) { CheckUtil.checkTaskEntity(taskEntity); - this.targetName = targetName; this.taskEntity = taskEntity; } @@ -108,19 +72,12 @@ public class DownloadGroupTask extends AbsGroupTask { * @param schedulers {@link ISchedulers} */ public DownloadGroupTask.Builder setOutHandler(ISchedulers schedulers) { - try { - outHandler = new Handler(schedulers); - } catch (Exception e) { - e.printStackTrace(); - outHandler = new Handler(Looper.getMainLooper(), schedulers); - } + outHandler = new Handler(Looper.getMainLooper(), schedulers); return this; } public DownloadGroupTask build() { - DownloadGroupTask task = new DownloadGroupTask(taskEntity, outHandler); - task.setTargetName(targetName); - return task; + return new DownloadGroupTask(taskEntity, outHandler); } } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java index b688ffaf..312f7aff 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java @@ -47,12 +47,12 @@ public class DownloadReceiver extends AbsReceiver { /** * 设置最大下载速度,单位:kb - * 该方法为实验性功能,清不要轻易在生产环境中使用。 * * @param maxSpeed 为0表示不限速 */ - @Deprecated public void setMaxSpeed(int maxSpeed) { + public DownloadReceiver setMaxSpeed(int maxSpeed) { AriaManager.getInstance(AriaManager.APP).getDownloadConfig().setMaxSpeed(maxSpeed); + return this; } /** @@ -160,15 +160,17 @@ public class DownloadReceiver extends AbsReceiver { ALog.e(TAG, String.format("【%s】观察者为空", targetName)); return; } - Set dCounter = ProxyHelper.getInstance().downloadCounter; - Set dgCounter = ProxyHelper.getInstance().downloadGroupCounter; - Set dgsCounter = ProxyHelper.getInstance().downloadGroupSubCounter; - if (dCounter != null && dCounter.contains(targetName)) { - DownloadSchedulers.getInstance().register(obj); - } - if ((dgCounter != null && dgCounter.contains(targetName)) || (dgsCounter != null - && dgsCounter.contains(targetName))) { - DownloadGroupSchedulers.getInstance().register(obj); + Set set = ProxyHelper.getInstance().checkProxyType(obj.getClass()); + if (set != null && !set.isEmpty()) { + for (Integer type : set) { + if (type == ProxyHelper.PROXY_TYPE_DOWNLOAD) { + DownloadSchedulers.getInstance().register(obj); + } else if (type == ProxyHelper.PROXY_TYPE_DOWNLOAD_GROUP) { + DownloadGroupSchedulers.getInstance().register(obj); + } + } + } else { + ALog.w(TAG, "没有Aria的注解方法"); } } @@ -204,15 +206,15 @@ public class DownloadReceiver extends AbsReceiver { ALog.e(TAG, String.format("【%s】观察者为空", targetName)); return; } - Set dCounter = ProxyHelper.getInstance().downloadCounter; - Set dgCounter = ProxyHelper.getInstance().downloadGroupCounter; - Set dgsCounter = ProxyHelper.getInstance().downloadGroupSubCounter; - if (dCounter != null && dCounter.contains(targetName)) { - DownloadSchedulers.getInstance().unRegister(obj); - } - if (dgCounter != null && dgCounter.contains(targetName) || (dgsCounter != null - && dgsCounter.contains(targetName))) { - DownloadGroupSchedulers.getInstance().unRegister(obj); + Set set = ProxyHelper.getInstance().mProxyCache.get(obj.getClass().getName()); + if (set != null) { + for (Integer integer : set) { + if (integer == ProxyHelper.PROXY_TYPE_DOWNLOAD) { + DownloadSchedulers.getInstance().unRegister(obj); + } else if (integer == ProxyHelper.PROXY_TYPE_DOWNLOAD_GROUP) { + DownloadGroupSchedulers.getInstance().unRegister(obj); + } + } } } @@ -286,7 +288,7 @@ public class DownloadReceiver extends AbsReceiver { * @return {@code true}存在,{@code false} 不存在 */ public boolean taskExists(String downloadUrl) { - return DownloadEntity.findFirst(DownloadEntity.class, "url=?", downloadUrl) != null; + return DbEntity.checkDataExist(DownloadTaskEntity.class, "url=?", downloadUrl); } /** @@ -299,8 +301,7 @@ public class DownloadReceiver extends AbsReceiver { return false; } String groupName = CommonUtil.getMd5Code(urls); - return DownloadGroupEntity.findFirst(DownloadGroupEntity.class, "groupName=?", groupName) - != null; + return DbEntity.checkDataExist(DownloadGroupEntity.class, "groupName=?", groupName); } /** @@ -368,7 +369,7 @@ public class DownloadReceiver extends AbsReceiver { public void stopAllTask() { AriaManager.getInstance(AriaManager.APP) .setCmd(NormalCmdFactory.getInstance() - .createCmd(targetName, new DownloadTaskEntity(), NormalCmdFactory.TASK_STOP_ALL, + .createCmd(new DownloadTaskEntity(), NormalCmdFactory.TASK_STOP_ALL, ICmd.TASK_TYPE_DOWNLOAD)) .exe(); } @@ -381,7 +382,7 @@ public class DownloadReceiver extends AbsReceiver { public void resumeAllTask() { AriaManager.getInstance(AriaManager.APP) .setCmd(NormalCmdFactory.getInstance() - .createCmd(targetName, new DownloadTaskEntity(), NormalCmdFactory.TASK_RESUME_ALL, + .createCmd(new DownloadTaskEntity(), NormalCmdFactory.TASK_RESUME_ALL, ICmd.TASK_TYPE_DOWNLOAD)) .exe(); } @@ -395,7 +396,7 @@ public class DownloadReceiver extends AbsReceiver { public void removeAllTask(boolean removeFile) { final AriaManager ariaManager = AriaManager.getInstance(AriaManager.APP); CancelAllCmd cancelCmd = - (CancelAllCmd) CommonUtil.createNormalCmd(targetName, new DownloadTaskEntity(), + (CancelAllCmd) CommonUtil.createNormalCmd(new DownloadTaskEntity(), NormalCmdFactory.TASK_CANCEL_ALL, ICmd.TASK_TYPE_DOWNLOAD); cancelCmd.removeFile = removeFile; ariaManager.setCmd(cancelCmd).exe(); diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java index 5014e30c..14ad617d 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java @@ -18,8 +18,9 @@ package com.arialyy.aria.core.download; import android.support.annotation.CheckResult; import android.support.annotation.NonNull; import com.arialyy.aria.core.common.RequestEnum; -import com.arialyy.aria.core.delegate.HttpHeaderDelegate; -import com.arialyy.aria.core.inf.IHttpHeaderTarget; +import com.arialyy.aria.core.common.http.HttpHeaderDelegate; +import com.arialyy.aria.core.common.http.PostDelegate; +import com.arialyy.aria.core.inf.IHttpHeaderDelegate; import java.net.Proxy; import java.util.Map; @@ -28,9 +29,8 @@ import java.util.Map; * https://github.com/AriaLyy/Aria */ public class DownloadTarget extends BaseNormalTarget - implements IHttpHeaderTarget { - private HttpHeaderDelegate mDelegate; - + implements IHttpHeaderDelegate { + private HttpHeaderDelegate mHeaderDelegate; DownloadTarget(DownloadEntity entity, String targetName) { this(entity.getUrl(), targetName); @@ -38,7 +38,14 @@ public class DownloadTarget extends BaseNormalTarget DownloadTarget(String url, String targetName) { initTarget(url, targetName); - mDelegate = new HttpHeaderDelegate<>(this, mTaskEntity); + mHeaderDelegate = new HttpHeaderDelegate<>(this); + } + + /** + * Post处理 + */ + public PostDelegate asPost() { + return new PostDelegate<>(this); } /** @@ -53,17 +60,6 @@ public class DownloadTarget extends BaseNormalTarget return this; } - /** - * 设置URL的代理 - * - * @param proxy {@link Proxy} - */ - @CheckResult - public DownloadTarget setUrlProxy(Proxy proxy) { - mTaskEntity.setProxy(proxy); - return this; - } - /** * 设置文件存储路径 * 该api后续版本会删除 @@ -89,6 +85,21 @@ public class DownloadTarget extends BaseNormalTarget return this; } + /** + * 设置文件存储路径,如果需要修改新的文件名,修改路径便可。 + * 如:原文件路径 /mnt/sdcard/test.zip + * 如果需要将test.zip改为game.zip,只需要重新设置文件路径为:/mnt/sdcard/game.zip + * + * @param filePath 路径必须为文件路径,不能为文件夹路径 + * @param forceDownload {@code true}强制下载,不考虑未见路径是否被占用 + */ + @CheckResult + public DownloadTarget setFilePath(@NonNull String filePath, boolean forceDownload) { + mTempFilePath = filePath; + this.forceDownload = forceDownload; + return this; + } + /** * 从header中获取文件描述信息 */ @@ -100,18 +111,24 @@ public class DownloadTarget extends BaseNormalTarget return HTTP; } + /** + * 设置URL的代理 + * + * @param proxy {@link Proxy} + */ + @CheckResult + @Override public DownloadTarget setUrlProxy(Proxy proxy) { + return mHeaderDelegate.setUrlProxy(proxy); + } + @CheckResult @Override public DownloadTarget addHeader(@NonNull String key, @NonNull String value) { - return mDelegate.addHeader(key, value); + return mHeaderDelegate.addHeader(key, value); } @CheckResult @Override public DownloadTarget addHeaders(Map headers) { - return mDelegate.addHeaders(headers); + return mHeaderDelegate.addHeaders(headers); } - @CheckResult - @Override public DownloadTarget setRequestMode(RequestEnum requestEnum) { - return mDelegate.setRequestMode(requestEnum); - } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java index 56181f2f..83a3f5e2 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java @@ -19,9 +19,9 @@ package com.arialyy.aria.core.download; import android.os.Handler; import android.os.Looper; import com.arialyy.aria.core.AriaManager; -import com.arialyy.aria.core.common.IUtil; import com.arialyy.aria.core.download.downloader.SimpleDownloadUtil; import com.arialyy.aria.core.inf.AbsNormalTask; +import com.arialyy.aria.core.inf.IDownloadListener; import com.arialyy.aria.core.scheduler.ISchedulers; import com.arialyy.aria.util.ALog; import java.io.File; @@ -30,19 +30,15 @@ import java.io.File; * Created by lyy on 2016/8/11. * 下载任务类 */ -public class DownloadTask extends AbsNormalTask { +public class DownloadTask extends AbsNormalTask { public static final String TAG = "DownloadTask"; - private DownloadListener mListener; - private DownloadEntity mEntity; - private IUtil mUtil; - private DownloadTask(DownloadTaskEntity taskEntity, Handler outHandler) { mTaskEntity = taskEntity; mOutHandler = outHandler; mContext = AriaManager.APP; - mListener = new DownloadListener(this, mOutHandler); - mUtil = new SimpleDownloadUtil(taskEntity, mListener); + mListener = new BaseDListener(this, mOutHandler); + mUtil = new SimpleDownloadUtil(taskEntity, (IDownloadListener) mListener); mEntity = taskEntity.getEntity(); } @@ -76,76 +72,10 @@ public class DownloadTask extends AbsNormalTask { return mEntity.getUrl(); } - /** - * 是否真正下载 - * - * @return {@code true} 真正下载 - */ - @Override public boolean isRunning() { - return mUtil.isRunning(); - } - public DownloadEntity getDownloadEntity() { return mEntity; } - /** - * 暂停任务,并让任务处于等待状态 - */ - @Override public void stopAndWait() { - stop(true); - } - - /** - * 设置最大下载速度,单位:kb - * - * @param maxSpeed 为0表示不限速 - */ - public void setMaxSpeed(double maxSpeed) { - mUtil.setMaxSpeed(maxSpeed); - } - - /** - * 开始下载 - */ - @Override public void start() { - mListener.isWait = false; - if (mUtil.isRunning()) { - ALog.d(TAG, "任务正在下载"); - } else { - mUtil.start(); - } - } - - /** - * 停止下载 - */ - @Override public void stop() { - super.stop(); - stop(false); - } - - private void stop(boolean isWait) { - mListener.isWait = isWait; - if (mUtil.isRunning()) { - mUtil.stop(); - } else { - mListener.onStop(mEntity.getCurrentProgress()); - } - } - - /** - * 取消下载 - */ - @Override public void cancel() { - super.cancel(); - if (mUtil.isRunning()) { - mUtil.cancel(); - } else { - mListener.onCancel(); - } - } - @Override public String getTaskName() { return mEntity.getFileName(); } @@ -153,10 +83,8 @@ public class DownloadTask extends AbsNormalTask { public static class Builder { DownloadTaskEntity taskEntity; Handler outHandler; - String targetName; - public Builder(String targetName, DownloadTaskEntity taskEntity) { - this.targetName = targetName; + public Builder(DownloadTaskEntity taskEntity) { this.taskEntity = taskEntity; } @@ -166,19 +94,12 @@ public class DownloadTask extends AbsNormalTask { * @param schedulers {@link ISchedulers} */ public Builder setOutHandler(ISchedulers schedulers) { - try { - outHandler = new Handler(schedulers); - } catch (Exception e) { - ALog.w(TAG, ALog.getExceptionString(e)); - outHandler = new Handler(Looper.getMainLooper(), schedulers); - } + outHandler = new Handler(Looper.getMainLooper(), schedulers); return this; } public DownloadTask build() { - DownloadTask task = new DownloadTask(taskEntity, outHandler); - task.setTargetName(targetName); - return task; + return new DownloadTask(taskEntity, outHandler); } } } \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java index 0d046d50..f23f5f30 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java @@ -21,6 +21,7 @@ import com.arialyy.aria.orm.annotation.Foreign; import com.arialyy.aria.orm.annotation.Ignore; import com.arialyy.aria.orm.annotation.NoNull; import com.arialyy.aria.orm.annotation.Primary; +import java.util.Map; /** * Created by lyy on 2017/1/23. @@ -60,8 +61,6 @@ public class DownloadTaskEntity extends AbsNormalTaskEntity { onUpdate = ActionPolicy.CASCADE, onDelete = ActionPolicy.CASCADE) private String key; - - public DownloadTaskEntity() { } @@ -112,6 +111,4 @@ public class DownloadTaskEntity extends AbsNormalTaskEntity { public void setGroupTask(boolean groupTask) { isGroupTask = groupTask; } - - } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java index a5978483..4d0f2a5c 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java @@ -17,11 +17,14 @@ package com.arialyy.aria.core.download; import android.support.annotation.CheckResult; import android.text.TextUtils; -import com.arialyy.aria.core.delegate.FtpDelegate; +import com.arialyy.aria.core.FtpUrlEntity; +import com.arialyy.aria.core.common.ftp.FTPSConfig; +import com.arialyy.aria.core.common.ftp.FtpDelegate; import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.IFtpTarget; import com.arialyy.aria.core.manager.TEManager; import com.arialyy.aria.util.ALog; +import java.net.Proxy; /** * Created by Aria.Lao on 2017/7/26. @@ -29,7 +32,7 @@ import com.arialyy.aria.util.ALog; */ public class FtpDirDownloadTarget extends BaseGroupTarget implements IFtpTarget { - private FtpDelegate mDelegate; + private FtpDelegate mDelegate; FtpDirDownloadTarget(String url, String targetName) { mTargetName = targetName; @@ -44,7 +47,7 @@ public class FtpDirDownloadTarget extends BaseGroupTarget if (mEntity != null) { mDirPathTemp = mEntity.getDirPath(); } - mDelegate = new FtpDelegate<>(this, mTaskEntity); + mDelegate = new FtpDelegate<>(this); } @Override protected int getTargetType() { @@ -58,14 +61,34 @@ public class FtpDirDownloadTarget extends BaseGroupTarget mTaskEntity.save(); if (mTaskEntity.getSubTaskEntities() != null) { //初始化子项的登录信息 + FtpUrlEntity tUrlEntity = mTaskEntity.getUrlEntity(); for (DownloadTaskEntity entity : mTaskEntity.getSubTaskEntities()) { - entity.getUrlEntity().needLogin = mTaskEntity.getUrlEntity().needLogin; - entity.getUrlEntity().account = mTaskEntity.getUrlEntity().account; - entity.getUrlEntity().user = mTaskEntity.getUrlEntity().user; - entity.getUrlEntity().password = mTaskEntity.getUrlEntity().password; + FtpUrlEntity urlEntity = entity.getUrlEntity(); + urlEntity.needLogin = tUrlEntity.needLogin; + urlEntity.account = tUrlEntity.account; + urlEntity.user = tUrlEntity.user; + urlEntity.password = tUrlEntity.password; + // 处理ftps详细 + if (tUrlEntity.isFtps) { + urlEntity.isFtps = true; + urlEntity.protocol = tUrlEntity.protocol; + urlEntity.storePath = tUrlEntity.storePath; + urlEntity.storePass = tUrlEntity.storePass; + urlEntity.keyAlias = tUrlEntity.keyAlias; + } } } } + if (mTaskEntity.getUrlEntity().isFtps) { + if (TextUtils.isEmpty(mTaskEntity.getUrlEntity().storePath)) { + ALog.e(TAG, "证书路径为空"); + return false; + } + if (TextUtils.isEmpty(mTaskEntity.getUrlEntity().keyAlias)) { + ALog.e(TAG, "证书别名为空"); + return false; + } + } return b; } @@ -90,16 +113,34 @@ public class FtpDirDownloadTarget extends BaseGroupTarget } return true; } + + /** + * 是否是FTPS协议 + * 如果是FTPS协议,需要使用{@link FTPSConfig#setStorePath(String)} 、{@link FTPSConfig#setAlias(String)} + * 设置证书信息 + */ + @CheckResult + public FTPSConfig asFtps() { + mTaskEntity.getUrlEntity().isFtps = true; + return new FTPSConfig<>(this); + } + @CheckResult @Override public FtpDirDownloadTarget charSet(String charSet) { return mDelegate.charSet(charSet); } + @CheckResult @Override public FtpDirDownloadTarget login(String userName, String password) { return mDelegate.login(userName, password); } + @CheckResult @Override public FtpDirDownloadTarget login(String userName, String password, String account) { return mDelegate.login(userName, password, account); } + + @Override public FtpDirDownloadTarget setProxy(Proxy proxy) { + return mDelegate.setProxy(proxy); + } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/FtpDownloadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/FtpDownloadTarget.java index 6d73b43c..1c19c66c 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/FtpDownloadTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/FtpDownloadTarget.java @@ -17,10 +17,14 @@ package com.arialyy.aria.core.download; import android.support.annotation.CheckResult; import android.support.annotation.NonNull; -import com.arialyy.aria.core.delegate.FtpDelegate; +import android.text.TextUtils; +import com.arialyy.aria.core.common.ftp.FTPSConfig; +import com.arialyy.aria.core.common.ftp.FtpDelegate; import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.IFtpTarget; +import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.CommonUtil; +import java.net.Proxy; /** * Created by lyy on 2016/12/5. @@ -28,7 +32,7 @@ import com.arialyy.aria.util.CommonUtil; */ public class FtpDownloadTarget extends BaseNormalTarget implements IFtpTarget { - private FtpDelegate mDelegate; + private FtpDelegate mDelegate; public FtpDownloadTarget(DownloadEntity entity, String targetName) { this(entity.getUrl(), targetName); @@ -45,7 +49,32 @@ public class FtpDownloadTarget extends BaseNormalTarget mTaskEntity.setUrlEntity(CommonUtil.getFtpUrlInfo(url)); mTaskEntity.setRequestType(AbsTaskEntity.D_FTP); - mDelegate = new FtpDelegate<>(this, mTaskEntity); + mDelegate = new FtpDelegate<>(this); + } + + /** + * 是否是FTPS协议 + * 如果是FTPS协议,需要使用{@link FTPSConfig#setStorePath(String)} 、{@link FTPSConfig#setAlias(String)} + * 设置证书信息 + */ + @CheckResult + public FTPSConfig asFtps() { + mTaskEntity.getUrlEntity().isFtps = true; + return new FTPSConfig<>(this); + } + + @Override protected boolean checkEntity() { + if (mTaskEntity.getUrlEntity().isFtps){ + if (TextUtils.isEmpty(mTaskEntity.getUrlEntity().storePath)){ + ALog.e(TAG, "证书路径为空"); + return false; + } + if (TextUtils.isEmpty(mTaskEntity.getUrlEntity().keyAlias)){ + ALog.e(TAG, "证书别名为空"); + return false; + } + } + return super.checkEntity(); } /** @@ -90,4 +119,9 @@ public class FtpDownloadTarget extends BaseNormalTarget @Override public FtpDownloadTarget login(String userName, String password, String account) { return mDelegate.login(userName, password, account); } + + @CheckResult + @Override public FtpDownloadTarget setProxy(Proxy proxy) { + return mDelegate.setProxy(proxy); + } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/AbsGroupUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/AbsGroupUtil.java index 19b60b47..45e50fb5 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/AbsGroupUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/AbsGroupUtil.java @@ -22,23 +22,23 @@ import com.arialyy.aria.core.download.DownloadGroupTaskEntity; import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.inf.IDownloadListener; import com.arialyy.aria.core.inf.IEntity; +import com.arialyy.aria.exception.BaseException; +import com.arialyy.aria.exception.TaskException; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.NetUtils; import java.io.File; -import java.util.HashMap; import java.util.Map; import java.util.Set; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; /** * Created by AriaL on 2017/6/30. * 任务组核心逻辑 */ -public abstract class AbsGroupUtil implements IUtil { +public abstract class AbsGroupUtil implements IUtil, Runnable { private static final Object LOCK = new Object(); private final String TAG = "AbsGroupUtil"; /** @@ -55,30 +55,29 @@ public abstract class AbsGroupUtil implements IUtil { */ long mTotalLen = 0; long mCurrentLocation = 0; - private ExecutorService mExePool; protected IDownloadGroupListener mListener; DownloadGroupTaskEntity mGTEntity; private boolean isRunning = false; - private Timer mTimer; + private ScheduledThreadPoolExecutor mTimer; /** * 保存所有没有下载完成的任务,key为下载地址 */ - Map mExeMap = new HashMap<>(); + Map mExeMap = new ConcurrentHashMap<>(); /** * 下载失败的映射表,key为下载地址 */ - Map mFailMap = new HashMap<>(); + Map mFailMap = new ConcurrentHashMap<>(); /** * 该任务组对应的所有任务 */ - private Map mTasksMap = new HashMap<>(); + private Map mTasksMap = new ConcurrentHashMap<>(); /** * 下载器映射表,key为下载地址 */ - private Map mDownloaderMap = new HashMap<>(); + private Map mDownloaderMap = new ConcurrentHashMap<>(); /** * 是否需要读取文件长度,{@code true}需要 @@ -96,7 +95,6 @@ public abstract class AbsGroupUtil implements IUtil { AbsGroupUtil(IDownloadGroupListener listener, DownloadGroupTaskEntity groupEntity) { mListener = listener; mGTEntity = groupEntity; - mExePool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); mUpdateInterval = AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getUpdateInterval(); } @@ -227,10 +225,6 @@ public abstract class AbsGroupUtil implements IUtil { isCancel = true; closeTimer(); onCancel(); - if (!mExePool.isShutdown()) { - mExePool.shutdown(); - } - Set keys = mDownloaderMap.keySet(); for (String key : keys) { Downloader dt = mDownloaderMap.get(key); @@ -250,9 +244,6 @@ public abstract class AbsGroupUtil implements IUtil { isStop = true; closeTimer(); onStop(); - if (!mExePool.isShutdown()) { - mExePool.shutdown(); - } Set keys = mDownloaderMap.keySet(); for (String key : keys) { @@ -275,6 +266,7 @@ public abstract class AbsGroupUtil implements IUtil { */ protected void onPre() { mListener.onPre(); + isRunning = true; mGroupSize = mGTEntity.getSubTaskEntities().size(); mTotalLen = mGTEntity.getEntity().getFileSize(); isNeedLoadFileSize = mTotalLen <= 10; @@ -295,6 +287,10 @@ public abstract class AbsGroupUtil implements IUtil { } @Override public void start() { + new Thread(this).start(); + } + + @Override public void run() { if (isStop || isCancel) { closeTimer(); return; @@ -311,8 +307,14 @@ public abstract class AbsGroupUtil implements IUtil { start(); } - @Override public void setMaxSpeed(double maxSpeed) { - + @Override public void setMaxSpeed(int speed) { + Set keys = mDownloaderMap.keySet(); + for (String key : keys) { + Downloader dt = mDownloaderMap.get(key); + if (dt != null) { + dt.setMaxSpeed(speed); + } + } } private void clearState() { @@ -320,12 +322,9 @@ public abstract class AbsGroupUtil implements IUtil { mFailMap.clear(); } - void closeTimer() { - isRunning = false; - if (mTimer != null) { - mTimer.purge(); - mTimer.cancel(); - mTimer = null; + synchronized void closeTimer() { + if (mTimer != null && !mTimer.isShutdown()) { + mTimer.shutdown(); } } @@ -343,10 +342,10 @@ public abstract class AbsGroupUtil implements IUtil { startTimer(); } - private void startTimer() { + private synchronized void startTimer() { isRunning = true; - mTimer = new Timer(true); - mTimer.schedule(new TimerTask() { + mTimer = new ScheduledThreadPoolExecutor(1); + mTimer.scheduleWithFixedDelay(new Runnable() { @Override public void run() { if (!isRunning) { closeTimer(); @@ -363,7 +362,7 @@ public abstract class AbsGroupUtil implements IUtil { mListener.onProgress(t); } } - }, 0, mUpdateInterval); + }, 0, mUpdateInterval, TimeUnit.MILLISECONDS); } /** @@ -382,9 +381,8 @@ public abstract class AbsGroupUtil implements IUtil { ChildDownloadListener listener = new ChildDownloadListener(taskEntity); Downloader dt = new Downloader(listener, taskEntity); mDownloaderMap.put(taskEntity.getEntity().getUrl(), dt); - if (mExePool.isShutdown()) return dt; if (start) { - mExePool.execute(dt); + dt.start(); } return dt; } @@ -397,9 +395,9 @@ public abstract class AbsGroupUtil implements IUtil { private DownloadEntity subEntity; private int RUN_SAVE_INTERVAL = 5 * 1000; //5s保存一次下载中的进度 private long lastSaveTime; - private long lastLen = 0; - private Timer timer; - private boolean isNotNetRetry = false; + private long lastLen; + private ScheduledThreadPoolExecutor timer; + private boolean isNotNetRetry; ChildDownloadListener(DownloadTaskEntity entity) { subTaskEntity = entity; @@ -486,7 +484,7 @@ public abstract class AbsGroupUtil implements IUtil { } } - @Override public void onFail(boolean needRetry) { + @Override public void onFail(boolean needRetry, BaseException e) { subEntity.setFailNum(subEntity.getFailNum() + 1); saveData(IEntity.STATE_FAIL, lastLen); handleSpeed(0); @@ -497,22 +495,26 @@ public abstract class AbsGroupUtil implements IUtil { * 重试下载,只有全部都下载失败才会执行任务组的整体重试,否则只会执行单个子任务的重试 */ private void reTry(boolean needRetry) { - Downloader dt = mDownloaderMap.get(subEntity.getUrl()); synchronized (AbsGroupUtil.LOCK) { + Downloader dt = mDownloaderMap.get(subEntity.getUrl()); if (!isCancel && !isStop && dt != null && !dt.isBreak() && needRetry && subEntity.getFailNum() < 3 && (NetUtils.isConnected(AriaManager.APP) || isNotNetRetry)) { + ALog.d(TAG, "downloader retry"); reStartTask(dt); } else { mFailMap.put(subTaskEntity.getUrl(), subTaskEntity); - mListener.onSubFail(subEntity); + mListener.onSubFail(subEntity, new TaskException(TAG, + String.format("任务组子任务【%s】下载失败,下载地址【%s】", subEntity.getFileName(), + subEntity.getUrl()))); if (mFailMap.size() == mExeMap.size() || mFailMap.size() + mCompleteNum == mGroupSize) { closeTimer(); } if (mFailMap.size() == mGroupSize) { - mListener.onFail(true); + mListener.onFail(true, new TaskException(TAG, + String.format("任务组【%s】下载失败", mGTEntity.getEntity().getGroupName()))); } else if (mFailMap.size() + mCompleteNum >= mExeMap.size()) { mListener.onStop(mCurrentLocation); } @@ -521,18 +523,16 @@ public abstract class AbsGroupUtil implements IUtil { } private void reStartTask(final Downloader dt) { - if (timer != null) { - timer.purge(); - timer.cancel(); + if (timer == null || timer.isShutdown()) { + timer = new ScheduledThreadPoolExecutor(1); } - timer = new Timer(); - timer.schedule(new TimerTask() { + timer.schedule(new Runnable() { @Override public void run() { if (dt != null) { - dt.retryThreadTask(); + dt.retryTask(); } } - }, 5000); + }, 5, TimeUnit.SECONDS); } private void handleSpeed(long speed) { diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/ConnectionHelp.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/ConnectionHelp.java index 01277969..59d26807 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/ConnectionHelp.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/ConnectionHelp.java @@ -16,18 +16,21 @@ package com.arialyy.aria.core.download.downloader; import android.text.TextUtils; +import com.arialyy.aria.core.AriaManager; +import com.arialyy.aria.core.common.ProtocolType; import com.arialyy.aria.core.common.RequestEnum; import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.util.SSLContextUtil; import java.io.IOException; import java.io.InputStream; +import java.net.CookieManager; +import java.net.CookieStore; +import java.net.HttpCookie; import java.net.HttpURLConnection; import java.net.ProtocolException; import java.net.URL; import java.net.URLConnection; -import java.util.List; -import java.util.Map; import java.util.Set; import java.util.zip.GZIPInputStream; import java.util.zip.InflaterInputStream; @@ -75,11 +78,13 @@ class ConnectionHelp { urlConn = url.openConnection(); } if (urlConn instanceof HttpsURLConnection) { + AriaManager manager = AriaManager.getInstance(AriaManager.APP); conn = (HttpsURLConnection) urlConn; SSLContext sslContext = - SSLContextUtil.getSSLContext(SSLContextUtil.CA_ALIAS, SSLContextUtil.CA_PATH); + SSLContextUtil.getSSLContextFromAssets(manager.getDownloadConfig().getCaName(), + manager.getDownloadConfig().getCaPath(), ProtocolType.Default); if (sslContext == null) { - sslContext = SSLContextUtil.getDefaultSLLContext(); + sslContext = SSLContextUtil.getDefaultSLLContext(ProtocolType.Default); } SSLSocketFactory ssf = sslContext.getSocketFactory(); ((HttpsURLConnection) conn).setSSLSocketFactory(ssf); @@ -98,6 +103,8 @@ class ConnectionHelp { static HttpURLConnection setConnectParam(DownloadTaskEntity entity, HttpURLConnection conn) { if (entity.getRequestEnum() == RequestEnum.POST) { conn.setDoInput(true); + conn.setDoOutput(true); + conn.setUseCaches(false); } Set keys = null; if (entity.getHeaders() != null && entity.getHeaders().size() > 0) { @@ -106,7 +113,9 @@ class ConnectionHelp { conn.setRequestProperty(key, entity.getHeaders().get(key)); } } - + if (conn.getRequestProperty("Accept-Language") == null) { + conn.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7"); + } if (conn.getRequestProperty("Accept-Encoding") == null) { conn.setRequestProperty("Accept-Encoding", "identity"); } @@ -124,30 +133,40 @@ class ConnectionHelp { "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"); } if (conn.getRequestProperty("Accept") == null) { - StringBuilder accept = new StringBuilder(); + //StringBuilder accept = new StringBuilder(); //accept - //.append("image/gif, ") - //.append("image/jpeg, ") - //.append("image/pjpeg, ") - //.append("image/webp, ") - //.append("image/apng, ") - //.append("application/xml, ") - //.append("application/xaml+xml, ") - //.append("application/xhtml+xml, ") - //.append("application/x-shockwave-flash, ") - //.append("application/x-ms-xbap, ") - //.append("application/x-ms-application, ") - //.append("application/msword, ") - //.append("application/vnd.ms-excel, ") - //.append("application/vnd.ms-xpsdocument, ") - //.append("application/vnd.ms-powerpoint, ") - //.append("text/plain, ") - //.append("text/html, ") - //.append("*/*"); + //.append("image/gif, ") + //.append("image/jpeg, ") + //.append("image/pjpeg, ") + //.append("image/webp, ") + //.append("image/apng, ") + //.append("application/xml, ") + //.append("application/xaml+xml, ") + //.append("application/xhtml+xml, ") + //.append("application/x-shockwave-flash, ") + //.append("application/x-ms-xbap, ") + //.append("application/x-ms-application, ") + //.append("application/msword, ") + //.append("application/vnd.ms-excel, ") + //.append("application/vnd.ms-xpsdocument, ") + //.append("application/vnd.ms-powerpoint, ") + //.append("text/plain, ") + //.append("text/html, ") + //.append("*/*"); conn.setRequestProperty("Accept", "*/*"); } //302获取重定向地址 conn.setInstanceFollowRedirects(false); + + CookieManager manager = entity.getCookieManager(); + if (manager != null) { + CookieStore store = manager.getCookieStore(); + if (store != null && store.getCookies().size() > 0) { + conn.setRequestProperty("Cookie", + TextUtils.join(";", store.getCookies())); + } + } + return conn; } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadGroupUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadGroupUtil.java index f01a6436..fd9a8ccc 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadGroupUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadGroupUtil.java @@ -22,6 +22,8 @@ import com.arialyy.aria.core.common.OnFileInfoCallback; import com.arialyy.aria.core.download.DownloadGroupTaskEntity; import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.inf.IEntity; +import com.arialyy.aria.exception.BaseException; +import com.arialyy.aria.exception.TaskException; import com.arialyy.aria.util.ALog; import java.util.Set; import java.util.concurrent.ExecutorService; @@ -85,8 +87,8 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil { } if (mExeMap.size() == 0) { - ALog.e(TAG, "任务组无可执行任务"); - mListener.onFail(false); + mListener.onFail(false, new TaskException(TAG, + String.format("任务组【%s】无可执行任务", mGTEntity.getEntity().getGroupName()))); return; } Set keys = mExeMap.keySet(); @@ -133,7 +135,7 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil { checkStartFlow(); } - @Override public void onFail(String url, String errorMsg, boolean needRetry) { + @Override public void onFail(String url, BaseException e, boolean needRetry) { if (isStop) return; ALog.e(TAG, String.format("任务【%s】初始化失败", url)); DownloadTaskEntity te = mExeMap.get(url); @@ -163,9 +165,14 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil { */ private void checkStartFlow() { synchronized (DownloadGroupUtil.class) { + if (isStop) { + closeTimer(); + return; + } if (mInitFailNum == mExeNum) { closeTimer(); - mListener.onFail(true); + mListener.onFail(true, new TaskException(TAG, + String.format("任务组【%s】初始化失败", mGTEntity.getEntity().getGroupName()))); } if (!isStart && mInitCompleteNum + mInitFailNum == mExeNum || !isNeedLoadFileSize) { startRunningFlow(); diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java index 2335093d..4590213b 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java @@ -23,10 +23,9 @@ import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.IDownloadListener; -import com.arialyy.aria.util.ALog; +import com.arialyy.aria.exception.BaseException; +import com.arialyy.aria.exception.TaskException; import com.arialyy.aria.util.BufferedRandomAccessFile; -import com.arialyy.aria.util.CommonUtil; -import com.arialyy.aria.util.ErrorHelp; import java.io.File; import java.io.IOException; @@ -58,7 +57,10 @@ class Downloader extends AbsFileer { @Override protected boolean handleNewTask() { if (!mRecord.isBlock) { - CommonUtil.createFile(mTempFile.getPath()); + if (mTempFile.exists()) { + mTempFile.delete(); + } + //CommonUtil.createFile(mTempFile.getPath()); } BufferedRandomAccessFile file = null; try { @@ -69,8 +71,9 @@ class Downloader extends AbsFileer { } return true; } catch (IOException e) { - failDownload(String.format("下载失败【downloadUrl:%s】;【filePath:%s】\n %S", mEntity.getUrl(), - mEntity.getDownloadPath(), ALog.getExceptionString(e))); + failDownload(new TaskException(TAG, + String.format("下载失败,filePath: %s, url: %s", mEntity.getDownloadPath(), + mEntity.getUrl()), e)); } finally { if (file != null) { try { @@ -83,6 +86,15 @@ class Downloader extends AbsFileer { return false; } + @Override protected void onPostPre() { + super.onPostPre(); + ((IDownloadListener) mListener).onPostPre(mEntity.getFileSize()); + File file = new File(mEntity.getDownloadPath()); + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + } + @Override protected AbsThreadTask selectThreadTask(SubThreadConfig config) { switch (mTaskEntity.getRequestType()) { case AbsTaskEntity.D_FTP: @@ -94,11 +106,9 @@ class Downloader extends AbsFileer { return null; } - private void failDownload(String errorMsg) { + private void failDownload(BaseException e) { closeTimer(); - ALog.e(TAG, errorMsg); mConstance.isRunning = false; - mListener.onFail(false); - ErrorHelp.saveError(TAG, "", errorMsg); + mListener.onFail(false, e); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirDownloadUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirDownloadUtil.java index 00ec7df8..1cd0715c 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirDownloadUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirDownloadUtil.java @@ -19,6 +19,8 @@ import com.arialyy.aria.core.common.CompleteInfo; import com.arialyy.aria.core.common.OnFileInfoCallback; import com.arialyy.aria.core.download.DownloadGroupTaskEntity; import com.arialyy.aria.core.download.DownloadTaskEntity; +import com.arialyy.aria.exception.BaseException; +import com.arialyy.aria.exception.TaskException; import com.arialyy.aria.util.ErrorHelp; import java.util.Set; @@ -51,14 +53,13 @@ public class FtpDirDownloadUtil extends AbsGroupUtil { } } - @Override public void onFail(String url, String errorMsg, boolean needRetry) { + @Override public void onFail(String url, BaseException e, boolean needRetry) { DownloadTaskEntity te = mExeMap.get(url); if (te != null) { mFailMap.put(url, te); mExeMap.remove(url); } - mListener.onFail(needRetry); - ErrorHelp.saveError(TAG, "", errorMsg); + mListener.onFail(needRetry, e); } }).start(); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirInfoThread.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirInfoThread.java index 7c6ab6eb..7cdddfef 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirInfoThread.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirInfoThread.java @@ -15,10 +15,11 @@ */ package com.arialyy.aria.core.download.downloader; +import aria.apache.commons.net.ftp.FTPFile; import com.arialyy.aria.core.FtpUrlEntity; -import com.arialyy.aria.core.common.AbsFtpInfoThread; import com.arialyy.aria.core.common.CompleteInfo; import com.arialyy.aria.core.common.OnFileInfoCallback; +import com.arialyy.aria.core.common.ftp.AbsFtpInfoThread; import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadGroupEntity; import com.arialyy.aria.core.download.DownloadGroupTaskEntity; @@ -27,7 +28,6 @@ import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.util.CommonUtil; import java.nio.charset.Charset; import java.util.ArrayList; -import org.apache.commons.net.ftp.FTPFile; /** * Created by Aria.Lao on 2017/7/25. @@ -61,7 +61,7 @@ class FtpDirInfoThread extends AbsFtpInfoThread { + private final String TAG = "FtpFileInfoThread"; FtpFileInfoThread(DownloadTaskEntity taskEntity, OnFileInfoCallback callback) { super(taskEntity, callback); } + @Override protected void handleFile(String remotePath, FTPFile ftpFile) { + super.handleFile(remotePath, ftpFile); + if (!CommonUtil.checkSDMemorySpace(mEntity.getDownloadPath(), ftpFile.getSize())) { + mCallback.onFail(mEntity.getUrl(), + new AriaIOException(TAG, + String.format("获取ftp文件信息失败,内存空间不足, filePath: %s", mEntity.getDownloadPath())), + false); + } + } + @Override protected String setRemotePath() { return mTaskEntity.getUrlEntity().remotePath; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java index 4d2390e8..8a49a8cf 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java @@ -15,13 +15,16 @@ */ package com.arialyy.aria.core.download.downloader; -import com.arialyy.aria.core.AriaManager; -import com.arialyy.aria.core.common.AbsFtpThreadTask; +import aria.apache.commons.net.ftp.FTPClient; +import aria.apache.commons.net.ftp.FTPReply; import com.arialyy.aria.core.common.StateConstance; import com.arialyy.aria.core.common.SubThreadConfig; +import com.arialyy.aria.core.common.ftp.AbsFtpThreadTask; import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.inf.IDownloadListener; +import com.arialyy.aria.exception.AriaIOException; +import com.arialyy.aria.exception.TaskException; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.BufferedRandomAccessFile; import java.io.FileOutputStream; @@ -31,8 +34,6 @@ import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; -import org.apache.commons.net.ftp.FTPClient; -import org.apache.commons.net.ftp.FTPReply; /** * Created by Aria.Lao on 2017/7/24. @@ -46,20 +47,19 @@ class FtpThreadTask extends AbsFtpThreadTask FtpThreadTask(StateConstance constance, IDownloadListener listener, SubThreadConfig downloadInfo) { super(constance, listener, downloadInfo); - AriaManager manager = AriaManager.getInstance(AriaManager.APP); - mConnectTimeOut = manager.getDownloadConfig().getConnectTimeOut(); - mReadTimeOut = manager.getDownloadConfig().getIOTimeOut(); - mBufSize = manager.getDownloadConfig().getBuffSize(); - isNotNetRetry = manager.getDownloadConfig().isNotNetRetry(); + mConnectTimeOut = mAridManager.getDownloadConfig().getConnectTimeOut(); + mReadTimeOut = mAridManager.getDownloadConfig().getIOTimeOut(); + mBufSize = mAridManager.getDownloadConfig().getBuffSize(); + isNotNetRetry = mAridManager.getDownloadConfig().isNotNetRetry(); isOpenDynamicFile = STATE.TASK_RECORD.isOpenDynamicFile; isBlock = STATE.TASK_RECORD.isBlock; - setMaxSpeed(manager.getDownloadConfig().getMaxSpeed()); } - @Override public void run() { + @Override public FtpThreadTask call() throws Exception { + super.call(); if (mConfig.THREAD_RECORD.isComplete) { handleComplete(); - return; + return this; } mChildCurrentLocation = mConfig.START_LOCATION; FTPClient client = null; @@ -70,7 +70,10 @@ class FtpThreadTask extends AbsFtpThreadTask String.format("任务【%s】线程__%s__开始下载【开始位置 : %s,结束位置:%s】", mConfig.TEMP_FILE.getName(), mConfig.THREAD_ID, mConfig.START_LOCATION, mConfig.END_LOCATION)); client = createClient(); - if (client == null) return; + if (client == null) { + fail(mChildCurrentLocation, new TaskException(TAG, "ftp client 创建失败")); + return this; + } if (mConfig.START_LOCATION > 0) { client.setRestartOffset(mConfig.START_LOCATION); } @@ -78,10 +81,10 @@ class FtpThreadTask extends AbsFtpThreadTask int reply = client.getReplyCode(); if (!FTPReply.isPositivePreliminary(reply) && reply != FTPReply.COMMAND_OK) { fail(mChildCurrentLocation, - String.format("获取文件信息错误,错误码为:%s,msg:%s", reply, client.getReplyString()), - null); + new AriaIOException(TAG, + String.format("获取文件信息错误,错误码为:%s,msg:%s", reply, client.getReplyString()))); client.disconnect(); - return; + return this; } String remotePath = new String(mTaskEntity.getUrlEntity().remotePath.getBytes(charSet), SERVER_CHARSET); @@ -90,10 +93,10 @@ class FtpThreadTask extends AbsFtpThreadTask reply = client.getReplyCode(); if (!FTPReply.isPositivePreliminary(reply)) { fail(mChildCurrentLocation, - String.format("获取流失败,错误码为:%s,msg:%s", reply, client.getReplyString()), - null); + new AriaIOException(TAG, + String.format("获取流失败,错误码为:%s,msg:%s", reply, client.getReplyString()))); client.disconnect(); - return; + return this; } if (isOpenDynamicFile) { @@ -103,9 +106,11 @@ class FtpThreadTask extends AbsFtpThreadTask handleComplete(); } } catch (IOException e) { - fail(mChildCurrentLocation, String.format("下载失败【%s】", mConfig.URL), e); + fail(mChildCurrentLocation, + new AriaIOException(TAG, String.format("下载失败【%s】", mConfig.URL), e)); } catch (Exception e) { - fail(mChildCurrentLocation, "获取流失败", e); + fail(mChildCurrentLocation, + new AriaIOException(TAG, String.format("下载失败【%s】", mConfig.URL), e)); } finally { try { if (is != null) { @@ -118,6 +123,7 @@ class FtpThreadTask extends AbsFtpThreadTask e.printStackTrace(); } } + return this; } /** @@ -135,9 +141,10 @@ class FtpThreadTask extends AbsFtpThreadTask if (isBlock) { boolean success = mergeFile(); if (!success) { - ALog.e(TAG, String.format("任务【%s】分块文件合并失败", mConfig.TEMP_FILE.getName())); + //ALog.e(TAG, String.format("任务【%s】分块文件合并失败", mConfig.TEMP_FILE.getName())); STATE.isRunning = false; - mListener.onFail(false); + mListener.onFail(false, + new TaskException(TAG, String.format("任务【%s】分块文件合并失败", mConfig.TEMP_FILE.getName()))); return; } } @@ -147,7 +154,8 @@ class FtpThreadTask extends AbsFtpThreadTask } if (STATE.isFail()) { STATE.isRunning = false; - mListener.onFail(false); + mListener.onFail(false, + new TaskException(TAG, String.format("任务【%s】下载失败", mConfig.TEMP_FILE.getName()))); } } @@ -164,12 +172,12 @@ class FtpThreadTask extends AbsFtpThreadTask foc = fos.getChannel(); fic = Channels.newChannel(is); ByteBuffer bf = ByteBuffer.allocate(mBufSize); - while ((len = fic.read(bf)) != -1) { + while (isLive() && (len = fic.read(bf)) != -1) { if (isBreak()) { break; } - if (mSleepTime > 0) { - Thread.sleep(mSleepTime); + if (mSpeedBandUtil != null) { + mSpeedBandUtil.limitNextBytes(len); } if (mChildCurrentLocation + len >= mConfig.END_LOCATION) { len = (int) (mConfig.END_LOCATION - mChildCurrentLocation); @@ -186,10 +194,9 @@ class FtpThreadTask extends AbsFtpThreadTask } } handleComplete(); - } catch (InterruptedException e) { - e.printStackTrace(); } catch (IOException e) { - fail(mChildCurrentLocation, String.format("下载失败【%s】", mConfig.URL), e); + fail(mChildCurrentLocation, + new AriaIOException(TAG, String.format("下载失败【%s】", mConfig.URL), e)); } finally { try { if (fos != null) { @@ -217,11 +224,13 @@ class FtpThreadTask extends AbsFtpThreadTask file.seek(mConfig.START_LOCATION); byte[] buffer = new byte[mBufSize]; int len; - while ((len = is.read(buffer)) != -1) { + while (isLive() && (len = is.read(buffer)) != -1) { if (isBreak()) { break; } - if (mSleepTime > 0) Thread.sleep(mSleepTime); + if (mSpeedBandUtil != null) { + mSpeedBandUtil.limitNextBytes(len); + } if (mChildCurrentLocation + len >= mConfig.END_LOCATION) { len = (int) (mConfig.END_LOCATION - mChildCurrentLocation); file.write(buffer, 0, len); @@ -233,9 +242,8 @@ class FtpThreadTask extends AbsFtpThreadTask } } } catch (IOException e) { - fail(mChildCurrentLocation, String.format("下载失败【%s】", mConfig.URL), e); - } catch (InterruptedException e) { - e.printStackTrace(); + fail(mChildCurrentLocation, + new AriaIOException(TAG, String.format("下载失败【%s】", mConfig.URL), e)); } finally { try { if (file != null) { @@ -246,4 +254,8 @@ class FtpThreadTask extends AbsFtpThreadTask } } } + + @Override public int getMaxSpeed() { + return mAridManager.getDownloadConfig().getMaxSpeed(); + } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java index 71b206c8..3cd5e123 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java @@ -15,12 +15,18 @@ */ package com.arialyy.aria.core.download.downloader; +import android.os.Process; import android.text.TextUtils; +import android.util.Log; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.common.CompleteInfo; import com.arialyy.aria.core.common.OnFileInfoCallback; +import com.arialyy.aria.core.common.RequestEnum; import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadTaskEntity; +import com.arialyy.aria.exception.AriaIOException; +import com.arialyy.aria.exception.BaseException; +import com.arialyy.aria.exception.TaskException; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.CheckUtil; import com.arialyy.aria.util.CommonUtil; @@ -28,9 +34,18 @@ import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.CookieHandler; +import java.net.CookieManager; +import java.net.HttpCookie; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * 下载文件信息获取 @@ -51,6 +66,7 @@ class HttpFileInfoThread implements Runnable { } @Override public void run() { + Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); HttpURLConnection conn = null; try { URL url = new URL(CommonUtil.convertUrl(mEntity.getUrl())); @@ -62,12 +78,9 @@ class HttpFileInfoThread implements Runnable { conn.connect(); handleConnect(conn); } catch (IOException e) { - failDownload("下载失败【downloadUrl:" - + mEntity.getUrl() - + "】\n【filePath:" - + mEntity.getDownloadPath() - + "】\n" - + ALog.getExceptionString(e), true); + failDownload(new AriaIOException(TAG, + String.format("下载失败,filePath: %s, url: %s", mEntity.getDownloadPath(), mEntity.getUrl())), + true); } finally { if (conn != null) { conn.disconnect(); @@ -76,6 +89,23 @@ class HttpFileInfoThread implements Runnable { } private void handleConnect(HttpURLConnection conn) throws IOException { + if (mTaskEntity.getRequestEnum() == RequestEnum.POST) { + Map params = mTaskEntity.getParams(); + if (params != null) { + OutputStreamWriter dos = new OutputStreamWriter(conn.getOutputStream()); + Set keys = params.keySet(); + StringBuilder sb = new StringBuilder(); + for (String key : keys) { + sb.append(key).append("=").append(URLEncoder.encode(params.get(key))).append("&"); + } + String url = sb.toString(); + url = url.substring(0, url.length() - 1); + dos.write(url); + dos.flush(); + dos.close(); + } + } + long len = conn.getContentLength(); if (len < 0) { String temp = conn.getHeaderField("Content-Length"); @@ -92,6 +122,14 @@ class HttpFileInfoThread implements Runnable { } } } + + if (!CommonUtil.checkSDMemorySpace(mEntity.getDownloadPath(), len)) { + failDownload(new TaskException(TAG, + String.format("下载失败,内存空间不足;filePath: %s, url: %s", mEntity.getDownloadPath(), + mEntity.getUrl())), false); + return; + } + int code = conn.getResponseCode(); boolean end = false; if (TextUtils.isEmpty(mEntity.getMd5Code())) { @@ -104,7 +142,7 @@ class HttpFileInfoThread implements Runnable { if (!TextUtils.isEmpty(str) && str.equals("chunked")) { isChunked = true; } - //Map> headers = conn.getHeaderFields(); + Map> headers = conn.getHeaderFields(); String disposition = conn.getHeaderField("Content-Disposition"); if (mTaskEntity.isUseServerFileName() && !TextUtils.isEmpty(disposition)) { mEntity.setDisposition(CommonUtil.encryptBASE64(disposition)); @@ -114,19 +152,33 @@ class HttpFileInfoThread implements Runnable { if (info.startsWith("filename") && info.contains("=")) { String[] temp = info.split("="); if (temp.length > 1) { - String newName = URLDecoder.decode(temp[1], "utf-8"); + String newName = URLDecoder.decode(temp[1], "utf-8").replaceAll("\"", ""); mEntity.setServerFileName(newName); - fileRename(newName); + renameFile(newName); break; } } } } } + CookieManager msCookieManager = new CookieManager(); + List cookiesHeader = headers.get("Set-Cookie"); + + if (cookiesHeader != null) { + for (String cookie : cookiesHeader) { + msCookieManager.getCookieStore().add(null, HttpCookie.parse(cookie).get(0)); + } + mTaskEntity.setCookieManager(msCookieManager); + } mTaskEntity.setCode(code); if (code == HttpURLConnection.HTTP_PARTIAL) { if (!checkLen(len) && !isChunked) { + if (len < 0) { + failDownload( + new AriaIOException(TAG, String.format("任务下载失败,文件长度小于0, url: %s", mEntity.getUrl())), + false); + } return; } mEntity.setFileSize(len); @@ -149,6 +201,12 @@ class HttpFileInfoThread implements Runnable { handleUrlReTurn(conn, CommonUtil.getWindowReplaceUrl(sb.toString())); return; } else if (!checkLen(len) && !isChunked) { + if (len < 0) { + failDownload( + new AriaIOException(TAG, String.format("任务下载失败,文件长度小于0, url: %s", mEntity.getUrl())), + false); + } + ALog.d(TAG, "len < 0"); return; } mEntity.setFileSize(len); @@ -156,14 +214,18 @@ class HttpFileInfoThread implements Runnable { mTaskEntity.setSupportBP(false); end = true; } else if (code == HttpURLConnection.HTTP_NOT_FOUND) { - failDownload("任务【" + mEntity.getUrl() + "】下载失败,错误码:404", true); + failDownload(new AriaIOException(TAG, + String.format("任务下载失败,errorCode:404, url: %s", mEntity.getUrl())), true); } else if (code == HttpURLConnection.HTTP_MOVED_TEMP || code == HttpURLConnection.HTTP_MOVED_PERM || code == HttpURLConnection.HTTP_SEE_OTHER + || code == HttpURLConnection.HTTP_CREATED // 201 跳转 || code == 307) { handleUrlReTurn(conn, conn.getHeaderField("Location")); } else { - failDownload("任务【" + mEntity.getUrl() + "】下载失败,错误码:" + code, true); + failDownload(new AriaIOException(TAG, + String.format("任务下载失败,errorCode:%s, errorMsg: %s, url: %s", code, + conn.getResponseMessage(), mEntity.getUrl())), true); } if (end) { mTaskEntity.setChunked(isChunked); @@ -178,7 +240,7 @@ class HttpFileInfoThread implements Runnable { /** * 重命名文件 */ - private void fileRename(String newName) { + private void renameFile(String newName) { if (TextUtils.isEmpty(newName)) { ALog.w(TAG, "重命名失败【服务器返回的文件名为空】"); return; @@ -201,19 +263,20 @@ class HttpFileInfoThread implements Runnable { if (TextUtils.isEmpty(newUrl) || newUrl.equalsIgnoreCase("null") || !newUrl.startsWith( "http")) { if (onFileInfoCallback != null) { - onFileInfoCallback.onFail(mEntity.getUrl(), "获取重定向链接失败", false); + onFileInfoCallback.onFail(mEntity.getUrl(), new TaskException(TAG, "获取重定向链接失败"), false); } return; } if (!CheckUtil.checkUrl(newUrl)) { - failDownload("下载失败,重定向url错误", false); + failDownload(new TaskException(TAG, "下载失败,重定向url错误"), false); return; } mTaskEntity.setRedirectUrl(newUrl); mEntity.setRedirect(true); mEntity.setRedirectUrl(newUrl); String cookies = conn.getHeaderField("Set-Cookie"); - conn = (HttpURLConnection) new URL(newUrl).openConnection(); + URL url = new URL(CommonUtil.convertUrl(newUrl)); + conn = ConnectionHelp.handleConnection(url, mTaskEntity); conn = ConnectionHelp.setConnectParam(mTaskEntity, conn); conn.setRequestProperty("Cookie", cookies); conn.setRequestProperty("Range", "bytes=" + 0 + "-"); @@ -233,17 +296,12 @@ class HttpFileInfoThread implements Runnable { if (len != mEntity.getFileSize()) { mTaskEntity.setNewTask(true); } - if (len < 0) { - failDownload("任务【" + mEntity.getUrl() + "】下载失败,文件长度小于0", true); - return false; - } return true; } - private void failDownload(String errorMsg, boolean needRetry) { - ALog.e(TAG, errorMsg); + private void failDownload(BaseException e, boolean needRetry) { if (onFileInfoCallback != null) { - onFileInfoCallback.onFail(mEntity.getUrl(), errorMsg, needRetry); + onFileInfoCallback.onFail(mEntity.getUrl(), e, needRetry); } } } \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java index 7708c4f6..5ae61986 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java @@ -15,13 +15,15 @@ */ package com.arialyy.aria.core.download.downloader; -import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.common.AbsThreadTask; +import com.arialyy.aria.core.common.RequestEnum; import com.arialyy.aria.core.common.StateConstance; import com.arialyy.aria.core.common.SubThreadConfig; import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.inf.IDownloadListener; +import com.arialyy.aria.exception.AriaIOException; +import com.arialyy.aria.exception.TaskException; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.BufferedRandomAccessFile; import com.arialyy.aria.util.CommonUtil; @@ -29,13 +31,17 @@ import java.io.BufferedInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; +import java.net.URLEncoder; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; +import java.util.Map; +import java.util.Set; /** * Created by lyy on 2017/1/18. @@ -49,20 +55,19 @@ final class HttpThreadTask extends AbsThreadTask downloadInfo) { super(constance, listener, downloadInfo); - AriaManager manager = AriaManager.getInstance(AriaManager.APP); - mConnectTimeOut = manager.getDownloadConfig().getConnectTimeOut(); - mReadTimeOut = manager.getDownloadConfig().getIOTimeOut(); - mBufSize = manager.getDownloadConfig().getBuffSize(); - isNotNetRetry = manager.getDownloadConfig().isNotNetRetry(); + mConnectTimeOut = mAridManager.getDownloadConfig().getConnectTimeOut(); + mReadTimeOut = mAridManager.getDownloadConfig().getIOTimeOut(); + mBufSize = mAridManager.getDownloadConfig().getBuffSize(); + isNotNetRetry = mAridManager.getDownloadConfig().isNotNetRetry(); isOpenDynamicFile = STATE.TASK_RECORD.isOpenDynamicFile; isBlock = STATE.TASK_RECORD.isBlock; - setMaxSpeed(manager.getDownloadConfig().getMaxSpeed()); } - @Override public void run() { - if (mConfig.THREAD_RECORD.isComplete) { + @Override public HttpThreadTask call() throws Exception { + super.call(); + if (getThreadRecord().isComplete) { handleComplete(); - return; + return this; } HttpURLConnection conn = null; BufferedInputStream is = null; @@ -76,7 +81,6 @@ final class HttpThreadTask extends AbsThreadTask params = mTaskEntity.getParams(); + if (params != null) { + OutputStreamWriter dos = new OutputStreamWriter(conn.getOutputStream()); + Set keys = params.keySet(); + StringBuilder sb = new StringBuilder(); + for (String key : keys) { + sb.append(key).append("=").append(URLEncoder.encode(params.get(key))).append("&"); + } + String paramStr = sb.toString(); + paramStr = paramStr.substring(0, paramStr.length() - 1); + dos.write(paramStr); + dos.flush(); + dos.close(); + } + } + is = new BufferedInputStream(ConnectionHelp.convertInputStream(conn)); if (isOpenDynamicFile) { readDynamicFile(is); @@ -102,11 +123,17 @@ final class HttpThreadTask extends AbsThreadTask 0) { - Thread.sleep(mSleepTime); + if (mSpeedBandUtil != null) { + mSpeedBandUtil.limitNextBytes(len); + } + if (mChildCurrentLocation + len >= mConfig.END_LOCATION) { + len = (int) (mConfig.END_LOCATION - mChildCurrentLocation); + bf.flip(); + fos.write(bf.array(), 0, len); + bf.compact(); + progress(len); + break; + } else { + bf.flip(); + foc.write(bf); + bf.compact(); + progress(len); } - bf.flip(); - foc.write(bf); - bf.compact(); - progress(len); } handleComplete(); - } catch (InterruptedException e) { - e.printStackTrace(); } catch (IOException e) { - fail(mChildCurrentLocation, String.format("下载失败【%s】", mConfig.URL), e); + fail(mChildCurrentLocation, new AriaIOException(TAG, + String.format("文件下载失败,savePath: %s, url: %s", mEntity.getDownloadPath(), mConfig.URL), + e)); } finally { try { if (fos != null) { + fos.flush(); fos.close(); } if (foc != null) { @@ -177,7 +217,7 @@ final class HttpThreadTask extends AbsThreadTask 0) { - Thread.sleep(mSleepTime); + if (mSpeedBandUtil != null) { + mSpeedBandUtil.limitNextBytes(len); } file.write(buffer, 0, len); progress(len); @@ -219,9 +259,9 @@ final class HttpThreadTask extends AbsThreadTask - extends AbsTask { - - protected AbsGroupUtil mUtil; +public abstract class AbsGroupTask + extends AbsTask { @Override public String getKey() { return mTaskEntity.getEntity().getKey(); @@ -37,7 +35,7 @@ public abstract class AbsGroupTask */ public void startSubTask(String url) { if (mUtil != null) { - mUtil.startSubTask(url); + ((AbsGroupUtil) mUtil).startSubTask(url); } } @@ -48,7 +46,7 @@ public abstract class AbsGroupTask */ public void stopSubTask(String url) { if (mUtil != null) { - mUtil.stopSubTask(url); + ((AbsGroupUtil) mUtil).stopSubTask(url); } } @@ -59,7 +57,7 @@ public abstract class AbsGroupTask */ public void cancelSubTask(String url) { if (mUtil != null) { - mUtil.cancelSubTask(url); + ((AbsGroupUtil) mUtil).cancelSubTask(url); } } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalTask.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalTask.java index 7b86e535..3fd15067 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalTask.java @@ -18,15 +18,8 @@ package com.arialyy.aria.core.inf; /** * Created by lyy on 2017/6/3. */ -public abstract class AbsNormalTask - extends AbsTask { - - /** - * 暂停任务,并让任务处于等待状态 - */ - public void stopAndWait() { - - } +public abstract class AbsNormalTask + extends AbsTask { /** * 最高优先级命令,最高优先级命令有以下属性 diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java index e9c75be5..3eb6a485 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java @@ -21,10 +21,14 @@ import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.command.ICmd; import com.arialyy.aria.core.command.normal.CancelCmd; import com.arialyy.aria.core.command.normal.NormalCmdFactory; +import com.arialyy.aria.core.common.TaskRecord; +import com.arialyy.aria.core.common.http.PostDelegate; +import com.arialyy.aria.core.download.DownloadGroupEntity; import com.arialyy.aria.core.download.DownloadGroupTaskEntity; import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.manager.TEManager; import com.arialyy.aria.core.upload.UploadTaskEntity; +import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.CommonUtil; import java.util.ArrayList; @@ -34,8 +38,8 @@ import java.util.List; * Created by AriaL on 2017/7/3. */ public abstract class AbsTarget - implements ITarget { - protected String TAG ; + implements ITarget { + protected String TAG; protected ENTITY mEntity; protected TASK_ENTITY mTaskEntity; protected String mTargetName; @@ -64,17 +68,33 @@ public abstract class AbsTarget cmds = new ArrayList<>(); int taskType = checkTaskType(); cmds.add( - CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_STOP, - taskType)); - cmds.add(CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_START, - taskType)); + CommonUtil.createNormalCmd(mTaskEntity, NormalCmdFactory.TASK_STOP, taskType)); + cmds.add(CommonUtil.createNormalCmd(mTaskEntity, NormalCmdFactory.TASK_START, taskType)); AriaManager.getInstance(AriaManager.APP).setCmds(cmds).exe(); } } @@ -258,8 +289,9 @@ public abstract class AbsTarget implements ITask { +public abstract class AbsTask + implements ITask { + public static final String ERROR_INFO_KEY = "ERROR_INFO_KEY"; /** * 是否需要重试,默认为true @@ -30,19 +37,64 @@ public abstract class AbsTask implements ITas public boolean needRetry = true; protected TASK_ENTITY mTaskEntity; protected Handler mOutHandler; - - /** - * 用于生成该任务对象的hash码 - */ - private String mTargetName; protected Context mContext; - protected boolean isHeighestTask = false; + boolean isHeighestTask = false; private boolean isCancel = false, isStop = false; + protected IUtil mUtil; + /** + * 扩展信息 + */ + private Map mExpand = new HashMap<>(); + /** + * 该任务的调度类型 + */ + @TaskSchedulerType + private int mSchedulerType = TaskSchedulerType.TYPE_DEFAULT; + protected IEventListener mListener; + protected ENTITY mEntity; + protected String TAG; + + protected AbsTask() { + TAG = CommonUtil.getClassName(this); + } public Handler getOutHandler() { return mOutHandler; } + /** + * 添加扩展数据 + * 读取扩展数据{@link #getExpand(String)} + */ + public void putExpand(String key, Object obj) { + if (TextUtils.isEmpty(key)) { + ALog.e(TAG, "key 为空"); + return; + } else if (obj == null) { + ALog.e(TAG, "扩展数据为空"); + return; + } + mExpand.put(key, obj); + } + + /** + * 读取扩展数据 + */ + public Object getExpand(String key) { + return mExpand.get(key); + } + + /** + * 设置最大下载/上传速度 + * + * @param speed 单位为:kb + */ + public void setMaxSpeed(int speed) { + if (mUtil != null) { + mUtil.setMaxSpeed(speed); + } + } + /** * 任务是否完成 * @@ -118,16 +170,55 @@ public abstract class AbsTask implements ITas * * @return 如果实体不存在,则返回null,否则返回扩展字段 */ - @Override public String getExtendField() { + public String getExtendField() { return mTaskEntity.getEntity() == null ? null : mTaskEntity.getEntity().getStr(); } + @Override public void start() { + if (mUtil.isRunning()) { + ALog.d(TAG, "任务正在下载"); + } else { + mUtil.start(); + } + } + @Override public void stop() { + stop(TaskSchedulerType.TYPE_DEFAULT); + } + + @Override public void stop(@TaskSchedulerType int type) { isStop = true; + mSchedulerType = type; + if (mUtil.isRunning()) { + mUtil.stop(); + } else { + mListener.onStop(mEntity.getCurrentProgress()); + } } @Override public void cancel() { isCancel = true; + if (!mUtil.isRunning()) { + mListener.onCancel(); + } else { + mUtil.cancel(); + } + } + + /** + * 是否真正下载 + * + * @return {@code true} 真正下载 + */ + @Override public boolean isRunning() { + return mUtil.isRunning(); + } + + /** + * 任务的调度类型 + */ + public int getSchedulerType() { + return mSchedulerType; } /** @@ -199,14 +290,6 @@ public abstract class AbsTask implements ITas */ public abstract String getTaskName(); - public String getTargetName() { - return mTargetName; - } - - @Override public void setTargetName(String targetName) { - this.mTargetName = targetName; - } - public boolean isHighestPriorityTask() { return isHeighestTask; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java index eba12e79..74616c0a 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java @@ -19,8 +19,12 @@ import com.arialyy.aria.core.FtpUrlEntity; import com.arialyy.aria.core.common.RequestEnum; import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.orm.annotation.Ignore; +import java.net.CookieManager; +import java.net.HttpCookie; import java.net.Proxy; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -55,6 +59,8 @@ public abstract class AbsTaskEntity extends DbEntity { */ public static final int U_FTP = 0xA2; + @Ignore private CookieManager cookieManager; + /** * 账号和密码 */ @@ -70,6 +76,11 @@ public abstract class AbsTaskEntity extends DbEntity { */ @Ignore private boolean isNewTask = false; + /** + * 请求参数 + */ + @Ignore private Map params; + /** * 任务状态,和Entity的state同步 */ @@ -129,6 +140,14 @@ public abstract class AbsTaskEntity extends DbEntity { public abstract ENTITY getEntity(); + public CookieManager getCookieManager() { + return cookieManager; + } + + public void setCookieManager(CookieManager cookieManager) { + this.cookieManager = cookieManager; + } + /** * 获取任务下载状态 * @@ -256,4 +275,12 @@ public abstract class AbsTaskEntity extends DbEntity { public void setCode(int code) { this.code = code; } + + public Map getParams() { + return params; + } + + public void setParams(Map params) { + this.params = params; + } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/IEventListener.java b/Aria/src/main/java/com/arialyy/aria/core/inf/IEventListener.java index 11da04c7..2691797b 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/IEventListener.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/IEventListener.java @@ -15,6 +15,8 @@ */ package com.arialyy.aria.core.inf; +import com.arialyy.aria.exception.BaseException; + /** * Created by Aria.Lao on 2017/7/18. * 基础事件 @@ -58,8 +60,9 @@ public interface IEventListener { /** * 下载失败 + * * @param needRetry 是否需要重试{@code true} 需要 + * @param e 失败信息 */ - void onFail(boolean needRetry); - + void onFail(boolean needRetry, BaseException e); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/IFtpTarget.java b/Aria/src/main/java/com/arialyy/aria/core/inf/IFtpTarget.java index 129c70d3..2fc81a17 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/IFtpTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/IFtpTarget.java @@ -16,6 +16,7 @@ package com.arialyy.aria.core.inf; import android.support.annotation.CheckResult; +import java.net.Proxy; /** * Created by laoyuyu on 2018/3/9. @@ -45,4 +46,12 @@ public interface IFtpTarget { */ @CheckResult TARGET login(String userName, String password, String account); + + /** + * 设置代理 + * + * @param proxy {@link Proxy} + */ + @CheckResult + TARGET setProxy(Proxy proxy); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/IHttpHeaderTarget.java b/Aria/src/main/java/com/arialyy/aria/core/inf/IHttpHeaderDelegate.java similarity index 88% rename from Aria/src/main/java/com/arialyy/aria/core/inf/IHttpHeaderTarget.java rename to Aria/src/main/java/com/arialyy/aria/core/inf/IHttpHeaderDelegate.java index b68706e2..80307556 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/IHttpHeaderTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/IHttpHeaderDelegate.java @@ -19,13 +19,14 @@ import android.support.annotation.CheckResult; import android.support.annotation.NonNull; import com.arialyy.aria.core.common.RequestEnum; import com.arialyy.aria.core.download.DownloadEntity; +import java.net.Proxy; import java.util.Map; /** * Created by laoyuyu on 2018/3/9. * HTTP Header功能接口 */ -public interface IHttpHeaderTarget { +public interface IHttpHeaderDelegate { /** * 给url请求添加Header数据 @@ -46,11 +47,6 @@ public interface IHttpHeaderTarget { @CheckResult TARGET addHeaders(Map headers); - /** - * 设置HTTP请求类型 - * - * @param requestEnum {@link RequestEnum} - */ @CheckResult - TARGET setRequestMode(RequestEnum requestEnum); + TARGET setUrlProxy(Proxy proxy); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/IPostDelegate.java b/Aria/src/main/java/com/arialyy/aria/core/inf/IPostDelegate.java new file mode 100644 index 00000000..b5ace80a --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/IPostDelegate.java @@ -0,0 +1,31 @@ +/* + * 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 java.util.Map; + +/** + * post 通用处理接口 + */ +public interface IPostDelegate { + + /** + * 设置Post请求参数 + */ + TARGET setParams(Map params); + + TARGET setParam(String key, String value); +} diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/ITarget.java b/Aria/src/main/java/com/arialyy/aria/core/inf/ITarget.java index 8b4b998a..8176258a 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/ITarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/ITarget.java @@ -18,48 +18,7 @@ package com.arialyy.aria.core.inf; /** * Created by AriaL on 2017/6/29. */ -public interface ITarget { - /** - * 获取任务状态 - * - * @return {@link IEntity} - */ - int getTaskState(); - - /** - * 任务是否在执行 - * - * @return {@code true} 任务正在执行 - */ - boolean isRunning(); - - /** - * 任务是否存在 - * - * @return {@code true} 任务存在 - */ - boolean taskExists(); - - /** - * 任务文件大小 - */ - long getSize(); - - /** - * 转换后的大小 - */ - String getConvertSize(); - - /** - * 获取任务进度百分比 - */ - int getPercent(); - - /** - * 获取任务进度,如果任务存在,则返回当前进度 - */ - long getCurrentProgress(); - +public interface ITarget { /** * 开始下载 */ diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/ITask.java b/Aria/src/main/java/com/arialyy/aria/core/inf/ITask.java index 6a5016a9..d8d0dad2 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/ITask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/ITask.java @@ -25,11 +25,6 @@ public interface ITask { */ int getState(); - /** - * 获取扩展字段 - */ - String getExtendField(); - /** * 唯一标识符,DownloadTask 为下载地址,UploadTask 为文件路径 */ @@ -49,8 +44,17 @@ public interface ITask { void start(); + /** + * 停止任务 + */ void stop(); + /** + * 停止任务 + * @param type {@code 0}默认操作,{@code 1}停止任务不自动执行下一任务 + */ + void stop(int type); + void cancel(); /** @@ -89,6 +93,4 @@ public interface ITask { * @return 返回 3mb */ String getConvertCurrentProgress(); - - void setTargetName(String targetName); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/TaskSchedulerType.java b/Aria/src/main/java/com/arialyy/aria/core/inf/TaskSchedulerType.java new file mode 100644 index 00000000..b25496b7 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/TaskSchedulerType.java @@ -0,0 +1,22 @@ +package com.arialyy.aria.core.inf; + +import android.support.annotation.IntDef; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@IntDef({ + TaskSchedulerType.TYPE_DEFAULT, + TaskSchedulerType.TYPE_STOP_NOT_NEXT, + TaskSchedulerType.TYPE_STOP_AND_WAIT +}) +@Retention(RetentionPolicy.SOURCE) public @interface TaskSchedulerType { + int TYPE_DEFAULT = 1; + /** + * 停止当前任务并且不自动启动下一任务 + */ + int TYPE_STOP_NOT_NEXT = 2; + /** + * 停止任务并让当前任务处于等待状态 + */ + int TYPE_STOP_AND_WAIT = 3; +} \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/manager/DGTEFactory.java b/Aria/src/main/java/com/arialyy/aria/core/manager/DGTEFactory.java index 5dd0f510..73582af9 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/manager/DGTEFactory.java +++ b/Aria/src/main/java/com/arialyy/aria/core/manager/DGTEFactory.java @@ -59,15 +59,11 @@ class DGTEFactory implements IGTEFactory> mThreadTasks = new HashMap<>(); + + public static ThreadTaskManager getInstance() { + if (INSTANCE == null) { + synchronized (LOCK) { + INSTANCE = new ThreadTaskManager(); + } + } + return INSTANCE; + } + + private ThreadTaskManager() { + mExePool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + } + + /** + * 启动线程任务 + * + * @param key 任务对应的key{@link AbsTaskEntity#getKey()} + * @param threadTask 线程任务{@link AbsThreadTask} + */ + public synchronized void startThread(String key, AbsThreadTask threadTask) { + if (mExePool.isShutdown()) { + ALog.e(TAG, "线程池已经关闭"); + return; + } + key = getKey(key); + Set temp = mThreadTasks.get(key); + if (temp == null) { + temp = new HashSet<>(); + mThreadTasks.put(key, temp); + } + temp.add(mExePool.submit(threadTask)); + } + + /** + * 停止任务的所有线程 + * + * @param key 任务对应的key{@link AbsTaskEntity#getKey()} + */ + public synchronized void stopTaskThread(String key) { + if (mExePool.isShutdown()) { + ALog.e(TAG, "线程池已经关闭"); + return; + } + key = getKey(key); + Set temp = mThreadTasks.get(key); + if (temp != null && temp.size() > 0) { + try { + for (Future future : temp) { + if (future.isDone() || future.isCancelled()) { + continue; + } + AbsThreadTask task = (AbsThreadTask) future.get(); + task.setInterrupted(true); + future.cancel(true); + } + } catch (Exception e) { + ALog.e(TAG, e); + } + temp.clear(); + } + mThreadTasks.remove(key); + } + + /** + * 重试线程任务 + * + * @param task 线程任务 + */ + public synchronized void retryThread(AbsThreadTask task) { + if (mExePool.isShutdown()) { + ALog.e(TAG, "线程池已经关闭"); + return; + } + try { + if (task == null || task.isInterrupted()) { + ALog.e(TAG, "线程为空或线程已经中断"); + return; + } + } catch (Exception e) { + ALog.e(TAG, e); + return; + } + mExePool.submit(task); + } + + /** + * map中的key + * + * @param key 任务的key{@link AbsTaskEntity#getKey()} + * @return 转换后的map中的key + */ + private String getKey(String key) { + return CommonUtil.getStrMd5(key); + } +} diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java index 5a171948..3e1e6d85 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java @@ -19,9 +19,12 @@ package com.arialyy.aria.core.queue; import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.IEntity; +import com.arialyy.aria.core.inf.TaskSchedulerType; import com.arialyy.aria.core.queue.pool.BaseCachePool; import com.arialyy.aria.core.queue.pool.BaseExecutePool; import com.arialyy.aria.util.ALog; +import java.util.Map; +import java.util.Set; /** * Created by lyy on 2017/2/23. @@ -67,17 +70,37 @@ abstract class AbsTaskQueue tasks = mExecutePool.getAllTask(); + Set keys = tasks.keySet(); + for (String key : keys) { + TASK task = tasks.get(key); + task.setMaxSpeed(maxSpeed); + } } /** @@ -173,7 +196,6 @@ abstract class AbsTaskQueue tasks = mExecutePool.getAllTask(); - Set keys = tasks.keySet(); - for (String key : keys) { - DownloadTask task = tasks.get(key); - task.setMaxSpeed(maxSpeed); - } - } - - @Override public DownloadTask createTask(String target, DownloadTaskEntity entity) { + @Override public DownloadTask createTask(DownloadTaskEntity entity) { DownloadTask task = null; - if (!TextUtils.isEmpty(target)) { - if (mCachePool.getTask(entity.getEntity().getKey()) == null - && mExecutePool.getTask(entity.getEntity().getKey()) == null) { - task = (DownloadTask) TaskFactory.getInstance() - .createTask(target, entity, DownloadSchedulers.getInstance()); - mCachePool.putTask(task); - } else { - ALog.w(TAG, "任务已存在"); - } + if (mCachePool.getTask(entity.getEntity().getKey()) == null + && mExecutePool.getTask(entity.getEntity().getKey()) == null) { + task = (DownloadTask) TaskFactory.getInstance() + .createTask(entity, DownloadSchedulers.getInstance()); + mCachePool.putTask(task); } else { - ALog.e(TAG, "target name 为 null!!"); + ALog.w(TAG, "任务已存在"); } return task; diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/ITaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/ITaskQueue.java index f92325f1..c25c3d43 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/ITaskQueue.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/ITaskQueue.java @@ -113,10 +113,9 @@ public interface ITaskQueue ITask createTask( - String targetName, TASK_ENTITY entity, SCHEDULER schedulers) { + TASK_ENTITY entity, SCHEDULER schedulers) { if (entity instanceof DownloadTaskEntity) { - return createDownloadTask(targetName, (DownloadTaskEntity) entity, schedulers); + return createDownloadTask((DownloadTaskEntity) entity, schedulers); } else if (entity instanceof UploadTaskEntity) { - return createUploadTask(targetName, (UploadTaskEntity) entity, schedulers); + return createUploadTask((UploadTaskEntity) entity, schedulers); } else if (entity instanceof DownloadGroupTaskEntity) { - return createDownloadGroupTask(targetName, (DownloadGroupTaskEntity) entity, schedulers); + return createDownloadGroupTask((DownloadGroupTaskEntity) entity, schedulers); } return null; } @@ -78,9 +78,9 @@ class TaskFactory { * @param entity 下载任务实体{@link DownloadGroupTask} * @param schedulers {@link ISchedulers} */ - private DownloadGroupTask createDownloadGroupTask(String targetName, - DownloadGroupTaskEntity entity, ISchedulers schedulers) { - DownloadGroupTask.Builder builder = new DownloadGroupTask.Builder(targetName, entity); + private DownloadGroupTask createDownloadGroupTask(DownloadGroupTaskEntity entity, + ISchedulers schedulers) { + DownloadGroupTask.Builder builder = new DownloadGroupTask.Builder(entity); builder.setOutHandler(schedulers); return builder.build(); } @@ -89,10 +89,8 @@ class TaskFactory { * @param entity 上传任务实体{@link UploadTaskEntity} * @param schedulers {@link ISchedulers} */ - private UploadTask createUploadTask(String targetName, UploadTaskEntity entity, - ISchedulers schedulers) { + private UploadTask createUploadTask(UploadTaskEntity entity, ISchedulers schedulers) { UploadTask.Builder builder = new UploadTask.Builder(); - builder.setTargetName(targetName); builder.setUploadTaskEntity(entity); builder.setOutHandler(schedulers); return builder.build(); @@ -102,9 +100,8 @@ class TaskFactory { * @param entity 下载任务实体{@link DownloadTaskEntity} * @param schedulers {@link ISchedulers} */ - private DownloadTask createDownloadTask(String targetName, DownloadTaskEntity entity, - ISchedulers schedulers) { - DownloadTask.Builder builder = new DownloadTask.Builder(targetName, entity); + private DownloadTask createDownloadTask(DownloadTaskEntity entity, ISchedulers schedulers) { + DownloadTask.Builder builder = new DownloadTask.Builder(entity); builder.setOutHandler(schedulers); return builder.build(); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java index 570a0f0d..d235304d 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java @@ -16,7 +16,6 @@ package com.arialyy.aria.core.queue; -import android.text.TextUtils; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.queue.pool.BaseCachePool; import com.arialyy.aria.core.queue.pool.BaseExecutePool; @@ -62,19 +61,15 @@ public class UploadTaskQueue extends AbsTaskQueue return AriaManager.getInstance(AriaManager.APP).getUploadConfig().getMaxTaskNum(); } - @Override public UploadTask createTask(String targetName, UploadTaskEntity entity) { + @Override public UploadTask createTask(UploadTaskEntity entity) { UploadTask task = null; - if (!TextUtils.isEmpty(targetName)) { - if (mCachePool.getTask(entity.getEntity().getKey()) == null - && mExecutePool.getTask(entity.getEntity().getKey()) == null) { - task = (UploadTask) TaskFactory.getInstance() - .createTask(targetName, entity, UploadSchedulers.getInstance()); - mCachePool.putTask(task); - } else { - ALog.w(TAG, "任务已存在"); - } + if (mCachePool.getTask(entity.getEntity().getKey()) == null + && mExecutePool.getTask(entity.getEntity().getKey()) == null) { + task = (UploadTask) TaskFactory.getInstance() + .createTask(entity, UploadSchedulers.getInstance()); + mCachePool.putTask(task); } else { - ALog.e(TAG, "target name 为 null是!!"); + ALog.w(TAG, "任务已存在"); } return task; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulerListener.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulerListener.java index e6e36ebe..decb5ba6 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulerListener.java +++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulerListener.java @@ -56,6 +56,10 @@ public class AbsSchedulerListener, +abstract class AbsSchedulers> implements ISchedulers { private final String TAG = "AbsSchedulers"; @@ -139,7 +140,8 @@ abstract class AbsSchedulers reTryNum) { callback(FAIL, task); mQueue.removeTaskFormQueue(task.getKey()); - startNextTask(); - ALog.d(TAG, "retry_next"); + startNextTask(task); TEManager.getInstance().removeTEntity(task.getKey()); return; } @@ -302,8 +303,7 @@ abstract class AbsSchedulers { void onTaskCancel(TASK task); /** - * 任务下载失败 + * 任务失败 + * + * @deprecated {@link #onTaskFail(ITask, Exception)} */ + @Deprecated void onTaskFail(TASK task); + /** + * 任务失败 + */ + void onTaskFail(TASK task, Exception e); + /** * 任务完成 */ diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/BaseNormalTarget.java b/Aria/src/main/java/com/arialyy/aria/core/upload/BaseNormalTarget.java index 805bc1e5..df175a3e 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/BaseNormalTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/BaseNormalTarget.java @@ -80,6 +80,16 @@ abstract class BaseNormalTarget mEntity.save(); mTaskEntity.save(); } + if (mTaskEntity.getUrlEntity() != null && mTaskEntity.getUrlEntity().isFtps) { + if (TextUtils.isEmpty(mTaskEntity.getUrlEntity().storePath)) { + ALog.e(TAG, "证书路径为空"); + return false; + } + if (TextUtils.isEmpty(mTaskEntity.getUrlEntity().keyAlias)) { + ALog.e(TAG, "证书别名为空"); + return false; + } + } return b; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/BaseUListener.java b/Aria/src/main/java/com/arialyy/aria/core/upload/BaseUListener.java index e561b5e2..6de1f136 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/BaseUListener.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/BaseUListener.java @@ -16,128 +16,27 @@ package com.arialyy.aria.core.upload; import android.os.Handler; -import com.arialyy.aria.core.AriaManager; +import com.arialyy.aria.core.common.BaseListener; import com.arialyy.aria.core.common.TaskRecord; -import com.arialyy.aria.core.inf.AbsEntity; -import com.arialyy.aria.core.inf.AbsTask; -import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IUploadListener; -import com.arialyy.aria.core.scheduler.ISchedulers; import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.util.CommonUtil; -import java.lang.ref.WeakReference; /** * 下载监听类 */ -class BaseUListener, TASK extends AbsTask> +class BaseUListener extends BaseListener implements IUploadListener { - private WeakReference outHandler; - private int RUN_SAVE_INTERVAL = 5 * 1000; //5s保存一次下载中的进度 - private long mLastLen = 0; //上一次发送长度 - private boolean isFirst = true; - protected ENTITY mEntity; - protected TASK_ENTITY mTaskEntity; - protected TASK mTask; - private boolean isConvertSpeed = false; - boolean isWait = false; - private long mLastSaveTime; - private long mUpdateInterval; - BaseUListener(TASK task, Handler outHandler) { - this.outHandler = new WeakReference<>(outHandler); - this.mTask = new WeakReference<>(task).get(); - this.mEntity = this.mTask.getTaskEntity().getEntity(); - this.mTaskEntity = this.mTask.getTaskEntity(); - final AriaManager manager = AriaManager.getInstance(AriaManager.APP); - isConvertSpeed = manager.getDownloadConfig().isConvertSpeed(); - mLastLen = mEntity.getCurrentProgress(); - mLastSaveTime = System.currentTimeMillis(); + BaseUListener(UploadTask task, Handler outHandler) { + super(task, outHandler); + isConvertSpeed = manager.getUploadConfig().isConvertSpeed(); mUpdateInterval = manager.getUploadConfig().getUpdateInterval(); } - @Override public void onPre() { - saveData(IEntity.STATE_PRE, -1); - sendInState2Target(ISchedulers.PRE); - } - - @Override public void onStart(long startLocation) { - saveData(IEntity.STATE_RUNNING, startLocation); - sendInState2Target(ISchedulers.START); - } - - @Override public void onResume(long resumeLocation) { - saveData(IEntity.STATE_RUNNING, resumeLocation); - sendInState2Target(ISchedulers.RESUME); - } - - @Override public void onProgress(long currentLocation) { - mEntity.setCurrentProgress(currentLocation); - long speed = currentLocation - mLastLen; - if (isFirst) { - speed = 0; - isFirst = false; - } - handleSpeed(speed); - sendInState2Target(ISchedulers.RUNNING); - if (System.currentTimeMillis() - mLastSaveTime >= RUN_SAVE_INTERVAL) { - saveData(IEntity.STATE_RUNNING, currentLocation); - mLastSaveTime = System.currentTimeMillis(); - } - mLastLen = currentLocation; - } - - @Override public void onStop(long stopLocation) { - saveData(isWait ? IEntity.STATE_WAIT : IEntity.STATE_STOP, stopLocation); - handleSpeed(0); - sendInState2Target(ISchedulers.STOP); - } - - @Override public void onCancel() { - saveData(IEntity.STATE_CANCEL, -1); - handleSpeed(0); - sendInState2Target(ISchedulers.CANCEL); - } - - @Override public void onComplete() { - saveData(IEntity.STATE_COMPLETE, mEntity.getFileSize()); - handleSpeed(0); - sendInState2Target(ISchedulers.COMPLETE); - } - - @Override public void onFail(boolean needRetry) { - mEntity.setFailNum(mEntity.getFailNum() + 1); - saveData(IEntity.STATE_FAIL, mEntity.getCurrentProgress()); - handleSpeed(0); - mTask.needRetry = needRetry; - sendInState2Target(ISchedulers.FAIL); - } - - private void handleSpeed(long speed) { - if (mUpdateInterval != 1000) { - speed = speed * 1000 / mUpdateInterval; - } - if (isConvertSpeed) { - mEntity.setConvertSpeed(CommonUtil.formatFileSize(speed < 0 ? 0 : speed) + "/s"); - } - mEntity.setSpeed(speed < 0 ? 0 : speed); - mEntity.setPercent((int) (mEntity.getFileSize() <= 0 ? 0 - : mEntity.getCurrentProgress() * 100 / mEntity.getFileSize())); - } - - /** - * 将任务状态发送给下载器 - * - * @param state {@link ISchedulers#START} - */ - private void sendInState2Target(int state) { - if (outHandler.get() != null) { - outHandler.get().obtainMessage(state, mTask).sendToTarget(); - } - } - - private void saveData(int state, long location) { + @Override + protected void saveData(int state, long location) { mTaskEntity.setState(state); mEntity.setState(state); mEntity.setComplete(state == IEntity.STATE_COMPLETE); @@ -146,7 +45,7 @@ class BaseUListener implements IFtpTarget { - private FtpDelegate mDelegate; + private FtpDelegate mDelegate; private String mAccount, mUser, mPw; private boolean needLogin = false; @@ -42,7 +45,7 @@ public class FtpUploadTarget extends BaseNormalTarget private void initTask(String filePath) { initTarget(filePath); mTaskEntity.setRequestType(AbsTaskEntity.U_FTP); - mDelegate = new FtpDelegate<>(this, mTaskEntity); + mDelegate = new FtpDelegate<>(this); } /** @@ -51,7 +54,7 @@ public class FtpUploadTarget extends BaseNormalTarget public void add() { if (checkEntity()) { AriaManager.getInstance(AriaManager.APP) - .setCmd(CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_CREATE, + .setCmd(CommonUtil.createNormalCmd(mTaskEntity, NormalCmdFactory.TASK_CREATE, checkTaskType())) .exe(); } @@ -62,7 +65,16 @@ public class FtpUploadTarget extends BaseNormalTarget if (!b) { return false; } - mTaskEntity.setUrlEntity(CommonUtil.getFtpUrlInfo(mTempUrl)); + FtpUrlEntity temp = mTaskEntity.getUrlEntity(); + FtpUrlEntity newEntity = CommonUtil.getFtpUrlInfo(mTempUrl); + if (temp != null) { //处理FTPS的信息 + newEntity.isFtps = temp.isFtps; + newEntity.storePass = temp.storePass; + newEntity.keyAlias = temp.keyAlias; + newEntity.protocol = temp.protocol; + newEntity.storePath = temp.storePath; + } + mTaskEntity.setUrlEntity(newEntity); mTaskEntity.getUrlEntity().account = mAccount; mTaskEntity.getUrlEntity().user = mUser; mTaskEntity.getUrlEntity().password = mPw; @@ -70,6 +82,21 @@ public class FtpUploadTarget extends BaseNormalTarget return true; } + /** + * 是否是FTPS协议 + * 如果是FTPS协议,需要使用{@link FTPSConfig#setStorePath(String)} 、{@link FTPSConfig#setAlias(String)} + * 设置证书信息 + */ + @CheckResult + public FTPSConfig asFtps() { + if (mTaskEntity.getUrlEntity() == null) { + FtpUrlEntity urlEntity = new FtpUrlEntity(); + urlEntity.isFtps = true; + mTaskEntity.setUrlEntity(urlEntity); + } + return new FTPSConfig<>(this); + } + @CheckResult @Override public FtpUploadTarget charSet(String charSet) { return mDelegate.charSet(charSet); @@ -89,4 +116,8 @@ public class FtpUploadTarget extends BaseNormalTarget mAccount = account; return this; } + + @Override public FtpUploadTarget setProxy(Proxy proxy) { + return mDelegate.setProxy(proxy); + } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadListener.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadListener.java index 17506e92..c37416c2 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadListener.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadListener.java @@ -16,6 +16,7 @@ package com.arialyy.aria.core.upload; import com.arialyy.aria.core.inf.IUploadListener; +import com.arialyy.aria.exception.BaseException; /** * Created by lyy on 2017/2/23. @@ -49,7 +50,7 @@ class UploadListener implements IUploadListener { } - @Override public void onFail(boolean needRetry) { + @Override public void onFail(boolean needRetry, BaseException e) { } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java index e5fd9cca..63c3de42 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java @@ -20,6 +20,7 @@ import android.support.annotation.NonNull; import android.text.TextUtils; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.command.ICmd; +import com.arialyy.aria.core.command.normal.CancelAllCmd; import com.arialyy.aria.core.command.normal.NormalCmdFactory; import com.arialyy.aria.core.common.ProxyHelper; import com.arialyy.aria.core.inf.AbsReceiver; @@ -39,6 +40,16 @@ import java.util.Set; public class UploadReceiver extends AbsReceiver { private static final String TAG = "UploadReceiver"; + /** + * 设置最大上传速度,单位:kb + * + * @param maxSpeed 为0表示不限速 + */ + public UploadReceiver setMaxSpeed(int maxSpeed) { + AriaManager.getInstance(AriaManager.APP).getUploadConfig().setMaxSpeed(maxSpeed); + return this; + } + /** * 加载HTTP单文件上传任务 * @@ -78,7 +89,7 @@ public class UploadReceiver extends AbsReceiver { * @return {@code true}存在,{@code false} 不存在 */ public boolean taskExists(String filePath) { - return DbEntity.findFirst(UploadEntity.class, "filePath=?", filePath) != null; + return DbEntity.checkDataExist(UploadTaskEntity.class, "key=?", filePath); } /** @@ -112,7 +123,7 @@ public class UploadReceiver extends AbsReceiver { public void stopAllTask() { AriaManager.getInstance(AriaManager.APP) .setCmd(NormalCmdFactory.getInstance() - .createCmd(targetName, new UploadTaskEntity(), NormalCmdFactory.TASK_STOP_ALL, + .createCmd(new UploadTaskEntity(), NormalCmdFactory.TASK_STOP_ALL, ICmd.TASK_TYPE_UPLOAD)) .exe(); } @@ -125,10 +136,11 @@ public class UploadReceiver extends AbsReceiver { */ public void removeAllTask(boolean removeFile) { final AriaManager am = AriaManager.getInstance(AriaManager.APP); - - am.setCmd(CommonUtil.createNormalCmd(targetName, new UploadTaskEntity(), - NormalCmdFactory.TASK_CANCEL_ALL, ICmd.TASK_TYPE_UPLOAD)).exe(); - + CancelAllCmd cancelCmd = + (CancelAllCmd) CommonUtil.createNormalCmd(new UploadTaskEntity(), + NormalCmdFactory.TASK_CANCEL_ALL, ICmd.TASK_TYPE_UPLOAD); + cancelCmd.removeFile = removeFile; + am.setCmd(cancelCmd).exe(); Set keys = am.getReceiver().keySet(); for (String key : keys) { am.getReceiver().remove(key); @@ -148,9 +160,15 @@ public class UploadReceiver extends AbsReceiver { ALog.e(TAG, String.format("【%s】观察者为空", targetName)); return; } - Set cCounter = ProxyHelper.getInstance().uploadCounter; - if (cCounter != null && cCounter.contains(targetName)) { - UploadSchedulers.getInstance().register(obj); + Set set = ProxyHelper.getInstance().checkProxyType(obj.getClass()); + if (set != null && !set.isEmpty()) { + for (Integer type : set) { + if (type == ProxyHelper.PROXY_TYPE_UPLOAD) { + UploadSchedulers.getInstance().register(obj); + } + } + } else { + ALog.i(TAG, "没有Aria的注解方法"); } } @@ -179,9 +197,14 @@ public class UploadReceiver extends AbsReceiver { ALog.e(TAG, String.format("【%s】观察者为空", targetName)); return; } - Set dCounter = ProxyHelper.getInstance().uploadCounter; - if (dCounter != null && dCounter.contains(targetName)) { - UploadSchedulers.getInstance().unRegister(obj); + + Set set = ProxyHelper.getInstance().mProxyCache.get(obj.getClass().getName()); + if (set != null) { + for (Integer integer : set) { + if (integer == ProxyHelper.PROXY_TYPE_UPLOAD) { + UploadSchedulers.getInstance().unRegister(obj); + } + } } } } \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java index a87e1bee..fdd91f7d 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java @@ -17,10 +17,11 @@ package com.arialyy.aria.core.upload; import android.support.annotation.CheckResult; import android.support.annotation.NonNull; -import com.arialyy.aria.core.common.RequestEnum; -import com.arialyy.aria.core.delegate.HttpHeaderDelegate; +import com.arialyy.aria.core.common.http.HttpHeaderDelegate; +import com.arialyy.aria.core.common.http.PostDelegate; import com.arialyy.aria.core.inf.AbsTaskEntity; -import com.arialyy.aria.core.inf.IHttpHeaderTarget; +import com.arialyy.aria.core.inf.IHttpHeaderDelegate; +import java.net.Proxy; import java.util.Map; /** @@ -28,8 +29,8 @@ import java.util.Map; * http 单文件上传 */ public class UploadTarget extends BaseNormalTarget - implements IHttpHeaderTarget { - private HttpHeaderDelegate mDelegate; + implements IHttpHeaderDelegate { + private HttpHeaderDelegate mDelegate; UploadTarget(String filePath, String targetName) { this.mTargetName = targetName; @@ -42,7 +43,14 @@ public class UploadTarget extends BaseNormalTarget //http暂时不支持断点上传 mTaskEntity.setSupportBP(false); mTaskEntity.setRequestType(AbsTaskEntity.U_HTTP); - mDelegate = new HttpHeaderDelegate<>(this, mTaskEntity); + mDelegate = new HttpHeaderDelegate<>(this); + } + + /** + * Post处理 + */ + public PostDelegate asPost() { + return new PostDelegate<>(this); } /** @@ -86,8 +94,7 @@ public class UploadTarget extends BaseNormalTarget return mDelegate.addHeaders(headers); } - @CheckResult - @Override public UploadTarget setRequestMode(RequestEnum requestEnum) { - return mDelegate.setRequestMode(requestEnum); + @Override public UploadTarget setUrlProxy(Proxy proxy) { + return mDelegate.setUrlProxy(proxy); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpFileInfoThread.java b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpFileInfoThread.java index 2ad915da..406e101f 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpFileInfoThread.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpFileInfoThread.java @@ -15,7 +15,8 @@ */ package com.arialyy.aria.core.upload.uploader; -import com.arialyy.aria.core.common.AbsFtpInfoThread; +import aria.apache.commons.net.ftp.FTPFile; +import com.arialyy.aria.core.common.ftp.AbsFtpInfoThread; import com.arialyy.aria.core.common.CompleteInfo; import com.arialyy.aria.core.common.OnFileInfoCallback; import com.arialyy.aria.core.common.TaskRecord; @@ -25,7 +26,6 @@ import com.arialyy.aria.core.upload.UploadTaskEntity; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.DbHelper; import java.util.ArrayList; -import org.apache.commons.net.ftp.FTPFile; /** * Created by Aria.Lao on 2017/9/26. diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java index efe780a5..bc9b3c42 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java @@ -15,20 +15,21 @@ */ package com.arialyy.aria.core.upload.uploader; -import com.arialyy.aria.core.AriaManager; -import com.arialyy.aria.core.common.AbsFtpThreadTask; +import aria.apache.commons.net.ftp.FTPClient; +import aria.apache.commons.net.ftp.FTPReply; +import aria.apache.commons.net.ftp.OnFtpInputStreamListener; import com.arialyy.aria.core.common.StateConstance; import com.arialyy.aria.core.common.SubThreadConfig; +import com.arialyy.aria.core.common.ftp.AbsFtpThreadTask; import com.arialyy.aria.core.inf.IEventListener; import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadTaskEntity; +import com.arialyy.aria.exception.AriaIOException; +import com.arialyy.aria.exception.TaskException; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.BufferedRandomAccessFile; import java.io.IOException; import java.io.UnsupportedEncodingException; -import org.apache.commons.net.ftp.FTPClient; -import org.apache.commons.net.ftp.FTPReply; -import org.apache.commons.net.ftp.OnFtpInputStreamListener; /** * Created by Aria.Lao on 2017/7/28. @@ -41,14 +42,18 @@ class FtpThreadTask extends AbsFtpThreadTask { FtpThreadTask(StateConstance constance, IEventListener listener, SubThreadConfig info) { super(constance, listener, info); - AriaManager manager = AriaManager.getInstance(AriaManager.APP); - mConnectTimeOut = manager.getUploadConfig().getConnectTimeOut(); - mReadTimeOut = manager.getUploadConfig().getIOTimeOut(); - mBufSize = manager.getUploadConfig().getBuffSize(); - isNotNetRetry = manager.getUploadConfig().isNotNetRetry(); + mConnectTimeOut = mAridManager.getUploadConfig().getConnectTimeOut(); + mReadTimeOut = mAridManager.getUploadConfig().getIOTimeOut(); + mBufSize = mAridManager.getUploadConfig().getBuffSize(); + isNotNetRetry = mAridManager.getUploadConfig().isNotNetRetry(); } - @Override public void run() { + @Override public int getMaxSpeed() { + return mAridManager.getUploadConfig().getMaxSpeed(); + } + + @Override public FtpThreadTask call() throws Exception { + super.call(); //当前子线程的下载位置 mChildCurrentLocation = mConfig.START_LOCATION; FTPClient client = null; @@ -58,16 +63,21 @@ class FtpThreadTask extends AbsFtpThreadTask { String.format("任务【%s】线程__%s__开始上传【开始位置 : %s,结束位置:%s】", mConfig.TEMP_FILE.getName(), mConfig.THREAD_ID, mConfig.START_LOCATION, mConfig.END_LOCATION)); client = createClient(); - if (client == null) return; + if (client == null) { + return this; + } initPath(); client.makeDirectory(dir); client.changeWorkingDirectory(dir); client.setRestartOffset(mConfig.START_LOCATION); int reply = client.getReplyCode(); if (!FTPReply.isPositivePreliminary(reply) && reply != FTPReply.FILE_ACTION_OK) { - fail(mChildCurrentLocation, "上传失败,错误码为:" + reply + ",msg:" + client.getReplyString(), null); + fail(mChildCurrentLocation, + new AriaIOException(TAG, + String.format("文件上传错误,错误码为:%s, msg:%s, filePath: %s", reply, + client.getReplyString(), mEntity.getFilePath()))); client.disconnect(); - return; + return this; } file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", mBufSize); @@ -77,7 +87,7 @@ class FtpThreadTask extends AbsFtpThreadTask { } upload(client, file); if (isBreak()) { - return; + return this; } ALog.i(TAG, String.format("任务【%s】线程__%s__上传完毕", mConfig.TEMP_FILE.getName(), mConfig.THREAD_ID)); @@ -90,12 +100,14 @@ class FtpThreadTask extends AbsFtpThreadTask { } if (STATE.isFail()) { STATE.isRunning = false; - mListener.onFail(false); + mListener.onFail(false, new TaskException(TAG, + String.format("上传失败,filePath: %s, uploadUrl: %s", mEntity.getFilePath(), mConfig.URL))); } } catch (IOException e) { - fail(mChildCurrentLocation, String.format("上传失败【%s】", mConfig.URL), e); + fail(mChildCurrentLocation, new AriaIOException(TAG, + String.format("上传失败,filePath: %s, uploadUrl: %s", mEntity.getFilePath(), mConfig.URL))); } catch (Exception e) { - fail(mChildCurrentLocation, "获取流失败", e); + fail(mChildCurrentLocation, new AriaIOException(TAG, null, e)); } finally { try { if (file != null) { @@ -108,6 +120,7 @@ class FtpThreadTask extends AbsFtpThreadTask { e.printStackTrace(); } } + return this; } private void initPath() throws UnsupportedEncodingException { @@ -122,28 +135,32 @@ class FtpThreadTask extends AbsFtpThreadTask { throws IOException { try { - ALog.d(TAG, String.format("remotePath【%s】", remotePath)); + ALog.d(TAG, String.format("remotePath: %s", remotePath)); client.storeFile(remotePath, new FtpFISAdapter(bis), new OnFtpInputStreamListener() { boolean isStoped = false; @Override public void onFtpInputStream(FTPClient client, long totalBytesTransferred, int bytesTransferred, long streamSize) { - if (isBreak() && !isStoped) { - try { + try { + if (isBreak() && !isStoped) { isStoped = true; client.abor(); - } catch (IOException e) { - e.printStackTrace(); } + if (mSpeedBandUtil != null) { + mSpeedBandUtil.limitNextBytes(bytesTransferred); + } + progress(bytesTransferred); + } catch (IOException e) { + e.printStackTrace(); } - progress(bytesTransferred); } }); } catch (IOException e) { - if (e.getMessage().contains("IOException caught while copying")) { + if (e.getMessage().contains("AriaIOException caught while copying")) { e.printStackTrace(); } else { - fail(mChildCurrentLocation, "上传失败", e); + fail(mChildCurrentLocation, + new AriaIOException(TAG, String.format("上传失败,filePath: %s", mEntity.getFilePath()), e)); } } @@ -151,8 +168,9 @@ class FtpThreadTask extends AbsFtpThreadTask { if (!FTPReply.isPositiveCompletion(reply)) { if (reply != FTPReply.TRANSFER_ABORTED) { fail(mChildCurrentLocation, - String.format("上传文件错误,错误码为:%s,msg:%s", reply, client.getReplyString()), - null); + new AriaIOException(TAG, + String.format("文件上传错误,错误码为:%s, msg:%s, filePath: %s", reply, + client.getReplyString(), mEntity.getFilePath()))); } if (client.isConnected()) { client.disconnect(); diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java index ac14c2a7..c5ce84fc 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java @@ -15,13 +15,14 @@ */ package com.arialyy.aria.core.upload.uploader; -import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.common.AbsThreadTask; import com.arialyy.aria.core.common.StateConstance; import com.arialyy.aria.core.common.SubThreadConfig; import com.arialyy.aria.core.inf.IUploadListener; import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadTaskEntity; +import com.arialyy.aria.exception.BaseException; +import com.arialyy.aria.exception.TaskException; import com.arialyy.aria.util.ALog; import java.io.BufferedReader; import java.io.File; @@ -52,19 +53,20 @@ class HttpThreadTask extends AbsThreadTask { HttpThreadTask(StateConstance constance, IUploadListener listener, SubThreadConfig uploadInfo) { super(constance, listener, uploadInfo); - AriaManager manager = AriaManager.getInstance(AriaManager.APP); - mConnectTimeOut = manager.getUploadConfig().getConnectTimeOut(); - mReadTimeOut = manager.getUploadConfig().getIOTimeOut(); - mBufSize = manager.getUploadConfig().getBuffSize(); - isNotNetRetry = manager.getUploadConfig().isNotNetRetry(); + mConnectTimeOut = mAridManager.getUploadConfig().getConnectTimeOut(); + mReadTimeOut = mAridManager.getUploadConfig().getIOTimeOut(); + mBufSize = mAridManager.getUploadConfig().getBuffSize(); + isNotNetRetry = mAridManager.getUploadConfig().isNotNetRetry(); } - @Override public void run() { + @Override public HttpThreadTask call() throws Exception { + super.call(); File uploadFile = new File(mEntity.getFilePath()); if (!uploadFile.exists()) { - ALog.e(TAG, String.format("【%s】,文件不存在。", mEntity.getFilePath())); - fail(); - return; + fail(new TaskException(TAG, + String.format("上传失败,文件不存在;filePath: %s, url: %s", mEntity.getFilePath(), + mEntity.getUrl()))); + return this; } mListener.onPre(); URL url; @@ -103,13 +105,15 @@ class HttpThreadTask extends AbsThreadTask { mListener.onComplete(); } catch (Exception e) { e.printStackTrace(); - fail(); + fail(new TaskException(TAG, + String.format("上传失败,filePath: %s, url: %s", mEntity.getFilePath(), mEntity.getUrl()), e)); } + return this; } - private void fail() { + private void fail(BaseException e1) { try { - mListener.onFail(true); + mListener.onFail(true, e1); STATE.isRunning = false; if (mOutputStream != null) { mOutputStream.close(); @@ -167,6 +171,9 @@ class HttpThreadTask extends AbsThreadTask { if (STATE.isCancel) { break; } + if (mSpeedBandUtil != null) { + mSpeedBandUtil.limitNextBytes(bytesRead); + } } mOutputStream.flush(); @@ -198,7 +205,7 @@ class HttpThreadTask extends AbsThreadTask { if (status == HttpURLConnection.HTTP_OK) { BufferedReader reader = new BufferedReader(new InputStreamReader(mHttpConn.getInputStream())); String line; - while ((line = reader.readLine()) != null) { + while (isLive() && (line = reader.readLine()) != null) { response.append(line); } reader.close(); @@ -212,4 +219,8 @@ class HttpThreadTask extends AbsThreadTask { mOutputStream.close(); return response.toString(); } + + @Override public int getMaxSpeed() { + return mAridManager.getUploadConfig().getMaxSpeed(); + } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/SimpleUploadUtil.java b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/SimpleUploadUtil.java index 9f4d1c1c..774fe935 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/SimpleUploadUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/SimpleUploadUtil.java @@ -22,6 +22,8 @@ import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.IUploadListener; import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadTaskEntity; +import com.arialyy.aria.exception.BaseException; +import com.arialyy.aria.exception.TaskException; import com.arialyy.aria.util.CheckUtil; /** @@ -60,8 +62,8 @@ public class SimpleUploadUtil implements IUtil, Runnable { } } - @Override public void onFail(String url, String errorMsg, boolean needRetry) { - mListener.onFail(needRetry); + @Override public void onFail(String url, BaseException e, boolean needRetry) { + mListener.onFail(needRetry, e); } }).start(); break; @@ -99,7 +101,7 @@ public class SimpleUploadUtil implements IUtil, Runnable { mUploader.cancel(); } - @Override public void setMaxSpeed(double maxSpeed) { - mUploader.setMaxSpeed(maxSpeed); + @Override public void setMaxSpeed(int speed) { + mUploader.setMaxSpeed(speed); } } diff --git a/Aria/src/main/java/com/arialyy/aria/exception/AriaIOException.java b/Aria/src/main/java/com/arialyy/aria/exception/AriaIOException.java new file mode 100644 index 00000000..db0ffc7a --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/exception/AriaIOException.java @@ -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.exception; + +public class AriaIOException extends BaseException{ + private static final String ARIA_NET_EXCEPTION = "Aria Net Exception:"; + + public AriaIOException(String tag, String message) { + super(tag, String.format("%s%s", ARIA_NET_EXCEPTION, message)); + } + + public AriaIOException(String tag, String message, Exception e){ + super(tag, message, e); + } +} diff --git a/Aria/src/main/java/com/arialyy/aria/exception/BaseException.java b/Aria/src/main/java/com/arialyy/aria/exception/BaseException.java new file mode 100644 index 00000000..98073c31 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/exception/BaseException.java @@ -0,0 +1,35 @@ +/* + * 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.exception; + +public abstract class BaseException extends Exception { + + private String tag; + + public BaseException(String tag, String message) { + super(message); + this.tag = tag; + } + + public BaseException(String tag, String message, Exception e) { + super(String.format("%s\n%s", message == null ? "" : message, e == null ? "" : e.getMessage())); + this.tag = tag; + } + + public String getTag() { + return tag; + } +} diff --git a/Aria/src/main/java/com/arialyy/aria/exception/TaskException.java b/Aria/src/main/java/com/arialyy/aria/exception/TaskException.java new file mode 100644 index 00000000..e8f7b765 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/exception/TaskException.java @@ -0,0 +1,31 @@ +/* + * 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.exception; + +/** + * 任务异常 + */ +public class TaskException extends BaseException { + private static final String ARIA_TASK_EXCEPTION = "Aria Task Exception:"; + + public TaskException(String tag, String detailMessage) { + super(tag, String.format("%s, %s", ARIA_TASK_EXCEPTION, detailMessage)); + } + + public TaskException(String tag, String message, Exception e){ + super(tag, message, e); + } +} diff --git a/Aria/src/main/java/com/arialyy/aria/orm/AbsDelegate.java b/Aria/src/main/java/com/arialyy/aria/orm/AbsDelegate.java index 0fc7e88c..eafac17d 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/AbsDelegate.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/AbsDelegate.java @@ -18,7 +18,6 @@ package com.arialyy.aria.orm; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.support.v4.util.LruCache; -import android.text.TextUtils; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.CommonUtil; import java.lang.reflect.Field; @@ -134,11 +133,13 @@ abstract class AbsDelegate { } void closeCursor(Cursor cursor) { - if (cursor != null && !cursor.isClosed()) { - try { - cursor.close(); - } catch (android.database.SQLException e) { - e.printStackTrace(); + synchronized (AbsDelegate.class) { + if (cursor != null && !cursor.isClosed()) { + try { + cursor.close(); + } catch (android.database.SQLException e) { + e.printStackTrace(); + } } } } diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java b/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java index 582cd5cc..fc6f89c1 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java @@ -35,7 +35,7 @@ class DBConfig { /*adb pull /mnt/sdcard/Android/data/com.arialyy.simple/files/DB/AriaLyyDb d:/db*/ static Map mapping = new HashMap<>(); static String DB_NAME; - static int VERSION = 39; + static int VERSION = 41; /** * 是否将数据库保存在Sd卡,{@code true} 是 diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java b/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java index f6856acc..15b71db8 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java @@ -102,6 +102,19 @@ public abstract class DbEntity { return util.findData(clazz, expression); } + /** + * 模糊查询一组数据 + * + * DownloadEntity.findDatas(DownloadEntity.class, "downloadUrl like http://"); + * + * + * @return 没有数据返回null + */ + public static List findDataByFuzzy(Class clazz, String conditions) { + DelegateWrapper util = DelegateWrapper.getInstance(); + return util.findDataByFuzzy(clazz, conditions); + } + /** * 查询一行数据 * diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DelegateFind.java b/Aria/src/main/java/com/arialyy/aria/orm/DelegateFind.java index 81c8a85d..2eb8fff0 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DelegateFind.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DelegateFind.java @@ -201,7 +201,7 @@ class DelegateFind extends AbsDelegate { * @param pColumnAlias 关联查询父表别名 * @param cColumnAlias 关联查询子表别名 */ - private List newInstanceEntity( + private synchronized List newInstanceEntity( Class clazz, Class

parent, Class child, Cursor cursor, @@ -355,6 +355,26 @@ class DelegateFind extends AbsDelegate { return data; } + /** + * 模糊查寻数据 + */ + List findDataByFuzzy(SQLiteDatabase db, Class clazz, String conditions) { + db = checkDb(db); + if(TextUtils.isEmpty(conditions)){ + throw new IllegalArgumentException("sql语句表达式不能为null或\"\""); + } + if(!conditions.toUpperCase().contains("LIKE")){ + throw new IllegalArgumentException("sql语句表达式未包含LIEK"); + } + String sql = + "SELECT rowid, * FROM " + CommonUtil.getClassName(clazz) + " WHERE "+conditions; + print(FIND_DATA, sql); + Cursor cursor = db.rawQuery(sql, null); + List data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null; + closeCursor(cursor); + close(db); + return data; + } /** * 查找表的所有数据 */ @@ -373,7 +393,7 @@ class DelegateFind extends AbsDelegate { /** * 根据数据游标创建一个具体的对象 */ - private List newInstanceEntity(Class clazz, Cursor cursor) { + private synchronized List newInstanceEntity(Class clazz, Cursor cursor) { List fields = CommonUtil.getAllFields(clazz); List entitys = new ArrayList<>(); if (fields != null && fields.size() > 0) { @@ -419,6 +439,10 @@ class DelegateFind extends AbsDelegate { */ private void setFieldValue(Class type, Field field, int column, Cursor cursor, Object entity) throws IllegalAccessException { + if (cursor == null || cursor.isClosed()) { + ALog.e(TAG, "cursor没有初始化"); + return; + } if (type == String.class) { String temp = cursor.getString(column); if (!TextUtils.isEmpty(temp)) { diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DelegateUpdate.java b/Aria/src/main/java/com/arialyy/aria/orm/DelegateUpdate.java index f1a87b81..66239fb9 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DelegateUpdate.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DelegateUpdate.java @@ -82,7 +82,7 @@ class DelegateUpdate extends AbsDelegate { /** * 删除某条数据 */ - void delData(SQLiteDatabase db, Class clazz, String... expression) { + synchronized void delData(SQLiteDatabase db, Class clazz, String... expression) { db = checkDb(db); CheckUtil.checkSqlExpression(expression); @@ -101,7 +101,7 @@ class DelegateUpdate extends AbsDelegate { /** * 修改某行数据 */ - void modifyData(SQLiteDatabase db, DbEntity dbEntity) { + synchronized void modifyData(SQLiteDatabase db, DbEntity dbEntity) { db = checkDb(db); Class clazz = dbEntity.getClass(); List fields = CommonUtil.getAllFields(clazz); @@ -141,7 +141,7 @@ class DelegateUpdate extends AbsDelegate { /** * 插入数据 */ - void insertData(SQLiteDatabase db, DbEntity dbEntity) { + synchronized void insertData(SQLiteDatabase db, DbEntity dbEntity) { db = checkDb(db); Class clazz = dbEntity.getClass(); List fields = CommonUtil.getAllFields(clazz); diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DelegateWrapper.java b/Aria/src/main/java/com/arialyy/aria/orm/DelegateWrapper.java index 1c909eeb..faa8fc25 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DelegateWrapper.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DelegateWrapper.java @@ -56,13 +56,6 @@ public class DelegateWrapper { return INSTANCE; } - ///** - // * 保存关联数据 - // */ - //void saveRelationData(AbsWrapper wrapper){ - // - //} - /** * 查询关联表数据 * @@ -125,6 +118,13 @@ public class DelegateWrapper { return mDManager.getDelegate(DelegateFind.class).findData(mDb, clazz, expression); } + /** + * 模糊查寻数据 + */ + List findDataByFuzzy(Class clazz, String conditions) { + return mDManager.getDelegate(DelegateFind.class).findDataByFuzzy(mDb, clazz, conditions); + } + /** * 通过rowId判断数据是否存在 */ diff --git a/Aria/src/main/java/com/arialyy/aria/orm/SqlUtil.java b/Aria/src/main/java/com/arialyy/aria/orm/SqlUtil.java index 857d470a..5e9116a7 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/SqlUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/SqlUtil.java @@ -35,7 +35,7 @@ import java.util.Map; import java.util.Set; /** - * Created by Aria.Lao on 2017/7/24. + * Created by lyy on 2017/7/24. * sql工具 */ final class SqlUtil { diff --git a/Aria/src/main/java/com/arialyy/aria/util/CheckUtil.java b/Aria/src/main/java/com/arialyy/aria/util/CheckUtil.java index 2e61f8c1..4ea24293 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/CheckUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/util/CheckUtil.java @@ -222,9 +222,9 @@ public class CheckUtil { } else if (TextUtils.isEmpty(entity.getUrl())) { throw new IllegalArgumentException("下载链接不能为空"); } else if (TextUtils.isEmpty(entity.getFileName())) { - throw new FileException("文件名不能为null"); + throw new NullPointerException("文件名不能为null"); } else if (TextUtils.isEmpty(entity.getDownloadPath())) { - throw new FileException("文件保存路径不能为null"); + throw new NullPointerException("文件保存路径不能为null"); } } } \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java b/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java index 98d5c51d..cdebd34a 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java @@ -21,6 +21,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; import android.os.Environment; +import android.os.StatFs; import android.text.TextUtils; import android.util.Base64; import com.arialyy.aria.core.AriaManager; @@ -53,14 +54,17 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.math.BigDecimal; import java.math.BigInteger; +import java.net.URLEncoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -71,13 +75,61 @@ import java.util.regex.Pattern; public class CommonUtil { private static final String TAG = "CommonUtil"; + /** + * 检查SD内存空间是否充足 + * + * @param filePath 文件保存路径 + * @param fileSize 文件大小 + * @return {@code false} 内存空间不足,{@code true}内存空间足够 + */ + public static boolean checkSDMemorySpace(String filePath, long fileSize) { + List dirs = FileUtil.getSDPathList(AriaManager.APP); + if (dirs == null || dirs.isEmpty()) { + return true; + } + for (String path : dirs) { + if (filePath.contains(path)) { + if (fileSize > 0 && fileSize > getAvailableExternalMemorySize(path)) { + return false; + } + } + } + return true; + } + + /** + * sdcard 可用大小 + * + * @param sdcardPath sdcard 根路径 + * @return 单位为:byte + */ + public static long getAvailableExternalMemorySize(String sdcardPath) { + StatFs stat = new StatFs(sdcardPath); + long blockSize = stat.getBlockSize(); + long availableBlocks = stat.getAvailableBlocks(); + return availableBlocks * blockSize; + } + + /** + * sdcard 总大小 + * + * @param sdcardPath sdcard 根路径 + * @return 单位为:byte + */ + public static long getTotalExternalMemorySize(String sdcardPath) { + StatFs stat = new StatFs(sdcardPath); + long blockSize = stat.getBlockSize(); + long totalBlocks = stat.getBlockCount(); + return totalBlocks * blockSize; + } + /** * 获取某包下所有类 * * @param className 过滤的类名 * @return 类的完整名称 */ - public static List getClassName(Context context, String className) { + public static List getPkgClassNames(Context context, String className) { List classNameList = new ArrayList<>(); String pPath = context.getPackageCodePath(); File dir = new File(pPath).getParentFile(); @@ -289,6 +341,7 @@ public class CommonUtil { entity.user = userInfo; } } + entity.scheme = uri.getScheme(); entity.remotePath = TextUtils.isEmpty(remotePath) ? "/" : remotePath; return entity; } @@ -302,25 +355,25 @@ public class CommonUtil { public static String convertUrl(String url) { Uri uri = Uri.parse(url); url = uri.toString(); - //if (hasDoubleCharacter(url)) { - // //预先处理空格,URLEncoder只会把空格转换为+ - // url = url.replaceAll(" ", "%20"); - // //匹配双字节字符(包括汉字在内) - // String regex = Regular.REG_DOUBLE_CHAR_AND_SPACE; - // Pattern p = Pattern.compile(regex); - // Matcher m = p.matcher(url); - // Set strs = new HashSet<>(); - // while (m.find()) { - // strs.add(m.group()); - // } - // try { - // for (String str : strs) { - // url = url.replaceAll(str, URLEncoder.encode(str, "UTF-8")); - // } - // } catch (UnsupportedEncodingException e) { - // e.printStackTrace(); - // } - //} + if (hasDoubleCharacter(url)) { + //预先处理空格,URLEncoder只会把空格转换为+ + url = url.replaceAll(" ", "%20"); + //匹配双字节字符(包括汉字在内) + String regex = Regular.REG_DOUBLE_CHAR_AND_SPACE; + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(url); + Set strs = new HashSet<>(); + while (m.find()) { + strs.add(m.group()); + } + try { + for (String str : strs) { + url = url.replaceAll(str, URLEncoder.encode(str, "UTF-8")); + } + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } return url; } @@ -395,6 +448,23 @@ public class CommonUtil { return md5; } + /** + * 获取字符串的md5 + * + * @return 字符串为空或获取md5失败,则返回"" + */ + public static String getStrMd5(String str) { + if (TextUtils.isEmpty(str)) return ""; + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(str.getBytes()); + return new BigInteger(1, md.digest()).toString(16); + } catch (NoSuchAlgorithmException e) { + ALog.e(TAG, e.getMessage()); + } + return ""; + } + /** * 删除任务组记录 * @@ -435,11 +505,14 @@ public class CommonUtil { } } } - File dir = new File(groupEntity.getDirPath()); - if (dir.exists() && (removeFile || !groupEntity.isComplete())) { - dir.delete(); + + if (!TextUtils.isEmpty(groupEntity.getDirPath())) { + File dir = new File(groupEntity.getDirPath()); + if (dir.exists() && (removeFile || !groupEntity.isComplete())) { + dir.delete(); + } + groupEntity.deleteData(); } - groupEntity.deleteData(); } /** @@ -619,9 +692,9 @@ public class CommonUtil { * @param taskType {@link ICmd#TASK_TYPE_DOWNLOAD}、{@link ICmd#TASK_TYPE_DOWNLOAD_GROUP}、{@link * ICmd#TASK_TYPE_UPLOAD} */ - public static AbsNormalCmd createNormalCmd(String target, T entity, + public static AbsNormalCmd createNormalCmd(T entity, int cmd, int taskType) { - return NormalCmdFactory.getInstance().createCmd(target, entity, cmd, taskType); + return NormalCmdFactory.getInstance().createCmd(entity, cmd, taskType); } /** @@ -870,8 +943,11 @@ public class CommonUtil { // 创建目标文件 if (file.exists()) { final File to = new File(file.getAbsolutePath() + System.currentTimeMillis()); - file.renameTo(to); - to.delete(); + if (file.renameTo(to)) { + to.delete(); + }else { + file.delete(); + } } try { if (file.createNewFile()) { diff --git a/Aria/src/main/java/com/arialyy/aria/util/ErrorHelp.java b/Aria/src/main/java/com/arialyy/aria/util/ErrorHelp.java index 8f53fc75..5f96c59c 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/ErrorHelp.java +++ b/Aria/src/main/java/com/arialyy/aria/util/ErrorHelp.java @@ -16,7 +16,6 @@ package com.arialyy.aria.util; import android.annotation.SuppressLint; -import android.util.Log; import com.arialyy.aria.core.AriaManager; import java.io.File; import java.io.FileWriter; @@ -38,8 +37,7 @@ public class ErrorHelp { * @param ex 异常 */ public static void saveError(String tag, String msg, String ex) { - String message = "\nmsg【" + msg + "】\nException:" + ex; - writeLogToFile(tag, message); + writeLogToFile(tag, String.format("\nmsg【%s】\nException:%s", msg, ex)); } /** @@ -48,10 +46,8 @@ public class ErrorHelp { * @return "/mnt/sdcard/Android/data/{package_name}/files/log/*" */ private static String getLogPath() { - String path = CommonUtil.getAppPath(AriaManager.APP) - + "log/AriaCrash_" - + getData("yyyy-MM-dd_HH:mm:ss") - + ".log"; + String path = String.format("%slog/AriaCrash_%s.log", CommonUtil.getAppPath(AriaManager.APP), + getData("yyyy-MM-dd_HH_mm_ss")); File log = new File(path); if (!log.getParentFile().exists()) { @@ -80,7 +76,11 @@ public class ErrorHelp { stringBuffer.append("\n\n"); PrintWriter writer = null; try { - writer = new PrintWriter(new FileWriter(getLogPath(), true)); + File file = new File(getLogPath()); + if(!file.exists()){ + CommonUtil.createFile(file.getPath()); + } + writer = new PrintWriter(new FileWriter(file.getPath(), true)); writer.append(stringBuffer); writer.flush(); } catch (Exception e) { diff --git a/Aria/src/main/java/com/arialyy/aria/util/FileUtil.java b/Aria/src/main/java/com/arialyy/aria/util/FileUtil.java index 8732e99b..8fc0a22e 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/FileUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/util/FileUtil.java @@ -17,26 +17,43 @@ */ package com.arialyy.aria.util; +import android.app.ActivityManager; +import android.content.Context; +import android.os.Build; +import android.os.Environment; +import android.text.TextUtils; +import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; import java.io.SequenceInputStream; +import java.lang.reflect.Method; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; +import java.util.Scanner; +import java.util.regex.Pattern; /** * 文件操作工具类 */ public class FileUtil { private static final String TAG = "FileUtil"; + private static final Pattern DIR_SEPORATOR = Pattern.compile("/"); + private static final String EXTERNAL_STORAGE_PATH = + Environment.getExternalStorageDirectory().getPath(); /** * 合并文件 @@ -148,4 +165,290 @@ public class FileUtil { e.printStackTrace(); } } + + /** + * 获取SD卡目录列表 + */ + public static List getSDPathList(Context context) { + List paths; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + paths = getVolumeList(context); + if (paths == null || paths.isEmpty()) { + paths = getStorageDirectories(); + } + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { + paths = getVolumeList(context); + } else { + List mounts = readMountsFile(); + List volds = readVoldFile(); + paths = compareMountsWithVold(mounts, volds); + } + return paths; + } + + /** + * getSDPathList + */ + private static List getVolumeList(final Context context) { + List pathList = null; + try { + android.os.storage.StorageManager manager = + (android.os.storage.StorageManager) context.getSystemService(Context.STORAGE_SERVICE); + Method method = manager.getClass().getMethod("getVolumePaths"); + String[] paths = (String[]) method.invoke(manager); + pathList = Arrays.asList(paths); + } catch (Exception e) { + e.printStackTrace(); + } + if (pathList == null || pathList.isEmpty()) { + pathList = new ArrayList<>(); + pathList.add(EXTERNAL_STORAGE_PATH); + } + LinkedHashMap paths = new LinkedHashMap<>(); + for (String path : pathList) { + File root = new File(path); + if (!root.exists() || !root.isDirectory() || !canWrite(path)) { + continue; + } + //去除mount的相同目录 + int key = (root.getTotalSpace() + "-" + root.getUsableSpace()).hashCode(); + String prevPath = paths.get(key); + if (!TextUtils.isEmpty(prevPath) && prevPath.length() < path.length()) { + continue; + } + paths.put(key, path); + } + List list = new ArrayList<>(); + for (Integer key : paths.keySet()) { + list.add(paths.get(key)); + } + return list; + } + + private static boolean canWrite(String dirPath) { + File dir = new File(dirPath); + if (dir.canWrite()) { + return true; + } + boolean canWrite; + File testWriteFile = null; + try { + testWriteFile = new File(dirPath, "tw.txt"); + if (testWriteFile.exists()) { + testWriteFile.delete(); + } + testWriteFile.createNewFile(); + FileWriter writer = new FileWriter(testWriteFile); + writer.write(1); + writer.close(); + canWrite = true; + } catch (Exception e) { + e.printStackTrace(); + canWrite = false; + } finally { + try { + if (testWriteFile != null && testWriteFile.exists()) { + testWriteFile.delete(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + return canWrite; + } + + /** + * Raturns all available SD-Cards in the system (include emulated) Warning: Hack! Based on Android source code of version 4.3 + * (API 18) Because there is no standard way to get it. TODO: Test on future Android versions 4.2+ + * + * @return paths to all available SD-Cards in the system (include emulated) + */ + public static List getStorageDirectories() { + // Final set of paths + final List rv = new ArrayList<>(); + // Primary physical SD-CARD (not emulated) + final String rawExternalStorage = System.getenv("EXTERNAL_STORAGE"); + // All Secondary SD-CARDs (all exclude primary) separated by ":" + final String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE"); + // Primary emulated SD-CARD + final String rawEmulatedStorageTarget = System.getenv("EMULATED_STORAGE_TARGET"); + if (TextUtils.isEmpty(rawEmulatedStorageTarget)) { + // Device has physical external storage; use plain paths. + if (TextUtils.isEmpty(rawExternalStorage)) { + // EXTERNAL_STORAGE undefined; falling back to default. + rv.add("/storage/sdcard0"); + } else { + rv.add(rawExternalStorage); + } + } else { + // Device has emulated storage; external storage paths should have + // userId burned into them. + final String rawUserId; + + //if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + final String path = Environment.getExternalStorageDirectory().getAbsolutePath(); + final String[] folders = DIR_SEPORATOR.split(path); + final String lastFolder = folders[folders.length - 1]; + boolean isDigit = false; + if (!TextUtils.isEmpty(lastFolder) && TextUtils.isDigitsOnly(lastFolder)) { + isDigit = true; + } + rawUserId = isDigit ? lastFolder : ""; + //} else { + // rawUserId = ""; + //} + // /storage/emulated/0[1,2,...] + if (TextUtils.isEmpty(rawUserId)) { + rv.add(rawExternalStorage); + } else { + rv.add(rawEmulatedStorageTarget + File.separator + rawUserId); + } + } + // Add all secondary storages + if (!TextUtils.isEmpty(rawSecondaryStoragesStr)) { + // All Secondary SD-CARDs splited into array + final String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator); + Collections.addAll(rv, rawSecondaryStorages); + } + // checkout SD-CARDs writable + for (int i = rv.size() - 1; i >= 0; i--) { + String path = rv.get(i); + File root = new File(path); + if (!root.exists() || !root.isDirectory() || !canWrite(path)) { + rv.remove(i); + } + } + return rv; + } + + /** + * Scan the /proc/mounts file and look for lines like this: /dev/block/vold/179:1 /mnt/sdcard vfat + * rw,dirsync,nosuid,nodev,noexec ,relatime,uid=1000,gid=1015,fmask=0602,dmask=0602,allow_utime=0020, + * codepage=cp437,iocharset= iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0 When one is found, split it into its + * elements and then pull out the path to the that mount point and add it to the arraylist + */ + private static List readMountsFile() { + // some mount files don't list the default + // path first, so we add it here to + // ensure that it is first in our list + List mounts = new ArrayList<>(); + mounts.add(EXTERNAL_STORAGE_PATH); + try { + Scanner scanner = new Scanner(new File("/proc/mounts")); + while (scanner.hasNext()) { + String line = scanner.nextLine(); + if (line.startsWith("/dev/block/vold/") || line.startsWith("/dev/block//vold/")) {// + String[] lineElements = line.split(" "); + // String partition = lineElements[0]; + String element = lineElements[1]; + // don't add the default mount path + // it's already in the list. + if (!element.equals(EXTERNAL_STORAGE_PATH)) { + mounts.add(element); + } + } + } + scanner.close(); + } catch (Exception e) { + // e.printStackTrace(); + } + return mounts; + } + + private static List readVoldFile() { + // read /etc/vold.conf or /etc/vold.fstab (it depends on version what + // config file is present) + List vold = null; + Scanner scanner = null; + try { + try { + scanner = new Scanner(new File("/system/etc/vold.fstab")); + } catch (FileNotFoundException e1) { + // e1.printStackTrace(); + scanner = new Scanner(new File("/system/etc/vold.conf")); + } + vold = new ArrayList(); + vold.add(EXTERNAL_STORAGE_PATH); + while (scanner.hasNext()) { + String line = scanner.nextLine(); + if (TextUtils.isEmpty(line)) { + continue; + } + line = line.trim(); + if (line.startsWith("dev_mount")) { + String[] lineElements = line.split(" "); + if (lineElements.length < 3) { + continue; + } + String element = lineElements[2]; + if (element.contains(":")) { + element = element.substring(0, element.indexOf(":")); + } + // ignore default path + if (!element.equals(EXTERNAL_STORAGE_PATH)) { + vold.add(element); + } + } else if (line.startsWith("mount_point")) { + String element = line.replaceAll("mount_point", "").trim(); + if (!element.equals(EXTERNAL_STORAGE_PATH)) { + vold.add(element); + } + } + } + } catch (Exception e) { + // e.printStackTrace(); + } + return vold; + } + + private static List compareMountsWithVold(List mounts, List volds) { + /* + * 有时候这两个list中的数据并不相同,我们只需要取两个list的交集部分。 + */ + for (int i = mounts.size() - 1; i >= 0; i--) { + String mount = mounts.get(i); + File root = new File(mount); + // 判断目录是否存在并且可读 + if (!root.exists() || !root.isDirectory() || !root.canWrite()) { + mounts.remove(i); + continue; + } + if (volds != null && !volds.contains(mount)) { + mounts.remove(i); + } + } + // 清除无用数据 + if (volds != null) { + volds.clear(); + } + return mounts; + } + + public static long getTotalMemory() { + String file_path = "/proc/meminfo";// 系统内存信息文件 + String ram_info; + String[] arrayOfRam; + long initial_memory = 0L; + try { + FileReader fr = new FileReader(file_path); + BufferedReader localBufferedReader = new BufferedReader(fr, 8192); + // 读取meminfo第一行,系统总内存大小 + ram_info = localBufferedReader.readLine(); + arrayOfRam = ram_info.split("\\s+");// 实现多个空格切割的效果 + initial_memory = + Integer.valueOf(arrayOfRam[1]) * 1024;// 获得系统总内存,单位是KB,乘以1024转换为Byte + localBufferedReader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return initial_memory; + } + + public static long getAvailMemory(Context context) { + ActivityManager activityManager = + (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); + activityManager.getMemoryInfo(memoryInfo); + return memoryInfo.availMem; + } } diff --git a/Aria/src/main/java/com/arialyy/aria/util/SSLContextUtil.java b/Aria/src/main/java/com/arialyy/aria/util/SSLContextUtil.java index df832458..b6a9427d 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/SSLContextUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/util/SSLContextUtil.java @@ -17,6 +17,8 @@ package com.arialyy.aria.util; import android.text.TextUtils; import com.arialyy.aria.core.AriaManager; +import com.arialyy.aria.core.common.ProtocolType; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.security.KeyManagementException; @@ -29,6 +31,8 @@ import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.util.Map; +import java.util.WeakHashMap; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; @@ -42,30 +46,68 @@ import javax.net.ssl.X509TrustManager; * SSL证书工具 */ public class SSLContextUtil { + private static final String TAG = "SSLContextUtil"; + private static Map SSL_CACHE = new WeakHashMap<>(); - public static String CA_PATH, CA_ALIAS; + /** + * 从assets目录下加载证书 + * + * @param caAlias CA证书别名 + * @param caPath 保存在assets目录下的CA证书完整路径 + * @param protocol 连接协议 + */ + public static SSLContext getSSLContextFromAssets(String caAlias, String caPath, + @ProtocolType String protocol) { + if (TextUtils.isEmpty(caAlias) || TextUtils.isEmpty(caPath)){ + return null; + } + try { + String cacheKey = getCacheKey(caAlias, caPath); + SSLContext sslContext = SSL_CACHE.get(cacheKey); + if (sslContext != null) { + return sslContext; + } + InputStream caInput = AriaManager.APP.getAssets().open(caPath); + Certificate ca = loadCert(caInput); + return createContext(caAlias, ca, protocol, cacheKey); + } catch (IOException | CertificateException e) { + e.printStackTrace(); + } + return null; + } /** * 颁发服务器证书的 CA 未知 * * @param caAlias CA证书别名 - * @param caPath 保存在assets目录下的CA证书完整路径 + * @param caPath CA证书路径 + * @param protocol 连接协议 */ - public static SSLContext getSSLContext(String caAlias, String caPath) { + public static SSLContext getSSLContext(String caAlias, String caPath, + @ProtocolType String protocol) { if (TextUtils.isEmpty(caAlias) || TextUtils.isEmpty(caPath)) { return null; } - // Load CAs from an InputStream - // (could be from a resource or ByteArrayInputStream or ...) - CertificateFactory cf = null; try { - cf = CertificateFactory.getInstance("X.509"); - InputStream caInput = AriaManager.APP.getAssets().open(caPath); - Certificate ca; - ca = cf.generateCertificate(caInput); - System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN()); + String cacheKey = getCacheKey(caAlias, caPath); + SSLContext sslContext = SSL_CACHE.get(cacheKey); + if (sslContext != null) { + return sslContext; + } + Certificate ca = loadCert(new FileInputStream(caPath)); + return createContext(caAlias, ca, protocol, cacheKey); + } catch (CertificateException | IOException e) { + e.printStackTrace(); + } + return null; + } - // Create a KeyStore containing our trusted CAs + /** + * @param cacheKey 别名 + 证书路径,然后取md5 + */ + private static SSLContext createContext(String caAlias, Certificate ca, + @ProtocolType String protocol, String cacheKey) { + try { String keyStoreType = KeyStore.getDefaultType(); KeyStore keyStore = KeyStore.getInstance(keyStoreType); keyStore.load(null, null); @@ -80,8 +122,10 @@ public class SSLContextUtil { kmf.init(keyStore, null); // Create an SSLContext that uses our TrustManager - SSLContext context = SSLContext.getInstance("TLS"); + SSLContext context = + SSLContext.getInstance(TextUtils.isEmpty(protocol) ? ProtocolType.Default : protocol); context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom()); + SSL_CACHE.put(cacheKey, context); return context; } catch (CertificateException | NoSuchAlgorithmException | IOException | KeyStoreException | KeyManagementException | UnrecoverableKeyException e) { e.printStackTrace(); @@ -89,13 +133,32 @@ public class SSLContextUtil { return null; } + private static String getCacheKey(String alias, String path) { + return CommonUtil.getStrMd5(String.format("%s_%s", alias, path)); + } + + /** + * 加载CA证书 + * + * @param is CA证书文件流 + * @throws CertificateException + */ + private static Certificate loadCert(InputStream is) throws CertificateException, IOException { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + Certificate ca = cf.generateCertificate(is); + ALog.d(TAG, String.format("ca【%s】", ((X509Certificate) ca).getSubjectDN())); + is.close(); + return ca; + } + /** * 服务器证书不是由 CA 签署的,而是自签署时,获取默认的SSL */ - public static SSLContext getDefaultSLLContext() { + public static SSLContext getDefaultSLLContext(@ProtocolType String protocol) { SSLContext sslContext = null; try { - sslContext = SSLContext.getInstance("TLS"); + sslContext = + SSLContext.getInstance(TextUtils.isEmpty(protocol) ? ProtocolType.Default : protocol); sslContext.init(null, new TrustManager[] { trustManagers }, new SecureRandom()); } catch (Exception e) { e.printStackTrace(); diff --git a/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java b/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java index 7c40bf24..08a1cc02 100644 --- a/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java +++ b/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java @@ -21,7 +21,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Created by Aria.Lao on 2017/6/6. + * Created by lyy on 2017/6/6. * Aria下载事件被注解的方法中,参数仅能有一个,参数类型为{@link com.arialyy.aria.core.download.DownloadTask} *

  *   
diff --git a/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java b/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java
index bb26d4f1..b36529d6 100644
--- a/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java
+++ b/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java
@@ -21,7 +21,7 @@ import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
 /**
- * Created by Aria.Lao on 2017/6/6.
+ * Created by lyy on 2017/6/6.
  * Aria下载事件被注解的方法中,参数仅能有一个,参数类型为{@link com.arialyy.aria.core.download.DownloadGroupTask}
  * 
  *   
diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/CountFiler.java b/AriaCompiler/src/main/java/com/arialyy/compiler/CountFiler.java
index 7a6ed484..3783e222 100644
--- a/AriaCompiler/src/main/java/com/arialyy/compiler/CountFiler.java
+++ b/AriaCompiler/src/main/java/com/arialyy/compiler/CountFiler.java
@@ -35,7 +35,7 @@ import javax.lang.model.element.Modifier;
  * Created by lyy on 2017/9/6.
  * 各类注解统计技术类
  */
-final class CountFiler {
+@Deprecated final class CountFiler {
   private Filer mFiler;
   private ParamObtainUtil mPbUtil;
 
diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandler.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandler.java
index e497fe65..9d92dd12 100644
--- a/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandler.java
+++ b/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandler.java
@@ -142,7 +142,7 @@ class ElementHandler {
   void createProxyFile() {
     try {
       new EventProxyFiler(mFiler, mPbUtil).createEventProxyFile();
-      new CountFiler(mFiler, mPbUtil).createCountFile();
+      //new CountFiler(mFiler, mPbUtil).createCountFile();
     } catch (IOException e) {
       e.printStackTrace();
     }
diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/EventProxyFiler.java b/AriaCompiler/src/main/java/com/arialyy/compiler/EventProxyFiler.java
index 440b4bcc..bf48b248 100644
--- a/AriaCompiler/src/main/java/com/arialyy/compiler/EventProxyFiler.java
+++ b/AriaCompiler/src/main/java/com/arialyy/compiler/EventProxyFiler.java
@@ -16,6 +16,7 @@
 package com.arialyy.compiler;
 
 import com.arialyy.annotations.Download;
+import com.arialyy.annotations.DownloadGroup;
 import com.arialyy.annotations.Upload;
 import com.squareup.javapoet.ClassName;
 import com.squareup.javapoet.CodeBlock;
@@ -91,33 +92,54 @@ final class EventProxyFiler {
    *
    * @param taskEnum 任务类型枚举{@link TaskEnum}
    * @param annotation {@link Download}、{@link Upload}
-   * @param methodName 被代理类注解的方法名
+   * @param methodInfo 被代理类注解的方法信息
    */
   private MethodSpec createProxyMethod(TaskEnum taskEnum, Class annotation,
-      String methodName) {
+      MethodInfo methodInfo) {
     ClassName task = ClassName.get(taskEnum.getPkg(), taskEnum.getClassName());
 
     ParameterSpec taskParam =
         ParameterSpec.builder(task, "task").addModifiers(Modifier.FINAL).build();
 
     String callCode;
+
     if (taskEnum == TaskEnum.DOWNLOAD_GROUP_SUB) {
-      callCode = "task, subEntity";
+      if (methodInfo.params.get(methodInfo.params.size() - 1)
+          .asType()
+          .toString()
+          .equals(Exception.class.getName())
+          && annotation == DownloadGroup.onSubTaskFail.class) {
+        callCode = "task, subEntity, e";
+      } else {
+        callCode = "task, subEntity";
+      }
     } else {
-      callCode = "task";
+      if (methodInfo.params.get(methodInfo.params.size() - 1)
+          .asType()
+          .toString()
+          .equals(Exception.class.getName())
+          && (annotation == Download.onTaskFail.class
+          || annotation == Upload.onTaskFail.class
+          || annotation == DownloadGroup.onTaskFail.class)) {
+        callCode = "task, e";
+      } else {
+        callCode = "task";
+      }
     }
     StringBuilder sb = new StringBuilder();
-    sb.append("Set keys = keyMapping.get(\"").append(methodName).append("\");\n");
+    sb.append("Set keys = keyMapping.get(\"")
+        .append(methodInfo.methodName)
+        .append("\");\n");
     sb.append("if (keys != null) {\n\tif (keys.contains(task.getKey())) {\n")
         .append("\t\tobj.")
-        .append(methodName)
+        .append(methodInfo.methodName)
         .append("((")
         .append(taskEnum.getClassName())
         .append(")")
         .append(callCode)
         .append(");\n\t}\n} else {\n")
         .append("\tobj.")
-        .append(methodName)
+        .append(methodInfo.methodName)
         .append("((")
         .append(taskEnum.getClassName())
         .append(")")
@@ -133,12 +155,22 @@ final class EventProxyFiler {
 
     //任务组接口
     if (taskEnum == TaskEnum.DOWNLOAD_GROUP_SUB) {
-      ClassName subTask = ClassName.get(TaskEnum.DOWNLOAD_ENTITY.pkg, TaskEnum.DOWNLOAD_ENTITY.className);
+      ClassName subTask =
+          ClassName.get(TaskEnum.DOWNLOAD_ENTITY.pkg, TaskEnum.DOWNLOAD_ENTITY.className);
       ParameterSpec subTaskParam =
           ParameterSpec.builder(subTask, "subEntity").addModifiers(Modifier.FINAL).build();
 
       builder.addParameter(subTaskParam);
     }
+
+    if (annotation == Download.onTaskFail.class
+        || annotation == Upload.onTaskFail.class
+        || annotation == DownloadGroup.onTaskFail.class
+        || annotation == DownloadGroup.onSubTaskFail.class) {
+      ParameterSpec exception = ParameterSpec.builder(Exception.class, "e").build();
+      builder.addParameter(exception);
+    }
+
     return builder.build();
   }
 
@@ -161,12 +193,22 @@ final class EventProxyFiler {
         "keyMapping").addModifiers(Modifier.PRIVATE).initializer("new $T()", HashMap.class).build();
     builder.addField(mappingField);
 
+    //Set type = new HashSet<>();
     //添加注解方法
     for (TaskEnum te : entity.methods.keySet()) {
-      Map, String> temp = entity.methods.get(te);
-      if (temp != null) {
-        for (Class annotation : temp.keySet()) {
-          MethodSpec method = createProxyMethod(te, annotation, temp.get(annotation));
+      Map, MethodInfo> methodInfoMap = entity.methods.get(te);
+      //if (entity.proxyClassName.contains(TaskEnum.DOWNLOAD.proxySuffix)) {
+      //  type.add(1);
+      //} else if (entity.proxyClassName.contains(TaskEnum.DOWNLOAD_GROUP.proxySuffix)) {
+      //  type.add(2);
+      //} else if (entity.proxyClassName.contains(TaskEnum.UPLOAD.proxySuffix)) {
+      //  type.add(3);
+      //} else if (entity.proxyClassName.contains(TaskEnum.UPLOAD_GROUP.proxySuffix)) {
+      //  type.add(4);
+      //}
+      if (methodInfoMap != null) {
+        for (Class annotation : methodInfoMap.keySet()) {
+          MethodSpec method = createProxyMethod(te, annotation, methodInfoMap.get(annotation));
           builder.addMethod(method);
         }
       }
@@ -189,6 +231,24 @@ final class EventProxyFiler {
       sb.append("keyMapping.put(\"").append(methodName).append("\", ").append("set);\n");
       cb.add(sb.toString(), ClassName.get(HashSet.class));
     }
+    //注册当前类
+    //for (Integer i : type) {
+    //  String str = null;
+    //  switch (i) {
+    //    case 1:
+    //    case 2:
+    //      str = "$T.download(obj).register();\n";
+    //      break;
+    //    case 3:
+    //    case 4:
+    //      str = "$T.upload(obj).register();\n";
+    //      break;
+    //  }
+    //  if (str != null) {
+    //    cb.add(str, ClassName.get("com.arialyy.aria.core", "Aria"));
+    //  }
+    //}
+
     MethodSpec structure =
         MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC).addCode(cb.build()).build();
     builder.addMethod(structure);
diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/MethodInfo.java b/AriaCompiler/src/main/java/com/arialyy/compiler/MethodInfo.java
new file mode 100644
index 00000000..13867491
--- /dev/null
+++ b/AriaCompiler/src/main/java/com/arialyy/compiler/MethodInfo.java
@@ -0,0 +1,27 @@
+/*
+ * 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.compiler;
+
+import java.util.List;
+import javax.lang.model.element.VariableElement;
+
+/**
+ * 方法信息
+ */
+final class MethodInfo {
+  String methodName;
+  List params;
+}
diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ParamObtainUtil.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ParamObtainUtil.java
index 128b361a..422eb8e2 100644
--- a/AriaCompiler/src/main/java/com/arialyy/compiler/ParamObtainUtil.java
+++ b/AriaCompiler/src/main/java/com/arialyy/compiler/ParamObtainUtil.java
@@ -15,6 +15,9 @@
  */
 package com.arialyy.compiler;
 
+import com.arialyy.annotations.Download;
+import com.arialyy.annotations.DownloadGroup;
+import com.arialyy.annotations.Upload;
 import java.lang.annotation.Annotation;
 import java.util.Collections;
 import java.util.HashMap;
@@ -33,7 +36,7 @@ import javax.lang.model.element.VariableElement;
 import javax.lang.model.util.Elements;
 
 /**
- * Created by Aria.Lao on 2017/9/6.
+ * Created by lyy on 2017/9/6.
  * 构建代理文件的参数获取工具
  */
 class ParamObtainUtil {
@@ -70,11 +73,15 @@ class ParamObtainUtil {
         ExecutableElement method = (ExecutableElement) element;
         TypeElement classElement = (TypeElement) method.getEnclosingElement();
         PackageElement packageElement = mElementUtil.getPackageOf(classElement);
-        checkDownloadMethod(taskEnum, method);
+
         String methodName = method.getSimpleName().toString();
         String className = method.getEnclosingElement().toString(); //全类名\
         String key = className + taskEnum.proxySuffix;
         ProxyClassParam proxyEntity = mMethodParams.get(key);
+        MethodInfo methodInfo = new MethodInfo();
+        methodInfo.methodName = methodName;
+        methodInfo.params = (List) method.getParameters();
+        checkMethod(taskEnum, method, annotationClazz, methodInfo.params);
 
         if (proxyEntity == null) {
           proxyEntity = new ProxyClassParam();
@@ -90,9 +97,10 @@ class ParamObtainUtil {
         }
         proxyEntity.taskEnums.add(taskEnum);
         if (proxyEntity.methods.get(taskEnum) == null) {
-          proxyEntity.methods.put(taskEnum, new HashMap, String>());
+          proxyEntity.methods.put(taskEnum, new HashMap, MethodInfo>());
         }
-        proxyEntity.methods.get(taskEnum).put(annotationClazz, methodName);
+
+        proxyEntity.methods.get(taskEnum).put(annotationClazz, methodInfo);
         proxyEntity.keyMappings.put(methodName, getValues(taskEnum, method, annotationType));
       }
     }
@@ -144,52 +152,71 @@ class ParamObtainUtil {
   /**
    * 检查和下载相关的方法,如果被注解的方法为private或参数不合法,则抛异常
    */
-  private void checkDownloadMethod(TaskEnum taskEnum, ExecutableElement method) {
+  private void checkMethod(TaskEnum taskEnum, ExecutableElement method,
+      Class annotationClazz, List params) {
     String methodName = method.getSimpleName().toString();
     String className = method.getEnclosingElement().toString();
     Set modifiers = method.getModifiers();
     if (modifiers.contains(Modifier.PRIVATE)) {
-      throw new IllegalAccessError(className + "." + methodName + "不能为private方法");
+      throw new IllegalAccessError(String.format("%s.%s, 不能为private方法", className, methodName));
     }
-    List params = (List) method.getParameters();
     if (taskEnum == TaskEnum.DOWNLOAD_GROUP_SUB) {
-      if (params.size() != 2) {
-        throw new IllegalArgumentException(className
-            + "."
-            + methodName
-            + "参数错误, 参数只有两个,且第一个参数必须是"
-            + getCheckParams(taskEnum)
-            + ",第二个参数必须是"
-            + getCheckSubParams(taskEnum));
+      if (isFailAnnotation(annotationClazz)) {
+        if (params.size() != 3 && params.size() != 2) {
+          throw new IllegalArgumentException(
+              String.format("%s.%s参数错误, 参数只能是两个或三个,第一个参数是:%s,第二个参数是:%s,第三个参数(可选)是:%s", className,
+                  methodName,
+                  getCheckParams(taskEnum), getCheckSubParams(taskEnum),
+                  Exception.class.getSimpleName()));
+        }
+      } else {
+        if (params.size() != 2) {
+          throw new IllegalArgumentException(
+              String.format("%s.%s参数错误, 参数只能是两个,第一个参数是:%s,第二个参数是:%s", className, methodName,
+                  getCheckParams(taskEnum), getCheckSubParams(taskEnum)));
+        }
       }
     } else {
-      if (params.size() != 1) {
-        throw new IllegalArgumentException(
-            className + "." + methodName + "参数错误, 参数只能有一个,且参数必须是" + getCheckParams(taskEnum));
+      if (isFailAnnotation(annotationClazz)) {
+        if (params.size() != 1 && params.size() != 2) {
+          throw new IllegalArgumentException(
+              String.format("%s.%s参数错误, 参数只能有一个或两个,第一个参数是:%s,第二个参(可选)数是:%s", className, methodName,
+                  getCheckParams(taskEnum), Exception.class.getSimpleName()));
+        }
+      } else {
+        if (params.size() != 1) {
+          throw new IllegalArgumentException(
+              String.format("%s.%s参数错误, 参数只能有一个,且参数必须是:%s", className, methodName,
+                  getCheckParams(taskEnum)));
+        }
       }
     }
     if (!params.get(0).asType().toString().equals(getCheckParams(taskEnum))) {
-      throw new IllegalArgumentException(className
-          + "."
-          + methodName
-          + "参数【"
-          + params.get(0).getSimpleName()
-          + "】类型错误,参数必须是"
-          + getCheckParams(taskEnum));
+      throw new IllegalArgumentException(
+          String.format("%s.%s参数【%s】类型错误,参数必须是:%s", className, methodName,
+              params.get(0).getSimpleName(), getCheckParams(taskEnum)));
     }
     if (taskEnum == TaskEnum.DOWNLOAD_GROUP_SUB) {
       if (!params.get(1).asType().toString().equals(getCheckSubParams(taskEnum))) {
-        throw new IllegalArgumentException(className
-            + "."
-            + methodName
-            + "参数【"
-            + params.get(0).getSimpleName()
-            + "】类型错误,参数必须是"
-            + getCheckSubParams(taskEnum));
+        throw new IllegalArgumentException(
+            String.format("%s.%s参数【%s】类型错误,参数必须是:%s", className, methodName,
+                params.get(0).getSimpleName(), getCheckSubParams(taskEnum)));
       }
     }
   }
 
+  /**
+   * 判断是否是任务失败的回调注解
+   *
+   * @return {@code true}是任务失败的回调注解
+   */
+  private boolean isFailAnnotation(Class annotationClazz) {
+    return annotationClazz == Download.onTaskFail.class
+        || annotationClazz == DownloadGroup.onTaskFail.class
+        || annotationClazz == DownloadGroup.onSubTaskFail.class
+        || annotationClazz == Upload.onTaskFail.class;
+  }
+
   /**
    * 字符串数组转set
    *
diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/PrintLog.java b/AriaCompiler/src/main/java/com/arialyy/compiler/PrintLog.java
index 2ad5d754..3720ce6b 100644
--- a/AriaCompiler/src/main/java/com/arialyy/compiler/PrintLog.java
+++ b/AriaCompiler/src/main/java/com/arialyy/compiler/PrintLog.java
@@ -20,7 +20,7 @@ import javax.lang.model.element.Element;
 import javax.tools.Diagnostic;
 
 /**
- * Created by Aria.Lao on 2017/6/6.
+ * Created by lyy on 2017/6/6.
  */
 class PrintLog {
 
diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyClassParam.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyClassParam.java
index ddfaaeaf..b5f3f244 100644
--- a/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyClassParam.java
+++ b/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyClassParam.java
@@ -21,7 +21,7 @@ import java.util.Map;
 import java.util.Set;
 
 /**
- * Created by Aria.Lao on 2017/6/7.
+ * Created by lyy on 2017/6/7.
  * 代理类参数
  */
 class ProxyClassParam {
@@ -48,5 +48,5 @@ class ProxyClassParam {
 
   Set taskEnums;
   Map> keyMappings = new HashMap<>();
-  Map, String>> methods = new HashMap<>();
+  Map, MethodInfo>> methods = new HashMap<>();
 }
diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/TaskEnum.java b/AriaCompiler/src/main/java/com/arialyy/compiler/TaskEnum.java
index ee0fb4c8..d5a65feb 100644
--- a/AriaCompiler/src/main/java/com/arialyy/compiler/TaskEnum.java
+++ b/AriaCompiler/src/main/java/com/arialyy/compiler/TaskEnum.java
@@ -16,7 +16,7 @@
 package com.arialyy.compiler;
 
 /**
- * Created by Aria.Lao on 2017/7/10.
+ * Created by lyy on 2017/7/10.
  * 任务类型枚举
  */
 enum TaskEnum {
diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/DatagramSocketClient.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/DatagramSocketClient.java
similarity index 99%
rename from AriaFtpPlug/src/main/java/org/apache/commons/net/DatagramSocketClient.java
rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/DatagramSocketClient.java
index 38e49fcc..2ddf9be4 100644
--- a/AriaFtpPlug/src/main/java/org/apache/commons/net/DatagramSocketClient.java
+++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/DatagramSocketClient.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.commons.net;
+package aria.apache.commons.net;
 
 import java.net.DatagramSocket;
 import java.net.InetAddress;
@@ -33,7 +33,7 @@ import java.nio.charset.Charset;
  * especially useful for adding things like proxy support as well as better
  * support for applets.  For
  * example, you could create a
- * {@link org.apache.commons.net.DatagramSocketFactory}
+ * {@link DatagramSocketFactory}
  *  that
  * requests browser security capabilities before creating a socket.
  * All classes derived from DatagramSocketClient should use the
diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/DatagramSocketFactory.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/DatagramSocketFactory.java
similarity index 98%
rename from AriaFtpPlug/src/main/java/org/apache/commons/net/DatagramSocketFactory.java
rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/DatagramSocketFactory.java
index e2013155..385cceb4 100644
--- a/AriaFtpPlug/src/main/java/org/apache/commons/net/DatagramSocketFactory.java
+++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/DatagramSocketFactory.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.commons.net;
+package aria.apache.commons.net;
 
 import java.net.DatagramSocket;
 import java.net.InetAddress;
diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/DefaultDatagramSocketFactory.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/DefaultDatagramSocketFactory.java
similarity index 98%
rename from AriaFtpPlug/src/main/java/org/apache/commons/net/DefaultDatagramSocketFactory.java
rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/DefaultDatagramSocketFactory.java
index 8ba558b8..e269124d 100644
--- a/AriaFtpPlug/src/main/java/org/apache/commons/net/DefaultDatagramSocketFactory.java
+++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/DefaultDatagramSocketFactory.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.commons.net;
+package aria.apache.commons.net;
 
 import java.net.DatagramSocket;
 import java.net.InetAddress;
diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/DefaultSocketFactory.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/DefaultSocketFactory.java
similarity index 99%
rename from AriaFtpPlug/src/main/java/org/apache/commons/net/DefaultSocketFactory.java
rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/DefaultSocketFactory.java
index d5d0faa9..1fec9085 100644
--- a/AriaFtpPlug/src/main/java/org/apache/commons/net/DefaultSocketFactory.java
+++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/DefaultSocketFactory.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.commons.net;
+package aria.apache.commons.net;
 
 import java.io.IOException;
 import java.net.InetAddress;
diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/MalformedServerReplyException.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/MalformedServerReplyException.java
similarity index 98%
rename from AriaFtpPlug/src/main/java/org/apache/commons/net/MalformedServerReplyException.java
rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/MalformedServerReplyException.java
index fe0fa919..c63818fc 100644
--- a/AriaFtpPlug/src/main/java/org/apache/commons/net/MalformedServerReplyException.java
+++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/MalformedServerReplyException.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.commons.net;
+package aria.apache.commons.net;
 
 import java.io.IOException;
 
diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/PrintCommandListener.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/PrintCommandListener.java
similarity index 99%
rename from AriaFtpPlug/src/main/java/org/apache/commons/net/PrintCommandListener.java
rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/PrintCommandListener.java
index 9ef813db..14f92c78 100644
--- a/AriaFtpPlug/src/main/java/org/apache/commons/net/PrintCommandListener.java
+++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/PrintCommandListener.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.commons.net;
+package aria.apache.commons.net;
 
 import java.io.PrintStream;
 import java.io.PrintWriter;
diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ProtocolCommandEvent.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ProtocolCommandEvent.java
similarity index 98%
rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ProtocolCommandEvent.java
rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ProtocolCommandEvent.java
index 4c2f094f..9f0154e7 100644
--- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ProtocolCommandEvent.java
+++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ProtocolCommandEvent.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.commons.net;
+package aria.apache.commons.net;
 
 import java.util.EventObject;
 
@@ -25,7 +25,7 @@ import java.util.EventObject;
  * ASCII text reply.  For debugging and other purposes, it is extremely
  * useful to log or keep track of the contents of the protocol messages.
  * The ProtocolCommandEvent class coupled with the
- * {@link org.apache.commons.net.ProtocolCommandListener}
+ * {@link ProtocolCommandListener}
  *  interface facilitate this process.
  *
  *
diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ProtocolCommandListener.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ProtocolCommandListener.java
similarity index 95%
rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ProtocolCommandListener.java
rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ProtocolCommandListener.java
index e9bf74ef..12f8e00e 100644
--- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ProtocolCommandListener.java
+++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ProtocolCommandListener.java
@@ -15,8 +15,9 @@
  * limitations under the License.
  */
 
-package org.apache.commons.net;
+package aria.apache.commons.net;
 
+import aria.apache.commons.net.ftp.FTPClient;
 import java.util.EventListener;
 
 /***
@@ -30,7 +31,7 @@ import java.util.EventListener;
  * To receive ProtocolCommandEvents, you merely implement the
  * ProtocolCommandListener interface and register the class as a listener
  * with a ProtocolCommandEvent source such as
- * {@link org.apache.commons.net.ftp.FTPClient}.
+ * {@link FTPClient}.
  *
  *
  * @see ProtocolCommandEvent
diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ProtocolCommandSupport.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ProtocolCommandSupport.java
similarity index 93%
rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ProtocolCommandSupport.java
rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ProtocolCommandSupport.java
index c420259f..01b1888e 100644
--- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ProtocolCommandSupport.java
+++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ProtocolCommandSupport.java
@@ -15,12 +15,12 @@
  * limitations under the License.
  */
 
-package org.apache.commons.net;
+package aria.apache.commons.net;
 
 import java.io.Serializable;
 import java.util.EventListener;
 
-import org.apache.commons.net.util.ListenerList;
+import aria.apache.commons.net.util.ListenerList;
 
 /***
  * ProtocolCommandSupport is a convenience class for managing a list of
@@ -53,7 +53,7 @@ public class ProtocolCommandSupport implements Serializable {
   /***
    * Fires a ProtocolCommandEvent signalling the sending of a command to all
    * registered listeners, invoking their
-   * {@link org.apache.commons.net.ProtocolCommandListener#protocolCommandSent protocolCommandSent() }
+   * {@link ProtocolCommandListener#protocolCommandSent protocolCommandSent() }
    *  methods.
    *
    * @param command The string representation of the command type sent, not
@@ -74,7 +74,7 @@ public class ProtocolCommandSupport implements Serializable {
   /***
    * Fires a ProtocolCommandEvent signalling the reception of a command reply
    * to all registered listeners, invoking their
-   * {@link org.apache.commons.net.ProtocolCommandListener#protocolReplyReceived protocolReplyReceived() }
+   * {@link ProtocolCommandListener#protocolReplyReceived protocolReplyReceived() }
    *  methods.
    *
    * @param replyCode The integer code indicating the natureof the reply.
diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/SocketClient.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/SocketClient.java
similarity index 99%
rename from AriaFtpPlug/src/main/java/org/apache/commons/net/SocketClient.java
rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/SocketClient.java
index bd472916..0ac183a7 100644
--- a/AriaFtpPlug/src/main/java/org/apache/commons/net/SocketClient.java
+++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/SocketClient.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.commons.net;
+package aria.apache.commons.net;
 
 import java.io.Closeable;
 import java.io.IOException;
@@ -119,7 +119,7 @@ public abstract class SocketClient {
    * _socket_ to null, _timeout_ to 0, _defaultPort to 0,
    * _isConnected_ to false, charset to {@code Charset.defaultCharset()}
    * and _socketFactory_ to a shared instance of
-   * {@link org.apache.commons.net.DefaultSocketFactory}.
+   * {@link DefaultSocketFactory}.
    */
   public SocketClient() {
     _socket_ = null;
diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/Configurable.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/Configurable.java
similarity index 97%
rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/Configurable.java
rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/Configurable.java
index dd8767ee..b0361f80 100644
--- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/Configurable.java
+++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/Configurable.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.commons.net.ftp;
+package aria.apache.commons.net.ftp;
 
 /**
  * This interface adds the aspect of configurability by means of
diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTP.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTP.java
similarity index 97%
rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTP.java
rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTP.java
index de9c840f..12a99b15 100644
--- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTP.java
+++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTP.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.commons.net.ftp;
+package aria.apache.commons.net.ftp;
 
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
@@ -30,21 +30,21 @@ import java.net.SocketException;
 import java.net.SocketTimeoutException;
 import java.util.ArrayList;
 
-import org.apache.commons.net.MalformedServerReplyException;
-import org.apache.commons.net.ProtocolCommandSupport;
-import org.apache.commons.net.SocketClient;
-import org.apache.commons.net.io.CRLFLineReader;
+import aria.apache.commons.net.MalformedServerReplyException;
+import aria.apache.commons.net.ProtocolCommandSupport;
+import aria.apache.commons.net.SocketClient;
+import aria.apache.commons.net.io.CRLFLineReader;
 
 /***
  * FTP provides the basic the functionality necessary to implement your
- * own FTP client.  It extends org.apache.commons.net.SocketClient since
+ * own FTP client.  It extends SocketClient since
  * extending TelnetClient was causing unwanted behavior (like connections
  * that did not time out properly).
  * 

* To derive the full benefits of the FTP class requires some knowledge * of the FTP protocol defined in RFC 959. However, there is no reason * why you should have to use the FTP class. The - * {@link org.apache.commons.net.ftp.FTPClient} class, + * {@link FTPClient} class, * derived from FTP, * implements all the functionality required of an FTP client. The * FTP class is made public to provide access to various FTP constants @@ -57,16 +57,16 @@ import org.apache.commons.net.io.CRLFLineReader; * close a connection if the client has been idle for longer than a * given time period (usually 900 seconds). The FTP class will detect a * premature FTP server connection closing when it receives a - * {@link org.apache.commons.net.ftp.FTPReply#SERVICE_NOT_AVAILABLE FTPReply.SERVICE_NOT_AVAILABLE } + * {@link FTPReply#SERVICE_NOT_AVAILABLE FTPReply.SERVICE_NOT_AVAILABLE } * response to a command. * When that occurs, the FTP class method encountering that reply will throw - * an {@link org.apache.commons.net.ftp.FTPConnectionClosedException} + * an {@link FTPConnectionClosedException} * . FTPConectionClosedException * is a subclass of IOException and therefore need not be * caught separately, but if you are going to catch it separately, its * catch block must appear before the more general IOException * catch block. When you encounter an - * {@link org.apache.commons.net.ftp.FTPConnectionClosedException} + * {@link FTPConnectionClosedException} * , you must disconnect the connection with * {@link #disconnect disconnect() } to properly clean up the * system resources used by FTP. Before disconnecting, you may check the @@ -80,7 +80,7 @@ import org.apache.commons.net.io.CRLFLineReader; * Rather than list it separately for each method, we mention here that * every method communicating with the server and throwing an IOException * can also throw a - * {@link org.apache.commons.net.MalformedServerReplyException} + * {@link MalformedServerReplyException} * , which is a subclass * of IOException. A MalformedServerReplyException will be thrown when * the reply received from the server deviates enough from the protocol @@ -89,7 +89,7 @@ import org.apache.commons.net.io.CRLFLineReader; * * @see FTPClient * @see FTPConnectionClosedException - * @see org.apache.commons.net.MalformedServerReplyException + * @see MalformedServerReplyException * @version $Id: FTP.java 1782546 2017-02-11 00:05:41Z sebb $ ***/ @@ -1105,7 +1105,7 @@ public class FTP extends SocketClient { * A convenience method to send the FTP RETR command to the server, * receive the reply, and return the reply code. Remember, it is up * to you to manage the data connection. If you don't need this low - * level of access, use {@link org.apache.commons.net.ftp.FTPClient} + * level of access, use {@link FTPClient} * , which will handle all low level details for you. * * @param pathname The pathname of the file to retrieve. @@ -1126,7 +1126,7 @@ public class FTP extends SocketClient { * A convenience method to send the FTP STOR command to the server, * receive the reply, and return the reply code. Remember, it is up * to you to manage the data connection. If you don't need this low - * level of access, use {@link org.apache.commons.net.ftp.FTPClient} + * level of access, use {@link FTPClient} * , which will handle all low level details for you. * * @param pathname The pathname to use for the file when stored at @@ -1148,7 +1148,7 @@ public class FTP extends SocketClient { * A convenience method to send the FTP STOU command to the server, * receive the reply, and return the reply code. Remember, it is up * to you to manage the data connection. If you don't need this low - * level of access, use {@link org.apache.commons.net.ftp.FTPClient} + * level of access, use {@link FTPClient} * , which will handle all low level details for you. * * @return The reply code received from the server. @@ -1168,7 +1168,7 @@ public class FTP extends SocketClient { * A convenience method to send the FTP STOU command to the server, * receive the reply, and return the reply code. Remember, it is up * to you to manage the data connection. If you don't need this low - * level of access, use {@link org.apache.commons.net.ftp.FTPClient} + * level of access, use {@link FTPClient} * , which will handle all low level details for you. * @param pathname The base pathname to use for the file when stored at * the remote end of the transfer. Some FTP servers @@ -1190,7 +1190,7 @@ public class FTP extends SocketClient { * A convenience method to send the FTP APPE command to the server, * receive the reply, and return the reply code. Remember, it is up * to you to manage the data connection. If you don't need this low - * level of access, use {@link org.apache.commons.net.ftp.FTPClient} + * level of access, use {@link FTPClient} * , which will handle all low level details for you. * * @param pathname The pathname to use for the file when stored at @@ -1418,7 +1418,7 @@ public class FTP extends SocketClient { * A convenience method to send the FTP LIST command to the server, * receive the reply, and return the reply code. Remember, it is up * to you to manage the data connection. If you don't need this low - * level of access, use {@link org.apache.commons.net.ftp.FTPClient} + * level of access, use {@link FTPClient} * , which will handle all low level details for you. * * @return The reply code received from the server. @@ -1438,7 +1438,7 @@ public class FTP extends SocketClient { * A convenience method to send the FTP LIST command to the server, * receive the reply, and return the reply code. Remember, it is up * to you to manage the data connection. If you don't need this low - * level of access, use {@link org.apache.commons.net.ftp.FTPClient} + * level of access, use {@link FTPClient} * , which will handle all low level details for you. * * @param pathname The pathname to list, @@ -1460,7 +1460,7 @@ public class FTP extends SocketClient { * A convenience method to send the FTP MLSD command to the server, * receive the reply, and return the reply code. Remember, it is up * to you to manage the data connection. If you don't need this low - * level of access, use {@link org.apache.commons.net.ftp.FTPClient} + * level of access, use {@link FTPClient} * , which will handle all low level details for you. * * @return The reply code received from the server. @@ -1481,7 +1481,7 @@ public class FTP extends SocketClient { * A convenience method to send the FTP MLSD command to the server, * receive the reply, and return the reply code. Remember, it is up * to you to manage the data connection. If you don't need this low - * level of access, use {@link org.apache.commons.net.ftp.FTPClient} + * level of access, use {@link FTPClient} * , which will handle all low level details for you. * * @param path the path to report on @@ -1504,7 +1504,7 @@ public class FTP extends SocketClient { * A convenience method to send the FTP MLST command to the server, * receive the reply, and return the reply code. Remember, it is up * to you to manage the data connection. If you don't need this low - * level of access, use {@link org.apache.commons.net.ftp.FTPClient} + * level of access, use {@link FTPClient} * , which will handle all low level details for you. * * @return The reply code received from the server. @@ -1525,7 +1525,7 @@ public class FTP extends SocketClient { * A convenience method to send the FTP MLST command to the server, * receive the reply, and return the reply code. Remember, it is up * to you to manage the data connection. If you don't need this low - * level of access, use {@link org.apache.commons.net.ftp.FTPClient} + * level of access, use {@link FTPClient} * , which will handle all low level details for you. * * @param path the path to report on @@ -1548,7 +1548,7 @@ public class FTP extends SocketClient { * A convenience method to send the FTP NLST command to the server, * receive the reply, and return the reply code. Remember, it is up * to you to manage the data connection. If you don't need this low - * level of access, use {@link org.apache.commons.net.ftp.FTPClient} + * level of access, use {@link FTPClient} * , which will handle all low level details for you. * * @return The reply code received from the server. @@ -1568,7 +1568,7 @@ public class FTP extends SocketClient { * A convenience method to send the FTP NLST command to the server, * receive the reply, and return the reply code. Remember, it is up * to you to manage the data connection. If you don't need this low - * level of access, use {@link org.apache.commons.net.ftp.FTPClient} + * level of access, use {@link FTPClient} * , which will handle all low level details for you. * * @param pathname The pathname to list, diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPClient.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPClient.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPClient.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPClient.java index 862bea2f..4bcf98dc 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPClient.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPClient.java @@ -14,8 +14,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.net.ftp; - +package aria.apache.commons.net.ftp; + +import aria.apache.commons.net.SocketClient; +import aria.apache.commons.net.ftp.parser.ParserInitializationException; +import aria.apache.commons.net.io.CopyStreamAdapter; +import aria.apache.commons.net.io.CopyStreamEvent; +import aria.apache.commons.net.io.CopyStreamException; +import aria.apache.commons.net.io.CopyStreamListener; +import aria.apache.commons.net.io.FromNetASCIIInputStream; +import aria.apache.commons.net.io.SocketInputStream; +import aria.apache.commons.net.io.SocketOutputStream; +import aria.apache.commons.net.io.ToNetASCIIOutputStream; +import aria.apache.commons.net.io.Util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; @@ -42,28 +53,22 @@ import java.util.Properties; import java.util.Random; import java.util.Set; -import org.apache.commons.net.MalformedServerReplyException; -import org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory; -import org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory; -import org.apache.commons.net.ftp.parser.MLSxEntryParser; -import org.apache.commons.net.io.CRLFLineReader; -import org.apache.commons.net.io.CopyStreamAdapter; -import org.apache.commons.net.io.CopyStreamEvent; -import org.apache.commons.net.io.CopyStreamListener; -import org.apache.commons.net.io.FromNetASCIIInputStream; -import org.apache.commons.net.io.ToNetASCIIOutputStream; -import org.apache.commons.net.io.Util; +import aria.apache.commons.net.MalformedServerReplyException; +import aria.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory; +import aria.apache.commons.net.ftp.parser.FTPFileEntryParserFactory; +import aria.apache.commons.net.ftp.parser.MLSxEntryParser; +import aria.apache.commons.net.io.CRLFLineReader; /** * FTPClient encapsulates all the functionality necessary to store and * retrieve files from an FTP server. This class takes care of all * low level details of interacting with an FTP server and provides * a convenient higher level interface. As with all classes derived - * from {@link org.apache.commons.net.SocketClient}, + * from {@link SocketClient}, * you must first connect to the server with - * {@link org.apache.commons.net.SocketClient#connect connect } + * {@link SocketClient#connect connect } * before doing anything, and finally - * {@link org.apache.commons.net.SocketClient#disconnect disconnect } + * {@link SocketClient#disconnect disconnect } * after you're completely finished interacting with the server. * Then you need to check the FTP reply code to see if the connection * was successful. For example: @@ -162,14 +167,14 @@ import org.apache.commons.net.io.Util; * {@link FTPReply#SERVICE_NOT_AVAILABLE FTPReply.SERVICE_NOT_AVAILABLE } * response to a command. * When that occurs, the FTP class method encountering that reply will throw - * an {@link org.apache.commons.net.ftp.FTPConnectionClosedException} + * an {@link FTPConnectionClosedException} * . * FTPConnectionClosedException * is a subclass of IOException and therefore need not be * caught separately, but if you are going to catch it separately, its * catch block must appear before the more general IOException * catch block. When you encounter an - * {@link org.apache.commons.net.ftp.FTPConnectionClosedException} + * {@link FTPConnectionClosedException} * , you must disconnect the connection with * {@link #disconnect disconnect() } to properly clean up the * system resources used by FTPClient. Before disconnecting, you may check the @@ -184,7 +189,7 @@ import org.apache.commons.net.io.Util; * Rather than list it separately for each method, we mention here that * every method communicating with the server and throwing an IOException * can also throw a - * {@link org.apache.commons.net.MalformedServerReplyException} + * {@link MalformedServerReplyException} * , which is a subclass * of IOException. A MalformedServerReplyException will be thrown when * the reply received from the server deviates enough from the protocol @@ -291,7 +296,7 @@ import org.apache.commons.net.io.Util; * @see FTPFileEntryParserFactory * @see DefaultFTPFileEntryParserFactory * @see FTPClientConfig - * @see org.apache.commons.net.MalformedServerReplyException + * @see MalformedServerReplyException */ public class FTPClient extends FTP implements Configurable { /** @@ -320,7 +325,7 @@ public class FTPClient extends FTP implements Configurable { * For example: *

    * Plan 9=Unix
-   * OS410=org.apache.commons.net.ftp.parser.OS400FTPEntryParser
+   * OS410=OS400FTPEntryParser
    * 
* * @since 3.0 @@ -713,7 +718,7 @@ public class FTPClient extends FTP implements Configurable { } else { output = socket.getOutputStream(); } - return new org.apache.commons.net.io.SocketOutputStream(socket, output); + return new SocketOutputStream(socket, output); } /** @@ -1757,7 +1762,7 @@ public class FTPClient extends FTP implements Configurable { * of the client being idle or some other reason causing the server * to send FTP reply code 421. This exception may be caught either * as an IOException or independently as itself. - * @throws org.apache.commons.net.io.CopyStreamException If an I/O error occurs while actually + * @throws CopyStreamException If an I/O error occurs while actually * transferring the file. The CopyStreamException allows you to * determine the number of bytes transferred and the IOException * causing the error. This exception may be caught either @@ -1874,7 +1879,7 @@ public class FTPClient extends FTP implements Configurable { } else { input = socket.getInputStream(); } - return new org.apache.commons.net.io.SocketInputStream(socket, input); + return new SocketInputStream(socket, input); } /** @@ -1892,7 +1897,7 @@ public class FTPClient extends FTP implements Configurable { * of the client being idle or some other reason causing the server * to send FTP reply code 421. This exception may be caught either * as an IOException or independently as itself. - * @throws org.apache.commons.net.io.CopyStreamException If an I/O error occurs while actually + * @throws CopyStreamException If an I/O error occurs while actually * transferring the file. The CopyStreamException allows you to * determine the number of bytes transferred and the IOException * causing the error. This exception may be caught either @@ -1965,7 +1970,7 @@ public class FTPClient extends FTP implements Configurable { * of the client being idle or some other reason causing the server * to send FTP reply code 421. This exception may be caught either * as an IOException or independently as itself. - * @throws org.apache.commons.net.io.CopyStreamException If an I/O error occurs while actually + * @throws CopyStreamException If an I/O error occurs while actually * transferring the file. The CopyStreamException allows you to * determine the number of bytes transferred and the IOException * causing the error. This exception may be caught either @@ -2026,7 +2031,7 @@ public class FTPClient extends FTP implements Configurable { * of the client being idle or some other reason causing the server * to send FTP reply code 421. This exception may be caught either * as an IOException or independently as itself. - * @throws org.apache.commons.net.io.CopyStreamException If an I/O error occurs while actually + * @throws CopyStreamException If an I/O error occurs while actually * transferring the file. The CopyStreamException allows you to * determine the number of bytes transferred and the IOException * causing the error. This exception may be caught either @@ -2087,7 +2092,7 @@ public class FTPClient extends FTP implements Configurable { * of the client being idle or some other reason causing the server * to send FTP reply code 421. This exception may be caught either * as an IOException or independently as itself. - * @throws org.apache.commons.net.io.CopyStreamException If an I/O error occurs while actually + * @throws CopyStreamException If an I/O error occurs while actually * transferring the file. The CopyStreamException allows you to * determine the number of bytes transferred and the IOException * causing the error. This exception may be caught either @@ -2826,7 +2831,7 @@ public class FTPClient extends FTP implements Configurable { * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply * from the server. - * @throws org.apache.commons.net.ftp.parser.ParserInitializationException Thrown if the + * @throws ParserInitializationException Thrown if the * parserKey * parameter cannot be * resolved by the selected parser factory. @@ -2834,13 +2839,13 @@ public class FTPClient extends FTP implements Configurable { * happen when parserKey is neither * the fully qualified class name of a class * implementing the interface - * org.apache.commons.net.ftp.FTPFileEntryParser + * FTPFileEntryParser * nor a string containing one of the recognized keys * mapping to such a parser or if class loader * security issues prevent its being loaded. * @see DefaultFTPFileEntryParserFactory * @see FTPFileEntryParserFactory - * @see org.apache.commons.net.ftp.FTPFileEntryParser + * @see FTPFileEntryParser */ public FTPFile[] listFiles(String pathname) throws IOException { FTPListParseEngine engine = initiateListParsing((String) null, pathname); @@ -2875,7 +2880,7 @@ public class FTPClient extends FTP implements Configurable { * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply * from the server. - * @throws org.apache.commons.net.ftp.parser.ParserInitializationException Thrown if the + * @throws ParserInitializationException Thrown if the * parserKey * parameter cannot be * resolved by the selected parser factory. @@ -2883,13 +2888,13 @@ public class FTPClient extends FTP implements Configurable { * happen when parserKey is neither * the fully qualified class name of a class * implementing the interface - * org.apache.commons.net.ftp.FTPFileEntryParser + * FTPFileEntryParser * nor a string containing one of the recognized keys * mapping to such a parser or if class loader * security issues prevent its being loaded. * @see DefaultFTPFileEntryParserFactory * @see FTPFileEntryParserFactory - * @see org.apache.commons.net.ftp.FTPFileEntryParser + * @see FTPFileEntryParser */ public FTPFile[] listFiles() throws IOException { return listFiles((String) null); @@ -2934,7 +2939,7 @@ public class FTPClient extends FTP implements Configurable { * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply * from the server. - * @throws org.apache.commons.net.ftp.parser.ParserInitializationException Thrown if the + * @throws ParserInitializationException Thrown if the * parserKey * parameter cannot be * resolved by the selected parser factory. @@ -2942,13 +2947,13 @@ public class FTPClient extends FTP implements Configurable { * happen when parserKey is neither * the fully qualified class name of a class * implementing the interface - * org.apache.commons.net.ftp.FTPFileEntryParser + * FTPFileEntryParser * nor a string containing one of the recognized keys * mapping to such a parser or if class loader * security issues prevent its being loaded. * @see DefaultFTPFileEntryParserFactory * @see FTPFileEntryParserFactory - * @see org.apache.commons.net.ftp.FTPFileEntryParser + * @see FTPFileEntryParser * @since 3.0 */ public FTPFile[] listDirectories() throws IOException { @@ -2980,7 +2985,7 @@ public class FTPClient extends FTP implements Configurable { * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply * from the server. - * @throws org.apache.commons.net.ftp.parser.ParserInitializationException Thrown if the + * @throws ParserInitializationException Thrown if the * parserKey * parameter cannot be * resolved by the selected parser factory. @@ -2988,13 +2993,13 @@ public class FTPClient extends FTP implements Configurable { * happen when parserKey is neither * the fully qualified class name of a class * implementing the interface - * org.apache.commons.net.ftp.FTPFileEntryParser + * FTPFileEntryParser * nor a string containing one of the recognized keys * mapping to such a parser or if class loader * security issues prevent its being loaded. * @see DefaultFTPFileEntryParserFactory * @see FTPFileEntryParserFactory - * @see org.apache.commons.net.ftp.FTPFileEntryParser + * @see FTPFileEntryParser * @since 3.0 */ public FTPFile[] listDirectories(String parent) throws IOException { @@ -3027,7 +3032,7 @@ public class FTPClient extends FTP implements Configurable { * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. - * @throws org.apache.commons.net.ftp.parser.ParserInitializationException Thrown if the + * @throws ParserInitializationException Thrown if the * autodetect mechanism cannot * resolve the type of system we are connected with. * @see FTPListParseEngine @@ -3079,7 +3084,7 @@ public class FTPClient extends FTP implements Configurable { * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. - * @throws org.apache.commons.net.ftp.parser.ParserInitializationException Thrown if the + * @throws ParserInitializationException Thrown if the * autodetect mechanism cannot * resolve the type of system we are connected with. * @see FTPListParseEngine @@ -3127,7 +3132,7 @@ public class FTPClient extends FTP implements Configurable { * as an IOException or independently as itself. * @throws IOException If an I/O error occurs while either sending a * command to the server or receiving a reply from the server. - * @throws org.apache.commons.net.ftp.parser.ParserInitializationException Thrown if the + * @throws ParserInitializationException Thrown if the * parserKey * parameter cannot be * resolved by the selected parser factory. @@ -3135,7 +3140,7 @@ public class FTPClient extends FTP implements Configurable { * happen when parserKey is neither * the fully qualified class name of a class * implementing the interface - * org.apache.commons.net.ftp.FTPFileEntryParser + * FTPFileEntryParser * nor a string containing one of the recognized keys * mapping to such a parser or if class loader * security issues prevent its being loaded. diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPClientConfig.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPClientConfig.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPClientConfig.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPClientConfig.java index 4d8acf56..abe8902e 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPClientConfig.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPClientConfig.java @@ -15,8 +15,10 @@ * limitations under the License. */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; +import aria.apache.commons.net.ftp.parser.ConfigurableFTPFileEntryParserImpl; +import aria.apache.commons.net.ftp.parser.FTPTimestampParserImpl; import java.text.DateFormatSymbols; import java.util.Collection; import java.util.Locale; @@ -131,8 +133,8 @@ import java.util.TreeMap; * * @see Configurable * @see FTPClient - * @see org.apache.commons.net.ftp.parser.FTPTimestampParserImpl#configure(FTPClientConfig) - * @see org.apache.commons.net.ftp.parser.ConfigurableFTPFileEntryParserImpl + * @see FTPTimestampParserImpl#configure(FTPClientConfig) + * @see ConfigurableFTPFileEntryParserImpl * @since 1.4 */ public class FTPClientConfig { diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPCmd.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPCmd.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPCmd.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPCmd.java index a56fb772..de14835b 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPCmd.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPCmd.java @@ -16,7 +16,7 @@ * */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; /** * @since 3.3 diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPCommand.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPCommand.java similarity index 99% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPCommand.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPCommand.java index dee027f4..3a1aef89 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPCommand.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPCommand.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; /** * FTPCommand stores a set of constants for FTP command codes. To interpret diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPConnectionClosedException.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPConnectionClosedException.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPConnectionClosedException.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPConnectionClosedException.java index 381aa19d..aa95277e 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPConnectionClosedException.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPConnectionClosedException.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; import java.io.IOException; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFile.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFile.java similarity index 99% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFile.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFile.java index 937c704a..5edcc119 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFile.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFile.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; import java.io.Serializable; import java.util.Calendar; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFileEntryParser.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFileEntryParser.java similarity index 99% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFileEntryParser.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFileEntryParser.java index 955c02d7..0c04b265 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFileEntryParser.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFileEntryParser.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; import java.io.BufferedReader; import java.io.IOException; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFileEntryParserImpl.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFileEntryParserImpl.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFileEntryParserImpl.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFileEntryParserImpl.java index 599f7609..5af13643 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFileEntryParserImpl.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFileEntryParserImpl.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; import java.io.BufferedReader; import java.io.IOException; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFileFilter.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFileFilter.java similarity index 96% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFileFilter.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFileFilter.java index 84fd5efc..898ee154 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFileFilter.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFileFilter.java @@ -16,7 +16,7 @@ * */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; /** * Perform filtering on FTPFile entries. diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFileFilters.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFileFilters.java similarity index 97% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFileFilters.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFileFilters.java index 138ebc42..40a59a99 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFileFilters.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFileFilters.java @@ -16,7 +16,7 @@ * */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; /** * Implements some simple FTPFileFilter classes. diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPHTTPClient.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPHTTPClient.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPHTTPClient.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPHTTPClient.java index caa39687..0304e427 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPHTTPClient.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPHTTPClient.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; import java.io.BufferedReader; import java.io.IOException; @@ -30,7 +30,7 @@ import java.net.SocketException; import java.util.ArrayList; import java.util.List; -import org.apache.commons.net.util.Base64; +import aria.apache.commons.net.util.Base64; /** * Experimental attempt at FTP client that tunnels over an HTTP proxy connection. diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPListParseEngine.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPListParseEngine.java similarity index 99% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPListParseEngine.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPListParseEngine.java index 4998a939..51e117e5 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPListParseEngine.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPListParseEngine.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; import java.io.BufferedReader; import java.io.IOException; @@ -27,7 +27,7 @@ import java.util.LinkedList; import java.util.List; import java.util.ListIterator; -import org.apache.commons.net.util.Charsets; +import aria.apache.commons.net.util.Charsets; /** * This class handles the entire process of parsing a listing of diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPReply.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPReply.java similarity index 99% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPReply.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPReply.java index 986d76fd..991cb93d 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPReply.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPReply.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; /*** * FTPReply stores a set of constants for FTP reply codes. To interpret diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSClient.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSClient.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSClient.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSClient.java index 512a5628..7f79e98b 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSClient.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSClient.java @@ -15,8 +15,10 @@ * limitations under the License. */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; +import aria.apache.commons.net.SocketClient; +import aria.apache.commons.net.util.KeyManagerUtils; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; @@ -33,10 +35,10 @@ import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; -import org.apache.commons.net.util.Base64; -import org.apache.commons.net.util.SSLContextUtils; -import org.apache.commons.net.util.SSLSocketUtils; -import org.apache.commons.net.util.TrustManagerUtils; +import aria.apache.commons.net.util.Base64; +import aria.apache.commons.net.util.SSLContextUtils; +import aria.apache.commons.net.util.SSLSocketUtils; +import aria.apache.commons.net.util.TrustManagerUtils; /** * FTP over SSL processing. If desired, the JVM property -Djavax.net.debug=all can be used to @@ -219,7 +221,7 @@ public class FTPSClient extends FTPClient { * rather than reimplementing all of the connect() methods. * * @throws IOException If it throw by _connectAction_. - * @see org.apache.commons.net.SocketClient#_connectAction_() + * @see SocketClient#_connectAction_() */ @Override protected void _connectAction_() throws IOException { // Implicit mode. @@ -324,7 +326,7 @@ public class FTPSClient extends FTPClient { * Set a {@link KeyManager} to use * * @param keyManager The KeyManager implementation to set. - * @see org.apache.commons.net.util.KeyManagerUtils + * @see KeyManagerUtils */ public void setKeyManager(KeyManager keyManager) { this.keyManager = keyManager; @@ -697,7 +699,7 @@ public class FTPSClient extends FTPClient { * the default TrustManager from the JVM will be used. * * @param trustManager The TrustManager implementation to set, may be {@code null} - * @see org.apache.commons.net.util.TrustManagerUtils + * @see TrustManagerUtils */ public void setTrustManager(TrustManager trustManager) { this.trustManager = trustManager; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSCommand.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSCommand.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSCommand.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSCommand.java index 1cbb46f8..5937638b 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSCommand.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSCommand.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; /** * FTPS-specific commands. diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSServerSocketFactory.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSServerSocketFactory.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSServerSocketFactory.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSServerSocketFactory.java index 2ef046e5..168067bc 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSServerSocketFactory.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSServerSocketFactory.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; import java.io.IOException; import java.net.InetAddress; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSSocketFactory.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSSocketFactory.java similarity index 99% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSSocketFactory.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSSocketFactory.java index 2015681e..7bbf818c 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSSocketFactory.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSSocketFactory.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; import java.io.IOException; import java.net.InetAddress; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSTrustManager.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSTrustManager.java similarity index 91% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSTrustManager.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSTrustManager.java index 5a5d7e93..0923ac02 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSTrustManager.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSTrustManager.java @@ -15,8 +15,9 @@ * limitations under the License. */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; +import aria.apache.commons.net.util.TrustManagerUtils; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; @@ -27,7 +28,7 @@ import javax.net.ssl.X509TrustManager; * * @since 2.0 * @deprecated 3.0 use - * {@link org.apache.commons.net.util.TrustManagerUtils#getValidateServerCertificateTrustManager() + * {@link TrustManagerUtils#getValidateServerCertificateTrustManager() * TrustManagerUtils#getValidateServerCertificateTrustManager()} instead */ @Deprecated public class FTPSTrustManager implements X509TrustManager { diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/OnFtpInputStreamListener.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/OnFtpInputStreamListener.java similarity index 92% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/OnFtpInputStreamListener.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/OnFtpInputStreamListener.java index 9966080e..f7adaf6d 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/OnFtpInputStreamListener.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/OnFtpInputStreamListener.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.net.ftp; +package aria.apache.commons.net.ftp; -import org.apache.commons.net.io.CopyStreamListener; +import aria.apache.commons.net.io.CopyStreamListener; /** * Created by AriaL on 2017/9/26. diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/package-info.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/package-info.java similarity index 95% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/package-info.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/package-info.java index 496aba13..f7df7cf0 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/package-info.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/package-info.java @@ -18,4 +18,4 @@ /** * FTP and FTPS support classes */ -package org.apache.commons.net.ftp; \ No newline at end of file +package aria.apache.commons.net.ftp; \ No newline at end of file diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/CompositeFileEntryParser.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/CompositeFileEntryParser.java similarity index 91% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/CompositeFileEntryParser.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/CompositeFileEntryParser.java index a05e7ba7..638f67fb 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/CompositeFileEntryParser.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/CompositeFileEntryParser.java @@ -15,11 +15,11 @@ * limitations under the License. */ -package org.apache.commons.net.ftp.parser; +package aria.apache.commons.net.ftp.parser; -import org.apache.commons.net.ftp.FTPFile; -import org.apache.commons.net.ftp.FTPFileEntryParser; -import org.apache.commons.net.ftp.FTPFileEntryParserImpl; +import aria.apache.commons.net.ftp.FTPFile; +import aria.apache.commons.net.ftp.FTPFileEntryParser; +import aria.apache.commons.net.ftp.FTPFileEntryParserImpl; /** * This implementation allows to pack some FileEntryParsers together diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/ConfigurableFTPFileEntryParserImpl.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/ConfigurableFTPFileEntryParserImpl.java similarity index 96% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/ConfigurableFTPFileEntryParserImpl.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/ConfigurableFTPFileEntryParserImpl.java index 3aebd8a7..1d8988b6 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/ConfigurableFTPFileEntryParserImpl.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/ConfigurableFTPFileEntryParserImpl.java @@ -15,14 +15,13 @@ * limitations under the License. */ -package org.apache.commons.net.ftp.parser; +package aria.apache.commons.net.ftp.parser; +import aria.apache.commons.net.ftp.Configurable; +import aria.apache.commons.net.ftp.FTPClientConfig; import java.text.ParseException; import java.util.Calendar; -import org.apache.commons.net.ftp.Configurable; -import org.apache.commons.net.ftp.FTPClientConfig; - /** *

* This abstract class implements the common timestamp parsing diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactory.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactory.java similarity index 96% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactory.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactory.java index 80888917..cc499c71 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactory.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactory.java @@ -15,23 +15,23 @@ * limitations under the License. */ -package org.apache.commons.net.ftp.parser; +package aria.apache.commons.net.ftp.parser; +import aria.apache.commons.net.ftp.Configurable; +import aria.apache.commons.net.ftp.FTPClient; +import aria.apache.commons.net.ftp.FTPClientConfig; +import aria.apache.commons.net.ftp.FTPFileEntryParser; import java.util.regex.Pattern; -import org.apache.commons.net.ftp.Configurable; -import org.apache.commons.net.ftp.FTPClientConfig; -import org.apache.commons.net.ftp.FTPFileEntryParser; - /** * This is the default implementation of the * FTPFileEntryParserFactory interface. This is the * implementation that will be used by - * org.apache.commons.net.ftp.FTPClient.listFiles() + * FTPClient.listFiles() * if no other implementation has been specified. * - * @see org.apache.commons.net.ftp.FTPClient#listFiles - * @see org.apache.commons.net.ftp.FTPClient#setParserFactory + * @see FTPClient#listFiles + * @see FTPClient#setParserFactory */ public class DefaultFTPFileEntryParserFactory implements FTPFileEntryParserFactory { @@ -104,7 +104,7 @@ public class DefaultFTPFileEntryParserFactory implements FTPFileEntryParserFacto } catch (ClassCastException e) { throw new ParserInitializationException(parserClass.getName() + " does not implement the interface " - + "org.apache.commons.net.ftp.FTPFileEntryParser.", e); + + "FTPFileEntryParser.", e); } catch (Exception e) { throw new ParserInitializationException("Error initializing parser", e); } catch (ExceptionInInitializerError e) { diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParser.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParser.java similarity index 95% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParser.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParser.java index 98ae8aee..ca31583a 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParser.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParser.java @@ -15,12 +15,12 @@ * limitations under the License. */ -package org.apache.commons.net.ftp.parser; +package aria.apache.commons.net.ftp.parser; +import aria.apache.commons.net.ftp.FTPFile; +import aria.apache.commons.net.ftp.FTPFileEntryParser; import java.util.Calendar; -import org.apache.commons.net.ftp.FTPFile; - /** * Parser for the Connect Enterprise Unix FTP Server From Sterling Commerce. * Here is a sample of the sort of output line this parser processes: @@ -32,8 +32,8 @@ import org.apache.commons.net.ftp.FTPFile; * * * @version $Id: EnterpriseUnixFTPEntryParser.java 1741829 2016-05-01 00:24:44Z sebb $ - * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions) - * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory + * @see FTPFileEntryParser FTPFileEntryParser (for usage instructions) + * @see DefaultFTPFileEntryParserFactory */ public class EnterpriseUnixFTPEntryParser extends RegexFTPFileEntryParserImpl { diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/FTPFileEntryParserFactory.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/FTPFileEntryParserFactory.java similarity index 94% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/FTPFileEntryParserFactory.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/FTPFileEntryParserFactory.java index c01cac15..2e3c84e0 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/FTPFileEntryParserFactory.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/FTPFileEntryParserFactory.java @@ -15,10 +15,10 @@ * limitations under the License. */ -package org.apache.commons.net.ftp.parser; +package aria.apache.commons.net.ftp.parser; -import org.apache.commons.net.ftp.FTPClientConfig; -import org.apache.commons.net.ftp.FTPFileEntryParser; +import aria.apache.commons.net.ftp.FTPClientConfig; +import aria.apache.commons.net.ftp.FTPFileEntryParser; /** * The interface describes a factory for creating FTPFileEntryParsers. diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParser.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/FTPTimestampParser.java similarity index 97% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParser.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/FTPTimestampParser.java index 52f48de1..dab122a4 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParser.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/FTPTimestampParser.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.ftp.parser; +package aria.apache.commons.net.ftp.parser; import java.text.ParseException; import java.util.Calendar; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java similarity index 97% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java index b0291dce..e84209ff 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java @@ -15,8 +15,10 @@ * limitations under the License. */ -package org.apache.commons.net.ftp.parser; +package aria.apache.commons.net.ftp.parser; +import aria.apache.commons.net.ftp.Configurable; +import aria.apache.commons.net.ftp.FTPClientConfig; import java.text.DateFormatSymbols; import java.text.ParseException; import java.text.ParsePosition; @@ -25,12 +27,9 @@ import java.util.Calendar; import java.util.Date; import java.util.TimeZone; -import org.apache.commons.net.ftp.Configurable; -import org.apache.commons.net.ftp.FTPClientConfig; - /** * Default implementation of the {@link FTPTimestampParser FTPTimestampParser} - * interface also implements the {@link org.apache.commons.net.ftp.Configurable Configurable} + * interface also implements the {@link Configurable Configurable} * interface to allow the parsing to be configured from the outside. * * @see ConfigurableFTPFileEntryParserImpl @@ -355,7 +354,7 @@ public class FTPTimestampParserImpl implements FTPTimestampParser, Configurable * to parse timestamps. *

  • otherwise use default English month names
  • *

    - * Finally if a {@link org.apache.commons.net.ftp.FTPClientConfig#setServerTimeZoneId(String) + * Finally if a {@link FTPClientConfig#setServerTimeZoneId(String) * serverTimeZoneId} * has been supplied via the config, set that into all date formats that have * been configured. diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/MLSxEntryParser.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/MLSxEntryParser.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/MLSxEntryParser.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/MLSxEntryParser.java index c28b4a3f..b6d11bb8 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/MLSxEntryParser.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/MLSxEntryParser.java @@ -15,8 +15,10 @@ * limitations under the License. */ -package org.apache.commons.net.ftp.parser; +package aria.apache.commons.net.ftp.parser; +import aria.apache.commons.net.ftp.FTPFile; +import aria.apache.commons.net.ftp.FTPFileEntryParserImpl; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Calendar; @@ -26,9 +28,6 @@ import java.util.HashMap; import java.util.Locale; import java.util.TimeZone; -import org.apache.commons.net.ftp.FTPFile; -import org.apache.commons.net.ftp.FTPFileEntryParserImpl; - /** * Parser class for MSLT and MLSD replies. See RFC 3659. *

    diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParser.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/MVSFTPEntryParser.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParser.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/MVSFTPEntryParser.java index ff87813f..85a01925 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParser.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/MVSFTPEntryParser.java @@ -15,20 +15,20 @@ * limitations under the License. */ -package org.apache.commons.net.ftp.parser; +package aria.apache.commons.net.ftp.parser; +import aria.apache.commons.net.ftp.FTPClientConfig; +import aria.apache.commons.net.ftp.FTPFile; +import aria.apache.commons.net.ftp.FTPFileEntryParser; import java.text.ParseException; import java.util.List; -import org.apache.commons.net.ftp.FTPClientConfig; -import org.apache.commons.net.ftp.FTPFile; - /** * Implementation of FTPFileEntryParser and FTPFileListParser for IBM zOS/MVS * Systems. * * @version $Id: MVSFTPEntryParser.java 1752660 2016-07-14 13:25:39Z sebb $ - * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for + * @see FTPFileEntryParser FTPFileEntryParser (for * usage instructions) */ public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl { diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/MacOsPeterFTPEntryParser.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/MacOsPeterFTPEntryParser.java similarity index 96% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/MacOsPeterFTPEntryParser.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/MacOsPeterFTPEntryParser.java index 5752a9b9..2c8414d6 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/MacOsPeterFTPEntryParser.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/MacOsPeterFTPEntryParser.java @@ -15,18 +15,18 @@ * limitations under the License. */ -package org.apache.commons.net.ftp.parser; +package aria.apache.commons.net.ftp.parser; +import aria.apache.commons.net.ftp.FTPClientConfig; +import aria.apache.commons.net.ftp.FTPFile; +import aria.apache.commons.net.ftp.FTPFileEntryParser; import java.text.ParseException; -import org.apache.commons.net.ftp.FTPClientConfig; -import org.apache.commons.net.ftp.FTPFile; - /** * Implementation FTPFileEntryParser and FTPFileListParser for pre MacOS-X Systems. * * @version $Id: MacOsPeterFTPEntryParser.java 1752660 2016-07-14 13:25:39Z sebb $ - * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions) + * @see FTPFileEntryParser FTPFileEntryParser (for usage instructions) * @since 3.1 */ public class diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/NTFTPEntryParser.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/NTFTPEntryParser.java similarity index 93% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/NTFTPEntryParser.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/NTFTPEntryParser.java index 7a45a226..cee2811a 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/NTFTPEntryParser.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/NTFTPEntryParser.java @@ -15,20 +15,20 @@ * limitations under the License. */ -package org.apache.commons.net.ftp.parser; +package aria.apache.commons.net.ftp.parser; +import aria.apache.commons.net.ftp.Configurable; +import aria.apache.commons.net.ftp.FTPClientConfig; +import aria.apache.commons.net.ftp.FTPFile; +import aria.apache.commons.net.ftp.FTPFileEntryParser; import java.text.ParseException; import java.util.regex.Pattern; -import org.apache.commons.net.ftp.Configurable; -import org.apache.commons.net.ftp.FTPClientConfig; -import org.apache.commons.net.ftp.FTPFile; - /** * Implementation of FTPFileEntryParser and FTPFileListParser for NT Systems. * * @version $Id: NTFTPEntryParser.java 1752660 2016-07-14 13:25:39Z sebb $ - * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions) + * @see FTPFileEntryParser FTPFileEntryParser (for usage instructions) */ public class NTFTPEntryParser extends ConfigurableFTPFileEntryParserImpl { diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java similarity index 95% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java index 387755ea..7585ebbe 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java @@ -15,13 +15,13 @@ * limitations under the License. */ -package org.apache.commons.net.ftp.parser; +package aria.apache.commons.net.ftp.parser; +import aria.apache.commons.net.ftp.FTPClientConfig; +import aria.apache.commons.net.ftp.FTPFile; +import aria.apache.commons.net.ftp.FTPFileEntryParser; import java.text.ParseException; -import org.apache.commons.net.ftp.FTPClientConfig; -import org.apache.commons.net.ftp.FTPFile; - /** * Implementation of FTPFileEntryParser and FTPFileListParser for Netware Systems. Note that some of * the proprietary @@ -31,7 +31,7 @@ import org.apache.commons.net.ftp.FTPFile; * for more details. * * @version $Id: NetwareFTPEntryParser.java 1752660 2016-07-14 13:25:39Z sebb $ - * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions) + * @see FTPFileEntryParser FTPFileEntryParser (for usage instructions) * @since 1.5 */ public class NetwareFTPEntryParser extends ConfigurableFTPFileEntryParserImpl { diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParser.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/OS2FTPEntryParser.java similarity index 93% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParser.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/OS2FTPEntryParser.java index 261aa7f6..fc2413e9 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParser.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/OS2FTPEntryParser.java @@ -15,18 +15,18 @@ * limitations under the License. */ -package org.apache.commons.net.ftp.parser; +package aria.apache.commons.net.ftp.parser; +import aria.apache.commons.net.ftp.FTPClientConfig; +import aria.apache.commons.net.ftp.FTPFile; +import aria.apache.commons.net.ftp.FTPFileEntryParser; import java.text.ParseException; -import org.apache.commons.net.ftp.FTPClientConfig; -import org.apache.commons.net.ftp.FTPFile; - /** * Implementation of FTPFileEntryParser and FTPFileListParser for OS2 Systems. * * @version $Id: OS2FTPEntryParser.java 1752660 2016-07-14 13:25:39Z sebb $ - * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions) + * @see FTPFileEntryParser FTPFileEntryParser (for usage instructions) */ public class OS2FTPEntryParser extends ConfigurableFTPFileEntryParserImpl diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/OS400FTPEntryParser.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/OS400FTPEntryParser.java similarity index 99% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/OS400FTPEntryParser.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/OS400FTPEntryParser.java index 306a911d..43198267 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/OS400FTPEntryParser.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/OS400FTPEntryParser.java @@ -15,14 +15,13 @@ * limitations under the License. */ -package org.apache.commons.net.ftp.parser; +package aria.apache.commons.net.ftp.parser; +import aria.apache.commons.net.ftp.FTPClientConfig; +import aria.apache.commons.net.ftp.FTPFile; import java.io.File; import java.text.ParseException; -import org.apache.commons.net.ftp.FTPClientConfig; -import org.apache.commons.net.ftp.FTPFile; - /** * @version $Id: OS400FTPEntryParser.java 1752660 2016-07-14 13:25:39Z sebb $ *

    diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/ParserInitializationException.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/ParserInitializationException.java
    similarity index 97%
    rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/ParserInitializationException.java
    rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/ParserInitializationException.java
    index dacc3468..72576687 100644
    --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/ParserInitializationException.java
    +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/ParserInitializationException.java
    @@ -15,7 +15,7 @@
      * limitations under the License.
      */
     
    -package org.apache.commons.net.ftp.parser;
    +package aria.apache.commons.net.ftp.parser;
     
     /**
      * This class encapsulates all errors that may be thrown by
    diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/RegexFTPFileEntryParserImpl.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/RegexFTPFileEntryParserImpl.java
    similarity index 98%
    rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/RegexFTPFileEntryParserImpl.java
    rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/RegexFTPFileEntryParserImpl.java
    index 035d8349..90100f89 100644
    --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/RegexFTPFileEntryParserImpl.java
    +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/RegexFTPFileEntryParserImpl.java
    @@ -15,15 +15,14 @@
      * limitations under the License.
      */
     
    -package org.apache.commons.net.ftp.parser;
    +package aria.apache.commons.net.ftp.parser;
     
    +import aria.apache.commons.net.ftp.FTPFileEntryParserImpl;
     import java.util.regex.MatchResult;
     import java.util.regex.Matcher;
     import java.util.regex.Pattern;
     import java.util.regex.PatternSyntaxException;
     
    -import org.apache.commons.net.ftp.FTPFileEntryParserImpl;
    -
     /**
      * This abstract class implements both the older FTPFileListParser and
      * newer FTPFileEntryParser interfaces with default functionality.
    diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
    similarity index 97%
    rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
    rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
    index 5a1a49c5..5e35f308 100644
    --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
    +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
    @@ -15,15 +15,15 @@
      * limitations under the License.
      */
     
    -package org.apache.commons.net.ftp.parser;
    +package aria.apache.commons.net.ftp.parser;
     
    +import aria.apache.commons.net.ftp.FTPClientConfig;
    +import aria.apache.commons.net.ftp.FTPFile;
    +import aria.apache.commons.net.ftp.FTPFileEntryParser;
     import java.text.ParseException;
     import java.util.List;
     import java.util.ListIterator;
     
    -import org.apache.commons.net.ftp.FTPClientConfig;
    -import org.apache.commons.net.ftp.FTPFile;
    -
     /**
      * Implementation FTPFileEntryParser and FTPFileListParser for standard
      * Unix Systems.
    @@ -33,7 +33,7 @@ import org.apache.commons.net.ftp.FTPFile;
      * new FTPFileEntryParser interface.
      *
      * @version $Id: UnixFTPEntryParser.java 1781925 2017-02-06 16:43:40Z sebb $
    - * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
    + * @see FTPFileEntryParser FTPFileEntryParser (for usage instructions)
      */
     public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
     
    diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParser.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/VMSFTPEntryParser.java
    similarity index 95%
    rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParser.java
    rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/VMSFTPEntryParser.java
    index 3371371a..b2578cd0 100644
    --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParser.java
    +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/VMSFTPEntryParser.java
    @@ -15,16 +15,17 @@
      * limitations under the License.
      */
     
    -package org.apache.commons.net.ftp.parser;
    +package aria.apache.commons.net.ftp.parser;
     
    +import aria.apache.commons.net.ftp.FTPClientConfig;
    +import aria.apache.commons.net.ftp.FTPFile;
    +import aria.apache.commons.net.ftp.FTPFileEntryParser;
    +import aria.apache.commons.net.ftp.FTPListParseEngine;
     import java.io.BufferedReader;
     import java.io.IOException;
     import java.text.ParseException;
     import java.util.StringTokenizer;
     
    -import org.apache.commons.net.ftp.FTPClientConfig;
    -import org.apache.commons.net.ftp.FTPFile;
    -
     /**
      * Implementation FTPFileEntryParser and FTPFileListParser for VMS Systems.
      * This is a sample of VMS LIST output
    @@ -43,8 +44,8 @@ import org.apache.commons.net.ftp.FTPFile;
      * 

    * * @version $Id: VMSFTPEntryParser.java 1752660 2016-07-14 13:25:39Z sebb $ - * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions) - * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory + * @see FTPFileEntryParser FTPFileEntryParser (for usage instructions) + * @see DefaultFTPFileEntryParserFactory */ public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl { @@ -234,8 +235,8 @@ public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl { * @deprecated (2.2) No other FTPFileEntryParser implementations have this method. */ @Deprecated public FTPFile[] parseFileList(java.io.InputStream listStream) throws IOException { - org.apache.commons.net.ftp.FTPListParseEngine engine = - new org.apache.commons.net.ftp.FTPListParseEngine(this); + FTPListParseEngine engine = + new FTPListParseEngine(this); engine.readServerList(listStream, null); return engine.getFiles(); } diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/VMSVersioningFTPEntryParser.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/VMSVersioningFTPEntryParser.java similarity index 96% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/VMSVersioningFTPEntryParser.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/VMSVersioningFTPEntryParser.java index b8d0d396..948662a7 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/VMSVersioningFTPEntryParser.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/VMSVersioningFTPEntryParser.java @@ -15,8 +15,10 @@ * limitations under the License. */ -package org.apache.commons.net.ftp.parser; +package aria.apache.commons.net.ftp.parser; +import aria.apache.commons.net.ftp.FTPClientConfig; +import aria.apache.commons.net.ftp.FTPFileEntryParser; import java.util.HashMap; import java.util.List; import java.util.ListIterator; @@ -25,8 +27,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; -import org.apache.commons.net.ftp.FTPClientConfig; - /** * Special implementation VMSFTPEntryParser with versioning turned on. * This parser removes all duplicates and only leaves the version with the highest @@ -43,7 +43,7 @@ import org.apache.commons.net.ftp.FTPClientConfig; *

    * * @version $Id: VMSVersioningFTPEntryParser.java 1747119 2016-06-07 02:22:24Z ggregory $ - * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions) + * @see FTPFileEntryParser FTPFileEntryParser (for usage instructions) */ public class VMSVersioningFTPEntryParser extends VMSFTPEntryParser { diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/package-info.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/package-info.java similarity index 95% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/package-info.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/package-info.java index 7dc0ffd5..147da7ad 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/package-info.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/package-info.java @@ -18,4 +18,4 @@ /** * FTP file listing parser classes */ -package org.apache.commons.net.ftp.parser; \ No newline at end of file +package aria.apache.commons.net.ftp.parser; \ No newline at end of file diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/CRLFLineReader.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CRLFLineReader.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/io/CRLFLineReader.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CRLFLineReader.java index d124115a..593214d7 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/CRLFLineReader.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CRLFLineReader.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.io; +package aria.apache.commons.net.io; import java.io.BufferedReader; import java.io.IOException; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/CopyStreamAdapter.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CopyStreamAdapter.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/io/CopyStreamAdapter.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CopyStreamAdapter.java index 81ca9a50..0f67dda9 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/CopyStreamAdapter.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CopyStreamAdapter.java @@ -15,11 +15,11 @@ * limitations under the License. */ -package org.apache.commons.net.io; +package aria.apache.commons.net.io; import java.util.EventListener; -import org.apache.commons.net.util.ListenerList; +import aria.apache.commons.net.util.ListenerList; /** * The CopyStreamAdapter will relay CopyStreamEvents to a list of listeners diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/CopyStreamEvent.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CopyStreamEvent.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/io/CopyStreamEvent.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CopyStreamEvent.java index cd45f083..f44d918e 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/CopyStreamEvent.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CopyStreamEvent.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.io; +package aria.apache.commons.net.io; import java.util.EventObject; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/CopyStreamException.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CopyStreamException.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/io/CopyStreamException.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CopyStreamException.java index f4ad9faf..4314967c 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/CopyStreamException.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CopyStreamException.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.io; +package aria.apache.commons.net.io; import java.io.IOException; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/CopyStreamListener.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CopyStreamListener.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/io/CopyStreamListener.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CopyStreamListener.java index da0da990..14670feb 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/CopyStreamListener.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CopyStreamListener.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.io; +package aria.apache.commons.net.io; import java.util.EventListener; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/DotTerminatedMessageReader.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/DotTerminatedMessageReader.java similarity index 99% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/io/DotTerminatedMessageReader.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/io/DotTerminatedMessageReader.java index 9d703510..e554a359 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/DotTerminatedMessageReader.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/DotTerminatedMessageReader.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.io; +package aria.apache.commons.net.io; import java.io.BufferedReader; import java.io.IOException; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/DotTerminatedMessageWriter.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/DotTerminatedMessageWriter.java similarity index 99% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/io/DotTerminatedMessageWriter.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/io/DotTerminatedMessageWriter.java index 2102dccf..637399bd 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/DotTerminatedMessageWriter.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/DotTerminatedMessageWriter.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.io; +package aria.apache.commons.net.io; import java.io.IOException; import java.io.Writer; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/FromNetASCIIInputStream.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/FromNetASCIIInputStream.java similarity index 99% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/io/FromNetASCIIInputStream.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/io/FromNetASCIIInputStream.java index a65793e8..f8aeeded 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/FromNetASCIIInputStream.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/FromNetASCIIInputStream.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.io; +package aria.apache.commons.net.io; import java.io.IOException; import java.io.InputStream; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/FromNetASCIIOutputStream.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/FromNetASCIIOutputStream.java similarity index 99% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/io/FromNetASCIIOutputStream.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/io/FromNetASCIIOutputStream.java index 160fd17e..85e6112d 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/FromNetASCIIOutputStream.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/FromNetASCIIOutputStream.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.io; +package aria.apache.commons.net.io; import java.io.FilterOutputStream; import java.io.IOException; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/SocketInputStream.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/SocketInputStream.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/io/SocketInputStream.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/io/SocketInputStream.java index 87e27727..531e4029 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/SocketInputStream.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/SocketInputStream.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.io; +package aria.apache.commons.net.io; import java.io.FilterInputStream; import java.io.IOException; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/SocketOutputStream.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/SocketOutputStream.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/io/SocketOutputStream.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/io/SocketOutputStream.java index 77e54755..3393ded7 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/SocketOutputStream.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/SocketOutputStream.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.io; +package aria.apache.commons.net.io; import java.io.FilterOutputStream; import java.io.IOException; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/ToNetASCIIInputStream.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/ToNetASCIIInputStream.java similarity index 99% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/io/ToNetASCIIInputStream.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/io/ToNetASCIIInputStream.java index f51191e5..e7ee8bc5 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/ToNetASCIIInputStream.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/ToNetASCIIInputStream.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.io; +package aria.apache.commons.net.io; import java.io.FilterInputStream; import java.io.IOException; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/ToNetASCIIOutputStream.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/ToNetASCIIOutputStream.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/io/ToNetASCIIOutputStream.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/io/ToNetASCIIOutputStream.java index 08235538..d54a8758 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/ToNetASCIIOutputStream.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/ToNetASCIIOutputStream.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.io; +package aria.apache.commons.net.io; import java.io.FilterOutputStream; import java.io.IOException; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/Util.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/Util.java similarity index 99% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/io/Util.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/io/Util.java index 04fbdb0d..bdf74b76 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/Util.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/Util.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.io; +package aria.apache.commons.net.io; import java.io.Closeable; import java.io.IOException; @@ -92,7 +92,7 @@ public final class Util { byte[] buffer = new byte[bufferSize > 0 ? bufferSize : DEFAULT_COPY_BUFFER_SIZE]; try { - while ((numBytes = source.read(buffer)) != -1) { + while (!Thread.currentThread().isInterrupted() && (numBytes = source.read(buffer)) != -1) { // Technically, some read(byte[]) methods may return 0 and we cannot // accept that as an indication of EOF. diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/package-info.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/package-info.java similarity index 96% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/io/package-info.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/io/package-info.java index 90fd4baa..06207d12 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/io/package-info.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/io/package-info.java @@ -18,4 +18,4 @@ /** * Utility classes for IO support. */ -package org.apache.commons.net.io; \ No newline at end of file +package aria.apache.commons.net.io; \ No newline at end of file diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/Base64.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/Base64.java similarity index 99% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/util/Base64.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/util/Base64.java index 93a7f206..a03150e0 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/Base64.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/Base64.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.util; +package aria.apache.commons.net.util; import java.io.UnsupportedEncodingException; import java.math.BigInteger; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/Charsets.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/Charsets.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/util/Charsets.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/util/Charsets.java index c5968197..5001fcc0 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/Charsets.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/Charsets.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.util; +package aria.apache.commons.net.util; import java.nio.charset.Charset; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/KeyManagerUtils.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/KeyManagerUtils.java similarity index 99% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/util/KeyManagerUtils.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/util/KeyManagerUtils.java index a90f1e59..012493b0 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/KeyManagerUtils.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/KeyManagerUtils.java @@ -16,8 +16,9 @@ * */ -package org.apache.commons.net.util; +package aria.apache.commons.net.util; +import aria.apache.commons.net.io.Util; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -34,8 +35,6 @@ import java.util.Enumeration; import javax.net.ssl.KeyManager; import javax.net.ssl.X509ExtendedKeyManager; -import org.apache.commons.net.io.Util; - /** * General KeyManager utilities *

    diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/ListenerList.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/ListenerList.java similarity index 97% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/util/ListenerList.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/util/ListenerList.java index 72f81597..2ddfa637 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/ListenerList.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/ListenerList.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.net.util; +package aria.apache.commons.net.util; import java.io.Serializable; import java.util.EventListener; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/SSLContextUtils.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/SSLContextUtils.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/util/SSLContextUtils.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/util/SSLContextUtils.java index 469a7037..ddec2139 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/SSLContextUtils.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/SSLContextUtils.java @@ -16,7 +16,7 @@ * */ -package org.apache.commons.net.util; +package aria.apache.commons.net.util; import java.io.IOException; import java.security.GeneralSecurityException; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/SSLSocketUtils.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/SSLSocketUtils.java similarity index 98% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/util/SSLSocketUtils.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/util/SSLSocketUtils.java index ff3f1b62..24f335ed 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/SSLSocketUtils.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/SSLSocketUtils.java @@ -16,7 +16,7 @@ * */ -package org.apache.commons.net.util; +package aria.apache.commons.net.util; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/SubnetUtils.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/SubnetUtils.java similarity index 99% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/util/SubnetUtils.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/util/SubnetUtils.java index 05a35fe6..9dd2e22e 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/SubnetUtils.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/SubnetUtils.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.net.util; +package aria.apache.commons.net.util; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/TrustManagerUtils.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/TrustManagerUtils.java similarity index 93% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/util/TrustManagerUtils.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/util/TrustManagerUtils.java index 35894ced..a609f284 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/TrustManagerUtils.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/TrustManagerUtils.java @@ -15,13 +15,16 @@ * limitations under the License. */ -package org.apache.commons.net.util; +package aria.apache.commons.net.util; import java.security.GeneralSecurityException; import java.security.KeyStore; +import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import javax.net.ssl.KeyManager; +import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; @@ -92,7 +95,7 @@ public final class TrustManagerUtils { * Return the default TrustManager provided by the JVM. *

    * This should be the same as the default used by - * {@link javax.net.ssl.SSLContext#init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], * java.security.SecureRandom) + * {@link javax.net.ssl.SSLContext#init(KeyManager[], javax.net.ssl.TrustManager[], SecureRandom)} * SSLContext#init(KeyManager[], TrustManager[], SecureRandom)} * when the TrustManager parameter is set to {@code null} * diff --git a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/package-info.java b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/package-info.java similarity index 95% rename from AriaFtpPlug/src/main/java/org/apache/commons/net/util/package-info.java rename to AriaFtpPlug/src/main/java/aria/apache/commons/net/util/package-info.java index 5515190e..7b95d75d 100644 --- a/AriaFtpPlug/src/main/java/org/apache/commons/net/util/package-info.java +++ b/AriaFtpPlug/src/main/java/aria/apache/commons/net/util/package-info.java @@ -18,4 +18,4 @@ /** * Utility classes */ -package org.apache.commons.net.util; \ No newline at end of file +package aria.apache.commons.net.util; \ No newline at end of file diff --git a/DEV_LOG.md b/DEV_LOG.md index a5ba12cc..3357ff74 100644 --- a/DEV_LOG.md +++ b/DEV_LOG.md @@ -1,4 +1,73 @@ ## 开发日志 + + v_3.5.2 + - 添加Serializable接口支持 https://github.com/AriaLyy/Aria/issues/320 + - 失败回调增加错误原因 https://github.com/AriaLyy/Aria/issues/310 + ``` + @Download.onTaskFail void taskFail(DownloadTask task, Exception e) { + e.getMessage(); + ... + } + ``` + - fix bug https://github.com/AriaLyy/Aria/issues/322 + - 新增201 重定向支持 https://github.com/AriaLyy/Aria/issues/318 + - 修复使用`useServerFileName(true)`中含有`"`导致的文件后缀名错误问题 + - 优化logcat日志提示 + - 修改下载线程的优先级为`Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);` + - fix bug https://github.com/AriaLyy/Aria/issues/319 + + v_3.5.1 + - 优化`taskExists`方法 + - 添加`post`参数请求支持 + ```java + Aria.download(SingleTaskActivity.this) + .load(DOWNLOAD_URL) + .setFilePath(path) + .asPost() // post请求 + .setParam("key", "value") //传递参数 + //.setParams(Map) // 传递多参数 + .start(); + ``` + - 增加强制设置文件路径的api, https://github.com/AriaLyy/Aria/issues/311 + ``` + Aria.download(SingleTaskActivity.this) + .load(DOWNLOAD_URL) + .setFilePath(path, true) // true表示忽略路径是否被占用 + .start(); + ``` + + v_3.5 + - fix bug https://github.com/AriaLyy/Aria/issues/302 + - fix bug https://github.com/AriaLyy/Aria/issues/283 + - fix bug https://github.com/AriaLyy/Aria/issues/305 + - fix bug https://github.com/AriaLyy/Aria/issues/306 + - fix bug https://github.com/AriaLyy/Aria/issues/272 (现在,停止所有任务,未开始的任务状态将变为停止) + - fix bug https://github.com/AriaLyy/Aria/issues/277 + - fix bug https://github.com/AriaLyy/Aria/issues/303 + - 优化停止任务的速度 + - 修复组合任务修改子任务文件名失败的问题 + + v_3.4.12 + - fix bug https://github.com/AriaLyy/Aria/issues/286 + - 优化线程池任务 + + v_3.4.11 + - fix bug https://github.com/AriaLyy/Aria/issues/288 + - fix bug https://github.com/AriaLyy/Aria/issues/282 + + v_3.4.10 + - fix bug https://github.com/AriaLyy/Aria/issues/280 + + v_3.4.9 + - fix bug https://github.com/AriaLyy/Aria/issues/276 + + v_3.4.8 + - 组合任务新增`updateUrls(List)`用于修改组合子任务的url,[see](https://aria.laoyuyu.me/aria_doc/api/update_url.html) + - 出于安全考虑,FTP数据库去掉密码的保存 + - 增加FTPS支持 [see](https://aria.laoyuyu.me/aria_doc/download/ftps.html) + - 增加速度限制支持[see](https://aria.laoyuyu.me/aria_doc/api/speed_handle.html) + - 增加内存空间不足验证 + + v_3.4.7 + - 修复分块任务异常操作导致的问题 + + v_3.4.6 + - 修复android 4.4.4 版本多dex下无法进行回调的问题 + - 新增`updateUrl(newUrl)`用于修改任务的url,[see](https://aria.laoyuyu.me/aria_doc/api/task_handle.html#%E6%9B%B4%E6%96%B0%E4%BB%BB%E5%8A%A1url) + - 优化分块下载 + - 修复了字符串中有特殊字符导致的路径冲突问题;修复ftp分块下载失败问题 + - 修复连接中有`+`导致的地址呗使用问题。 + - 修复表重复创建导致的崩溃问题 https://github.com/AriaLyy/Aria/issues/264 + v_3.4.4 - 实现[多线程分块下载](https://aria.laoyuyu.me/aria_doc/start/config.html) - 修复`stopAll()`和`resumeAll()`导致的进度为0问题 diff --git a/README.md b/README.md index 4099c6a9..6a4e9f26 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Aria有以下特点: - 支持HTTP任务组\FTP文件夹,断点续传下载 - 支持HTTP表单上传 - 支持文件FTP断点续传上传 + - 支持FTPS/SFTP断点续传,[see](https://aria.laoyuyu.me/aria_doc/download/ftps.html) + 支持https地址下载 - 在配置文件中很容易就可以设置CA证书的信息 + 支持[多线程分块下载](https://aria.laoyuyu.me/aria_doc/start/config.html),能更有效的发挥机器IO性能 @@ -31,8 +32,8 @@ Aria有以下特点: [![Download](https://api.bintray.com/packages/arialyy/maven/AriaApi/images/download.svg)](https://bintray.com/arialyy/maven/AriaApi/_latestVersion) [![Download](https://api.bintray.com/packages/arialyy/maven/AriaCompiler/images/download.svg)](https://bintray.com/arialyy/maven/AriaCompiler/_latestVersion) ```java -compile 'com.arialyy.aria:aria-core:3.4.4' -annotationProcessor 'com.arialyy.aria:aria-compiler:3.4.4' +compile 'com.arialyy.aria:aria-core:3.5.1' +annotationProcessor 'com.arialyy.aria:aria-compiler:3.5.1' ``` 如果出现android support,请将 `compile 'com.arialyy.aria:aria-core:'`替换为 ``` @@ -100,10 +101,25 @@ protected void onCreate(Bundle savedInstanceState) { ### 版本日志 - + v_3.4.4 - - 实现[多线程分块下载](https://aria.laoyuyu.me/aria_doc/start/config.html) - - 修复`stopAll()`和`resumeAll()`导致的进度为0问题 - - 修复任务组添加header无效的问题 ++ v_3.5.1 + - 优化`taskExists`方法 + - 添加`post`参数请求支持 + ```java + Aria.download(SingleTaskActivity.this) + .load(DOWNLOAD_URL) + .setFilePath(path) + .asPost() // post请求 + .setParam("key", "value") //传递参数 + //.setParams(Map) // 传递多参数 + .start(); + ``` + - 增加强制设置文件路径的api, https://github.com/AriaLyy/Aria/issues/311 + ``` + Aria.download(SingleTaskActivity.this) + .load(DOWNLOAD_URL) + .setFilePath(path, true) // true表示忽略路径是否被占用 + .start(); + ``` [更多版本记录](https://github.com/AriaLyy/Aria/blob/master/DEV_LOG.md) diff --git a/app/build.gradle b/app/build.gradle index 3f35f8e5..d0b770e4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,6 @@ apply plugin: 'com.android.application' -//apply plugin: 'kotlin-android' -//apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' //apply plugin: 'kotlin-kapt' android { @@ -51,7 +51,7 @@ dependencies { compile 'com.arialyy.frame:MVVM2:2.2.0' compile project(':Aria') compile project(':AriaCompiler') - // compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" + compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" // compile 'com.arialyy.aria:aria-core:3.3.16' // annotationProcessor 'com.arialyy.aria:aria-compiler:3.3.16' debugCompile 'com.amitshekhar.android:debug-db:1.0.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index adab4328..3015fdb8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,5 +1,6 @@ @@ -12,13 +13,13 @@ android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" - android:theme="@style/AppTheme.NoActionBar"> - - + android:theme="@style/AppTheme.NoActionBar" + tools:ignore="GoogleAppIndexingWarning"> + + - @@ -28,18 +29,17 @@ - + - + - diff --git a/app/src/main/assets/aria_config.xml b/app/src/main/assets/aria_config.xml index 55c155be..4e5da29d 100644 --- a/app/src/main/assets/aria_config.xml +++ b/app/src/main/assets/aria_config.xml @@ -11,6 +11,10 @@ + + + + - + - + - + @@ -66,7 +70,8 @@ - + + diff --git a/app/src/main/java/com/arialyy/simple/MainActivity.java b/app/src/main/java/com/arialyy/simple/MainActivity.java index 52291d32..aa8f7d8c 100644 --- a/app/src/main/java/com/arialyy/simple/MainActivity.java +++ b/app/src/main/java/com/arialyy/simple/MainActivity.java @@ -20,6 +20,7 @@ import android.content.Intent; import android.os.Bundle; import android.view.View; import butterknife.OnClick; +import com.arialyy.aria.core.Aria; import com.arialyy.simple.base.BaseActivity; import com.arialyy.simple.databinding.ActivityMainBinding; import com.arialyy.simple.download.DownloadActivity; @@ -30,7 +31,7 @@ import com.arialyy.simple.upload.FtpUploadActivity; import com.arialyy.simple.upload.HttpUploadActivity; /** - * Created by Aria.Lao on 2017/3/1. + * Created by lyy on 2017/3/1. */ public class MainActivity extends BaseActivity { @@ -39,6 +40,7 @@ public class MainActivity extends BaseActivity { setSupportActionBar(mBar); mBar.setTitle("Aria Demo"); getSupportActionBar().setDisplayHomeAsUpEnabled(false); + } @Override protected int setLayoutId() { diff --git a/app/src/main/java/com/arialyy/simple/download/DownloadDialogFragment.java b/app/src/main/java/com/arialyy/simple/download/DownloadDialogFragment.java index 91a091fb..a6be21c8 100644 --- a/app/src/main/java/com/arialyy/simple/download/DownloadDialogFragment.java +++ b/app/src/main/java/com/arialyy/simple/download/DownloadDialogFragment.java @@ -17,7 +17,7 @@ import com.arialyy.simple.base.BaseDialog; import com.arialyy.simple.databinding.DialogFragmentDownloadBinding; /** - * Created by Aria.Lao on 2017/8/8. + * Created by lyy on 2017/8/8. */ @SuppressLint("ValidFragment") public class DownloadDialogFragment extends BaseDialog { diff --git a/app/src/main/java/com/arialyy/simple/download/FtpDownloadActivity.java b/app/src/main/java/com/arialyy/simple/download/FtpDownloadActivity.java index 332183f6..1a13aa42 100644 --- a/app/src/main/java/com/arialyy/simple/download/FtpDownloadActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/FtpDownloadActivity.java @@ -31,7 +31,7 @@ import com.arialyy.simple.databinding.ActivityFtpDownloadBinding; import java.io.File; /** - * Created by Aria.Lao on 2017/7/25. + * Created by lyy on 2017/7/25. * Ftp下载测试 */ public class FtpDownloadActivity extends BaseActivity { diff --git a/app/src/main/java/com/arialyy/simple/download/KotlinDownloadActivity.kt b/app/src/main/java/com/arialyy/simple/download/KotlinDownloadActivity.kt index 8a22289a..ef873639 100644 --- a/app/src/main/java/com/arialyy/simple/download/KotlinDownloadActivity.kt +++ b/app/src/main/java/com/arialyy/simple/download/KotlinDownloadActivity.kt @@ -1,73 +1,75 @@ -package com.arialyy.simple.download - -import android.os.Bundle -import android.os.Environment -import android.support.v7.app.AppCompatActivity -import android.util.Log -import android.view.View -import com.arialyy.annotations.Download -import com.arialyy.aria.core.Aria -import com.arialyy.aria.core.download.DownloadTask -import com.arialyy.simple.R -import com.arialyy.simple.base.BaseActivity - -/** - * Created by Aria.Lao on 2017/10/23. - */ -class KotlinDownloadActivity : AppCompatActivity() { - - private val DOWNLOAD_URL = "http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk" - - private val TAG = "KotlinDownloadActivity"; - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(setLayoutId()) - } - - fun setLayoutId(): Int { - return R.layout.activity_single - } - - fun init(savedInstanceState: Bundle?) { - title = "单任务下载" -// val target = Aria.download(this).load(DOWNLOAD_URL) -// binding.progress = target.getPercent() -// if (target.getTaskState() == IEntity.STATE_STOP) { -// mStart.setText("恢复") -// mStart.setTextColor(resources.getColor(android.R.color.holo_blue_light)) -// setBtState(true) -// } else if (target.isDownloading()) { -// setBtState(false) +//package com.arialyy.simple.download +// +//import android.os.Bundle +//import android.os.Environment +//import android.support.v7.app.AppCompatActivity +//import android.util.Log +//import android.view.View +//import com.arialyy.annotations.Download +//import com.arialyy.aria.core.Aria +//import com.arialyy.aria.core.download.DownloadTask +//import com.arialyy.simple.R +//import com.arialyy.simple.base.BaseActivity +// +///** +// * Created by lyy on 2017/10/23. +// */ +//class KotlinDownloadActivity : AppCompatActivity() { +// +// private val DOWNLOAD_URL = "http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk" +// +// private val TAG = "KotlinDownloadActivity"; +// +// override fun onCreate(savedInstanceState: Bundle?) { +// super.onCreate(savedInstanceState) +// setContentView(setLayoutId()) +// } +// +// fun setLayoutId(): Int { +// return R.layout.activity_single +// } +// +// fun init(savedInstanceState: Bundle?) { +// title = "单任务下载" +//// val target = Aria.download(this).load(DOWNLOAD_URL) +//// binding.progress = target.getPercent() +//// if (target.getTaskState() == IEntity.STATE_STOP) { +//// mStart.setText("恢复") +//// mStart.setTextColor(resources.getColor(android.R.color.holo_blue_light)) +//// setBtState(true) +//// } else if (target.isDownloading()) { +//// setBtState(false) +//// } +//// binding.fileSize = target.getConvertFileSize() +// Aria.get(this).downloadConfig.maxTaskNum = 2 +// Aria.download(this).register() +// } +// +// @Download.onTaskRunning +// protected fun running(task: DownloadTask) { +// Log.d(TAG, task.percent.toString() + "") +//// val len = task.fileSize +//// if (len == 0L) { +//// binding.progress = 0 +//// } else { +//// binding.progress = task.percent +//// } +//// binding.speed = task.convertSpeed +// } +// +// fun onClick(view: View) { +// when (view.id) { +// R.id.start -> startD() +// R.id.stop -> Aria.download(this).load(DOWNLOAD_URL).stop() +// R.id.cancel -> Aria.download(this).load(DOWNLOAD_URL).cancel() // } -// binding.fileSize = target.getConvertFileSize() - Aria.download(this).register() - } - - @Download.onTaskRunning protected fun running(task: DownloadTask) { - Log.d(TAG, task.percent.toString() + "") - val len = task.fileSize -// if (len == 0L) { -// binding.progress = 0 -// } else { -// binding.progress = task.percent -// } -// binding.speed = task.convertSpeed - } - - fun onClick(view: View) { - when (view.id) { - R.id.start -> startD() - R.id.stop -> Aria.download(this).load(DOWNLOAD_URL).stop() - R.id.cancel -> Aria.download(this).load(DOWNLOAD_URL).cancel() - } - } - - private fun startD() { - Aria.download(this) - .load(DOWNLOAD_URL, true) - .addHeader("groupName", "value") - .setDownloadPath(Environment.getExternalStorageDirectory().path + "/hhhhhhhh.apk") - .start() - } -} \ No newline at end of file +// } +// +// private fun startD() { +// Aria.download(this) +// .load(DOWNLOAD_URL) +// .addHeader("groupName", "value") +// .setDownloadPath(Environment.getExternalStorageDirectory().path + "/hhhhhhhh.apk") +// .start() +// } +//} \ No newline at end of file diff --git a/app/src/main/java/com/arialyy/simple/download/SimpleNotification.java b/app/src/main/java/com/arialyy/simple/download/SimpleNotification.java index 23346c15..285e066a 100644 --- a/app/src/main/java/com/arialyy/simple/download/SimpleNotification.java +++ b/app/src/main/java/com/arialyy/simple/download/SimpleNotification.java @@ -26,7 +26,7 @@ //import com.arialyy.simple.R; // ///** -// * Created by Aria.Lao on 2017/1/18. +// * Created by lyy on 2017/1/18. // */ // //public class SimpleNotification { diff --git a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java index 8d5e1477..deb06a53 100644 --- a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java @@ -16,7 +16,9 @@ package com.arialyy.simple.download; +import android.content.ContentResolver; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.util.Log; @@ -33,6 +35,7 @@ import com.arialyy.aria.core.common.RequestEnum; import com.arialyy.aria.core.download.DownloadTarget; import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.core.inf.IEntity; +import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.CommonUtil; import com.arialyy.frame.util.show.L; import com.arialyy.frame.util.show.T; @@ -40,19 +43,25 @@ import com.arialyy.simple.R; import com.arialyy.simple.base.BaseActivity; import com.arialyy.simple.databinding.ActivitySingleBinding; import java.io.File; +import java.util.Map; public class SingleTaskActivity extends BaseActivity { private static final String DOWNLOAD_URL = //"http://kotlinlang.org/docs/kotlin-docs.pdf"; //"https://atom-installer.github.com/v1.13.0/AtomSetup.exe?s=1484074138&ext=.exe"; - //"http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk"; + //"http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apks"; + //"http://120.55.95.61:8811/ghcg/zg/武义总规纲要成果.zip"; + //"https://yizi-kejian.oss-cn-beijing.aliyuncs.com/qimeng/package1/qmtable11.zip"; + //"http://rs.0.gaoshouyou.com/d/04/1e/400423a7551e1f3f0eb1812afa1f9b44.apk"; //"http://58.210.9.131/tpk/sipgt//TDLYZTGH.tpk"; //chunked 下载 //"https://static.donguo.me//video/ip/course/pfys_1.mp4"; //"https://www.baidu.com/link?url=_LFCuTPtnzFxVJByJ504QymRywIA1Z_T5xUxe9ZLuxcGM0C_RcdpWyB1eGjbJC-e5wv5wAKM4WmLMAS5KeF6EZJHB8Va3YqZUiaErqK_pxm&wd=&eqid=e8583fe70002d126000000065a99f864"; //"https://d.pcs.baidu.com/file/a02c89a2d479d4fd2756f3313d42491d?fid=4232431903-250528-1114369760340736&dstime=1525491372&rt=sh&sign=FDtAERVY-DCb740ccc5511e5e8fedcff06b081203-3C13vkOkuk4TqXvVYW05zj1K0ao%3D&expires=8h&chkv=1&chkbd=0&chkpc=et&dp-logid=8651730921842106225&dp-callid=0&r=165533013"; //"http://apk500.bce.baidu-mgame.com/game/67000/67734/20170622040827_oem_5502845.apk?r=1"; - "https://dl.genymotion.com/releases/genymotion-2.12.1/genymotion-2.12.1-vbox.exe"; + //"https://dl.genymotion.com/releases/genymotion-2.12.1/genymotion-2.12.1-vbox.exe"; + //"http://9.9.9.59:5000/download/CentOS-7-x86_64-Minimal-1804.iso"; + "https://firmwareapi.azurewebsites.net/firmware-overview?name=A19_Filament_W_IMG0038_00102411-encrypted.ota"; @Bind(R.id.start) Button mStart; @Bind(R.id.stop) Button mStop; @Bind(R.id.cancel) Button mCancel; @@ -130,6 +139,7 @@ public class SingleTaskActivity extends BaseActivity { } @Download.onTaskRunning protected void running(DownloadTask task) { + ALog.d(TAG, String.format("%s_running_%s", getClass().getName(), hashCode())); if (task.getKey().equals(DOWNLOAD_URL)) { //Log.d(TAG, task.getKey()); long len = task.getFileSize(); @@ -168,10 +178,11 @@ public class SingleTaskActivity extends BaseActivity { } } - @Download.onTaskFail void taskFail(DownloadTask task) { + @Download.onTaskFail void taskFail(DownloadTask task, Exception e) { if (task.getKey().equals(DOWNLOAD_URL)) { Toast.makeText(SingleTaskActivity.this, "下载失败", Toast.LENGTH_SHORT).show(); setBtState(true); + //ALog.d(TAG, ALog.getExceptionString(e)); } } @@ -186,6 +197,11 @@ public class SingleTaskActivity extends BaseActivity { L.d(TAG, "path ==> " + task.getDownloadEntity().getDownloadPath()); L.d(TAG, "md5Code ==> " + CommonUtil.getFileMD5(new File(task.getDownloadPath()))); L.d(TAG, "data ==> " + Aria.download(this).getDownloadEntity(DOWNLOAD_URL)); + Intent install = new Intent(Intent.ACTION_VIEW); + install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + File apkFile = new File(task.getDownloadPath()); + install.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive"); + startActivity(install); } } @@ -220,12 +236,14 @@ public class SingleTaskActivity extends BaseActivity { startD(); break; case R.id.stop: - //Aria.download(this).load(DOWNLOAD_URL).stop(); - startActivity(new Intent(this, SingleTaskActivity.class)); + Aria.download(this).load(DOWNLOAD_URL).stop(); + //startActivity(new Intent(this, SingleTaskActivity.class)); + //Aria.download(this).unRegister(); //Aria.download(this).load(DOWNLOAD_URL).removeRecord(); + //Log.d(TAG, Aria.download(this).taskExists(DOWNLOAD_URL) + ""); break; case R.id.cancel: - Aria.download(this).load(DOWNLOAD_URL).cancel(); + Aria.download(this).load(DOWNLOAD_URL).cancel(true); //Aria.download(this).load(DOWNLOAD_URL).removeRecord(); break; } @@ -234,15 +252,24 @@ public class SingleTaskActivity extends BaseActivity { private void startD() { //Aria.get(this).setLogLevel(ALog.LOG_CLOSE); //Aria.download(this).load("aaaa.apk"); + String path = Environment.getExternalStorageDirectory().getPath() + "/ggsg11.ota"; + //File file = new File(path); + //if (file.exists()){ + // file.delete(); + //} + Aria.download(SingleTaskActivity.this) .load(DOWNLOAD_URL) //.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8") - //.addHeader("Accept-Encoding", "gzip, deflate") + .addHeader("Accept-Encoding", "gzip, deflate") //.addHeader("DNT", "1") //.addHeader("Cookie", "BAIDUID=648E5FF020CC69E8DD6F492D1068AAA9:FG=1; BIDUPSID=648E5FF020CC69E8DD6F492D1068AAA9; PSTM=1519099573; BD_UPN=12314753; locale=zh; BDSVRTM=0") - //.useServerFileName(true) - //.setRequestMode(RequestEnum.GET) - .setFilePath(Environment.getExternalStorageDirectory().getPath() + "/ggsg3.apk") + .useServerFileName(true) + .setFilePath(path, true) + //.asPost().setParam("key", "value") + //.setExtendField("{\n" + // + "\"id\":\"你的样子\"\n< > " + // + "}") //.resetState() .start(); //.add(); diff --git a/app/src/main/java/com/arialyy/simple/download/fragment_download/DownloadFragment.java b/app/src/main/java/com/arialyy/simple/download/fragment_download/DownloadFragment.java index d8ba2fb4..2f27ca33 100644 --- a/app/src/main/java/com/arialyy/simple/download/fragment_download/DownloadFragment.java +++ b/app/src/main/java/com/arialyy/simple/download/fragment_download/DownloadFragment.java @@ -35,7 +35,7 @@ import com.arialyy.simple.databinding.FragmentDownloadBinding; import com.arialyy.simple.widget.HorizontalProgressBarWithNumber; /** - * Created by Aria.Lao on 2017/1/4. + * Created by lyy on 2017/1/4. */ public class DownloadFragment extends AbsFragment { @Bind(R.id.start) Button mStart; diff --git a/app/src/main/java/com/arialyy/simple/download/fragment_download/FragmentActivity.java b/app/src/main/java/com/arialyy/simple/download/fragment_download/FragmentActivity.java index adb2fc96..3d0c1344 100644 --- a/app/src/main/java/com/arialyy/simple/download/fragment_download/FragmentActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/fragment_download/FragmentActivity.java @@ -23,7 +23,7 @@ import com.arialyy.simple.base.BaseActivity; import com.arialyy.simple.databinding.FragmentDownloadBinding; /** - * Created by Aria.Lao on 2017/1/4. + * Created by lyy on 2017/1/4. */ public class FragmentActivity extends BaseActivity { diff --git a/app/src/main/java/com/arialyy/simple/download/group/ChildHandleDialog.java b/app/src/main/java/com/arialyy/simple/download/group/ChildHandleDialog.java index 3de6d4f7..0b013adb 100644 --- a/app/src/main/java/com/arialyy/simple/download/group/ChildHandleDialog.java +++ b/app/src/main/java/com/arialyy/simple/download/group/ChildHandleDialog.java @@ -39,7 +39,7 @@ import com.arialyy.simple.widget.HorizontalProgressBarWithNumber; import java.util.List; /** - * Created by Aria.Lao on 2017/9/5. + * Created by lyy on 2017/9/5. */ @SuppressLint("ValidFragment") public class ChildHandleDialog extends BaseDialog { diff --git a/app/src/main/java/com/arialyy/simple/download/group/DownloadGroupActivity.java b/app/src/main/java/com/arialyy/simple/download/group/DownloadGroupActivity.java index 16fc2b0f..d100451c 100644 --- a/app/src/main/java/com/arialyy/simple/download/group/DownloadGroupActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/group/DownloadGroupActivity.java @@ -22,6 +22,7 @@ import android.view.View; import butterknife.Bind; import com.arialyy.annotations.DownloadGroup; import com.arialyy.aria.core.Aria; +import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadGroupEntity; import com.arialyy.aria.core.download.DownloadGroupTask; import com.arialyy.aria.core.download.DownloadGroupTaskEntity; @@ -31,10 +32,11 @@ import com.arialyy.simple.R; import com.arialyy.simple.base.BaseActivity; import com.arialyy.simple.databinding.ActivityDownloadGroupBinding; import com.arialyy.simple.widget.SubStateLinearLayout; +import java.util.ArrayList; import java.util.List; /** - * Created by Aria.Lao on 2017/7/6. + * Created by lyy on 2017/7/6. */ public class DownloadGroupActivity extends BaseActivity { @@ -79,21 +81,25 @@ public class DownloadGroupActivity extends BaseActivity temp = new ArrayList<>(); + temp.add("https://d.pcs.baidu.com/file/130335545f3f4d9cc38afe709c19af5a?fid=1411168371-250528-1010657263806840&dstime=1531134714&rt=sh&sign=FDtAERVY-DCb740ccc5511e5e8fedcff06b081203-h8KgJ6gl4oY9UR6NqvwJsT4nVSM%3D&expires=8h&chkv=1&chkbd=0&chkpc=et&dp-logid=4401996296756616039&dp-callid=0&r=279987343"); Aria.download(this) .loadGroup(mUrls) .setDirPath( - Environment.getExternalStorageDirectory().getPath() + "/Download/group_test_3") + //Environment.getExternalStorageDirectory().getPath() + "/Download/group_test_5") + Environment.getExternalStorageDirectory().getPath() + "/Download/group_test_1") .setGroupAlias("任务组测试") - //.setSubFileName(getModule(GroupModule.class).getSubName()) - //.setFileSize(32895492) + //.setSubFileName(getModule(GroupModule.class).getSubName2()) + .setSubFileName(getModule(GroupModule.class).getSubName()) + //.updateUrls(temp) .start(); break; case R.id.stop: Aria.download(this).loadGroup(mUrls).stop(); break; case R.id.cancel: - //Aria.download(this).load(mUrls).cancel(true); - Aria.download(this).removeAllTask(true); + Aria.download(this).loadGroup(mUrls).cancel(true); + //Aria.download(this).removeAllTask(true); //mUrls = getModule(GroupModule.class).getUrls1(); //Aria.download(this) // .load(mUrls) @@ -141,6 +147,7 @@ public class DownloadGroupActivity extends BaseActivity { private static final String dir = "ftp://192.168.1.2:21/upload/测试"; diff --git a/app/src/main/java/com/arialyy/simple/download/group/GroupModule.java b/app/src/main/java/com/arialyy/simple/download/group/GroupModule.java index b102585e..ad01a50a 100644 --- a/app/src/main/java/com/arialyy/simple/download/group/GroupModule.java +++ b/app/src/main/java/com/arialyy/simple/download/group/GroupModule.java @@ -23,7 +23,7 @@ import java.util.Collections; import java.util.List; /** - * Created by Aria.Lao on 2017/7/6. + * Created by lyy on 2017/7/6. */ public class GroupModule extends BaseModule { public GroupModule(Context context) { @@ -32,15 +32,16 @@ public class GroupModule extends BaseModule { public List getUrls() { List urls = new ArrayList<>(); - String[] str = getContext().getResources().getStringArray(R.array.group_url4); + String[] str = getContext().getResources().getStringArray(R.array.group_urls_1); Collections.addAll(urls, str); return urls; } List getUrls1() { List urls = new ArrayList<>(); - String[] str = getContext().getResources().getStringArray(R.array.group_urls); - Collections.addAll(urls, str); + //String[] str = getContext().getResources().getStringArray(R.array.group_urls); + //Collections.addAll(urls, str); + urls.add("https://d.pcs.baidu.com/file/130335545f3f4d9cc38afe709c19af5a?fid=1411168371-250528-1010657263806840&dstime=1531134607&rt=sh&sign=FDtAERVY-DCb740ccc5511e5e8fedcff06b081203-sNCujT7lC42aMcfiHcgqAzYHuw4%3D&expires=8h&chkv=1&chkbd=0&chkpc=et&dp-logid=4401967667009194668&dp-callid=0&r=540192514"); return urls; } @@ -50,4 +51,78 @@ public class GroupModule extends BaseModule { Collections.addAll(names, str); return names; } + + List getSubName2() { + List taskSubFile; + taskSubFile = new ArrayList<>(); + //taskSubFile.add("2156.mp4"); + // taskSubFile.add("2115.mp4"); + //taskSubFile.add("2009.mp4"); + //taskSubFile.add("1893.mp4"); + taskSubFile.add("1952.mp4"); + taskSubFile.add("1958.mp4"); + taskSubFile.add("1994.mp4"); + //taskSubFile.add("2083.mp4"); + taskSubFile.add("2305.JPG"); + taskSubFile.add("2183.JPG"); + taskSubFile.add("2154.JPG"); + taskSubFile.add("2153.JPG"); + taskSubFile.add("2152.JPG"); + taskSubFile.add("2151.JPG"); + taskSubFile.add("2149.JPG"); + taskSubFile.add("2148.JPG"); + taskSubFile.add("2147.JPG"); + taskSubFile.add("2146.JPG"); + taskSubFile.add("1949.JPG"); + taskSubFile.add("1887.JPG"); + taskSubFile.add("1996.txt"); + return taskSubFile; + } + + public List getUrls2() { + List downLoadUrls; + downLoadUrls = new ArrayList<>(); + //downLoadUrls.add( + // "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2156&clientId=A000011106034058176"); + // downLoadUrls.add("http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2115&clientId=A000011106034058176"); + //downLoadUrls.add( + // "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2009&clientId=A000011106034058176"); + //downLoadUrls.add( + // "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1893&clientId=A000011106034058176"); + downLoadUrls.add( + "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1952&clientId=A000011106034058176"); + downLoadUrls.add( + "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1958&clientId=A000011106034058176"); + downLoadUrls.add( + "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1994&clientId=A000011106034058176"); + //downLoadUrls.add( + // "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2083&clientId=A000011106034058176"); + downLoadUrls.add( + "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2305&clientId=A000011106034058176"); + downLoadUrls.add( + "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2183&clientId=A000011106034058176"); + downLoadUrls.add( + "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2154&clientId=A000011106034058176"); + downLoadUrls.add( + "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2153&clientId=A000011106034058176"); + downLoadUrls.add( + "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2152&clientId=A000011106034058176"); + downLoadUrls.add( + "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2151&clientId=A000011106034058176"); + downLoadUrls.add( + "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2149&clientId=A000011106034058176"); + downLoadUrls.add( + "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2148&clientId=A000011106034058176"); + downLoadUrls.add( + "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2147&clientId=A000011106034058176"); + downLoadUrls.add( + "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2146&clientId=A000011106034058176"); + downLoadUrls.add( + "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1949&clientId=A000011106034058176"); + downLoadUrls.add( + "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1887&clientId=A000011106034058176"); + downLoadUrls.add( + "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1996&clientId=A000011106034058176"); + return downLoadUrls; + } } diff --git a/app/src/main/java/com/arialyy/simple/download/multi_download/MultiDownloadActivity.java b/app/src/main/java/com/arialyy/simple/download/multi_download/MultiDownloadActivity.java index d3cb6075..583bda82 100644 --- a/app/src/main/java/com/arialyy/simple/download/multi_download/MultiDownloadActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/multi_download/MultiDownloadActivity.java @@ -117,7 +117,7 @@ public class MultiDownloadActivity extends BaseActivity { mAdapter.updateBtState(task.getKey(), false); } + @DownloadGroup.onWait void groupTaskWait(DownloadGroupTask task) { + ALog.d(TAG, String.format("group【%s】wait---", task.getTaskName())); + mAdapter.updateBtState(task.getKey(), true); + } + @DownloadGroup.onTaskStop void groupTaskStop(DownloadGroupTask task) { mAdapter.updateBtState(task.getKey(), true); Log.d(TAG, String.format("group【%s】stop", task.getTaskName())); diff --git a/app/src/main/java/com/arialyy/simple/download/service_download/DownloadNotification.java b/app/src/main/java/com/arialyy/simple/download/service_download/DownloadNotification.java index 4495530f..8ab9469c 100644 --- a/app/src/main/java/com/arialyy/simple/download/service_download/DownloadNotification.java +++ b/app/src/main/java/com/arialyy/simple/download/service_download/DownloadNotification.java @@ -22,7 +22,7 @@ import android.support.v4.app.NotificationCompat; import com.arialyy.simple.R; /** - * Created by Aria.Lao on 2017/1/18. + * Created by lyy on 2017/1/18. */ public class DownloadNotification { diff --git a/app/src/main/java/com/arialyy/simple/download/service_download/DownloadService.java b/app/src/main/java/com/arialyy/simple/download/service_download/DownloadService.java index 4994bfaa..4d32568c 100644 --- a/app/src/main/java/com/arialyy/simple/download/service_download/DownloadService.java +++ b/app/src/main/java/com/arialyy/simple/download/service_download/DownloadService.java @@ -26,7 +26,7 @@ import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.frame.util.show.T; /** - * Created by Aria.Lao on 2017/4/5. + * Created by lyy on 2017/4/5. * 在服务中使用 Aria进行下载 */ public class DownloadService extends Service { diff --git a/app/src/main/java/com/arialyy/simple/test/AnyRunActivity.java b/app/src/main/java/com/arialyy/simple/test/AnyRunActivity.java index fef44ccf..a0f1d547 100644 --- a/app/src/main/java/com/arialyy/simple/test/AnyRunActivity.java +++ b/app/src/main/java/com/arialyy/simple/test/AnyRunActivity.java @@ -27,8 +27,12 @@ public class AnyRunActivity extends BaseActivity { //String URL = "http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk"; //private final String URL = "ftp://192.168.29.140:21/download/AriaPrj.rar"; //String URL = "https://dl.genymotion.com/releases/genymotion-2.12.1/genymotion-2.12.1-vbox.exe"; - String URL = "ftp://192.168.29.140:21/download/SDK_Demo-release.apk"; + //String URL = "ftp://192.168.29.140:21/download/SDK_Demo-release.apk"; + //String URL = "ftps://192.168.29.140:990/download/SDK_Demo-release.apk"; + //String URL = "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1994&clientId=A000011106034058176"; //String URL = "ftp://z:z@dygod18.com:21211/[电影天堂www.dy2018.com]猩球崛起3:终极之战BD国英双语中英双字.mkv"; + //String URL = "https://app-dl.byfen.com//app//201810//ef0400d637e768e9c630b4d38633ee06.zip"; + String URL = "ftps://9.9.9.59:990/download/SDK_Demo-release.apk"; //private String URL = "https://www.bilibili.com/bangumi/play/ep77693"; //private String URL = "http://cn-hbsjz-cmcc-v-03.acgvideo.com/upgcxcode/63/82/5108263/5108263-1-80.flv?expires=1530178500&platform=pc&ssig=vr7gLl0duyqWqSMnIpzaDA&oi=3746029570&nfa=BpfiWF+i4mNW8KzjZFHzBQ==&dynamic=1&hfa=2030547937&hfb=Yjk5ZmZjM2M1YzY4ZjAwYTMzMTIzYmIyNWY4ODJkNWI=&trid=3476be01a9254115b15f8cc7198600fe&nfc=1"; diff --git a/app/src/main/java/com/arialyy/simple/test/AnyRunnModule.java b/app/src/main/java/com/arialyy/simple/test/AnyRunnModule.java index c54fa1eb..86bb4a03 100644 --- a/app/src/main/java/com/arialyy/simple/test/AnyRunnModule.java +++ b/app/src/main/java/com/arialyy/simple/test/AnyRunnModule.java @@ -10,7 +10,6 @@ import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.util.CommonUtil; import com.arialyy.frame.util.show.L; import java.io.File; -import java.net.Proxy; /** * Created by laoyuyu on 2018/4/13. @@ -65,10 +64,9 @@ public class AnyRunnModule { void start(String url) { mUrl = url; - String path = Environment.getExternalStorageDirectory().getPath() + "/aaas.apk"; + String path = Environment.getExternalStorageDirectory().getPath() + "/mmm2.mp4"; Aria.download(this) .load(url) - .setRequestMode(RequestEnum.GET) .setFilePath(path) .resetState() .start(); @@ -79,7 +77,11 @@ public class AnyRunnModule { Aria.download(this) .loadFtp(url) .login("lao", "123456") - .setFilePath(Environment.getExternalStorageDirectory().getPath() + "/") + .setFilePath(Environment.getExternalStorageDirectory().getPath() + "/Download/") + .asFtps() + .setStorePath("/mnt/sdcard/Download/server.crt") + .setAlias("www.laoyuyu.me") + .setStorePass("123456") .start(); } diff --git a/app/src/main/java/com/arialyy/simple/test/TestActivity.java b/app/src/main/java/com/arialyy/simple/test/TestFTPActivity.java similarity index 83% rename from app/src/main/java/com/arialyy/simple/test/TestActivity.java rename to app/src/main/java/com/arialyy/simple/test/TestFTPActivity.java index 4c680de5..fd585c27 100644 --- a/app/src/main/java/com/arialyy/simple/test/TestActivity.java +++ b/app/src/main/java/com/arialyy/simple/test/TestFTPActivity.java @@ -6,6 +6,7 @@ import android.util.Log; import android.view.View; import com.arialyy.annotations.Upload; import com.arialyy.aria.core.Aria; +import com.arialyy.aria.core.common.ProtocolType; import com.arialyy.aria.core.common.RequestEnum; import com.arialyy.aria.core.upload.UploadTask; import com.arialyy.aria.util.ALog; @@ -19,12 +20,12 @@ import java.io.File; * Created by Administrator on 2018/4/12. */ -public class TestActivity extends BaseActivity { - String TAG = "TestActivity"; +public class TestFTPActivity extends BaseActivity { + String TAG = "TestFTPActivity"; //String URL = "http://58.210.9.131/tpk/sipgt//TDLYZTGH.tpk"; //chunked 下载 //private final String URL = "ftp://192.168.1.3:21/download//AriaPrj.rar"; - private final String FILE_PATH = "/mnt/sdcard/AriaPrj.rar"; - private final String URL = "ftp://192.168.1.2:21/aa//你好"; + private final String FILE_PATH = "/mnt/sdcard/mmm.mp4"; + private final String URL = "ftps://9.9.9.59:990/aa/你好"; @Override protected int setLayoutId() { @@ -35,7 +36,7 @@ public class TestActivity extends BaseActivity { super.init(savedInstanceState); mBar.setVisibility(View.GONE); Aria.upload(this).register(); - + Aria.upload(this).setMaxSpeed(128); } @Upload.onWait void onWait(UploadTask task) { @@ -51,7 +52,7 @@ public class TestActivity extends BaseActivity { } @Upload.onTaskRunning protected void running(UploadTask task) { - Log.d(TAG, "running"); + Log.d(TAG, "running,speed=" + task.getConvertSpeed()); } @Upload.onTaskResume void taskResume(UploadTask task) { @@ -81,7 +82,9 @@ public class TestActivity extends BaseActivity { .loadFtp(FILE_PATH) .login("lao", "123456") .setUploadUrl(URL) - .setExtendField("韩寒哈大双") + .asFtps() + .setStorePath("/mnt/sdcard/Download/server.crt") + .setAlias("www.laoyuyu.me") .start(); //Uri uri = Uri.parse("ftp://z:z@dygod18.com:21211/[电影天堂www.dy2018.com]猩球崛起3:终极之战BD国英双语中英双字.mkv"); //ALog.d(TAG, "sh = " + uri.getScheme() + ", user = " + uri.getUserInfo() + ", host = " + uri.getHost() + ", port = " + uri.getPort() + " remotePath = " + uri.getPath()); diff --git a/app/src/main/java/com/arialyy/simple/test/TestGroupActivity.java b/app/src/main/java/com/arialyy/simple/test/TestFTPDirActivity.java similarity index 90% rename from app/src/main/java/com/arialyy/simple/test/TestGroupActivity.java rename to app/src/main/java/com/arialyy/simple/test/TestFTPDirActivity.java index d8856485..74831170 100644 --- a/app/src/main/java/com/arialyy/simple/test/TestGroupActivity.java +++ b/app/src/main/java/com/arialyy/simple/test/TestFTPDirActivity.java @@ -17,9 +17,9 @@ import java.util.List; * Created by Administrator on 2018/4/12. */ -public class TestGroupActivity extends BaseActivity { +public class TestFTPDirActivity extends BaseActivity { List mUrls; - private static final String dir = "ftp://192.168.1.8:21/upload/测试"; + private static final String dir = "ftps://192.168.29.140:990/upload/测试"; @Override protected int setLayoutId() { return R.layout.activity_test; @@ -87,6 +87,10 @@ public class TestGroupActivity extends BaseActivity { .setGroupAlias("ftp文件夹下载") //.setSubTaskFileName(getModule(GroupModule.class).getSubName()) .login("lao", "123456") + .asFtps() + .setStorePath("/mnt/sdcard/Download/server.crt") + .setAlias("www.laoyuyu.me") + .setStorePass("123456") .start(); break; case R.id.stop: diff --git a/app/src/main/java/com/arialyy/simple/upload/FtpUploadActivity.java b/app/src/main/java/com/arialyy/simple/upload/FtpUploadActivity.java index 21f8927c..7a3248e2 100644 --- a/app/src/main/java/com/arialyy/simple/upload/FtpUploadActivity.java +++ b/app/src/main/java/com/arialyy/simple/upload/FtpUploadActivity.java @@ -31,7 +31,7 @@ import com.arialyy.simple.databinding.ActivityFtpUploadBinding; import java.io.File; /** - * Created by Aria.Lao on 2017/7/28. + * Created by lyy on 2017/7/28. * Ftp 文件上传demo */ public class FtpUploadActivity extends BaseActivity { diff --git a/app/src/main/java/com/arialyy/simple/upload/HttpUploadActivity.java b/app/src/main/java/com/arialyy/simple/upload/HttpUploadActivity.java index c0b942c7..048800c9 100644 --- a/app/src/main/java/com/arialyy/simple/upload/HttpUploadActivity.java +++ b/app/src/main/java/com/arialyy/simple/upload/HttpUploadActivity.java @@ -32,7 +32,7 @@ import com.arialyy.simple.widget.HorizontalProgressBarWithNumber; import java.io.File; /** - * Created by Aria.Lao on 2017/2/9. + * Created by lyy on 2017/2/9. */ public class HttpUploadActivity extends BaseActivity { private static final String TAG = "HttpUploadActivity"; @@ -56,7 +56,7 @@ public class HttpUploadActivity extends BaseActivity { "http://lib-test.xzxyun.com:8042/Api/upload?data={\"type\":\"1\",\"fileType\":\".apk\"}") //.setUploadUrl("http://192.168.1.6:8080/upload/sign_file/").setAttachment("file") //.addHeader("iplanetdirectorypro", "11a09102fb934ad0bc206f9c611d7933") - .setRequestMode(RequestEnum.POST) + .asPost() .start(); } diff --git a/app/src/main/java/com/arialyy/simple/widget/SubStateLinearLayout.java b/app/src/main/java/com/arialyy/simple/widget/SubStateLinearLayout.java index 337b873b..ad89fa56 100644 --- a/app/src/main/java/com/arialyy/simple/widget/SubStateLinearLayout.java +++ b/app/src/main/java/com/arialyy/simple/widget/SubStateLinearLayout.java @@ -18,6 +18,7 @@ package com.arialyy.simple.widget; import android.content.Context; import android.support.annotation.Nullable; import android.util.AttributeSet; +import android.util.Log; import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; @@ -31,10 +32,10 @@ import java.util.Map; import java.util.WeakHashMap; /** - * Created by Aria.Lao on 2017/7/17. + * Created by lyy on 2017/7/17. */ public class SubStateLinearLayout extends LinearLayout implements View.OnClickListener { - + private final String TAG = "SubStateLinearLayout"; interface OnShowCallback { void onShow(boolean visibility); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index baaa53cc..d1c46d05 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -60,7 +60,7 @@ http://static.gaoshouyou.com/d/12/0d/7f120f50c80d2e7b8c4ba24ece4f9cdd.apk - http://static.ilongyuan.cn/rayark/RayarkFZ_2.0.7.apk + @@ -85,9 +85,9 @@ - + 王者荣耀.apk 战斗吧剑灵.apk - 天魔幻想.apk + diff --git a/aria/src/main/java/com/arialyy/aria/core/Configuration.java b/aria/src/main/java/com/arialyy/aria/core/Configuration.java index 99ffc7a3..7e518ed5 100644 --- a/aria/src/main/java/com/arialyy/aria/core/Configuration.java +++ b/aria/src/main/java/com/arialyy/aria/core/Configuration.java @@ -17,6 +17,7 @@ package com.arialyy.aria.core; import android.text.TextUtils; import com.arialyy.aria.core.common.QueueMod; +import com.arialyy.aria.core.queue.DownloadGroupTaskQueue; import com.arialyy.aria.core.queue.DownloadTaskQueue; import com.arialyy.aria.core.queue.UploadTaskQueue; import com.arialyy.aria.util.ALog; @@ -33,7 +34,7 @@ import java.util.Properties; * Created by lyy on 2016/12/8. * 信息配置 */ -class Configuration { +public class Configuration { static final String TAG = "Configuration"; static final String DOWNLOAD_CONFIG_FILE = "/Aria/DownloadConfig.properties"; static final String UPLOAD_CONFIG_FILE = "/Aria/UploadConfig.properties"; @@ -247,6 +248,21 @@ class Configuration { */ int iOTimeOut = 20 * 1000; + /** + * 设置最大下载/上传速度,单位:kb, 为0表示不限速 + */ + int maxSpeed = 0; + + public int getMaxSpeed() { + return maxSpeed; + } + + public BaseTaskConfig setMaxSpeed(int maxSpeed) { + this.maxSpeed = maxSpeed; + saveKey("maxSpeed", String.valueOf(maxSpeed)); + return this; + } + public long getUpdateInterval() { return updateInterval; } @@ -374,11 +390,6 @@ class Configuration { */ int threadNum = 3; - /** - * 设置最大下载速度,单位:kb, 为0表示不限速 - */ - int maxSpeed = 0; - /** * 多线程下载是否使用块下载模式,{@code true}使用,{@code false}不使用 * 注意: @@ -393,6 +404,13 @@ class Configuration { return useBlock; } + @Override public DownloadConfig setMaxSpeed(int maxSpeed) { + super.setMaxSpeed(maxSpeed); + DownloadTaskQueue.getInstance().setMaxSpeed(maxSpeed); + DownloadGroupTaskQueue.getInstance().setMaxSpeed(maxSpeed); + return this; + } + public DownloadConfig setUseBlock(boolean useBlock) { this.useBlock = useBlock; saveKey("useBlock", String.valueOf(useBlock)); @@ -407,17 +425,6 @@ class Configuration { return this; } - public int getMaxSpeed() { - return maxSpeed; - } - - public DownloadConfig setMaxSpeed(int maxSpeed) { - this.maxSpeed = maxSpeed; - saveKey("maxSpeed", String.valueOf(maxSpeed)); - DownloadTaskQueue.getInstance().setMaxSpeed(maxSpeed); - return this; - } - public DownloadConfig setThreadNum(int threadNum) { this.threadNum = threadNum; saveKey("threadNum", String.valueOf(threadNum)); @@ -478,6 +485,12 @@ class Configuration { loadConfig(); } + @Override public UploadConfig setMaxSpeed(int maxSpeed) { + super.setMaxSpeed(maxSpeed); + UploadTaskQueue.getInstance().setMaxSpeed(maxSpeed); + return this; + } + public UploadConfig setMaxTaskNum(int maxTaskNum) { oldMaxTaskNum = this.maxTaskNum; this.maxTaskNum = maxTaskNum; diff --git a/aria/src/main/java/com/arialyy/aria/core/upload/UploadTask.java b/aria/src/main/java/com/arialyy/aria/core/upload/UploadTask.java index f2c91750..a8c6d6fc 100644 --- a/aria/src/main/java/com/arialyy/aria/core/upload/UploadTask.java +++ b/aria/src/main/java/com/arialyy/aria/core/upload/UploadTask.java @@ -18,65 +18,31 @@ package com.arialyy.aria.core.upload; import android.os.Handler; import android.os.Looper; import com.arialyy.aria.core.inf.AbsNormalTask; +import com.arialyy.aria.core.inf.IUploadListener; import com.arialyy.aria.core.scheduler.ISchedulers; import com.arialyy.aria.core.upload.uploader.SimpleUploadUtil; -import com.arialyy.aria.util.ALog; /** * Created by lyy on 2017/2/23. * 上传任务 */ -public class UploadTask extends AbsNormalTask { - private static final String TAG = "UploadTask"; - - private SimpleUploadUtil mUtil; - private BaseUListener mListener; +public class UploadTask extends AbsNormalTask { private UploadTask(UploadTaskEntity taskEntity, Handler outHandler) { mTaskEntity = taskEntity; mOutHandler = outHandler; - mListener = new BaseUListener<>(this, mOutHandler); - mUtil = new SimpleUploadUtil(taskEntity, mListener); + mListener = new BaseUListener(this, mOutHandler); + mUtil = new SimpleUploadUtil(taskEntity, (IUploadListener) mListener); } @Override public String getKey() { return mTaskEntity.getEntity().getFilePath(); } - @Override public boolean isRunning() { - return mUtil.isRunning(); - } - public UploadEntity getEntity() { return mTaskEntity.getEntity(); } - @Override public void start() { - if (mUtil.isRunning()) { - ALog.d(TAG, "任务正在下载"); - } else { - mUtil.start(); - } - } - - @Override public void stop() { - super.stop(); - if (mUtil.isRunning()) { - mUtil.stop(); - } else { - mListener.onStop(getCurrentProgress()); - } - } - - @Override public void cancel() { - super.cancel(); - if (mUtil.isRunning()) { - mUtil.cancel(); - } else { - mListener.onCancel(); - } - } - @Override public String getTaskName() { return mTaskEntity.getEntity().getFileName(); } @@ -84,33 +50,21 @@ public class UploadTask extends AbsNormalTask { public static class Builder { private Handler mOutHandler; private UploadTaskEntity mTaskEntity; - private String mTargetName; public void setOutHandler(ISchedulers outHandler) { - try { - mOutHandler = new Handler(outHandler); - } catch (Exception e) { - e.printStackTrace(); - mOutHandler = new Handler(Looper.getMainLooper(), outHandler); - } + mOutHandler = new Handler(Looper.getMainLooper(), outHandler); } public void setUploadTaskEntity(UploadTaskEntity taskEntity) { mTaskEntity = taskEntity; } - public void setTargetName(String targetName) { - mTargetName = targetName; - } - public Builder() { } public UploadTask build() { - UploadTask task = new UploadTask(mTaskEntity, mOutHandler); - task.setTargetName(mTargetName); - return task; + return new UploadTask(mTaskEntity, mOutHandler); } } } diff --git a/aria/src/main/java/com/arialyy/aria/exception/FileException.java b/aria/src/main/java/com/arialyy/aria/exception/FileException.java index 7122da80..0c4ffed5 100644 --- a/aria/src/main/java/com/arialyy/aria/exception/FileException.java +++ b/aria/src/main/java/com/arialyy/aria/exception/FileException.java @@ -19,10 +19,14 @@ package com.arialyy.aria.exception; * Created by lyy on 2017/1/18. * Aria 文件异常 */ -public class FileException extends NullPointerException { - private static final String ARIA_FILE_EXCEPTION = "Aria Exception:"; +public class FileException extends BaseException { + private static final String ARIA_FILE_EXCEPTION = "Aria File Exception:"; - public FileException(String detailMessage) { - super(ARIA_FILE_EXCEPTION + detailMessage); + public FileException(String tag, String detailMessage) { + super(tag, String.format("%s%s", ARIA_FILE_EXCEPTION, detailMessage)); + } + + public FileException(String tag, String message, Exception e){ + super(tag, message, e); } } diff --git a/build.gradle b/build.gradle index e172e363..b421632b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { -// ext.kotlin_version = '1.1.51' + ext.kotlin_version = '1.1.51' repositories { jcenter() mavenCentral() @@ -9,7 +9,7 @@ buildscript { // classpath 'com.android.tools.build:gradle:2.3.3' classpath 'com.android.tools.build:gradle:2.2.2' classpath 'com.novoda:bintray-release:0.5.0' -// classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7' // classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' // NOTE: Do not place your application dependencies here; they belong @@ -39,8 +39,8 @@ task clean(type: Delete) { ext { userOrg = 'arialyy' groupId = 'com.arialyy.aria' - publishVersion = '3.4.5' -// publishVersion = '1.0.3' //FTP插件 + publishVersion = '3.5.2_dev_2' +// publishVersion = '1.0.4' //FTP插件 repoName='maven' desc = 'android 下载框架' website = 'https://github.com/AriaLyy/Aria' diff --git a/gradle.properties b/gradle.properties index 36ed63a9..2a4e2533 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,5 +17,5 @@ #org.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 # gradle proxy https://chaosleong.github.io/2017/02/10/Configuring-Gradle-Proxy/ #systemProp.socksProxyHost=127.0.0.1 -#systemProp.socksProxyPort=60777 +#systemProp.socksProxyPort=1080 #systemprop.socksProxyVersion=5 \ No newline at end of file diff --git a/py/download.py b/py/download.py new file mode 100644 index 00000000..e42927df --- /dev/null +++ b/py/download.py @@ -0,0 +1,21 @@ +# coding=utf-8 + +import os +from flask import Flask, send_from_directory, request + +app = Flask(__name__) + + +@app.route("/download/", methods=['POST', 'GET']) +def downloader(filename): + """ + 不支持断点的下载 + """ + data = request.values.get('key') + print data + dirpath = 'D:/test' + return send_from_directory(dirpath, filename, as_attachment=True) # as_attachment=True 一定要写,不然会变成打开,而不是下载 + + +if __name__ == '__main__': + app.run(host='0.0.0.0', debug=True) # 需要关闭防火墙 diff --git a/py/upload.py b/py/upload.py new file mode 100644 index 00000000..7dd9ad97 --- /dev/null +++ b/py/upload.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +import os +from flask import Flask, request, url_for, send_from_directory +from werkzeug import secure_filename + +ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif', 'rar', 'apk']) + +app = Flask(__name__) +app.config['UPLOAD_FOLDER'] = 'd:/db/' +app.config['MAX_CONTENT_LENGTH'] = 1600 * 1024 * 1024 + +""" +可以选择这个扩展 +Flask-Uploads +""" + +html = ''' + + Upload File +

    图片上传

    +
    + + +
    + ''' + + +def allowed_file(filename): + return '.' in filename and \ + filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS + + +@app.route('/uploads/') +def uploaded_file(filename): + return send_from_directory(app.config['UPLOAD_FOLDER'], + filename) + + +@app.route('/', methods=['GET', 'POST']) +def test(): + return'test' + + +@app.route('/upload/', methods=['GET', 'POST']) +def upload_file(): + print 'upload' + if request.method == 'POST': + print 'post' + file = request.files['file'] + print file + if file and allowed_file(file.filename): + print 'start save' + filename = secure_filename(file.filename) + file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) + # file_url = url_for('uploaded_file', filename=filename) + # return html + '
    ' + return '200' + return '405' + + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000)