修复FTP上传文件不完整的bug,尝试处理ftp 断点续传上传

pull/330/head
AriaLyy 7 years ago
parent 9d354fa935
commit afb47c8446
  1. 4
      Aria/build.gradle
  2. 196
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFtpInfoThread.java
  3. 81
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFtpThreadTask.java
  4. 23
      Aria/src/main/java/com/arialyy/aria/core/common/AbsThreadTask.java
  5. 4
      Aria/src/main/java/com/arialyy/aria/core/common/OnFileInfoCallback.java
  6. 155
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/AbsFtpInfoThread.java
  7. 1
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadGroupUtil.java
  8. 1
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirDownloadUtil.java
  9. 14
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirInfoThread.java
  10. 13
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpFileInfoThread.java
  11. 44
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java
  12. 1
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java
  13. 1
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/SimpleDownloadUtil.java
  14. 3
      Aria/src/main/java/com/arialyy/aria/core/upload/FtpUploadTarget.java
  15. 55
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpFileInfoThread.java
  16. 129
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java
  17. 74
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/ProgressInputStream.java
  18. 13
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/SimpleUploadUtil.java
  19. 2
      Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java
  20. 1
      Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java
  21. 55
      AriaFtpPlug/src/main/java/org/apache/commons/net/DatagramSocketClient.java
  22. 6
      AriaFtpPlug/src/main/java/org/apache/commons/net/DatagramSocketFactory.java
  23. 17
      AriaFtpPlug/src/main/java/org/apache/commons/net/DefaultDatagramSocketFactory.java
  24. 66
      AriaFtpPlug/src/main/java/org/apache/commons/net/DefaultSocketFactory.java
  25. 10
      AriaFtpPlug/src/main/java/org/apache/commons/net/MalformedServerReplyException.java
  26. 42
      AriaFtpPlug/src/main/java/org/apache/commons/net/PrintCommandListener.java
  27. 27
      AriaFtpPlug/src/main/java/org/apache/commons/net/ProtocolCommandEvent.java
  28. 5
      AriaFtpPlug/src/main/java/org/apache/commons/net/ProtocolCommandListener.java
  29. 30
      AriaFtpPlug/src/main/java/org/apache/commons/net/ProtocolCommandSupport.java
  30. 166
      AriaFtpPlug/src/main/java/org/apache/commons/net/SocketClient.java
  31. 1
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/Configurable.java
  32. 333
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTP.java
  33. 1030
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPClient.java
  34. 72
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPClientConfig.java
  35. 45
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPCmd.java
  36. 29
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPCommand.java
  37. 11
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPConnectionClosedException.java
  38. 115
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFile.java
  39. 9
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFileEntryParser.java
  40. 19
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFileEntryParserImpl.java
  41. 1
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFileFilter.java
  42. 11
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPFileFilters.java
  43. 30
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPHTTPClient.java
  44. 48
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPListParseEngine.java
  45. 28
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPReply.java
  46. 178
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSClient.java
  47. 4
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSCommand.java
  48. 14
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSServerSocketFactory.java
  49. 58
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSSocketFactory.java
  50. 21
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/FTPSTrustManager.java
  51. 33
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/OnFtpInputStreamListener.java
  52. 26
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/CompositeFileEntryParser.java
  53. 24
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/ConfigurableFTPFileEntryParserImpl.java
  54. 127
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactory.java
  55. 67
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParser.java
  56. 17
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/FTPFileEntryParserFactory.java
  57. 3
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParser.java
  58. 48
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java
  59. 28
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/MLSxEntryParser.java
  60. 47
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParser.java
  61. 118
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/MacOsPeterFTPEntryParser.java
  62. 75
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/NTFTPEntryParser.java
  63. 38
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java
  64. 55
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParser.java
  65. 137
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/OS400FTPEntryParser.java
  66. 4
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/ParserInitializationException.java
  67. 28
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/RegexFTPFileEntryParserImpl.java
  68. 142
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
  69. 97
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParser.java
  70. 52
      AriaFtpPlug/src/main/java/org/apache/commons/net/ftp/parser/VMSVersioningFTPEntryParser.java
  71. 14
      AriaFtpPlug/src/main/java/org/apache/commons/net/io/CRLFLineReader.java
  72. 39
      AriaFtpPlug/src/main/java/org/apache/commons/net/io/CopyStreamAdapter.java
  73. 40
      AriaFtpPlug/src/main/java/org/apache/commons/net/io/CopyStreamEvent.java
  74. 20
      AriaFtpPlug/src/main/java/org/apache/commons/net/io/CopyStreamException.java
  75. 9
      AriaFtpPlug/src/main/java/org/apache/commons/net/io/CopyStreamListener.java
  76. 59
      AriaFtpPlug/src/main/java/org/apache/commons/net/io/DotTerminatedMessageReader.java
  77. 58
      AriaFtpPlug/src/main/java/org/apache/commons/net/io/DotTerminatedMessageWriter.java
  78. 53
      AriaFtpPlug/src/main/java/org/apache/commons/net/io/FromNetASCIIInputStream.java
  79. 53
      AriaFtpPlug/src/main/java/org/apache/commons/net/io/FromNetASCIIOutputStream.java
  80. 10
      AriaFtpPlug/src/main/java/org/apache/commons/net/io/SocketInputStream.java
  81. 16
      AriaFtpPlug/src/main/java/org/apache/commons/net/io/SocketOutputStream.java
  82. 44
      AriaFtpPlug/src/main/java/org/apache/commons/net/io/ToNetASCIIInputStream.java
  83. 29
      AriaFtpPlug/src/main/java/org/apache/commons/net/io/ToNetASCIIOutputStream.java
  84. 95
      AriaFtpPlug/src/main/java/org/apache/commons/net/io/Util.java
  85. 396
      AriaFtpPlug/src/main/java/org/apache/commons/net/util/Base64.java
  86. 9
      AriaFtpPlug/src/main/java/org/apache/commons/net/util/Charsets.java
  87. 51
      AriaFtpPlug/src/main/java/org/apache/commons/net/util/KeyManagerUtils.java
  88. 19
      AriaFtpPlug/src/main/java/org/apache/commons/net/util/ListenerList.java
  89. 20
      AriaFtpPlug/src/main/java/org/apache/commons/net/util/SSLContextUtils.java
  90. 9
      AriaFtpPlug/src/main/java/org/apache/commons/net/util/SSLSocketUtils.java
  91. 103
      AriaFtpPlug/src/main/java/org/apache/commons/net/util/SubnetUtils.java
  92. 27
      AriaFtpPlug/src/main/java/org/apache/commons/net/util/TrustManagerUtils.java
  93. 2
      app/src/main/java/com/arialyy/simple/download/FtpDownloadActivity.java
  94. 4
      app/src/main/java/com/arialyy/simple/upload/FtpUploadActivity.java

@ -23,8 +23,8 @@ 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.0'
// compile project(':AriaFtpPlug')
// compile 'com.arialyy.aria:aria-ftp-plug:1.0.0'
compile project(':AriaFtpPlug')
}
apply from: 'bintray-release.gradle'

@ -0,0 +1,196 @@
/*
* 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.text.TextUtils;
import android.util.Log;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
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.util.CommonUtil;
import java.io.IOException;
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;
/**
* Created by Aria.Lao on 2017/7/25.
* 获取ftp文件夹信息
*/
public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>>
implements Runnable {
private final String TAG = "HttpFileInfoThread";
protected ENTITY mEntity;
protected TASK_ENTITY mTaskEntity;
private int mConnectTimeOut;
protected OnFileInfoCallback mCallback;
protected long mSize = 0;
protected String mServerIp, mPort;
protected String charSet = "UTF-8";
private boolean isUpload = false;
public AbsFtpInfoThread(TASK_ENTITY taskEntity, OnFileInfoCallback callback) {
mTaskEntity = taskEntity;
mEntity = taskEntity.getEntity();
mConnectTimeOut =
AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getConnectTimeOut();
mCallback = callback;
if (mEntity instanceof UploadEntity) {
isUpload = true;
}
}
/**
* 设置请求的远程文件路径
*
* @return 远程文件路径
*/
protected abstract String setRemotePath();
@Override public void run() {
FTPClient client = null;
try {
client = createFtpClient();
if (client == null) return;
String remotePath =
new String(setRemotePath().getBytes(charSet), AbsFtpThreadTask.SERVER_CHARSET);
FTPFile[] files = client.listFiles(remotePath);
mSize = getFileSize(files, client, remotePath);
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
if (isUpload) {
//服务器上没有该文件路径,表示该任务为新的上传任务
mTaskEntity.isNewTask = true;
} else {
client.disconnect();
failDownload("获取文件信息错误,错误码为:" + reply);
return;
}
}
mTaskEntity.code = reply;
mEntity.update();
mTaskEntity.update();
onPreComplete(reply);
} catch (IOException e) {
failDownload(e.getMessage());
} finally {
if (client != null) {
try {
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void start() {
new Thread(this).start();
}
protected void onPreComplete(int code) {
}
/**
* 创建FTP客户端
*/
private FTPClient createFtpClient() throws IOException {
String url = "";
if (mEntity instanceof DownloadEntity) {
url = ((DownloadEntity) mEntity).getUrl();
} else if (mEntity instanceof UploadEntity) {
url = ((UploadEntity) mEntity).getUrl();
} else if (mEntity instanceof DownloadGroupEntity) {
url = mEntity.getKey();
} else {
failDownload("未知实体");
Log.e(TAG, "未知实体");
return null;
}
String[] pp = url.split("/")[2].split(":");
mServerIp = pp[0];
mPort = pp[1];
FTPClient client = new FTPClient();
// 连接服务器
client.connect(mServerIp, Integer.parseInt(mPort));
if (!TextUtils.isEmpty(mTaskEntity.account)) {
client.login(mTaskEntity.userName, mTaskEntity.userPw);
} else {
client.login(mTaskEntity.userName, mTaskEntity.userPw, mTaskEntity.account);
}
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
client.disconnect();
failDownload("无法连接到ftp服务器,错误码为:" + reply);
return null;
}
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码
charSet = "UTF-8";
if (!TextUtils.isEmpty(mTaskEntity.charSet) || !FTPReply.isPositiveCompletion(
client.sendCommand("OPTS UTF8", "ON"))) {
charSet = mTaskEntity.charSet;
}
client.setControlEncoding(charSet);
client.setDataTimeout(10 * 1000);
client.enterLocalPassiveMode();
client.setFileType(FTP.BINARY_FILE_TYPE);
client.setControlKeepAliveTimeout(5);
return client;
}
/**
* 遍历FTP服务器上对应文件或文件夹大小
*
* @throws IOException 字符串编码转换错误
*/
private long getFileSize(FTPFile[] files, FTPClient client, String dirName) throws IOException {
long size = 0;
String path = dirName + "/";
for (FTPFile file : files) {
if (file.isFile()) {
size += file.getSize();
handleFile(path + file.getName(), file);
} else {
size += getFileSize(client.listFiles(
CommonUtil.strCharSetConvert(path + file.getName(), mTaskEntity.charSet)), client,
path + file.getName());
}
}
return size;
}
/**
* 处理FTP文件信息
*
* @param remotePath ftp服务器文件夹路径
* @param ftpFile ftp服务器上对应的文件
*/
protected void handleFile(String remotePath, FTPFile ftpFile) {
}
private void failDownload(String errorMsg) {
Log.e(TAG, errorMsg);
if (mCallback != null) {
mCallback.onFail(mEntity.getKey(), errorMsg);
}
}
}

@ -0,0 +1,81 @@
/*
* 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.text.TextUtils;
import com.arialyy.aria.core.inf.AbsNormalEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IEventListener;
import java.io.IOException;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
/**
* Created by lyy on 2017/9/26.
* FTP单任务父类
*/
public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>>
extends AbsThreadTask<ENTITY, TASK_ENTITY> {
protected String charSet, serverIp, port;
/**
* FTP 服务器编码
*/
public static String SERVER_CHARSET = "ISO-8859-1";
protected AbsFtpThreadTask(StateConstance constance, IEventListener listener,
SubThreadConfig<TASK_ENTITY> info) {
super(constance, listener, info);
}
/**
* 构建FTP客户端
*/
protected FTPClient createClient() throws IOException {
String url = mEntity.getUrl();
String[] pp = url.split("/")[2].split(":");
serverIp = pp[0];
port = pp[1];
FTPClient client = new FTPClient();
// 连接服务器
client.connect(serverIp, Integer.parseInt(port));
if (!TextUtils.isEmpty(mTaskEntity.account)) {
client.login(mTaskEntity.userName, mTaskEntity.userPw);
} else {
client.login(mTaskEntity.userName, mTaskEntity.userPw, mTaskEntity.account);
}
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
client.disconnect();
fail(STATE.CURRENT_LOCATION, "无法连接到ftp服务器,错误码为:" + reply, null);
return null;
}
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码
charSet = "UTF-8";
if (!TextUtils.isEmpty(mTaskEntity.charSet) || !FTPReply.isPositiveCompletion(
client.sendCommand("OPTS UTF8", "ON"))) {
charSet = mTaskEntity.charSet;
}
client.setControlEncoding(charSet);
client.setDataTimeout(STATE.READ_TIME_OUT);
client.enterLocalPassiveMode();
client.setFileType(FTP.BINARY_FILE_TYPE);
client.setBufferSize(mBufSize);
//client.setControlKeepAliveTimeout(5);
//client.setCopyStreamListener();
return client;
}
}

@ -19,7 +19,7 @@ import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.inf.AbsEntity;
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.upload.UploadEntity;
@ -37,7 +37,7 @@ import java.util.TimerTask;
* Created by lyy on 2017/1/18.
* 任务线程
*/
public abstract class AbsThreadTask<ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>>
public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>>
implements Runnable {
/**
* 线程重试次数
@ -56,10 +56,6 @@ public abstract class AbsThreadTask<ENTITY extends AbsEntity, TASK_ENTITY extend
protected SubThreadConfig<TASK_ENTITY> mConfig;
protected ENTITY mEntity;
protected TASK_ENTITY mTaskEntity;
/**
* FTP 服务器编码
*/
public static String SERVER_CHARSET = "ISO-8859-1";
private int mFailNum = 0;
private String mTaskType;
private Timer mFailTimer;
@ -74,9 +70,7 @@ public abstract class AbsThreadTask<ENTITY extends AbsEntity, TASK_ENTITY extend
mConfig = info;
mTaskEntity = mConfig.TASK_ENTITY;
mEntity = mTaskEntity.getEntity();
if (mConfig.SUPPORT_BP) {
mConfigFPath = info.CONFIG_FILE_PATH;
}
mBufSize = manager.getDownloadConfig().getBuffSize();
setMaxSpeed(AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getMsxSpeed());
mTaskType = getTaskType();
@ -105,14 +99,15 @@ public abstract class AbsThreadTask<ENTITY extends AbsEntity, TASK_ENTITY extend
synchronized (AriaManager.LOCK) {
try {
if (mConfig.SUPPORT_BP) {
final long currentTemp = mChildCurrentLocation;
STATE.STOP_NUM++;
Log.d(TAG, "任务【"
+ mConfig.TEMP_FILE.getName()
+ "】thread__"
+ mConfig.THREAD_ID
+ "__停止, stop location ==> "
+ mChildCurrentLocation);
writeConfig(false, mChildCurrentLocation);
+ currentTemp);
writeConfig(false, currentTemp);
if (STATE.isStop()) {
Log.d(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】已停止");
STATE.isRunning = false;
@ -170,7 +165,7 @@ public abstract class AbsThreadTask<ENTITY extends AbsEntity, TASK_ENTITY extend
/**
* 任务失败
*/
protected void fail(long currentLocation, String msg, Exception ex) {
protected void fail(final long currentLocation, String msg, Exception ex) {
synchronized (AriaManager.LOCK) {
try {
if (ex != null) {
@ -213,7 +208,8 @@ public abstract class AbsThreadTask<ENTITY extends AbsEntity, TASK_ENTITY extend
mFailNum++;
Log.w(TAG,
"任务【" + mConfig.TEMP_FILE.getName() + "】thread__" + mConfig.THREAD_ID + "__正在重试");
mConfig.START_LOCATION = mChildCurrentLocation;
final long retryLocation = mChildCurrentLocation;
mConfig.START_LOCATION = retryLocation;
AbsThreadTask.this.run();
}
}, RETRY_INTERVAL);
@ -231,8 +227,9 @@ public abstract class AbsThreadTask<ENTITY extends AbsEntity, TASK_ENTITY extend
/**
* 将记录写入到配置文件
*/
protected void writeConfig(boolean isComplete, long record) throws IOException {
protected void writeConfig(boolean isComplete, final long record) throws IOException {
synchronized (AriaManager.LOCK) {
Log.d(TAG, "really record == " + record);
String key = null, value = null;
if (0 < record && record < mConfig.END_LOCATION) {
key = mConfig.TEMP_FILE.getName() + "_record_" + mConfig.THREAD_ID;

@ -1,6 +1,6 @@
package com.arialyy.aria.core.download.downloader;
package com.arialyy.aria.core.common;
interface OnFileInfoCallback {
public interface OnFileInfoCallback {
/**
* 处理完成
*

@ -1,155 +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.download.downloader;
import android.text.TextUtils;
import android.util.Log;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.AbsThreadTask;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.util.CommonUtil;
import java.io.IOException;
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;
/**
* Created by Aria.Lao on 2017/7/25.
* 获取ftp文件夹信息
*/
abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>>
implements Runnable {
private final String TAG = "HttpFileInfoThread";
protected ENTITY mEntity;
protected TASK_ENTITY mTaskEntity;
private int mConnectTimeOut;
private OnFileInfoCallback mCallback;
protected long mSize = 0;
AbsFtpInfoThread(TASK_ENTITY taskEntity, OnFileInfoCallback callback) {
mTaskEntity = taskEntity;
mEntity = taskEntity.getEntity();
mConnectTimeOut =
AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getConnectTimeOut();
mCallback = callback;
}
@Override public void run() {
FTPClient client = null;
try {
String url = mTaskEntity.getEntity().getKey();
String[] pp = url.split("/")[2].split(":");
String serverIp = pp[0];
int port = Integer.parseInt(pp[1]);
String remotePath = url.substring(url.indexOf(pp[1]) + pp[1].length(), url.length());
client = new FTPClient();
client.connect(serverIp, port);
if (!TextUtils.isEmpty(mTaskEntity.account)) {
client.login(mTaskEntity.userName, mTaskEntity.userPw);
} else {
client.login(mTaskEntity.userName, mTaskEntity.userPw, mTaskEntity.account);
}
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
client.disconnect();
failDownload("无法连接到ftp服务器,错误码为:" + reply);
return;
}
client.setDataTimeout(mConnectTimeOut);
String charSet = "UTF-8";
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码
if (!TextUtils.isEmpty(mTaskEntity.charSet) || !FTPReply.isPositiveCompletion(
client.sendCommand("OPTS UTF8", "ON"))) {
charSet = mTaskEntity.charSet;
}
client.setControlEncoding(charSet);
client.enterLocalPassiveMode();
client.setFileType(FTP.BINARY_FILE_TYPE);
FTPFile[] files =
client.listFiles(new String(remotePath.getBytes(charSet), AbsThreadTask.SERVER_CHARSET));
mSize = getFileSize(files, client, remotePath);
reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
client.disconnect();
failDownload("获取文件信息错误,错误码为:" + reply);
return;
}
mTaskEntity.code = reply;
onPreComplete();
mEntity.update();
mTaskEntity.update();
mCallback.onComplete(mEntity.getKey(), reply);
} catch (IOException e) {
failDownload(e.getMessage());
} finally {
if (client != null) {
try {
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
void start() {
new Thread(this).start();
}
protected void onPreComplete() {
}
/**
* 遍历FTP服务器上对应文件或文件夹大小
*
* @throws IOException
*/
private long getFileSize(FTPFile[] files, FTPClient client, String dirName) throws IOException {
long size = 0;
String path = dirName + "/";
for (FTPFile file : files) {
if (file.isFile()) {
size += file.getSize();
handleFile(path + file.getName(), file);
} else {
size += getFileSize(client.listFiles(
CommonUtil.strCharSetConvert(path + file.getName(), mTaskEntity.charSet)), client,
path + file.getName());
}
}
return size;
}
/**
* 处理FTP文件信息
*
* @param remotePath ftp服务器文件夹路径
* @param ftpFile ftp服务器上对应的文件
*/
void handleFile(String remotePath, FTPFile ftpFile) {
}
private void failDownload(String errorMsg) {
Log.e(TAG, errorMsg);
if (mCallback != null) {
mCallback.onFail(mEntity.getKey(), errorMsg);
}
}
}

@ -17,6 +17,7 @@ package com.arialyy.aria.core.download.downloader;
import android.util.SparseArray;
import com.arialyy.aria.core.common.IUtil;
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;

@ -15,6 +15,7 @@
*/
package com.arialyy.aria.core.download.downloader;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;

@ -15,6 +15,8 @@
*/
package com.arialyy.aria.core.download.downloader;
import com.arialyy.aria.core.common.AbsFtpInfoThread;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
@ -33,14 +35,20 @@ class FtpDirInfoThread extends AbsFtpInfoThread<DownloadGroupEntity, DownloadGro
super(taskEntity, callback);
}
@Override void handleFile(String remotePath, FTPFile ftpFile) {
@Override protected String setRemotePath() {
String url = mEntity.getKey();
return url.substring(url.indexOf(mPort) + mPort.length(), url.length());
}
@Override protected void handleFile(String remotePath, FTPFile ftpFile) {
super.handleFile(remotePath, ftpFile);
addEntity(remotePath, ftpFile);
}
@Override protected void onPreComplete() {
super.onPreComplete();
@Override protected void onPreComplete(int code) {
super.onPreComplete(code);
mEntity.setFileSize(mSize);
mCallback.onComplete(mEntity.getKey(), code);
}
private void addEntity(String remotePath, FTPFile ftpFile) {

@ -15,6 +15,8 @@
*/
package com.arialyy.aria.core.download.downloader;
import com.arialyy.aria.core.common.AbsFtpInfoThread;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
@ -28,8 +30,15 @@ class FtpFileInfoThread extends AbsFtpInfoThread<DownloadEntity, DownloadTaskEnt
super(taskEntity, callback);
}
@Override protected void onPreComplete() {
super.onPreComplete();
@Override protected String setRemotePath() {
String url = mEntity.getUrl();
return url.substring(url.indexOf(mPort) + mPort.length(), url.length())
+ "/"
+ mEntity.getFileName();
}
@Override protected void onPreComplete(int code) {
super.onPreComplete(code);
if (mSize != mTaskEntity.getEntity().getFileSize()) {
mTaskEntity.isNewTask = true;
}

@ -15,9 +15,8 @@
*/
package com.arialyy.aria.core.download.downloader;
import android.text.TextUtils;
import android.util.Log;
import com.arialyy.aria.core.common.AbsThreadTask;
import com.arialyy.aria.core.common.AbsFtpThreadTask;
import com.arialyy.aria.core.common.StateConstance;
import com.arialyy.aria.core.common.SubThreadConfig;
import com.arialyy.aria.core.download.DownloadEntity;
@ -27,7 +26,6 @@ import com.arialyy.aria.util.BufferedRandomAccessFile;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
@ -35,7 +33,7 @@ import org.apache.commons.net.ftp.FTPReply;
* Created by Aria.Lao on 2017/7/24.
* Ftp下载任务
*/
class FtpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEntity> {
class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity> {
private final String TAG = "FtpThreadTask";
FtpThreadTask(StateConstance constance, IDownloadListener listener,
@ -57,40 +55,16 @@ class FtpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEntity> {
+ ",结束位置:"
+ mConfig.END_LOCATION
+ "】");
client = createClient();
if (client == null) return;
String url = mEntity.getUrl();
String[] pp = url.split("/")[2].split(":");
String serverIp = pp[0];
int port = Integer.parseInt(pp[1]);
String remotePath = url.substring(url.indexOf(pp[1]) + pp[1].length(), url.length());
client = new FTPClient();
client.connect(serverIp, port);
if (!TextUtils.isEmpty(mTaskEntity.account)) {
client.login(mTaskEntity.userName, mTaskEntity.userPw);
} else {
client.login(mTaskEntity.userName, mTaskEntity.userPw, mTaskEntity.account);
}
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
client.disconnect();
fail(STATE.CURRENT_LOCATION, "无法连接到ftp服务器,错误码为:" + reply, null);
return;
}
String charSet = "UTF-8";
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码
if (!TextUtils.isEmpty(mTaskEntity.charSet) || !FTPReply.isPositiveCompletion(
client.sendCommand("OPTS UTF8", "ON"))) {
charSet = mTaskEntity.charSet;
}
client.setControlEncoding(charSet);
client.setDataTimeout(STATE.READ_TIME_OUT);
client.enterLocalPassiveMode();
client.setFileType(FTP.BINARY_FILE_TYPE);
String remotePath = new String(
url.substring(url.indexOf(port) + port.length(), url.length()).getBytes(charSet),
SERVER_CHARSET);
client.setRestartOffset(mConfig.START_LOCATION);
client.allocate(mBufSize);
is = client.retrieveFileStream(
new String(remotePath.getBytes(charSet), SERVER_CHARSET));
is = client.retrieveFileStream(remotePath);
//发送第二次指令时,还需要再做一次判断
reply = client.getReplyCode();
int reply = client.getReplyCode();
if (!FTPReply.isPositivePreliminary(reply)) {
client.disconnect();
fail(mChildCurrentLocation, "获取文件信息错误,错误码为:" + reply, null);

@ -18,6 +18,7 @@ package com.arialyy.aria.core.download.downloader;
import android.text.TextUtils;
import android.util.Log;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.util.CommonUtil;

@ -17,6 +17,7 @@
package com.arialyy.aria.core.download.downloader;
import com.arialyy.aria.core.common.IUtil;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IDownloadListener;

@ -45,6 +45,9 @@ public class FtpUploadTarget
File file = new File(filePath);
mEntity.setFileName(file.getName());
mEntity.setFileSize(file.length());
//暂时不支持断点续传上传
mTaskEntity.isSupportBP = false;
}
/**

@ -0,0 +1,55 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.upload.uploader;
import com.arialyy.aria.core.common.AbsFtpInfoThread;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTaskEntity;
import org.apache.commons.net.ftp.FTPFile;
/**
* Created by Aria.Lao on 2017/9/26.
* FTP远程服务器文件信息
*/
class FtpFileInfoThread extends AbsFtpInfoThread<UploadEntity, UploadTaskEntity> {
static final int CODE_EXISTS = 0xab1;
private boolean exists = false;
FtpFileInfoThread(UploadTaskEntity taskEntity, OnFileInfoCallback callback) {
super(taskEntity, callback);
}
@Override protected String setRemotePath() {
String url = mEntity.getUrl();
return url.substring(url.indexOf(mPort) + mPort.length(), url.length())
+ "/"
+ mEntity.getFileName();
}
@Override protected void handleFile(String remotePath, FTPFile ftpFile) {
super.handleFile(remotePath, ftpFile);
//远程文件已完成
if (ftpFile != null && ftpFile.getSize() == mEntity.getFileSize()) {
exists = true;
}
}
@Override protected void onPreComplete(int code) {
super.onPreComplete(code);
mCallback.onComplete(mEntity.getKey(), exists ? CODE_EXISTS : code);
}
}

@ -15,9 +15,8 @@
*/
package com.arialyy.aria.core.upload.uploader;
import android.text.TextUtils;
import android.util.Log;
import com.arialyy.aria.core.common.AbsThreadTask;
import com.arialyy.aria.core.common.AbsFtpThreadTask;
import com.arialyy.aria.core.common.StateConstance;
import com.arialyy.aria.core.common.SubThreadConfig;
import com.arialyy.aria.core.inf.IEventListener;
@ -27,28 +26,29 @@ import com.arialyy.aria.util.BufferedRandomAccessFile;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.commons.net.ftp.FTP;
import java.io.UnsupportedEncodingException;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.OnFtpInputStreamListener;
import org.apache.commons.net.io.CopyStreamEvent;
import org.apache.commons.net.io.CopyStreamListener;
/**
* Created by Aria.Lao on 2017/7/28.
* FTP 单线程上传任务需要FTP 服务器给用户打开删除和读入IO的权限
*/
class FtpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
private final String TAG = "FtpThreadTask";
private String dir, remotePath, charSet;
private String dir, remotePath;
FtpThreadTask(StateConstance constance, IEventListener listener,
SubThreadConfig<UploadTaskEntity> info) {
super(constance, listener, info);
}
@Override public void run() {
FTPClient client = null;
OutputStream os = null;
BufferedRandomAccessFile file = null;
try {
Log.d(TAG, "任务【"
@ -64,22 +64,16 @@ class FtpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
mChildCurrentLocation = mConfig.START_LOCATION;
client = createClient();
if (client == null) return;
initPath();
client.makeDirectory(dir);
client.changeWorkingDirectory(dir);
client.setRestartOffset(mConfig.START_LOCATION);
file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", mBufSize);
file.seek(mConfig.START_LOCATION);
if (!isRemoteComplete(client)) {
os = client.storeFileStream(new String(remotePath.getBytes(charSet), SERVER_CHARSET));
//发送第二次指令时,还需要再做一次判断
int reply = client.getReplyCode();
if (!FTPReply.isPositivePreliminary(reply)) {
client.disconnect();
fail(mChildCurrentLocation, "上传文件错误,错误码为:" + reply, null);
return;
}
upload(file, os);
if (mConfig.START_LOCATION != 0) {
file.skipBytes((int) mConfig.START_LOCATION);
//file.seek(mConfig.START_LOCATION);
}
upload(client, file);
if (STATE.isCancel || STATE.isStop) return;
Log.i(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】线程__" + mConfig.THREAD_ID + "__上传完毕");
writeConfig(true, 1);
@ -101,9 +95,6 @@ class FtpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
if (file != null) {
file.close();
}
if (os != null) {
os.close();
}
if (client != null && client.isConnected()) {
client.disconnect();
}
@ -113,14 +104,55 @@ class FtpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
}
}
/**
* 远程文件是否已经玩飞车
*
* @return true 任务已经完成
*/
private boolean isRemoteComplete(FTPClient client) throws IOException {
FTPFile[] files = client.listFiles(new String(remotePath.getBytes(charSet), SERVER_CHARSET));
return files.length != 0 && files[0].getSize() == mEntity.getFileSize();
private void initPath() throws UnsupportedEncodingException {
String url = mEntity.getUrl();
String temp = url.substring(url.indexOf(port) + port.length(), url.length());
dir = new String(temp.getBytes(charSet), SERVER_CHARSET);
remotePath = new String((temp + "/" + mEntity.getFileName()).getBytes(charSet), SERVER_CHARSET);
}
private void upload(final FTPClient client, final BufferedRandomAccessFile bis)
throws IOException {
//client.storeFile(remotePath,
// new ProgressInputStream(bis, new ProgressInputStream.ProgressCallback() {
// @Override public void onProgressCallback(byte[] buffer, int byteOffset, int byteCount)
// throws IOException {
// if (STATE.isCancel || STATE.isStop) {
// long s = client.abor();
// Log.d(TAG, "s = " + s);
// client.disconnect();
// }
// progress(byteCount);
// }
// }));
try {
client.storeFile(remotePath, new ProgressInputStream(bis), new OnFtpInputStreamListener() {
@Override public void onFtpInputStream(FTPClient client, long totalBytesTransferred,
int bytesTransferred, long streamSize) {
if (STATE.isCancel || STATE.isStop) {
try {
client.abor();
} catch (IOException e) {
e.printStackTrace();
}
}
progress(bytesTransferred);
}
});
} catch (IOException e) {
//e.printStackTrace();
}
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
client.disconnect();
fail(mChildCurrentLocation, "上传文件错误,错误码为:" + reply, null);
}
}
/**
@ -143,48 +175,11 @@ class FtpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
os.write(buffer, 0, len);
progress(len);
}
Log.d(TAG, len + "");
}
}
/**
* 构建FTP客户端
*/
private FTPClient createClient() throws IOException {
String url = mEntity.getUrl();
String[] pp = url.split("/")[2].split(":");
String serverIp = pp[0];
int port = Integer.parseInt(pp[1]);
dir = url.substring(url.indexOf(pp[1]) + pp[1].length(), url.length());
remotePath = dir + "/" + mEntity.getFileName();
FTPClient client = new FTPClient();
client.connect(serverIp, port);
if (!TextUtils.isEmpty(mTaskEntity.account)) {
client.login(mTaskEntity.userName, mTaskEntity.userPw);
} else {
client.login(mTaskEntity.userName, mTaskEntity.userPw, mTaskEntity.account);
}
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
client.disconnect();
fail(STATE.CURRENT_LOCATION, "无法连接到ftp服务器,错误码为:" + reply, null);
return null;
}
charSet = "UTF-8";
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码
if (!TextUtils.isEmpty(mTaskEntity.charSet) || !FTPReply.isPositiveCompletion(
client.sendCommand("OPTS UTF8", "ON"))) {
charSet = mTaskEntity.charSet;
}
client.setControlEncoding(charSet);
client.setDataTimeout(STATE.READ_TIME_OUT);
client.enterLocalPassiveMode();
client.setFileType(FTP.BINARY_FILE_TYPE);
client.allocate(mBufSize);
return client;
}
@Override protected String getTaskType() {
return "FTP_UPLOAD";
}
}

@ -0,0 +1,74 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.upload.uploader;
import android.support.annotation.NonNull;
import com.arialyy.aria.util.BufferedRandomAccessFile;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by lyy on 2017/9/26.
* 具有进度的InputStream
*/
final class ProgressInputStream extends InputStream {
private BufferedRandomAccessFile mIs;
private ProgressCallback mCallback;
private int count;
interface ProgressCallback {
void onProgressCallback(byte[] buffer, int byteOffset, int byteCount) throws IOException;
}
ProgressInputStream(@NonNull BufferedRandomAccessFile is, @NonNull ProgressCallback callback) {
mIs = is;
mCallback = callback;
}
ProgressInputStream(@NonNull BufferedRandomAccessFile is) {
mIs = is;
}
@Override public void close() throws IOException {
mIs.close();
}
@Override public int read() throws IOException {
return mIs.read();
}
@Override public int read(@NonNull byte[] buffer) throws IOException {
count = mIs.read(buffer);
if (mCallback != null) {
mCallback.onProgressCallback(buffer, 0, count);
}
return count;
}
@Override public int read(@NonNull byte[] buffer, int byteOffset, int byteCount)
throws IOException {
count = mIs.read(buffer, byteOffset, byteCount);
if (mCallback != null) {
mCallback.onProgressCallback(buffer, byteOffset, byteCount);
}
return count;
}
@Override public long skip(long byteCount) throws IOException {
return mIs.skipBytes((int) byteCount);
}
}

@ -16,6 +16,7 @@
package com.arialyy.aria.core.upload.uploader;
import com.arialyy.aria.core.common.IUtil;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.inf.IUploadListener;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTaskEntity;
@ -46,8 +47,20 @@ public class SimpleUploadUtil implements IUtil, Runnable {
@Override public void run() {
mListener.onPre();
new FtpFileInfoThread(mTaskEntity, new OnFileInfoCallback() {
@Override public void onComplete(String url, int code) {
if (code == FtpFileInfoThread.CODE_EXISTS) {
mListener.onComplete();
} else {
mUploader.start();
}
}
@Override public void onFail(String url, String errorMsg) {
mListener.onFail(true);
}
}).start();
}
@Override public long getFileSize() {
return mUploader.getFileSize();

@ -230,7 +230,7 @@ final class SqlHelper extends SQLiteOpenHelper {
}
/**
* 遍历所有数据
* 查找表的所有数据
*/
static synchronized <T extends DbEntity> List<T> findAllData(SQLiteDatabase db, Class<T> clazz) {
db = checkDb(db);

@ -705,6 +705,7 @@ public class CommonUtil {
* 设置打印的异常格式
*/
public static String getPrintException(Throwable ex) {
if (ex == null) return "";
StringBuilder err = new StringBuilder();
err.append("ExceptionDetailed:\n");
err.append("====================Exception Info====================\n");

@ -47,8 +47,7 @@ import java.nio.charset.Charset;
* @see DatagramSocketFactory
***/
public abstract class DatagramSocketClient
{
public abstract class DatagramSocketClient {
/***
* The default DatagramSocketFactory shared by all DatagramSocketClient
* instances.
@ -79,15 +78,13 @@ public abstract class DatagramSocketClient
* Default constructor for DatagramSocketClient. Initializes
* _socket_ to null, _timeout_ to 0, and _isOpen_ to false.
***/
public DatagramSocketClient()
{
public DatagramSocketClient() {
_socket_ = null;
_timeout_ = 0;
_isOpen_ = false;
_socketFactory_ = __DEFAULT_SOCKET_FACTORY;
}
/***
* Opens a DatagramSocket on the local host at the first available port.
* Also sets the timeout on the socket to the default timeout set
@ -99,14 +96,12 @@ public abstract class DatagramSocketClient
* @throws SocketException If the socket could not be opened or the
* timeout could not be set.
***/
public void open() throws SocketException
{
public void open() throws SocketException {
_socket_ = _socketFactory_.createDatagramSocket();
_socket_.setSoTimeout(_timeout_);
_isOpen_ = true;
}
/***
* Opens a DatagramSocket on the local host at a specified port.
* Also sets the timeout on the socket to the default timeout set
@ -119,14 +114,12 @@ public abstract class DatagramSocketClient
* @throws SocketException If the socket could not be opened or the
* timeout could not be set.
***/
public void open(int port) throws SocketException
{
public void open(int port) throws SocketException {
_socket_ = _socketFactory_.createDatagramSocket(port);
_socket_.setSoTimeout(_timeout_);
_isOpen_ = true;
}
/***
* Opens a DatagramSocket at the specified address on the local host
* at a specified port.
@ -141,23 +134,19 @@ public abstract class DatagramSocketClient
* @throws SocketException If the socket could not be opened or the
* timeout could not be set.
***/
public void open(int port, InetAddress laddr) throws SocketException
{
public void open(int port, InetAddress laddr) throws SocketException {
_socket_ = _socketFactory_.createDatagramSocket(port, laddr);
_socket_.setSoTimeout(_timeout_);
_isOpen_ = true;
}
/***
* Closes the DatagramSocket used for the connection.
* You should call this method after you've finished using the class
* instance and also before you call {@link #open open() }
* again. _isOpen_ is set to false and _socket_ is set to null.
***/
public void close()
{
public void close() {
if (_socket_ != null) {
_socket_.close();
}
@ -165,18 +154,15 @@ public abstract class DatagramSocketClient
_isOpen_ = false;
}
/***
* Returns true if the client has a currently open socket.
*
* @return True if the client has a currently open socket, false otherwise.
***/
public boolean isOpen()
{
public boolean isOpen() {
return _isOpen_;
}
/***
* Set the default timeout in milliseconds to use when opening a socket.
* After a call to open, the timeout for the socket is set using this value.
@ -188,12 +174,10 @@ public abstract class DatagramSocketClient
* @param timeout The timeout in milliseconds to use for the datagram socket
* connection.
***/
public void setDefaultTimeout(int timeout)
{
public void setDefaultTimeout(int timeout) {
_timeout_ = timeout;
}
/***
* Returns the default timeout in milliseconds that is used when
* opening a socket.
@ -201,12 +185,10 @@ public abstract class DatagramSocketClient
* @return The default timeout in milliseconds that is used when
* opening a socket.
***/
public int getDefaultTimeout()
{
public int getDefaultTimeout() {
return _timeout_;
}
/***
* Set the timeout in milliseconds of a currently open connection.
* Only call this method after a connection has been opened
@ -216,12 +198,10 @@ public abstract class DatagramSocketClient
* open datagram socket connection.
* @throws SocketException if an error setting the timeout
***/
public void setSoTimeout(int timeout) throws SocketException
{
public void setSoTimeout(int timeout) throws SocketException {
_socket_.setSoTimeout(timeout);
}
/***
* Returns the timeout in milliseconds of the currently opened socket.
* If you call this method when the client socket is not open,
@ -230,12 +210,10 @@ public abstract class DatagramSocketClient
* @return The timeout in milliseconds of the currently opened socket.
* @throws SocketException if an error getting the timeout
***/
public int getSoTimeout() throws SocketException
{
public int getSoTimeout() throws SocketException {
return _socket_.getSoTimeout();
}
/***
* Returns the port number of the open socket on the local host used
* for the connection. If you call this method when the client socket
@ -244,12 +222,10 @@ public abstract class DatagramSocketClient
* @return The port number of the open socket on the local host used
* for the connection.
***/
public int getLocalPort()
{
public int getLocalPort() {
return _socket_.getLocalPort();
}
/***
* Returns the local address to which the client's socket is bound.
* If you call this method when the client socket is not open, a
@ -257,12 +233,10 @@ public abstract class DatagramSocketClient
*
* @return The local address to which the client's socket is bound.
***/
public InetAddress getLocalAddress()
{
public InetAddress getLocalAddress() {
return _socket_.getLocalAddress();
}
/***
* Sets the DatagramSocketFactory used by the DatagramSocketClient
* to open DatagramSockets. If the factory value is null, then a default
@ -272,8 +246,7 @@ public abstract class DatagramSocketClient
* @param factory The new DatagramSocketFactory the DatagramSocketClient
* should use.
***/
public void setDatagramSocketFactory(DatagramSocketFactory factory)
{
public void setDatagramSocketFactory(DatagramSocketFactory factory) {
if (factory == null) {
_socketFactory_ = __DEFAULT_SOCKET_FACTORY;
} else {

@ -35,8 +35,7 @@ import java.net.SocketException;
*
***/
public interface DatagramSocketFactory
{
public interface DatagramSocketFactory {
/***
* Creates a DatagramSocket on the local host at the first available port.
@ -64,6 +63,5 @@ public interface DatagramSocketFactory
* @return the socket
* @throws SocketException If the socket could not be created.
***/
public DatagramSocket createDatagramSocket(int port, InetAddress laddr)
throws SocketException;
public DatagramSocket createDatagramSocket(int port, InetAddress laddr) throws SocketException;
}

@ -34,17 +34,14 @@ import java.net.SocketException;
* @see DatagramSocketClient#setDatagramSocketFactory
***/
public class DefaultDatagramSocketFactory implements DatagramSocketFactory
{
public class DefaultDatagramSocketFactory implements DatagramSocketFactory {
/***
* Creates a DatagramSocket on the local host at the first available port.
* @return a new DatagramSocket
* @throws SocketException If the socket could not be created.
***/
@Override
public DatagramSocket createDatagramSocket() throws SocketException
{
@Override public DatagramSocket createDatagramSocket() throws SocketException {
return new DatagramSocket();
}
@ -55,9 +52,7 @@ public class DefaultDatagramSocketFactory implements DatagramSocketFactory
* @return a new DatagramSocket
* @throws SocketException If the socket could not be created.
***/
@Override
public DatagramSocket createDatagramSocket(int port) throws SocketException
{
@Override public DatagramSocket createDatagramSocket(int port) throws SocketException {
return new DatagramSocket(port);
}
@ -70,10 +65,8 @@ public class DefaultDatagramSocketFactory implements DatagramSocketFactory
* @return a new DatagramSocket
* @throws SocketException If the socket could not be created.
***/
@Override
public DatagramSocket createDatagramSocket(int port, InetAddress laddr)
throws SocketException
{
@Override public DatagramSocket createDatagramSocket(int port, InetAddress laddr)
throws SocketException {
return new DatagramSocket(port, laddr);
}
}

@ -40,16 +40,14 @@ import javax.net.SocketFactory;
* @see SocketClient#setSocketFactory
***/
public class DefaultSocketFactory extends SocketFactory
{
public class DefaultSocketFactory extends SocketFactory {
/** The proxy to use when creating new sockets. */
private final Proxy connProxy;
/**
* The default constructor.
*/
public DefaultSocketFactory()
{
public DefaultSocketFactory() {
this(null);
}
@ -59,8 +57,7 @@ public class DefaultSocketFactory extends SocketFactory
* @param proxy The Proxy to use when creating new Sockets.
* @since 3.2
*/
public DefaultSocketFactory(Proxy proxy)
{
public DefaultSocketFactory(Proxy proxy) {
connProxy = proxy;
}
@ -71,11 +68,8 @@ public class DefaultSocketFactory extends SocketFactory
* @throws IOException If an I/O error occurs while creating the Socket.
* @since 3.2
*/
@Override
public Socket createSocket() throws IOException
{
if (connProxy != null)
{
@Override public Socket createSocket() throws IOException {
if (connProxy != null) {
return new Socket(connProxy);
}
return new Socket();
@ -90,12 +84,9 @@ public class DefaultSocketFactory extends SocketFactory
* @throws UnknownHostException If the hostname cannot be resolved.
* @throws IOException If an I/O error occurs while creating the Socket.
***/
@Override
public Socket createSocket(String host, int port)
throws UnknownHostException, IOException
{
if (connProxy != null)
{
@Override public Socket createSocket(String host, int port)
throws UnknownHostException, IOException {
if (connProxy != null) {
Socket s = new Socket(connProxy);
s.connect(new InetSocketAddress(host, port));
return s;
@ -111,12 +102,8 @@ public class DefaultSocketFactory extends SocketFactory
* @return A Socket connected to the given host and port.
* @throws IOException If an I/O error occurs while creating the Socket.
***/
@Override
public Socket createSocket(InetAddress address, int port)
throws IOException
{
if (connProxy != null)
{
@Override public Socket createSocket(InetAddress address, int port) throws IOException {
if (connProxy != null) {
Socket s = new Socket(connProxy);
s.connect(new InetSocketAddress(address, port));
return s;
@ -136,13 +123,9 @@ public class DefaultSocketFactory extends SocketFactory
* @throws UnknownHostException If the hostname cannot be resolved.
* @throws IOException If an I/O error occurs while creating the Socket.
***/
@Override
public Socket createSocket(String host, int port,
InetAddress localAddr, int localPort)
throws UnknownHostException, IOException
{
if (connProxy != null)
{
@Override public Socket createSocket(String host, int port, InetAddress localAddr, int localPort)
throws UnknownHostException, IOException {
if (connProxy != null) {
Socket s = new Socket(connProxy);
s.bind(new InetSocketAddress(localAddr, localPort));
s.connect(new InetSocketAddress(host, port));
@ -162,13 +145,9 @@ public class DefaultSocketFactory extends SocketFactory
* @return A Socket connected to the given host and port.
* @throws IOException If an I/O error occurs while creating the Socket.
***/
@Override
public Socket createSocket(InetAddress address, int port,
InetAddress localAddr, int localPort)
throws IOException
{
if (connProxy != null)
{
@Override public Socket createSocket(InetAddress address, int port, InetAddress localAddr,
int localPort) throws IOException {
if (connProxy != null) {
Socket s = new Socket(connProxy);
s.bind(new InetSocketAddress(localAddr, localPort));
s.connect(new InetSocketAddress(address, port));
@ -186,8 +165,7 @@ public class DefaultSocketFactory extends SocketFactory
* @throws IOException If an I/O error occurs while creating
* the ServerSocket.
***/
public ServerSocket createServerSocket(int port) throws IOException
{
public ServerSocket createServerSocket(int port) throws IOException {
return new ServerSocket(port);
}
@ -202,9 +180,7 @@ public class DefaultSocketFactory extends SocketFactory
* @throws IOException If an I/O error occurs while creating
* the ServerSocket.
***/
public ServerSocket createServerSocket(int port, int backlog)
throws IOException
{
public ServerSocket createServerSocket(int port, int backlog) throws IOException {
return new ServerSocket(port, backlog);
}
@ -221,10 +197,8 @@ public class DefaultSocketFactory extends SocketFactory
* @throws IOException If an I/O error occurs while creating
* the ServerSocket.
***/
public ServerSocket createServerSocket(int port, int backlog,
InetAddress bindAddr)
throws IOException
{
public ServerSocket createServerSocket(int port, int backlog, InetAddress bindAddr)
throws IOException {
return new ServerSocket(port, backlog, bindAddr);
}
}

@ -32,14 +32,12 @@ import java.io.IOException;
*
***/
public class MalformedServerReplyException extends IOException
{
public class MalformedServerReplyException extends IOException {
private static final long serialVersionUID = 6006765264250543945L;
/*** Constructs a MalformedServerReplyException with no message ***/
public MalformedServerReplyException()
{
public MalformedServerReplyException() {
super();
}
@ -48,9 +46,7 @@ public class MalformedServerReplyException extends IOException
*
* @param message The message explaining the reason for the exception.
***/
public MalformedServerReplyException(String message)
{
public MalformedServerReplyException(String message) {
super(message);
}
}

@ -28,8 +28,7 @@ import java.io.PrintWriter;
* @since 2.0
***/
public class PrintCommandListener implements ProtocolCommandListener
{
public class PrintCommandListener implements ProtocolCommandListener {
private final PrintWriter __writer;
private final boolean __nologin;
private final char __eolMarker;
@ -42,8 +41,7 @@ public class PrintCommandListener implements ProtocolCommandListener
* e.g. System.out
* @since 3.0
*/
public PrintCommandListener(PrintStream stream)
{
public PrintCommandListener(PrintStream stream) {
this(new PrintWriter(stream));
}
@ -53,7 +51,6 @@ public class PrintCommandListener implements ProtocolCommandListener
*
* @param stream where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
*
* @since 3.0
*/
public PrintCommandListener(PrintStream stream, boolean suppressLogin) {
@ -67,7 +64,6 @@ public class PrintCommandListener implements ProtocolCommandListener
* @param stream where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
* @param eolMarker if non-zero, add a marker just before the EOL.
*
* @since 3.0
*/
public PrintCommandListener(PrintStream stream, boolean suppressLogin, char eolMarker) {
@ -81,11 +77,12 @@ public class PrintCommandListener implements ProtocolCommandListener
* @param stream where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
* @param eolMarker if non-zero, add a marker just before the EOL.
* @param showDirection if {@code true}, add {@code "> "} or {@code "< "} as appropriate to the output
*
* @param showDirection if {@code true}, add {@code "> "} or {@code "< "} as appropriate to the
* output
* @since 3.0
*/
public PrintCommandListener(PrintStream stream, boolean suppressLogin, char eolMarker, boolean showDirection) {
public PrintCommandListener(PrintStream stream, boolean suppressLogin, char eolMarker,
boolean showDirection) {
this(new PrintWriter(stream), suppressLogin, eolMarker, showDirection);
}
@ -94,8 +91,7 @@ public class PrintCommandListener implements ProtocolCommandListener
*
* @param writer where to write the commands and responses
*/
public PrintCommandListener(PrintWriter writer)
{
public PrintCommandListener(PrintWriter writer) {
this(writer, false);
}
@ -104,11 +100,9 @@ public class PrintCommandListener implements ProtocolCommandListener
*
* @param writer where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
*
* @since 3.0
*/
public PrintCommandListener(PrintWriter writer, boolean suppressLogin)
{
public PrintCommandListener(PrintWriter writer, boolean suppressLogin) {
this(writer, suppressLogin, (char) 0);
}
@ -119,11 +113,9 @@ public class PrintCommandListener implements ProtocolCommandListener
* @param writer where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
* @param eolMarker if non-zero, add a marker just before the EOL.
*
* @since 3.0
*/
public PrintCommandListener(PrintWriter writer, boolean suppressLogin, char eolMarker)
{
public PrintCommandListener(PrintWriter writer, boolean suppressLogin, char eolMarker) {
this(writer, suppressLogin, eolMarker, false);
}
@ -134,21 +126,19 @@ public class PrintCommandListener implements ProtocolCommandListener
* @param writer where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
* @param eolMarker if non-zero, add a marker just before the EOL.
* @param showDirection if {@code true}, add {@code ">} " or {@code "< "} as appropriate to the output
*
* @param showDirection if {@code true}, add {@code ">} " or {@code "< "} as appropriate to the
* output
* @since 3.0
*/
public PrintCommandListener(PrintWriter writer, boolean suppressLogin, char eolMarker, boolean showDirection)
{
public PrintCommandListener(PrintWriter writer, boolean suppressLogin, char eolMarker,
boolean showDirection) {
__writer = writer;
__nologin = suppressLogin;
__eolMarker = eolMarker;
__directionMarker = showDirection;
}
@Override
public void protocolCommandSent(ProtocolCommandEvent event)
{
@Override public void protocolCommandSent(ProtocolCommandEvent event) {
if (__directionMarker) {
__writer.print("> ");
}
@ -189,9 +179,7 @@ public class PrintCommandListener implements ProtocolCommandListener
return msg;
}
@Override
public void protocolReplyReceived(ProtocolCommandEvent event)
{
@Override public void protocolReplyReceived(ProtocolCommandEvent event) {
if (__directionMarker) {
__writer.print("< ");
}

@ -16,6 +16,7 @@
*/
package org.apache.commons.net;
import java.util.EventObject;
/***
@ -32,8 +33,7 @@ import java.util.EventObject;
* @see ProtocolCommandSupport
***/
public class ProtocolCommandEvent extends EventObject
{
public class ProtocolCommandEvent extends EventObject {
private static final long serialVersionUID = 403743538418947240L;
private final int __replyCode;
@ -52,8 +52,7 @@ public class ProtocolCommandEvent extends EventObject
* @param message The entire command string verbatim as sent to the server,
* including all arguments.
***/
public ProtocolCommandEvent(Object source, String command, String message)
{
public ProtocolCommandEvent(Object source, String command, String message) {
super(source);
__replyCode = 0;
__message = message;
@ -61,7 +60,6 @@ public class ProtocolCommandEvent extends EventObject
__command = command;
}
/***
* Creates a ProtocolCommandEvent signalling a reply to a command was
* received. ProtocolCommandEvents created with this constructor
@ -76,8 +74,7 @@ public class ProtocolCommandEvent extends EventObject
* strings like OK rather than integer codes (i.e., POP3Repy.OK).
* @param message The entire reply as received from the server.
***/
public ProtocolCommandEvent(Object source, int replyCode, String message)
{
public ProtocolCommandEvent(Object source, int replyCode, String message) {
super(source);
__replyCode = replyCode;
__message = message;
@ -93,12 +90,10 @@ public class ProtocolCommandEvent extends EventObject
* @return The string representation of the command type sent, or null
* if this is a reply event.
***/
public String getCommand()
{
public String getCommand() {
return __command;
}
/***
* Returns the reply code of the received server reply. Undefined if
* this is not a reply event.
@ -106,8 +101,7 @@ public class ProtocolCommandEvent extends EventObject
* @return The reply code of the received server reply. Undefined if
* not a reply event.
***/
public int getReplyCode()
{
public int getReplyCode() {
return __replyCode;
}
@ -118,8 +112,7 @@ public class ProtocolCommandEvent extends EventObject
* @return true If the ProtocolCommandEvent was generated as a result
* of sending a command. False otherwise.
***/
public boolean isCommand()
{
public boolean isCommand() {
return __isCommand;
}
@ -130,8 +123,7 @@ public class ProtocolCommandEvent extends EventObject
* @return true If the ProtocolCommandEvent was generated as a result
* of receiving a reply. False otherwise.
***/
public boolean isReply()
{
public boolean isReply() {
return !isCommand();
}
@ -141,8 +133,7 @@ public class ProtocolCommandEvent extends EventObject
*
* @return The entire message sent to or received from the server.
***/
public String getMessage()
{
public String getMessage() {
return __message;
}
}

@ -16,6 +16,7 @@
*/
package org.apache.commons.net;
import java.util.EventListener;
/***
@ -36,8 +37,7 @@ import java.util.EventListener;
* @see ProtocolCommandSupport
***/
public interface ProtocolCommandListener extends EventListener
{
public interface ProtocolCommandListener extends EventListener {
/***
* This method is invoked by a ProtocolCommandEvent source after
@ -54,5 +54,4 @@ public interface ProtocolCommandListener extends EventListener
* @param event The ProtocolCommandEvent fired.
***/
public void protocolReplyReceived(ProtocolCommandEvent event);
}

@ -33,8 +33,7 @@ import org.apache.commons.net.util.ListenerList;
* @see ProtocolCommandListener
***/
public class ProtocolCommandSupport implements Serializable
{
public class ProtocolCommandSupport implements Serializable {
private static final long serialVersionUID = -8017692739988399978L;
private final Object __source;
@ -46,13 +45,11 @@ public class ProtocolCommandSupport implements Serializable
*
* @param source The source to use for all generated ProtocolCommandEvents.
***/
public ProtocolCommandSupport(Object source)
{
public ProtocolCommandSupport(Object source) {
__listeners = new ListenerList();
__source = source;
}
/***
* Fires a ProtocolCommandEvent signalling the sending of a command to all
* registered listeners, invoking their
@ -64,14 +61,12 @@ public class ProtocolCommandSupport implements Serializable
* @param message The entire command string verbatim as sent to the server,
* including all arguments.
***/
public void fireCommandSent(String command, String message)
{
public void fireCommandSent(String command, String message) {
ProtocolCommandEvent event;
event = new ProtocolCommandEvent(__source, command, message);
for (EventListener listener : __listeners)
{
for (EventListener listener : __listeners) {
((ProtocolCommandListener) listener).protocolCommandSent(event);
}
}
@ -89,13 +84,11 @@ public class ProtocolCommandSupport implements Serializable
* strings like OK rather than integer codes (i.e., POP3Repy.OK).
* @param message The entire reply as received from the server.
***/
public void fireReplyReceived(int replyCode, String message)
{
public void fireReplyReceived(int replyCode, String message) {
ProtocolCommandEvent event;
event = new ProtocolCommandEvent(__source, replyCode, message);
for (EventListener listener : __listeners)
{
for (EventListener listener : __listeners) {
((ProtocolCommandListener) listener).protocolReplyReceived(event);
}
}
@ -105,8 +98,7 @@ public class ProtocolCommandSupport implements Serializable
*
* @param listener The ProtocolCommandListener to add.
***/
public void addProtocolCommandListener(ProtocolCommandListener listener)
{
public void addProtocolCommandListener(ProtocolCommandListener listener) {
__listeners.addListener(listener);
}
@ -115,21 +107,17 @@ public class ProtocolCommandSupport implements Serializable
*
* @param listener The ProtocolCommandListener to remove.
***/
public void removeProtocolCommandListener(ProtocolCommandListener listener)
{
public void removeProtocolCommandListener(ProtocolCommandListener listener) {
__listeners.removeListener(listener);
}
/***
* Returns the number of ProtocolCommandListeners currently registered.
*
* @return The number of ProtocolCommandListeners currently registered.
***/
public int getListenerCount()
{
public int getListenerCount() {
return __listeners.getListenerCount();
}
}

@ -31,7 +31,6 @@ import java.nio.charset.Charset;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
/**
* The SocketClient provides the basic operations that are required of
* client objects accessing sockets. It is meant to be
@ -50,10 +49,10 @@ import javax.net.SocketFactory;
* them by directly invoking a constructor. By honoring this contract
* you guarantee that a user will always be able to provide his own
* Socket implementations by substituting his own SocketFactory.
*
* @see SocketFactory
*/
public abstract class SocketClient
{
public abstract class SocketClient {
/**
* The end of line character sequence used by most IETF protocols. That
* is a carriage return followed by a newline: "\r\n"
@ -61,8 +60,7 @@ public abstract class SocketClient
public static final String NETASCII_EOL = "\r\n";
/** The default SocketFactory shared by all SocketClient instances. */
private static final SocketFactory __DEFAULT_SOCKET_FACTORY =
SocketFactory.getDefault();
private static final SocketFactory __DEFAULT_SOCKET_FACTORY = SocketFactory.getDefault();
/** The default {@link ServerSocketFactory} */
private static final ServerSocketFactory __DEFAULT_SERVER_SOCKET_FACTORY =
@ -123,8 +121,7 @@ public abstract class SocketClient
* and _socketFactory_ to a shared instance of
* {@link org.apache.commons.net.DefaultSocketFactory}.
*/
public SocketClient()
{
public SocketClient() {
_socket_ = null;
_hostname_ = null;
_input_ = null;
@ -135,7 +132,6 @@ public abstract class SocketClient
_serverSocketFactory_ = __DEFAULT_SERVER_SOCKET_FACTORY;
}
/**
* Because there are so many connect() methods, the _connectAction_()
* method is provided as a means of performing some action immediately
@ -151,22 +147,22 @@ public abstract class SocketClient
* Subclasses overriding this method should start by calling
* <code> super._connectAction_() </code> first to ensure the
* initialization of the aforementioned protected variables.
*
* @throws IOException (SocketException) if a problem occurs with the socket
*/
protected void _connectAction_() throws IOException
{
protected void _connectAction_() throws IOException {
_socket_.setSoTimeout(_timeout_);
_input_ = _socket_.getInputStream();
_output_ = _socket_.getOutputStream();
}
/**
* Opens a Socket connected to a remote host at the specified port and
* originating from the current host at a system assigned port.
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
* <p>
*
* @param host The remote host.
* @param port The port to connect to on the remote host.
* @throws SocketException If the socket timeout could not be set.
@ -174,9 +170,7 @@ public abstract class SocketClient
* cases you will only want to catch IOException since SocketException is
* derived from it.
*/
public void connect(InetAddress host, int port)
throws SocketException, IOException
{
public void connect(InetAddress host, int port) throws SocketException, IOException {
_hostname_ = null;
_connect(host, port, null, -1);
}
@ -187,6 +181,7 @@ public abstract class SocketClient
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
* <p>
*
* @param hostname The name of the remote host.
* @param port The port to connect to on the remote host.
* @throws SocketException If the socket timeout could not be set.
@ -195,20 +190,18 @@ public abstract class SocketClient
* derived from it.
* @throws java.net.UnknownHostException If the hostname cannot be resolved.
*/
public void connect(String hostname, int port)
throws SocketException, IOException
{
public void connect(String hostname, int port) throws SocketException, IOException {
_hostname_ = hostname;
_connect(InetAddress.getByName(hostname), port, null, -1);
}
/**
* Opens a Socket connected to a remote host at the specified port and
* originating from the specified local address and port.
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
* <p>
*
* @param host The remote host.
* @param port The port to connect to on the remote host.
* @param localAddr The local address to use.
@ -218,18 +211,15 @@ public abstract class SocketClient
* cases you will only want to catch IOException since SocketException is
* derived from it.
*/
public void connect(InetAddress host, int port,
InetAddress localAddr, int localPort)
throws SocketException, IOException
{
public void connect(InetAddress host, int port, InetAddress localAddr, int localPort)
throws SocketException, IOException {
_hostname_ = null;
_connect(host, port, localAddr, localPort);
}
// helper method to allow code to be shared with connect(String,...) methods
private void _connect(InetAddress host, int port, InetAddress localAddr, int localPort)
throws SocketException, IOException
{
throws SocketException, IOException {
_socket_ = _socketFactory_.createSocket();
if (receiveBufferSize != -1) {
_socket_.setReceiveBufferSize(receiveBufferSize);
@ -250,6 +240,7 @@ public abstract class SocketClient
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
* <p>
*
* @param hostname The name of the remote host.
* @param port The port to connect to on the remote host.
* @param localAddr The local address to use.
@ -260,40 +251,37 @@ public abstract class SocketClient
* derived from it.
* @throws java.net.UnknownHostException If the hostname cannot be resolved.
*/
public void connect(String hostname, int port,
InetAddress localAddr, int localPort)
throws SocketException, IOException
{
public void connect(String hostname, int port, InetAddress localAddr, int localPort)
throws SocketException, IOException {
_hostname_ = hostname;
_connect(InetAddress.getByName(hostname), port, localAddr, localPort);
}
/**
* Opens a Socket connected to a remote host at the current default port
* and originating from the current host at a system assigned port.
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
* <p>
*
* @param host The remote host.
* @throws SocketException If the socket timeout could not be set.
* @throws IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
*/
public void connect(InetAddress host) throws SocketException, IOException
{
public void connect(InetAddress host) throws SocketException, IOException {
_hostname_ = null;
connect(host, _defaultPort_);
}
/**
* Opens a Socket connected to a remote host at the current default
* port and originating from the current host at a system assigned port.
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
* <p>
*
* @param hostname The name of the remote host.
* @throws SocketException If the socket timeout could not be set.
* @throws IOException If the socket could not be opened. In most
@ -301,12 +289,10 @@ public abstract class SocketClient
* derived from it.
* @throws java.net.UnknownHostException If the hostname cannot be resolved.
*/
public void connect(String hostname) throws SocketException, IOException
{
public void connect(String hostname) throws SocketException, IOException {
connect(hostname, _defaultPort_);
}
/**
* Disconnects the socket connection.
* You should call this method after you've finished using the class
@ -315,10 +301,10 @@ public abstract class SocketClient
* again. _isConnected_ is set to false, _socket_ is set to null,
* _input_ is set to null, and _output_ is set to null.
* <p>
*
* @throws IOException If there is an error closing the socket.
*/
public void disconnect() throws IOException
{
public void disconnect() throws IOException {
closeQuietly(_socket_);
closeQuietly(_input_);
closeQuietly(_output_);
@ -347,15 +333,16 @@ public abstract class SocketClient
}
}
}
/**
* Returns true if the client is currently connected to a server.
* <p>
* Delegates to {@link Socket#isConnected()}
*
* @return True if the client is currently connected to a server,
* false otherwise.
*/
public boolean isConnected()
{
public boolean isConnected() {
if (_socket_ == null) {
return false;
}
@ -367,14 +354,14 @@ public abstract class SocketClient
* Make various checks on the socket to test if it is available for use.
* Note that the only sure test is to use it, but these checks may help
* in some cases.
* @see <a href="https://issues.apache.org/jira/browse/NET-350">NET-350</a>
*
* @return {@code true} if the socket appears to be available for use
* @see <a href="https://issues.apache.org/jira/browse/NET-350">NET-350</a>
* @since 3.0
*/
public boolean isAvailable() {
if (isConnected()) {
try
{
try {
if (_socket_.getInetAddress() == null) {
return false;
}
@ -399,9 +386,7 @@ public abstract class SocketClient
/* ignore the result, catch exceptions: */
_socket_.getInputStream();
_socket_.getOutputStream();
}
catch (IOException ioex)
{
} catch (IOException ioex) {
return false;
}
return true;
@ -416,10 +401,10 @@ public abstract class SocketClient
* variable stores this value. If never set, the default port is equal
* to zero.
* <p>
*
* @param port The default port to set.
*/
public void setDefaultPort(int port)
{
public void setDefaultPort(int port) {
_defaultPort_ = port;
}
@ -427,14 +412,13 @@ public abstract class SocketClient
* Returns the current value of the default port (stored in
* {@link #_defaultPort_ _defaultPort_ }).
* <p>
*
* @return The current value of the default port.
*/
public int getDefaultPort()
{
public int getDefaultPort() {
return _defaultPort_;
}
/**
* Set the default timeout in milliseconds to use when opening a socket.
* This value is only used previous to a call to
@ -443,28 +427,26 @@ public abstract class SocketClient
* which operates on an the currently opened socket. _timeout_ contains
* the new timeout value.
* <p>
*
* @param timeout The timeout in milliseconds to use for the socket
* connection.
*/
public void setDefaultTimeout(int timeout)
{
public void setDefaultTimeout(int timeout) {
_timeout_ = timeout;
}
/**
* Returns the default timeout in milliseconds that is used when
* opening a socket.
* <p>
*
* @return The default timeout in milliseconds that is used when
* opening a socket.
*/
public int getDefaultTimeout()
{
public int getDefaultTimeout() {
return _timeout_;
}
/**
* Set the timeout in milliseconds of a currently open connection.
* Only call this method after a connection has been opened
@ -477,15 +459,14 @@ public abstract class SocketClient
* @throws SocketException If the operation fails.
* @throws NullPointerException if the socket is not currently open
*/
public void setSoTimeout(int timeout) throws SocketException
{
public void setSoTimeout(int timeout) throws SocketException {
_socket_.setSoTimeout(timeout);
}
/**
* Set the underlying socket send buffer size.
* <p>
*
* @param size The size of the buffer in bytes.
* @throws SocketException never thrown, but subclasses might want to do so
* @since 2.0
@ -496,6 +477,7 @@ public abstract class SocketClient
/**
* Get the current sendBuffer size
*
* @return the size, or -1 if not initialised
* @since 3.0
*/
@ -506,6 +488,7 @@ public abstract class SocketClient
/**
* Sets the underlying socket receive buffer size.
* <p>
*
* @param size The size of the buffer in bytes.
* @throws SocketException never (but subclasses may wish to do so)
* @since 2.0
@ -516,6 +499,7 @@ public abstract class SocketClient
/**
* Get the current receivedBuffer size
*
* @return the size, or -1 if not initialised
* @since 3.0
*/
@ -526,12 +510,12 @@ public abstract class SocketClient
/**
* Returns the timeout in milliseconds of the currently opened socket.
* <p>
*
* @return The timeout in milliseconds of the currently opened socket.
* @throws SocketException If the operation fails.
* @throws NullPointerException if the socket is not currently open
*/
public int getSoTimeout() throws SocketException
{
public int getSoTimeout() throws SocketException {
return _socket_.getSoTimeout();
}
@ -539,27 +523,26 @@ public abstract class SocketClient
* Enables or disables the Nagle's algorithm (TCP_NODELAY) on the
* currently opened socket.
* <p>
*
* @param on True if Nagle's algorithm is to be enabled, false if not.
* @throws SocketException If the operation fails.
* @throws NullPointerException if the socket is not currently open
*/
public void setTcpNoDelay(boolean on) throws SocketException
{
public void setTcpNoDelay(boolean on) throws SocketException {
_socket_.setTcpNoDelay(on);
}
/**
* Returns true if Nagle's algorithm is enabled on the currently opened
* socket.
* <p>
*
* @return True if Nagle's algorithm is enabled on the currently opened
* socket, false otherwise.
* @throws SocketException If the operation fails.
* @throws NullPointerException if the socket is not currently open
*/
public boolean getTcpNoDelay() throws SocketException
{
public boolean getTcpNoDelay() throws SocketException {
return _socket_.getTcpNoDelay();
}
@ -570,6 +553,7 @@ public abstract class SocketClient
* implementation dependent). It looks as though the Windows WSA sockets implementation
* allows a specific keepalive value to be set, although this seems not to be the case on
* other systems.
*
* @param keepAlive If true, keepAlive is turned on
* @throws SocketException if there is a problem with the socket
* @throws NullPointerException if the socket is not currently open
@ -582,6 +566,7 @@ public abstract class SocketClient
/**
* Returns the current value of the SO_KEEPALIVE flag on the currently opened socket.
* Delegates to {@link Socket#getKeepAlive()}
*
* @return True if SO_KEEPALIVE is enabled.
* @throws SocketException if there is a problem with the socket
* @throws NullPointerException if the socket is not currently open
@ -594,55 +579,52 @@ public abstract class SocketClient
/**
* Sets the SO_LINGER timeout on the currently opened socket.
* <p>
*
* @param on True if linger is to be enabled, false if not.
* @param val The linger timeout (in hundredths of a second?)
* @throws SocketException If the operation fails.
* @throws NullPointerException if the socket is not currently open
*/
public void setSoLinger(boolean on, int val) throws SocketException
{
public void setSoLinger(boolean on, int val) throws SocketException {
_socket_.setSoLinger(on, val);
}
/**
* Returns the current SO_LINGER timeout of the currently opened socket.
* <p>
*
* @return The current SO_LINGER timeout. If SO_LINGER is disabled returns
* -1.
* @throws SocketException If the operation fails.
* @throws NullPointerException if the socket is not currently open
*/
public int getSoLinger() throws SocketException
{
public int getSoLinger() throws SocketException {
return _socket_.getSoLinger();
}
/**
* Returns the port number of the open socket on the local host used
* for the connection.
* Delegates to {@link Socket#getLocalPort()}
* <p>
*
* @return The port number of the open socket on the local host used
* for the connection.
* @throws NullPointerException if the socket is not currently open
*/
public int getLocalPort()
{
public int getLocalPort() {
return _socket_.getLocalPort();
}
/**
* Returns the local address to which the client's socket is bound.
* Delegates to {@link Socket#getLocalAddress()}
* <p>
*
* @return The local address to which the client's socket is bound.
* @throws NullPointerException if the socket is not currently open
*/
public InetAddress getLocalAddress()
{
public InetAddress getLocalAddress() {
return _socket_.getLocalAddress();
}
@ -651,27 +633,24 @@ public abstract class SocketClient
* connected.
* Delegates to {@link Socket#getPort()}
* <p>
*
* @return The port number of the remote host to which the client is
* connected.
* @throws NullPointerException if the socket is not currently open
*/
public int getRemotePort()
{
public int getRemotePort() {
return _socket_.getPort();
}
/**
* @return The remote address to which the client is connected.
* Delegates to {@link Socket#getInetAddress()}
* @throws NullPointerException if the socket is not currently open
*/
public InetAddress getRemoteAddress()
{
public InetAddress getRemoteAddress() {
return _socket_.getInetAddress();
}
/**
* Verifies that the remote end of the given socket is connected to the
* the same host that the SocketClient is currently connected to. This
@ -679,11 +658,11 @@ public abstract class SocketClient
* accept a connection from a server, such as an FTP data connection or
* a BSD R command standard error stream.
* <p>
*
* @param socket the item to check against
* @return True if the remote hosts are the same, false if not.
*/
public boolean verifyRemote(Socket socket)
{
public boolean verifyRemote(Socket socket) {
InetAddress host1, host2;
host1 = socket.getInetAddress();
@ -692,7 +671,6 @@ public abstract class SocketClient
return host1.equals(host2);
}
/**
* Sets the SocketFactory used by the SocketClient to open socket
* connections. If the factory value is null, then a default
@ -700,10 +678,10 @@ public abstract class SocketClient
* previously altered it).
* Any proxy setting is discarded.
* <p>
*
* @param factory The new SocketFactory the SocketClient should use.
*/
public void setSocketFactory(SocketFactory factory)
{
public void setSocketFactory(SocketFactory factory) {
if (factory == null) {
_socketFactory_ = __DEFAULT_SOCKET_FACTORY;
} else {
@ -721,6 +699,7 @@ public abstract class SocketClient
* factory is used (only do this to reset the factory after having
* previously altered it).
* <p>
*
* @param factory The new ServerSocketFactory the SocketClient should use.
* @since 2.0
*/
@ -733,8 +712,10 @@ public abstract class SocketClient
}
/**
* Sets the connection timeout in milliseconds, which will be passed to the {@link Socket} object's
* Sets the connection timeout in milliseconds, which will be passed to the {@link Socket}
* object's
* connect() method.
*
* @param connectTimeout The connection timeout to use (in ms)
* @since 2.0
*/
@ -744,6 +725,7 @@ public abstract class SocketClient
/**
* Get the underlying socket connection timeout.
*
* @return timeout (in ms)
* @since 2.0
*/
@ -753,6 +735,7 @@ public abstract class SocketClient
/**
* Get the underlying {@link ServerSocketFactory}
*
* @return The server socket factory
* @since 2.2
*/
@ -760,7 +743,6 @@ public abstract class SocketClient
return _serverSocketFactory_;
}
/**
* Adds a ProtocolCommandListener.
*
@ -840,6 +822,7 @@ public abstract class SocketClient
/**
* Gets the proxy for use with all the connections.
*
* @return the current proxy for connections.
*/
public Proxy getProxy() {
@ -853,8 +836,7 @@ public abstract class SocketClient
* @since 3.3
* @deprecated Since the code now requires Java 1.6 as a mininmum
*/
@Deprecated
public String getCharsetName() {
@Deprecated public String getCharsetName() {
return charset.name();
}

@ -17,7 +17,6 @@
package org.apache.commons.net.ftp;
/**
* This interface adds the aspect of configurability by means of
* a supplied FTPClientConfig object to other classes in the

@ -16,6 +16,7 @@
*/
package org.apache.commons.net.ftp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
@ -92,8 +93,7 @@ import org.apache.commons.net.io.CRLFLineReader;
* @version $Id: FTP.java 1782546 2017-02-11 00:05:41Z sebb $
***/
public class FTP extends SocketClient
{
public class FTP extends SocketClient {
/*** The default FTP data port (20). ***/
public static final int DEFAULT_DATA_PORT = 20;
/*** The default FTP control port (21). ***/
@ -114,7 +114,6 @@ public class FTP extends SocketClient
***/
public static final int EBCDIC_FILE_TYPE = 1;
/***
* A constant used to indicate the file(s) being transferred should
* be treated as a binary image, i.e., no translations should be
@ -266,8 +265,7 @@ public class FTP extends SocketClient
* <code>DEFAULT_PORT</code> and initializes internal data structures
* for saving FTP reply information.
***/
public FTP()
{
public FTP() {
super();
setDefaultPort(DEFAULT_PORT);
_replyLines = new ArrayList<String>();
@ -288,31 +286,30 @@ public class FTP extends SocketClient
// test that the line starts with a digit rather than starting with
// the code.
private boolean __lenientCheck(String line) {
return (!(line.length() > REPLY_CODE_LEN&& line.charAt(REPLY_CODE_LEN) != '-' &&
Character.isDigit(line.charAt(0))));
return (!(line.length() > REPLY_CODE_LEN
&& line.charAt(REPLY_CODE_LEN) != '-'
&& Character.isDigit(line.charAt(0))));
}
/**
* Get the reply, and pass it to command listeners
*/
private void __getReply() throws IOException
{
private void __getReply() throws IOException {
__getReply(true);
}
/**
* Get the reply, but don't pass it to command listeners.
* Used for keep-alive processing only.
* @since 3.0
*
* @throws IOException on error
* @since 3.0
*/
protected void __getReplyNoReport() throws IOException
{
protected void __getReplyNoReport() throws IOException {
__getReply(false);
}
private void __getReply(boolean reportReply) throws IOException
{
private void __getReply(boolean reportReply) throws IOException {
int length;
_newReplyString = true;
@ -321,26 +318,21 @@ public class FTP extends SocketClient
String line = _controlInput_.readLine();
if (line == null) {
throw new FTPConnectionClosedException(
"Connection closed without indication.");
throw new FTPConnectionClosedException("Connection closed without indication.");
}
// In case we run into an anomaly we don't want fatal index exceptions
// to be thrown.
length = line.length();
if (length < REPLY_CODE_LEN) {
throw new MalformedServerReplyException(
"Truncated server reply: " + line);
throw new MalformedServerReplyException("Truncated server reply: " + line);
}
String code = null;
try
{
try {
code = line.substring(0, REPLY_CODE_LEN);
_replyCode = Integer.parseInt(code);
}
catch (NumberFormatException e)
{
} catch (NumberFormatException e) {
throw new MalformedServerReplyException(
"Could not parse response code.\nServer Reply: " + line);
}
@ -352,13 +344,11 @@ public class FTP extends SocketClient
char sep = line.charAt(REPLY_CODE_LEN);
// Get extra lines if message continues.
if (sep == '-') {
do
{
do {
line = _controlInput_.readLine();
if (line == null) {
throw new FTPConnectionClosedException(
"Connection closed without indication.");
throw new FTPConnectionClosedException("Connection closed without indication.");
}
_replyLines.add(line);
@ -366,9 +356,7 @@ public class FTP extends SocketClient
// The length() check handles problems that could arise from readLine()
// returning too soon after encountering a naked CR or some other
// anomaly.
}
while ( isStrictMultilineParsing() ? __strictCheck(line, code) : __lenientCheck(line));
} while (isStrictMultilineParsing() ? __strictCheck(line, code) : __lenientCheck(line));
} else if (isStrictReplyParsing()) {
if (length == REPLY_CODE_LEN + 1) { // expecting some text
throw new MalformedServerReplyException("Truncated server reply: '" + line + "'");
@ -385,7 +373,8 @@ public class FTP extends SocketClient
}
if (_replyCode == FTPReply.SERVICE_NOT_AVAILABLE) {
throw new FTPConnectionClosedException("FTP response 421 received. Server closed connection.");
throw new FTPConnectionClosedException(
"FTP response 421 received. Server closed connection.");
}
}
@ -393,13 +382,10 @@ public class FTP extends SocketClient
* Initiates control connections and gets initial reply.
* Initializes {@link #_controlInput_} and {@link #_controlOutput_}.
*/
@Override
protected void _connectAction_() throws IOException
{
@Override protected void _connectAction_() throws IOException {
_connectAction_(null);
}
/**
* Initiates control connections and gets initial reply.
* Initializes {@link #_controlInput_} and {@link #_controlOutput_}.
@ -411,13 +397,11 @@ public class FTP extends SocketClient
protected void _connectAction_(Reader socketIsReader) throws IOException {
super._connectAction_(); // sets up _input_ and _output_
if (socketIsReader == null) {
_controlInput_ =
new CRLFLineReader(new InputStreamReader(_input_, getControlEncoding()));
_controlInput_ = new CRLFLineReader(new InputStreamReader(_input_, getControlEncoding()));
} else {
_controlInput_ = new CRLFLineReader(socketIsReader);
}
_controlOutput_ =
new BufferedWriter(new OutputStreamWriter(_output_, getControlEncoding()));
_controlOutput_ = new BufferedWriter(new OutputStreamWriter(_output_, getControlEncoding()));
if (connectTimeout > 0) { // NET-385
int original = _socket_.getSoTimeout();
_socket_.setSoTimeout(connectTimeout);
@ -443,7 +427,6 @@ public class FTP extends SocketClient
}
}
/**
* Saves the character encoding to be used by the FTP control connection.
* Some FTP servers require that commands be issued in a non-ASCII
@ -458,7 +441,6 @@ public class FTP extends SocketClient
_controlEncoding = encoding;
}
/**
* @return The character encoding used to communicate over the
* control connection.
@ -467,7 +449,6 @@ public class FTP extends SocketClient
return _controlEncoding;
}
/***
* Closes the control connection to the FTP server and sets to null
* some internal data so that the memory may be reclaimed by the
@ -477,9 +458,7 @@ public class FTP extends SocketClient
*
* @throws IOException If an error occurs while disconnecting.
***/
@Override
public void disconnect() throws IOException
{
@Override public void disconnect() throws IOException {
super.disconnect();
_controlInput_ = null;
_controlOutput_ = null;
@ -487,7 +466,6 @@ public class FTP extends SocketClient
_replyString = null;
}
/***
* Sends an FTP command to the server, waits for a reply and returns the
* numerical response code. After invocation, for more detailed
@ -508,8 +486,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int sendCommand(String command, String args) throws IOException
{
public int sendCommand(String command, String args) throws IOException {
if (_controlOutput_ == null) {
throw new IOException("Connection is not open");
}
@ -529,8 +506,7 @@ public class FTP extends SocketClient
__commandBuffer.append(command);
if (args != null)
{
if (args != null) {
__commandBuffer.append(' ');
__commandBuffer.append(args);
}
@ -538,20 +514,15 @@ public class FTP extends SocketClient
return __commandBuffer.toString();
}
private void __send(String message) throws IOException,
FTPConnectionClosedException, SocketException {
private void __send(String message)
throws IOException, FTPConnectionClosedException, SocketException {
try {
_controlOutput_.write(message);
_controlOutput_.flush();
}
catch (SocketException e)
{
if (!isConnected())
{
} catch (SocketException e) {
if (!isConnected()) {
throw new FTPConnectionClosedException("Connection unexpectedly closed.");
}
else
{
} else {
throw e;
}
}
@ -592,9 +563,7 @@ public class FTP extends SocketClient
* command or receiving the server reply.
* @deprecated (3.3) Use {@link #sendCommand(FTPCmd, String)} instead
***/
@Deprecated
public int sendCommand(int command, String args) throws IOException
{
@Deprecated public int sendCommand(int command, String args) throws IOException {
return sendCommand(FTPCommand.getCommand(command), args);
}
@ -609,8 +578,8 @@ public class FTP extends SocketClient
* to send.
* @return The integer value of the FTP reply code returned by the server
* in response to the command.
* @throws FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a
* result
* 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.
@ -635,8 +604,8 @@ public class FTP extends SocketClient
* set to null, then the command is sent with no argument.
* @return The integer value of the FTP reply code returned by the server
* in response to the command.
* @throws FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a
* result
* 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.
@ -666,12 +635,10 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int sendCommand(String command) throws IOException
{
public int sendCommand(String command) throws IOException {
return sendCommand(command, null);
}
/***
* Sends an FTP command with no arguments to the server, waits for a
* reply and returns the numerical response code. After invocation, for
@ -691,12 +658,10 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int sendCommand(int command) throws IOException
{
public int sendCommand(int command) throws IOException {
return sendCommand(command, null);
}
/***
* Returns the integer value of the reply code of the last FTP reply.
* You will usually only use this method after you connect to the
@ -705,8 +670,7 @@ public class FTP extends SocketClient
*
* @return The integer value of the reply code of the last FTP reply.
***/
public int getReplyCode()
{
public int getReplyCode() {
return _replyCode;
}
@ -727,13 +691,11 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while receiving the
* server reply.
***/
public int getReply() throws IOException
{
public int getReply() throws IOException {
__getReply();
return _replyCode;
}
/***
* Returns the lines of text from the last FTP server response as an array
* of strings, one entry per line. The end of line markers of each are
@ -741,8 +703,7 @@ public class FTP extends SocketClient
*
* @return The lines of text from the last FTP response as an array.
***/
public String[] getReplyStrings()
{
public String[] getReplyStrings() {
return _replyLines.toArray(new String[_replyLines.size()]);
}
@ -753,8 +714,7 @@ public class FTP extends SocketClient
*
* @return The entire text from the last FTP response as a String.
***/
public String getReplyString()
{
public String getReplyString() {
StringBuilder buffer;
if (!_newReplyString) {
@ -773,7 +733,6 @@ public class FTP extends SocketClient
return (_replyString = buffer.toString());
}
/***
* A convenience method to send the FTP USER command to the server,
* receive the reply, and return the reply code.
@ -788,26 +747,25 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int user(String username) throws IOException
{
public int user(String username) throws IOException {
return sendCommand(FTPCmd.USER, username);
}
/**
* A convenience method to send the FTP PASS command to the server,
* receive the reply, and return the reply code.
*
* @param password The plain text password of the username being logged into.
* @return The reply code received from the server.
* @throws FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a
* result
* 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 IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
*/
public int pass(String password) throws IOException
{
public int pass(String password) throws IOException {
return sendCommand(FTPCmd.PASS, password);
}
@ -825,12 +783,10 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int acct(String account) throws IOException
{
public int acct(String account) throws IOException {
return sendCommand(FTPCmd.ACCT, account);
}
/***
* A convenience method to send the FTP ABOR command to the server,
* receive the reply, and return the reply code.
@ -844,8 +800,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int abor() throws IOException
{
public int abor() throws IOException {
return sendCommand(FTPCmd.ABOR);
}
@ -863,8 +818,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int cwd(String directory) throws IOException
{
public int cwd(String directory) throws IOException {
return sendCommand(FTPCmd.CWD, directory);
}
@ -881,8 +835,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int cdup() throws IOException
{
public int cdup() throws IOException {
return sendCommand(FTPCmd.CDUP);
}
@ -899,8 +852,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int quit() throws IOException
{
public int quit() throws IOException {
return sendCommand(FTPCmd.QUIT);
}
@ -917,8 +869,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int rein() throws IOException
{
public int rein() throws IOException {
return sendCommand(FTPCmd.REIN);
}
@ -936,8 +887,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int smnt(String dir) throws IOException
{
public int smnt(String dir) throws IOException {
return sendCommand(FTPCmd.SMNT, dir);
}
@ -956,8 +906,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int port(InetAddress host, int port) throws IOException
{
public int port(InetAddress host, int port) throws IOException {
int num;
StringBuilder info = new StringBuilder(24);
@ -996,8 +945,7 @@ public class FTP extends SocketClient
* command or receiving the server reply.
* @since 2.2
***/
public int eprt(InetAddress host, int port) throws IOException
{
public int eprt(InetAddress host, int port) throws IOException {
int num;
StringBuilder info = new StringBuilder();
String h;
@ -1040,8 +988,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int pasv() throws IOException
{
public int pasv() throws IOException {
return sendCommand(FTPCmd.PASV);
}
@ -1061,30 +1008,29 @@ public class FTP extends SocketClient
* command or receiving the server reply.
* @since 2.2
***/
public int epsv() throws IOException
{
public int epsv() throws IOException {
return sendCommand(FTPCmd.EPSV);
}
/**
* A convenience method to send the FTP TYPE command for text files
* to the server, receive the reply, and return the reply code.
*
* @param fileType The type of the file (one of the <code>FILE_TYPE</code>
* constants).
* @param formatOrByteSize The format of the file (one of the
* <code>_FORMAT</code> constants. In the case of
* <code>LOCAL_FILE_TYPE</code>, the byte size.
* @return The reply code received from the server.
* @throws FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a
* result
* 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 IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
*/
public int type(int fileType, int formatOrByteSize) throws IOException
{
public int type(int fileType, int formatOrByteSize) throws IOException {
StringBuilder arg = new StringBuilder();
arg.append(__modes.charAt(fileType));
@ -1098,7 +1044,6 @@ public class FTP extends SocketClient
return sendCommand(FTPCmd.TYPE, arg.toString());
}
/**
* A convenience method to send the FTP TYPE command to the server,
* receive the reply, and return the reply code.
@ -1106,18 +1051,16 @@ public class FTP extends SocketClient
* @param fileType The type of the file (one of the <code>FILE_TYPE</code>
* constants).
* @return The reply code received from the server.
* @throws FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a
* result
* 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 IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
*/
public int type(int fileType) throws IOException
{
return sendCommand(FTPCmd.TYPE,
__modes.substring(fileType, fileType + 1));
public int type(int fileType) throws IOException {
return sendCommand(FTPCmd.TYPE, __modes.substring(fileType, fileType + 1));
}
/***
@ -1135,10 +1078,8 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int stru(int structure) throws IOException
{
return sendCommand(FTPCmd.STRU,
__modes.substring(structure, structure + 1));
public int stru(int structure) throws IOException {
return sendCommand(FTPCmd.STRU, __modes.substring(structure, structure + 1));
}
/***
@ -1156,10 +1097,8 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int mode(int mode) throws IOException
{
return sendCommand(FTPCmd.MODE,
__modes.substring(mode, mode + 1));
public int mode(int mode) throws IOException {
return sendCommand(FTPCmd.MODE, __modes.substring(mode, mode + 1));
}
/***
@ -1179,8 +1118,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int retr(String pathname) throws IOException
{
public int retr(String pathname) throws IOException {
return sendCommand(FTPCmd.RETR, pathname);
}
@ -1202,8 +1140,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int stor(String pathname) throws IOException
{
public int stor(String pathname) throws IOException {
return sendCommand(FTPCmd.STOR, pathname);
}
@ -1223,8 +1160,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int stou() throws IOException
{
public int stou() throws IOException {
return sendCommand(FTPCmd.STOU);
}
@ -1246,8 +1182,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
*/
public int stou(String pathname) throws IOException
{
public int stou(String pathname) throws IOException {
return sendCommand(FTPCmd.STOU, pathname);
}
@ -1269,8 +1204,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int appe(String pathname) throws IOException
{
public int appe(String pathname) throws IOException {
return sendCommand(FTPCmd.APPE, pathname);
}
@ -1288,21 +1222,20 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int allo(int bytes) throws IOException
{
public int allo(int bytes) throws IOException {
return sendCommand(FTPCmd.ALLO, Integer.toString(bytes));
}
/**
* A convenience method to send the FTP FEAT command to the server, receive the reply,
* and return the reply code.
*
* @return The reply code received by the server
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
* @since 2.2
*/
public int feat() throws IOException
{
public int feat() throws IOException {
return sendCommand(FTPCmd.FEAT);
}
@ -1321,10 +1254,8 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int allo(int bytes, int recordSize) throws IOException
{
return sendCommand(FTPCmd.ALLO, Integer.toString(bytes) + " R " +
Integer.toString(recordSize));
public int allo(int bytes, int recordSize) throws IOException {
return sendCommand(FTPCmd.ALLO, Integer.toString(bytes) + " R " + Integer.toString(recordSize));
}
/***
@ -1341,24 +1272,20 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int rest(String marker) throws IOException
{
public int rest(String marker) throws IOException {
return sendCommand(FTPCmd.REST, marker);
}
/**
* @param file name of file
* @return the status
* @throws IOException on error
* @since 2.0
**/
public int mdtm(String file) throws IOException
{
public int mdtm(String file) throws IOException {
return sendCommand(FTPCmd.MDTM, file);
}
/**
* A convenience method to send the FTP MFMT command to the server,
* receive the reply, and return the reply code.
@ -1366,22 +1293,20 @@ public class FTP extends SocketClient
* @param pathname The pathname for which mtime is to be changed
* @param timeval Timestamp in <code>YYYYMMDDhhmmss</code> format
* @return The reply code received from the server.
* @throws FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a
* result
* 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 IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
* @since 2.2
* @see <a href="http://tools.ietf.org/html/draft-somers-ftp-mfxx-04">http://tools.ietf.org/html/draft-somers-ftp-mfxx-04</a>
* @since 2.2
**/
public int mfmt(String pathname, String timeval) throws IOException
{
public int mfmt(String pathname, String timeval) throws IOException {
return sendCommand(FTPCmd.MFMT, timeval + " " + pathname);
}
/***
* A convenience method to send the FTP RNFR command to the server,
* receive the reply, and return the reply code.
@ -1396,8 +1321,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int rnfr(String pathname) throws IOException
{
public int rnfr(String pathname) throws IOException {
return sendCommand(FTPCmd.RNFR, pathname);
}
@ -1415,8 +1339,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int rnto(String pathname) throws IOException
{
public int rnto(String pathname) throws IOException {
return sendCommand(FTPCmd.RNTO, pathname);
}
@ -1434,8 +1357,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int dele(String pathname) throws IOException
{
public int dele(String pathname) throws IOException {
return sendCommand(FTPCmd.DELE, pathname);
}
@ -1453,8 +1375,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int rmd(String pathname) throws IOException
{
public int rmd(String pathname) throws IOException {
return sendCommand(FTPCmd.RMD, pathname);
}
@ -1472,8 +1393,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int mkd(String pathname) throws IOException
{
public int mkd(String pathname) throws IOException {
return sendCommand(FTPCmd.MKD, pathname);
}
@ -1490,8 +1410,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int pwd() throws IOException
{
public int pwd() throws IOException {
return sendCommand(FTPCmd.PWD);
}
@ -1511,8 +1430,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int list() throws IOException
{
public int list() throws IOException {
return sendCommand(FTPCmd.LIST);
}
@ -1534,8 +1452,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int list(String pathname) throws IOException
{
public int list(String pathname) throws IOException {
return sendCommand(FTPCmd.LIST, pathname);
}
@ -1547,8 +1464,8 @@ public class FTP extends SocketClient
* , which will handle all low level details for you.
*
* @return The reply code received from the server.
* @throws FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a
* result
* 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.
@ -1556,8 +1473,7 @@ public class FTP extends SocketClient
* command or receiving the server reply.
* @since 3.0
*/
public int mlsd() throws IOException
{
public int mlsd() throws IOException {
return sendCommand(FTPCmd.MLSD);
}
@ -1571,8 +1487,8 @@ public class FTP extends SocketClient
* @param path the path to report on
* @return The reply code received from the server,
* may be {@code null} in which case the command is sent with no parameters
* @throws FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a
* result
* 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.
@ -1580,8 +1496,7 @@ public class FTP extends SocketClient
* command or receiving the server reply.
* @since 3.0
*/
public int mlsd(String path) throws IOException
{
public int mlsd(String path) throws IOException {
return sendCommand(FTPCmd.MLSD, path);
}
@ -1593,8 +1508,8 @@ public class FTP extends SocketClient
* , which will handle all low level details for you.
*
* @return The reply code received from the server.
* @throws FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a
* result
* 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.
@ -1602,8 +1517,7 @@ public class FTP extends SocketClient
* command or receiving the server reply.
* @since 3.0
*/
public int mlst() throws IOException
{
public int mlst() throws IOException {
return sendCommand(FTPCmd.MLST);
}
@ -1617,8 +1531,8 @@ public class FTP extends SocketClient
* @param path the path to report on
* @return The reply code received from the server,
* may be {@code null} in which case the command is sent with no parameters
* @throws FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a
* result
* 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.
@ -1626,8 +1540,7 @@ public class FTP extends SocketClient
* command or receiving the server reply.
* @since 3.0
*/
public int mlst(String path) throws IOException
{
public int mlst(String path) throws IOException {
return sendCommand(FTPCmd.MLST, path);
}
@ -1647,8 +1560,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int nlst() throws IOException
{
public int nlst() throws IOException {
return sendCommand(FTPCmd.NLST);
}
@ -1670,8 +1582,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int nlst(String pathname) throws IOException
{
public int nlst(String pathname) throws IOException {
return sendCommand(FTPCmd.NLST, pathname);
}
@ -1689,8 +1600,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int site(String parameters) throws IOException
{
public int site(String parameters) throws IOException {
return sendCommand(FTPCmd.SITE, parameters);
}
@ -1707,8 +1617,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int syst() throws IOException
{
public int syst() throws IOException {
return sendCommand(FTPCmd.SYST);
}
@ -1725,8 +1634,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int stat() throws IOException
{
public int stat() throws IOException {
return sendCommand(FTPCmd.STAT);
}
@ -1744,8 +1652,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int stat(String pathname) throws IOException
{
public int stat(String pathname) throws IOException {
return sendCommand(FTPCmd.STAT, pathname);
}
@ -1762,8 +1669,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int help() throws IOException
{
public int help() throws IOException {
return sendCommand(FTPCmd.HELP);
}
@ -1781,8 +1687,7 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int help(String command) throws IOException
{
public int help(String command) throws IOException {
return sendCommand(FTPCmd.HELP, command);
}
@ -1799,13 +1704,13 @@ public class FTP extends SocketClient
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int noop() throws IOException
{
public int noop() throws IOException {
return sendCommand(FTPCmd.NOOP);
}
/**
* Return whether strict multiline parsing is enabled, as per RFC 959, section 4.2.
*
* @return True if strict, false if lenient
* @since 2.0
*/
@ -1815,6 +1720,7 @@ public class FTP extends SocketClient
/**
* Set strict multiline parsing.
*
* @param strictMultilineParsing the setting
* @since 2.0
*/
@ -1829,6 +1735,7 @@ public class FTP extends SocketClient
* <br>
* If false, only the 3 digit code is required (as was the case for versions up to 3.5)
* <br>
*
* @return True if strict (default), false if additional checks are not made
* @since 3.6
*/
@ -1845,6 +1752,7 @@ public class FTP extends SocketClient
* <p>
* <b>This should not be required by a well-behaved FTP server</b>
* <br>
*
* @param strictReplyParsing the setting
* @since 3.6
*/
@ -1855,8 +1763,7 @@ public class FTP extends SocketClient
/**
* Provide command support to super-class
*/
@Override
protected ProtocolCommandSupport getCommandSupport() {
@Override protected ProtocolCommandSupport getCommandSupport() {
return _commandSupport_;
}
}

@ -129,14 +129,13 @@ import java.util.TreeMap;
* FTPFile[] files = listFiles(directory);
* </pre>
*
* @since 1.4
* @see Configurable
* @see FTPClient
* @see org.apache.commons.net.ftp.parser.FTPTimestampParserImpl#configure(FTPClientConfig)
* @see org.apache.commons.net.ftp.parser.ConfigurableFTPFileEntryParserImpl
* @since 1.4
*/
public class FTPClientConfig
{
public class FTPClientConfig {
/**
* Identifier by which a unix-based ftp server is known throughout
@ -149,6 +148,7 @@ public class FTPClientConfig
* trimmed from file names. This is to maintain backwards compatibility with
* the original behaviour of the parser which ignored multiple spaces between the date
* and the start of the file name.
*
* @since 3.4
*/
public static final String SYST_UNIX_TRIM_LEADING = "UNIX_LTRIM";
@ -228,9 +228,9 @@ public class FTPClientConfig
private String serverTimeZoneId = null;
private boolean saveUnparseableEntries = false;
/**
* The main constructor for an FTPClientConfig object
*
* @param systemKey key representing system type of the server being
* connected to. See {@link #getServerSystemKey() serverSystemKey}
* If set to the empty string, then FTPClient uses the system type returned by the server.
@ -251,6 +251,7 @@ public class FTPClientConfig
/**
* Constructor which allows setting of the format string member fields
*
* @param systemKey key representing system type of the server being
* connected to. See
* {@link #getServerSystemKey() serverSystemKey}
@ -260,10 +261,8 @@ public class FTPClientConfig
* {@link #setRecentDateFormatStr(String) recentDateFormatStr}
* @since 3.6
*/
public FTPClientConfig(String systemKey,
String defaultDateFormatStr,
String recentDateFormatStr)
{
public FTPClientConfig(String systemKey, String defaultDateFormatStr,
String recentDateFormatStr) {
this(systemKey);
this.defaultDateFormatStr = defaultDateFormatStr;
this.recentDateFormatStr = recentDateFormatStr;
@ -271,6 +270,7 @@ public class FTPClientConfig
/**
* Constructor which allows setting of most member fields
*
* @param systemKey key representing system type of the server being
* connected to. See
* {@link #getServerSystemKey() serverSystemKey}
@ -285,13 +285,8 @@ public class FTPClientConfig
* @param serverTimeZoneId See
* {@link #setServerTimeZoneId(String) serverTimeZoneId}
*/
public FTPClientConfig(String systemKey,
String defaultDateFormatStr,
String recentDateFormatStr,
String serverLanguageCode,
String shortMonthNames,
String serverTimeZoneId)
{
public FTPClientConfig(String systemKey, String defaultDateFormatStr, String recentDateFormatStr,
String serverLanguageCode, String shortMonthNames, String serverTimeZoneId) {
this(systemKey);
this.defaultDateFormatStr = defaultDateFormatStr;
this.recentDateFormatStr = recentDateFormatStr;
@ -302,6 +297,7 @@ public class FTPClientConfig
/**
* Constructor which allows setting of all member fields
*
* @param systemKey key representing system type of the server being
* connected to. See
* {@link #getServerSystemKey() serverSystemKey}
@ -320,15 +316,9 @@ public class FTPClientConfig
* @param saveUnparseableEntries See
* {@link #setUnparseableEntries(boolean) saveUnparseableEntries}
*/
public FTPClientConfig(String systemKey,
String defaultDateFormatStr,
String recentDateFormatStr,
String serverLanguageCode,
String shortMonthNames,
String serverTimeZoneId,
boolean lenientFutureDates,
boolean saveUnparseableEntries)
{
public FTPClientConfig(String systemKey, String defaultDateFormatStr, String recentDateFormatStr,
String serverLanguageCode, String shortMonthNames, String serverTimeZoneId,
boolean lenientFutureDates, boolean saveUnparseableEntries) {
this(systemKey);
this.defaultDateFormatStr = defaultDateFormatStr;
this.lenientFutureDates = lenientFutureDates;
@ -353,6 +343,7 @@ public class FTPClientConfig
/**
* Copy constructor
*
* @param config source
* @since 3.6
*/
@ -368,13 +359,12 @@ public class FTPClientConfig
}
private static final Map<String, Object> LANGUAGE_CODE_MAP = new TreeMap<String, Object>();
static {
// if there are other commonly used month name encodings which
// correspond to particular locales, please add them here.
// many locales code short names for months as all three letters
// these we handle simply.
LANGUAGE_CODE_MAP.put("en", Locale.ENGLISH);
@ -392,11 +382,9 @@ public class FTPClientConfig
LANGUAGE_CODE_MAP.put("sk", new Locale("sk", "", "")); // slovak
LANGUAGE_CODE_MAP.put("sl", new Locale("sl", "", "")); // slovenian
// some don't
LANGUAGE_CODE_MAP.put("fr",
"jan|f\u00e9v|mar|avr|mai|jun|jui|ao\u00fb|sep|oct|nov|d\u00e9c"); //french
}
/**
@ -406,6 +394,7 @@ public class FTPClientConfig
* or else the fully qualified class name of a parser implementing both
* the <code>FTPFileEntryParser</code> and <code>Configurable</code>
* interfaces.
*
* @return Returns the serverSystemKey property.
*/
public String getServerSystemKey() {
@ -415,6 +404,7 @@ public class FTPClientConfig
/**
* getter for the {@link #setDefaultDateFormatStr(String) defaultDateFormatStr}
* property.
*
* @return Returns the defaultDateFormatStr property.
*/
public String getDefaultDateFormatStr() {
@ -423,6 +413,7 @@ public class FTPClientConfig
/**
* getter for the {@link #setRecentDateFormatStr(String) recentDateFormatStr} property.
*
* @return Returns the recentDateFormatStr property.
*/
@ -432,6 +423,7 @@ public class FTPClientConfig
/**
* getter for the {@link #setServerTimeZoneId(String) serverTimeZoneId} property.
*
* @return Returns the serverTimeZoneId property.
*/
public String getServerTimeZoneId() {
@ -443,6 +435,7 @@ public class FTPClientConfig
* getter for the {@link #setShortMonthNames(String) shortMonthNames}
* property.
* </p>
*
* @return Returns the shortMonthNames.
*/
public String getShortMonthNames() {
@ -453,6 +446,7 @@ public class FTPClientConfig
* <p>
* getter for the {@link #setServerLanguageCode(String) serverLanguageCode} property.
* </p>
*
* @return Returns the serverLanguageCode property.
*/
public String getServerLanguageCode() {
@ -463,12 +457,14 @@ public class FTPClientConfig
* <p>
* getter for the {@link #setLenientFutureDates(boolean) lenientFutureDates} property.
* </p>
*
* @return Returns the lenientFutureDates.
* @since 1.5
*/
public boolean isLenientFutureDates() {
return lenientFutureDates;
}
/**
* <p>
* setter for the defaultDateFormatStr property. This property
@ -481,6 +477,7 @@ public class FTPClientConfig
* <code>java.text.SimpleDateFormat</code>.
* property.
* </p>
*
* @param defaultDateFormatStr The defaultDateFormatStr to set.
*/
public void setDefaultDateFormatStr(String defaultDateFormatStr) {
@ -502,6 +499,7 @@ public class FTPClientConfig
* This should be in the format described for
* <code>java.text.SimpleDateFormat</code>.
* </p>
*
* @param recentDateFormatStr The recentDateFormatStr to set.
*/
public void setRecentDateFormatStr(String recentDateFormatStr) {
@ -525,12 +523,14 @@ public class FTPClientConfig
* </p><p>
* This is used primarily in unix-based systems.
* </p>
*
* @param lenientFutureDates set true to compensate for out-of-synch
* conditions.
*/
public void setLenientFutureDates(boolean lenientFutureDates) {
this.lenientFutureDates = lenientFutureDates;
}
/**
* <p>
* setter for the serverTimeZoneId property. This property
@ -543,6 +543,7 @@ public class FTPClientConfig
* <code>java.util.TimeZone</code> to refer to time zones, for example,
* <code>America/Chicago</code> or <code>Asia/Rangoon</code>.
* </p>
*
* @param serverTimeZoneId The serverTimeZoneId to set.
*/
public void setServerTimeZoneId(String serverTimeZoneId) {
@ -564,6 +565,7 @@ public class FTPClientConfig
* conceivably be specified as
* <code>"jan|feb|mar|apr|ma&#xED;|j&#xFA;n|j&#xFA;l|&#xE1;g&#xFA;|sep|okt|n&#xF3;v|des"</code>.
* </p>
*
* @param shortMonthNames The value to set to the shortMonthNames property.
*/
public void setShortMonthNames(String shortMonthNames) {
@ -608,6 +610,7 @@ public class FTPClientConfig
* via the {@link #setDefaultDateFormatStr(String) defaultDateFormatStr} and/or
* {@link #setRecentDateFormatStr(String) recentDateFormatStr} parameters.
* </p>
*
* @param serverLanguageCode The value to set to the serverLanguageCode property.
*/
public void setServerLanguageCode(String serverLanguageCode) {
@ -620,14 +623,14 @@ public class FTPClientConfig
* short month names corresponding to the code. If there is no corresponding
* entry in the table, the object returned will be that for
* <code>Locale.US</code>
*
* @param languageCode See {@link #setServerLanguageCode(String) serverLanguageCode}
* @return a DateFormatSymbols object configured with short month names
* corresponding to the supplied code, or with month names for
* <code>Locale.US</code> if there is no corresponding entry in the internal
* table.
*/
public static DateFormatSymbols lookupDateFormatSymbols(String languageCode)
{
public static DateFormatSymbols lookupDateFormatSymbols(String languageCode) {
Object lang = LANGUAGE_CODE_MAP.get(languageCode);
if (lang != null) {
if (lang instanceof Locale) {
@ -642,13 +645,13 @@ public class FTPClientConfig
/**
* Returns a DateFormatSymbols object configured with short month names
* as in the supplied string
*
* @param shortmonths This should be as described in
* {@link #setShortMonthNames(String) shortMonthNames}
* @return a DateFormatSymbols object configured with short month names
* as in the supplied string
*/
public static DateFormatSymbols getDateFormatSymbols(String shortmonths)
{
public static DateFormatSymbols getDateFormatSymbols(String shortmonths) {
String[] months = splitShortMonthString(shortmonths);
DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
dfs.setShortMonths(months);
@ -659,8 +662,7 @@ public class FTPClientConfig
StringTokenizer st = new StringTokenizer(shortmonths, "|");
int monthcnt = st.countTokens();
if (12 != monthcnt) {
throw new IllegalArgumentException(
"expecting a pipe-delimited string containing 12 tokens");
throw new IllegalArgumentException("expecting a pipe-delimited string containing 12 tokens");
}
String[] months = new String[13];
int pos = 0;
@ -688,6 +690,7 @@ public class FTPClientConfig
* <p>
* In this case, the FTPFile will contain only the unparsed entry {@link FTPFile#getRawListing()}
* and {@link FTPFile#isValid()} will return {@code false}
*
* @param saveUnparseable if true, then create FTPFile entries if parsing fails
* @since 3.4
*/
@ -705,5 +708,4 @@ public class FTPClientConfig
public boolean getUnparseableEntries() {
return this.saveUnparseableEntries;
}
}

@ -22,47 +22,7 @@ package org.apache.commons.net.ftp;
* @since 3.3
*/
public enum FTPCmd {
ABOR,
ACCT,
ALLO,
APPE,
CDUP,
CWD,
DELE,
EPRT,
EPSV,
FEAT,
HELP,
LIST,
MDTM,
MFMT,
MKD,
MLSD,
MLST,
MODE,
NLST,
NOOP,
PASS,
PASV,
PORT,
PWD,
QUIT,
REIN,
REST,
RETR,
RMD,
RNFR,
RNTO,
SITE,
SMNT,
STAT,
STOR,
STOU,
STRU,
SYST,
TYPE,
USER,
;
ABOR, ACCT, ALLO, APPE, CDUP, CWD, DELE, EPRT, EPSV, FEAT, HELP, LIST, MDTM, MFMT, MKD, MLSD, MLST, MODE, NLST, NOOP, PASS, PASV, PORT, PWD, QUIT, REIN, REST, RETR, RMD, RNFR, RNTO, SITE, SMNT, STAT, STOR, STOU, STRU, SYST, TYPE, USER,;
// Aliases
@ -108,8 +68,7 @@ public enum FTPCmd {
* @return The FTP protcol command string corresponding to a specified
* command code.
*/
public final String getCommand()
{
public final String getCommand() {
return this.name();
}

@ -27,9 +27,7 @@ package org.apache.commons.net.ftp;
*
* @deprecated use {@link FTPCmd} instead
*/
@Deprecated
public final class FTPCommand
{
@Deprecated public final class FTPCommand {
public static final int USER = 0;
public static final int PASS = 1;
@ -77,12 +75,14 @@ public final class FTPCommand
/**
* Machine parseable list for a directory
*
* @since 3.0
*/
public static final int MLSD = 38;
/**
* Machine parseable list for a single file
*
* @since 3.0
*/
public static final int MLST = 39;
@ -135,24 +135,24 @@ public final class FTPCommand
public static final int SET_MOD_TIME = MFMT;
// Cannot be instantiated
private FTPCommand()
{}
private FTPCommand() {
}
private static final String[] _commands = {
"USER", "PASS", "ACCT", "CWD", "CDUP", "SMNT", "REIN", "QUIT", "PORT",
"PASV", "TYPE", "STRU", "MODE", "RETR", "STOR", "STOU", "APPE", "ALLO",
"REST", "RNFR", "RNTO", "ABOR", "DELE", "RMD", "MKD", "PWD", "LIST",
"NLST", "SITE", "SYST", "STAT", "HELP", "NOOP", "MDTM", "FEAT", "MFMT",
"EPSV", "EPRT", "MLSD", "MLST" };
"USER", "PASS", "ACCT", "CWD", "CDUP", "SMNT", "REIN", "QUIT", "PORT", "PASV", "TYPE", "STRU",
"MODE", "RETR", "STOR", "STOU", "APPE", "ALLO", "REST", "RNFR", "RNTO", "ABOR", "DELE", "RMD",
"MKD", "PWD", "LIST", "NLST", "SITE", "SYST", "STAT", "HELP", "NOOP", "MDTM", "FEAT", "MFMT",
"EPSV", "EPRT", "MLSD", "MLST"
};
// default access needed for Unit test
static void checkArray() {
int expectedLength = LAST + 1;
if (_commands.length != expectedLength) {
throw new RuntimeException("Incorrect _commands array. Should have length "
+expectedLength+" found "+_commands.length);
+ expectedLength
+ " found "
+ _commands.length);
}
}
@ -164,8 +164,7 @@ public final class FTPCommand
* @return The FTP protcol command string corresponding to a specified
* command code.
*/
public static final String getCommand(int command)
{
public static final String getCommand(int command) {
return _commands[command];
}
}

@ -16,6 +16,7 @@
*/
package org.apache.commons.net.ftp;
import java.io.IOException;
/***
@ -31,14 +32,12 @@ import java.io.IOException;
* @see FTPClient
***/
public class FTPConnectionClosedException extends IOException
{
public class FTPConnectionClosedException extends IOException {
private static final long serialVersionUID = 3500547241659379952L;
/*** Constructs a FTPConnectionClosedException with no message ***/
public FTPConnectionClosedException()
{
public FTPConnectionClosedException() {
super();
}
@ -47,9 +46,7 @@ public class FTPConnectionClosedException extends IOException
*
* @param message The message explaining the reason for the exception.
***/
public FTPConnectionClosedException(String message)
{
public FTPConnectionClosedException(String message) {
super(message);
}
}

@ -16,6 +16,7 @@
*/
package org.apache.commons.net.ftp;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
@ -30,8 +31,7 @@ import java.util.TimeZone;
* @see FTPClient#listFiles
***/
public class FTPFile implements Serializable
{
public class FTPFile implements Serializable {
private static final long serialVersionUID = 9010790363003271996L;
/** A constant indicating an FTPFile is a file. ***/
@ -68,8 +68,7 @@ public class FTPFile implements Serializable
private final boolean[] _permissions[]; // e.g. _permissions[USER_ACCESS][READ_PERMISSION]
/*** Creates an empty FTPFile. ***/
public FTPFile()
{
public FTPFile() {
_permissions = new boolean[3][3];
_type = UNKNOWN_TYPE;
// init these to values that do not occur in listings
@ -85,11 +84,11 @@ public class FTPFile implements Serializable
/**
* Constructor for use by {@link FTPListParseEngine} only.
* Used to create FTPFile entries for failed parses
*
* @param rawListing line that could not be parsed.
* @since 3.4
*/
FTPFile(String rawListing)
{
FTPFile(String rawListing) {
_permissions = null; // flag that entry is invalid
_rawListing = rawListing;
_type = UNKNOWN_TYPE;
@ -103,15 +102,13 @@ public class FTPFile implements Serializable
_name = null;
}
/***
* Set the original FTP server raw listing from which the FTPFile was
* created.
*
* @param rawListing The raw FTP server listing.
***/
public void setRawListing(String rawListing)
{
public void setRawListing(String rawListing) {
_rawListing = rawListing;
}
@ -121,20 +118,17 @@ public class FTPFile implements Serializable
* @return The original FTP server raw listing used to initialize the
* FTPFile.
***/
public String getRawListing()
{
public String getRawListing() {
return _rawListing;
}
/***
* Determine if the file is a directory.
*
* @return True if the file is of type <code>DIRECTORY_TYPE</code>, false if
* not.
***/
public boolean isDirectory()
{
public boolean isDirectory() {
return (_type == DIRECTORY_TYPE);
}
@ -144,8 +138,7 @@ public class FTPFile implements Serializable
* @return True if the file is of type <code>FILE_TYPE</code>, false if
* not.
***/
public boolean isFile()
{
public boolean isFile() {
return (_type == FILE_TYPE);
}
@ -155,8 +148,7 @@ public class FTPFile implements Serializable
* @return True if the file is of type <code>UNKNOWN_TYPE</code>, false if
* not.
***/
public boolean isSymbolicLink()
{
public boolean isSymbolicLink() {
return (_type == SYMBOLIC_LINK_TYPE);
}
@ -166,8 +158,7 @@ public class FTPFile implements Serializable
* @return True if the file is of type <code>UNKNOWN_TYPE</code>, false if
* not.
***/
public boolean isUnknown()
{
public boolean isUnknown() {
return (_type == UNKNOWN_TYPE);
}
@ -177,8 +168,9 @@ public class FTPFile implements Serializable
* Other methods may fail.
*
* Used in conjunction with list parsing that preseverves entries that failed to parse.
* @see FTPClientConfig#setUnparseableEntries(boolean)
*
* @return true if the entry is valid
* @see FTPClientConfig#setUnparseableEntries(boolean)
* @since 3.4
*/
public boolean isValid() {
@ -191,31 +183,26 @@ public class FTPFile implements Serializable
*
* @param type The integer code representing the type of the file.
***/
public void setType(int type)
{
public void setType(int type) {
_type = type;
}
/***
* Return the type of the file (one of the <code>_TYPE</code> constants),
* e.g., if it is a directory, a regular file, or a symbolic link.
*
* @return The type of the file.
***/
public int getType()
{
public int getType() {
return _type;
}
/***
* Set the name of the file.
*
* @param name The name of the file.
***/
public void setName(String name)
{
public void setName(String name) {
_name = name;
}
@ -224,89 +211,75 @@ public class FTPFile implements Serializable
*
* @return The name of the file.
***/
public String getName()
{
public String getName() {
return _name;
}
/**
* Set the file size in bytes.
*
* @param size The file size in bytes.
*/
public void setSize(long size)
{
public void setSize(long size) {
_size = size;
}
/***
* Return the file size in bytes.
*
* @return The file size in bytes.
***/
public long getSize()
{
public long getSize() {
return _size;
}
/***
* Set the number of hard links to this file. This is not to be
* confused with symbolic links.
*
* @param links The number of hard links to this file.
***/
public void setHardLinkCount(int links)
{
public void setHardLinkCount(int links) {
_hardLinkCount = links;
}
/***
* Return the number of hard links to this file. This is not to be
* confused with symbolic links.
*
* @return The number of hard links to this file.
***/
public int getHardLinkCount()
{
public int getHardLinkCount() {
return _hardLinkCount;
}
/***
* Set the name of the group owning the file. This may be
* a string representation of the group number.
*
* @param group The name of the group owning the file.
***/
public void setGroup(String group)
{
public void setGroup(String group) {
_group = group;
}
/***
* Returns the name of the group owning the file. Sometimes this will be
* a string representation of the group number.
*
* @return The name of the group owning the file.
***/
public String getGroup()
{
public String getGroup() {
return _group;
}
/***
* Set the name of the user owning the file. This may be
* a string representation of the user number;
*
* @param user The name of the user owning the file.
***/
public void setUser(String user)
{
public void setUser(String user) {
_user = user;
}
@ -316,24 +289,20 @@ public class FTPFile implements Serializable
*
* @return The name of the user owning the file.
***/
public String getUser()
{
public String getUser() {
return _user;
}
/***
* If the FTPFile is a symbolic link, use this method to set the name of the
* file being pointed to by the symbolic link.
*
* @param link The file pointed to by the symbolic link.
***/
public void setLink(String link)
{
public void setLink(String link) {
_link = link;
}
/***
* If the FTPFile is a symbolic link, this method returns the name of the
* file being pointed to by the symbolic link. Otherwise it returns null.
@ -341,12 +310,10 @@ public class FTPFile implements Serializable
* @return The file pointed to by the symbolic link (null if the FTPFile
* is not a symbolic link).
***/
public String getLink()
{
public String getLink() {
return _link;
}
/***
* Set the file timestamp. This usually the last modification time.
* The parameter is not cloned, so do not alter its value after calling
@ -354,23 +321,19 @@ public class FTPFile implements Serializable
*
* @param date A Calendar instance representing the file timestamp.
***/
public void setTimestamp(Calendar date)
{
public void setTimestamp(Calendar date) {
_date = date;
}
/***
* Returns the file timestamp. This usually the last modification time.
*
* @return A Calendar instance representing the file timestamp.
***/
public Calendar getTimestamp()
{
public Calendar getTimestamp() {
return _date;
}
/***
* Set if the given access group (one of the <code> _ACCESS </code>
* constants) has the given access permission (one of the
@ -383,12 +346,10 @@ public class FTPFile implements Serializable
* @param value True if permission is allowed, false if not.
* @throws ArrayIndexOutOfBoundsException if either of the parameters is out of range
***/
public void setPermission(int access, int permission, boolean value)
{
public void setPermission(int access, int permission, boolean value) {
_permissions[access][permission] = value;
}
/***
* Determines if the given access group (one of the <code> _ACCESS </code>
* constants) has the given access permission (one of the
@ -402,8 +363,7 @@ public class FTPFile implements Serializable
* @return true if {@link #isValid()} is {@code true &&} the associated permission is set;
* {@code false} otherwise.
***/
public boolean hasPermission(int access, int permission)
{
public boolean hasPermission(int access, int permission) {
if (_permissions == null) {
return false;
}
@ -415,9 +375,7 @@ public class FTPFile implements Serializable
*
* @return A string representation of the FTPFile information.
*/
@Override
public String toString()
{
@Override public String toString() {
return getRawListing();
}
@ -435,8 +393,7 @@ public class FTPFile implements Serializable
* @return A string representation of the FTPFile information.
* @since 3.0
*/
public String toFormattedString()
{
public String toFormattedString() {
return toFormattedString(null);
}
@ -448,13 +405,13 @@ public class FTPFile implements Serializable
* Note: if the instance is not valid {@link #isValid()}, no useful
* information can be returned. In this case, use {@link #getRawListing()}
* instead.
*
* @param timezone the timezone to use for displaying the time stamp
* If {@code null}, then use the Calendar entry timezone
* @return A string representation of the FTPFile information.
* @since 3.4
*/
public String toFormattedString(final String timezone)
{
public String toFormattedString(final String timezone) {
if (!isValid()) {
return "[Invalid: could not parse file entry]";

@ -16,6 +16,7 @@
*/
package org.apache.commons.net.ftp;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.List;
@ -78,8 +79,7 @@ import java.util.List;
* @see FTPFile
* @see FTPClient#listFiles()
*/
public interface FTPFileEntryParser
{
public interface FTPFileEntryParser {
/**
* Parses a line of an FTP server file listing and converts it into a usable
* format in the form of an <code> FTPFile </code> instance. If the
@ -100,13 +100,11 @@ public interface FTPFileEntryParser
*
* @param reader The BufferedReader object from which entries are to be
* read.
*
* @return A string representing the next ftp entry or null if none found.
* @throws IOException thrown on any IO Error reading from the reader.
*/
String readNextEntry(BufferedReader reader) throws IOException;
/**
* This method is a hook for those implementors (such as
* VMSVersioningFTPEntryParser, and possibly others) which need to
@ -116,12 +114,9 @@ public interface FTPFileEntryParser
* The default implementation can be a no-op.
*
* @param original Original list after it has been created from the server stream
*
* @return Original list as processed by this method.
*/
List<String> preParse(List<String> original);
}

@ -16,6 +16,7 @@
*/
package org.apache.commons.net.ftp;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.List;
@ -24,16 +25,12 @@ import java.util.List;
* This abstract class implements both the older FTPFileListParser and
* newer FTPFileEntryParser interfaces with default functionality.
* All the classes in the parser subpackage inherit from this.
*
*/
public abstract class FTPFileEntryParserImpl
implements FTPFileEntryParser
{
public abstract class FTPFileEntryParserImpl implements FTPFileEntryParser {
/**
* The constructor for a FTPFileEntryParserImpl object.
*/
public FTPFileEntryParserImpl()
{
public FTPFileEntryParserImpl() {
}
/**
@ -43,15 +40,13 @@ public abstract class FTPFileEntryParserImpl
*
* @param reader The BufferedReader object from which entries are to be
* read.
*
* @return A string representing the next ftp entry or null if none found.
* @throws IOException thrown on any IO Error reading from the reader.
*/
@Override
public String readNextEntry(BufferedReader reader) throws IOException
{
@Override public String readNextEntry(BufferedReader reader) throws IOException {
return reader.readLine();
}
/**
* This method is a hook for those implementors (such as
* VMSVersioningFTPEntryParser, and possibly others) which need to
@ -61,11 +56,9 @@ public abstract class FTPFileEntryParserImpl
* This default implementation does nothing.
*
* @param original Original list after it has been created from the server stream
*
* @return <code>original</code> unmodified.
*/
@Override
public List<String> preParse(List<String> original) {
@Override public List<String> preParse(List<String> original) {
return original;
}
}

@ -20,6 +20,7 @@ package org.apache.commons.net.ftp;
/**
* Perform filtering on FTPFile entries.
*
* @since 2.2
*/
public interface FTPFileFilter {

@ -20,6 +20,7 @@ package org.apache.commons.net.ftp;
/**
* Implements some simple FTPFileFilter classes.
*
* @since 2.2
*/
public class FTPFileFilters {
@ -28,8 +29,7 @@ public class FTPFileFilters {
* Accepts all FTPFile entries, including null.
*/
public static final FTPFileFilter ALL = new FTPFileFilter() {
@Override
public boolean accept(FTPFile file) {
@Override public boolean accept(FTPFile file) {
return true;
}
};
@ -38,8 +38,7 @@ public class FTPFileFilters {
* Accepts all non-null FTPFile entries.
*/
public static final FTPFileFilter NON_NULL = new FTPFileFilter() {
@Override
public boolean accept(FTPFile file) {
@Override public boolean accept(FTPFile file) {
return file != null;
}
};
@ -48,10 +47,8 @@ public class FTPFileFilters {
* Accepts all (non-null) FTPFile directory entries.
*/
public static final FTPFileFilter DIRECTORIES = new FTPFileFilter() {
@Override
public boolean accept(FTPFile file) {
@Override public boolean accept(FTPFile file) {
return file != null && file.isDirectory();
}
};
}

@ -60,7 +60,6 @@ public class FTPHTTPClient extends FTPClient {
this(proxyHost, proxyPort, null, null);
}
/**
* {@inheritDoc}
*
@ -69,9 +68,7 @@ public class FTPHTTPClient extends FTPClient {
*/
// Kept to maintain binary compatibility
// Not strictly necessary, but Clirr complains even though there is a super-impl
@Override
@Deprecated
protected Socket _openDataConnection_(int command, String arg)
@Override @Deprecated protected Socket _openDataConnection_(int command, String arg)
throws IOException {
return super._openDataConnection_(command, arg);
}
@ -82,9 +79,7 @@ public class FTPHTTPClient extends FTPClient {
* @throws IllegalStateException if connection mode is not passive
* @since 3.1
*/
@Override
protected Socket _openDataConnection_(String command, String arg)
throws IOException {
@Override protected Socket _openDataConnection_(String command, String arg) throws IOException {
//Force local passive mode, active mode not supported by through proxy
if (getDataConnectionMode() != PASSIVE_LOCAL_DATA_CONNECTION_MODE) {
throw new IllegalStateException("Only passive connection mode supported");
@ -126,8 +121,7 @@ public class FTPHTTPClient extends FTPClient {
return socket;
}
@Override
public void connect(String host, int port) throws SocketException, IOException {
@Override public void connect(String host, int port) throws SocketException, IOException {
_socket_ = _socketFactory_.createSocket(proxyHost, proxyPort);
_input_ = _socket_.getInputStream();
@ -135,8 +129,7 @@ public class FTPHTTPClient extends FTPClient {
Reader socketIsReader;
try {
socketIsReader = tunnelHandshake(host, port, _input_, _output_);
}
catch (Exception e) {
} catch (Exception e) {
IOException ioe = new IOException("Could not connect to " + host + " using port " + port);
ioe.initCause(e);
throw ioe;
@ -144,8 +137,8 @@ public class FTPHTTPClient extends FTPClient {
super._connectAction_(socketIsReader);
}
private BufferedReader tunnelHandshake(String host, int port, InputStream input, OutputStream output) throws IOException,
UnsupportedEncodingException {
private BufferedReader tunnelHandshake(String host, int port, InputStream input,
OutputStream output) throws IOException, UnsupportedEncodingException {
final String connectString = "CONNECT " + host + ":" + port + " HTTP/1.1";
final String hostString = "Host: " + host + ":" + port;
@ -157,18 +150,17 @@ public class FTPHTTPClient extends FTPClient {
if (proxyUsername != null && proxyPassword != null) {
final String auth = proxyUsername + ":" + proxyPassword;
final String header = "Proxy-Authorization: Basic "
+ base64.encodeToString(auth.getBytes("UTF-8"));
final String header =
"Proxy-Authorization: Basic " + base64.encodeToString(auth.getBytes("UTF-8"));
output.write(header.getBytes("UTF-8"));
}
output.write(CRLF);
List<String> response = new ArrayList<String>();
BufferedReader reader = new BufferedReader(
new InputStreamReader(input, getCharset()));
BufferedReader reader = new BufferedReader(new InputStreamReader(input, getCharset()));
for (String line = reader.readLine(); line != null
&& line.length() > 0; line = reader.readLine()) {
for (String line = reader.readLine(); line != null && line.length() > 0;
line = reader.readLine()) {
response.add(line);
}

@ -29,7 +29,6 @@ import java.util.ListIterator;
import org.apache.commons.net.util.Charsets;
/**
* This class handles the entire process of parsing a listing of
* file entries from the server.
@ -73,6 +72,7 @@ import org.apache.commons.net.util.Charsets;
* <p>
* For unpaged access, simply use FTPClient.listFiles(). That method
* uses this class transparently.
*
* @version $Id: FTPListParseEngine.java 1747119 2016-06-07 02:22:24Z ggregory $
*/
public class FTPListParseEngine {
@ -89,6 +89,7 @@ public class FTPListParseEngine {
/**
* Intended for use by FTPClient only
*
* @since 3.4
*/
FTPListParseEngine(FTPFileEntryParser parser, FTPClientConfig configuration) {
@ -108,13 +109,9 @@ public class FTPListParseEngine {
*
* @param stream input stream provided by the server socket.
* @param encoding the encoding to be used for reading the stream
*
* @throws IOException
* thrown on any failure to read from the sever.
* @throws IOException thrown on any failure to read from the sever.
*/
public void readServerList(InputStream stream, String encoding)
throws IOException
{
public void readServerList(InputStream stream, String encoding) throws IOException {
this.entries = new LinkedList<String>();
readStream(stream, encoding);
this.parser.preParse(this.entries);
@ -131,19 +128,15 @@ public class FTPListParseEngine {
*
* @param stream The socket stream on which the input will be read.
* @param encoding The encoding to use.
*
* @throws IOException
* thrown on any failure to read the stream
* @throws IOException thrown on any failure to read the stream
*/
private void readStream(InputStream stream, String encoding) throws IOException
{
BufferedReader reader = new BufferedReader(
new InputStreamReader(stream, Charsets.toCharset(encoding)));
private void readStream(InputStream stream, String encoding) throws IOException {
BufferedReader reader =
new BufferedReader(new InputStreamReader(stream, Charsets.toCharset(encoding)));
String line = this.parser.readNextEntry(reader);
while (line != null)
{
while (line != null) {
this.entries.add(line);
line = this.parser.readNextEntry(reader);
}
@ -161,9 +154,7 @@ public class FTPListParseEngine {
* After this method is called this object's internal iterator is advanced
* by a number of positions equal to the size of the array returned.
*
* @param quantityRequested
* the maximum number of entries we want to get.
*
* @param quantityRequested the maximum number of entries we want to get.
* @return an array of at most <code>quantityRequested</code> FTPFile
* objects starting at the current position of this iterator within its
* list and at least the number of elements which exist in the list at
@ -186,7 +177,6 @@ public class FTPListParseEngine {
count--;
}
return tmpResults.toArray(new FTPFile[tmpResults.size()]);
}
/**
@ -202,9 +192,7 @@ public class FTPListParseEngine {
* After this method is called this object's internal iterator is moved
* back by a number of positions equal to the size of the array returned.
*
* @param quantityRequested
* the maximum number of entries we want to get.
*
* @param quantityRequested the maximum number of entries we want to get.
* @return an array of at most <code>quantityRequested</code> FTPFile
* objects starting at the current position of this iterator within its
* list and at least the number of elements which exist in the list at
@ -239,8 +227,7 @@ public class FTPListParseEngine {
* None of the entries will be null
* @throws IOException - not ever thrown, may be removed in a later release
*/
public FTPFile[] getFiles()
throws IOException // TODO remove; not actually thrown
public FTPFile[] getFiles() throws IOException // TODO remove; not actually thrown
{
return getFiles(FTPFileFilters.NON_NULL);
}
@ -251,7 +238,6 @@ public class FTPListParseEngine {
* The files are filtered before being added to the array.
*
* @param filter FTPFileFilter, must not be <code>null</code>.
*
* @return an array of FTPFile objects containing the whole list of
* files returned by the server as read by this object's parser.
* <p><b>
@ -260,8 +246,8 @@ public class FTPListParseEngine {
* check each entry for null before referencing it, or use the
* a filter such as {@link FTPFileFilters#NON_NULL} which does not
* allow null entries.
* @since 2.2
* @throws IOException - not ever thrown, may be removed in a later release
* @since 2.2
*/
public FTPFile[] getFiles(FTPFileFilter filter)
throws IOException // TODO remove; not actually thrown
@ -279,7 +265,6 @@ public class FTPListParseEngine {
}
}
return tmpResults.toArray(new FTPFile[tmpResults.size()]);
}
/**
@ -315,15 +300,12 @@ public class FTPListParseEngine {
/**
* Do not use.
*
* @param stream the stream from which to read
* @throws IOException on error
* @deprecated use {@link #readServerList(InputStream, String)} instead
*/
@Deprecated
public void readServerList(InputStream stream)
throws IOException
{
@Deprecated public void readServerList(InputStream stream) throws IOException {
readServerList(stream, null);
}
}

@ -26,8 +26,7 @@ package org.apache.commons.net.ftp;
* TODO replace with an enum
***/
public final class FTPReply
{
public final class FTPReply {
public static final int RESTART_MARKER = 110;
public static final int SERVICE_NOT_READY = 120;
@ -100,8 +99,8 @@ public final class FTPReply
public static final int EXTENDED_PORT_FAILURE = 522;
// Cannot be instantiated
private FTPReply()
{}
private FTPReply() {
}
/***
* Determine if a reply code is a positive preliminary response. All
@ -115,8 +114,7 @@ public final class FTPReply
* @return True if a reply code is a postive preliminary response, false
* if not.
***/
public static boolean isPositivePreliminary(int reply)
{
public static boolean isPositivePreliminary(int reply) {
return (reply >= 100 && reply < 200);
}
@ -130,8 +128,7 @@ public final class FTPReply
* @return True if a reply code is a postive completion response, false
* if not.
***/
public static boolean isPositiveCompletion(int reply)
{
public static boolean isPositiveCompletion(int reply) {
return (reply >= 200 && reply < 300);
}
@ -148,8 +145,7 @@ public final class FTPReply
* @return True if a reply code is a postive intermediate response, false
* if not.
***/
public static boolean isPositiveIntermediate(int reply)
{
public static boolean isPositiveIntermediate(int reply) {
return (reply >= 300 && reply < 400);
}
@ -163,8 +159,7 @@ public final class FTPReply
* @return True if a reply code is a negative transient response, false
* if not.
***/
public static boolean isNegativeTransient(int reply)
{
public static boolean isNegativeTransient(int reply) {
return (reply >= 400 && reply < 500);
}
@ -178,24 +173,21 @@ public final class FTPReply
* @return True if a reply code is a negative permanent response, false
* if not.
***/
public static boolean isNegativePermanent(int reply)
{
public static boolean isNegativePermanent(int reply) {
return (reply >= 500 && reply < 600);
}
/**
* Determine if a reply code is a protected response.
*
* @param reply The reply code to test.
* @return True if a reply code is a protected response, false
* if not.
* @since 3.0
*/
public static boolean isProtectedReplyCode(int reply)
{
public static boolean isProtectedReplyCode(int reply) {
// actually, only 3 protected reply codes are
// defined in RFC 2228: 631, 632 and 633.
return (reply >= 600 && reply < 700);
}
}

@ -45,6 +45,7 @@ import org.apache.commons.net.util.TrustManagerUtils;
* Warning: the hostname is not verified against the certificate by default, use
* {@link #setHostnameVerifier(HostnameVerifier)} or {@link #setEndpointCheckingEnabled(boolean)}
* (on Java 1.7+) to enable verification. Verification is only performed on client mode connections.
*
* @version $Id: FTPSClient.java 1747829 2016-06-11 00:57:57Z sebb $
* @since 2.0
*/
@ -107,7 +108,8 @@ public class FTPSClient extends FTPClient {
/** The protocol versions */
private String[] protocols = null;
/** The FTPS {@link TrustManager} implementation, default validate only
/**
* The FTPS {@link TrustManager} implementation, default validate only
* {@link TrustManagerUtils#getValidateServerCertificateTrustManager()}.
*/
private TrustManager trustManager = TrustManagerUtils.getValidateServerCertificateTrustManager();
@ -124,7 +126,8 @@ public class FTPSClient extends FTPClient {
/**
* Constructor for FTPSClient, calls {@link #FTPSClient(String, boolean)}.
*
* Sets protocol to {@link #DEFAULT_PROTOCOL} - i.e. TLS - and security mode to explicit (isImplicit = false)
* Sets protocol to {@link #DEFAULT_PROTOCOL} - i.e. TLS - and security mode to explicit
* (isImplicit = false)
*/
public FTPSClient() {
this(DEFAULT_PROTOCOL, false);
@ -133,6 +136,7 @@ public class FTPSClient extends FTPClient {
/**
* Constructor for FTPSClient, using {@link #DEFAULT_PROTOCOL} - i.e. TLS
* Calls {@link #FTPSClient(String, boolean)}
*
* @param isImplicit The security mode (Implicit/Explicit).
*/
public FTPSClient(boolean isImplicit) {
@ -153,6 +157,7 @@ public class FTPSClient extends FTPClient {
* and security mode. If isImplicit is true, the port is set to
* {@link #DEFAULT_FTPS_PORT} i.e. 990.
* The default TrustManager is set from {@link TrustManagerUtils#getValidateServerCertificateTrustManager()}
*
* @param protocol the protocol
* @param isImplicit The security mode(Implicit/Explicit).
*/
@ -168,6 +173,7 @@ public class FTPSClient extends FTPClient {
/**
* Constructor for FTPSClient, using {@link #DEFAULT_PROTOCOL} - i.e. TLS
* The default TrustManager is set from {@link TrustManagerUtils#getValidateServerCertificateTrustManager()}
*
* @param isImplicit The security mode(Implicit/Explicit).
* @param context A pre-configured SSL Context
*/
@ -180,16 +186,17 @@ public class FTPSClient extends FTPClient {
* Constructor for FTPSClient, using {@link #DEFAULT_PROTOCOL} - i.e. TLS
* and isImplicit {@code false}
* Calls {@link #FTPSClient(boolean, SSLContext)}
*
* @param context A pre-configured SSL Context
*/
public FTPSClient(SSLContext context) {
this(false, context);
}
/**
* Set AUTH command use value.
* This processing is done before connected processing.
*
* @param auth AUTH command use value.
*/
public void setAuthValue(String auth) {
@ -198,23 +205,23 @@ public class FTPSClient extends FTPClient {
/**
* Return AUTH command use value.
*
* @return AUTH command use value.
*/
public String getAuthValue() {
return this.auth;
}
/**
* Because there are so many connect() methods,
* the _connectAction_() method is provided as a means of performing
* some action immediately after establishing a connection,
* rather than reimplementing all of the connect() methods.
*
* @throws IOException If it throw by _connectAction_.
* @see org.apache.commons.net.SocketClient#_connectAction_()
*/
@Override
protected void _connectAction_() throws IOException {
@Override protected void _connectAction_() throws IOException {
// Implicit mode.
if (isImplicit) {
sslNegotiation();
@ -229,6 +236,7 @@ public class FTPSClient extends FTPClient {
/**
* AUTH command.
*
* @throws SSLException If it server reply code not equal "234" and "334".
* @throws IOException If an I/O error occurs while either sending
* the command.
@ -245,6 +253,7 @@ public class FTPSClient extends FTPClient {
/**
* Performs a lazy init of the SSL context
*
* @throws IOException
*/
private void initSslContext() throws IOException {
@ -256,6 +265,7 @@ public class FTPSClient extends FTPClient {
/**
* SSL/TLS negotiation. Acquires an SSL socket of a control
* connection and carries out handshake processing.
*
* @throws IOException If server negotiation fails
*/
protected void sslNegotiation() throws IOException {
@ -265,8 +275,7 @@ public class FTPSClient extends FTPClient {
SSLSocketFactory ssf = context.getSocketFactory();
String host = (_hostname_ != null) ? _hostname_ : getRemoteAddress().getHostAddress();
int port = _socket_.getPort();
SSLSocket socket =
(SSLSocket) ssf.createSocket(_socket_, host, port, false);
SSLSocket socket = (SSLSocket) ssf.createSocket(_socket_, host, port, false);
socket.setEnableSessionCreation(isCreation);
socket.setUseClientMode(isClientMode);
@ -290,10 +299,10 @@ public class FTPSClient extends FTPClient {
// TODO the following setup appears to duplicate that in the super class methods
_socket_ = socket;
_controlInput_ = new BufferedReader(new InputStreamReader(
socket .getInputStream(), getControlEncoding()));
_controlOutput_ = new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream(), getControlEncoding()));
_controlInput_ =
new BufferedReader(new InputStreamReader(socket.getInputStream(), getControlEncoding()));
_controlOutput_ =
new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), getControlEncoding()));
if (isClientMode) {
if (hostnameVerifier != null && !hostnameVerifier.verify(host, socket.getSession())) {
@ -304,6 +313,7 @@ public class FTPSClient extends FTPClient {
/**
* Get the {@link KeyManager} instance.
*
* @return The {@link KeyManager} instance
*/
private KeyManager getKeyManager() {
@ -322,6 +332,7 @@ public class FTPSClient extends FTPClient {
/**
* Controls whether a new SSL session may be established by this socket.
*
* @param isCreation The established socket flag.
*/
public void setEnabledSessionCreation(boolean isCreation) {
@ -331,8 +342,10 @@ public class FTPSClient extends FTPClient {
/**
* Returns true if new SSL sessions may be established by this socket.
* When the underlying {@link Socket} instance is not SSL-enabled (i.e. an
* instance of {@link SSLSocket} with {@link SSLSocket}{@link #getEnableSessionCreation()}) enabled,
* instance of {@link SSLSocket} with {@link SSLSocket}{@link #getEnableSessionCreation()})
* enabled,
* this returns False.
*
* @return true - Indicates that sessions may be created;
* this is the default.
* false - indicates that an existing session must be resumed.
@ -346,6 +359,7 @@ public class FTPSClient extends FTPClient {
/**
* Configures the socket to require client authentication.
*
* @param isNeedClientAuth The need client auth flag.
*/
public void setNeedClientAuth(boolean isNeedClientAuth) {
@ -355,6 +369,7 @@ public class FTPSClient extends FTPClient {
/**
* Returns true if the socket will require client authentication.
* When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns false.
*
* @return true - If the server mode socket should request
* that the client authenticate itself.
*/
@ -369,6 +384,7 @@ public class FTPSClient extends FTPClient {
* Configures the socket to request client authentication,
* but only if such a request is appropriate to the cipher
* suite negotiated.
*
* @param isWantClientAuth The want client auth flag.
*/
public void setWantClientAuth(boolean isWantClientAuth) {
@ -378,6 +394,7 @@ public class FTPSClient extends FTPClient {
/**
* Returns true if the socket will request client authentication.
* When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns false.
*
* @return true - If the server mode socket should request
* that the client authenticate itself.
*/
@ -391,6 +408,7 @@ public class FTPSClient extends FTPClient {
/**
* Configures the socket to use client (or server) mode in its first
* handshake.
*
* @param isClientMode The use client mode flag.
*/
public void setUseClientMode(boolean isClientMode) {
@ -401,6 +419,7 @@ public class FTPSClient extends FTPClient {
* Returns true if the socket is set to use client mode
* in its first handshake.
* When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns false.
*
* @return true - If the socket should start its first handshake
* in "client" mode.
*/
@ -414,6 +433,7 @@ public class FTPSClient extends FTPClient {
/**
* Controls which particular cipher suites are enabled for use on this
* connection. Called before server negotiation.
*
* @param cipherSuites The cipher suites.
*/
public void setEnabledCipherSuites(String[] cipherSuites) {
@ -425,6 +445,7 @@ public class FTPSClient extends FTPClient {
* Returns the names of the cipher suites which could be enabled
* for use on this connection.
* When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns null.
*
* @return An array of cipher suite names, or <code>null</code>
*/
public String[] getEnabledCipherSuites() {
@ -437,6 +458,7 @@ public class FTPSClient extends FTPClient {
/**
* Controls which particular protocol versions are enabled for use on this
* connection. I perform setting before a server negotiation.
*
* @param protocolVersions The protocol versions.
*/
public void setEnabledProtocols(String[] protocolVersions) {
@ -448,6 +470,7 @@ public class FTPSClient extends FTPClient {
* Returns the names of the protocol versions which are currently
* enabled for use on this connection.
* When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns null.
*
* @return An array of protocols, or <code>null</code>
*/
public String[] getEnabledProtocols() {
@ -459,6 +482,7 @@ public class FTPSClient extends FTPClient {
/**
* PBSZ command. pbsz value: 0 to (2^32)-1 decimal integer.
*
* @param pbsz Protection Buffer Size.
* @throws SSLException If the server reply code does not equal "200".
* @throws IOException If an I/O error occurs while sending
@ -480,10 +504,10 @@ public class FTPSClient extends FTPClient {
* Issues the command and parses the response to return the negotiated value.
*
* @param pbsz Protection Buffer Size.
* @return the negotiated value.
* @throws SSLException If the server reply code does not equal "200".
* @throws IOException If an I/O error occurs while sending
* the command.
* @return the negotiated value.
* @see #execPBSZ(long)
* @since 3.0
*/
@ -539,12 +563,12 @@ public class FTPSClient extends FTPClient {
/**
* Check the value that can be set in PROT Command value.
*
* @param prot Data Channel Protection Level.
* @return True - A set point is right / False - A set point is not right
*/
private boolean checkPROTValue(String prot) {
for (String element : PROT_COMMAND_VALUE)
{
for (String element : PROT_COMMAND_VALUE) {
if (element.equals(prot)) {
return true;
}
@ -556,6 +580,7 @@ public class FTPSClient extends FTPClient {
* Send an FTP command.
* A successful CCC (Clear Command Channel) command causes the underlying {@link SSLSocket}
* instance to be assigned to a plain {@link Socket}
*
* @param command The FTP command.
* @return server reply.
* @throws IOException If an I/O error occurs while sending the command.
@ -563,8 +588,7 @@ public class FTPSClient extends FTPClient {
* @see FTP#sendCommand(String)
*/
// Would like to remove this method, but that will break any existing clients that are using CCC
@Override
public int sendCommand(String command, String args) throws IOException {
@Override public int sendCommand(String command, String args) throws IOException {
int repCode = super.sendCommand(command, args);
/* If CCC is issued, restore socket i/o streams to unsecured versions */
if (CMD_CCC.equals(command)) {
@ -572,11 +596,9 @@ public class FTPSClient extends FTPClient {
_socket_.close();
_socket_ = plainSocket;
_controlInput_ = new BufferedReader(
new InputStreamReader(
_socket_ .getInputStream(), getControlEncoding()));
new InputStreamReader(_socket_.getInputStream(), getControlEncoding()));
_controlOutput_ = new BufferedWriter(
new OutputStreamWriter(
_socket_.getOutputStream(), getControlEncoding()));
new OutputStreamWriter(_socket_.getOutputStream(), getControlEncoding()));
} else {
throw new SSLException(getReplyString());
}
@ -587,6 +609,7 @@ public class FTPSClient extends FTPClient {
/**
* Returns a socket of the data connection.
* Wrapped as an {@link SSLSocket}, which carries out handshake processing.
*
* @param command The int representation of the FTP command to send.
* @param arg The arguments to the FTP command.
* If this parameter is set to null, then the command is sent with
@ -601,15 +624,14 @@ public class FTPSClient extends FTPClient {
@Override
// Strictly speaking this is not needed, but it works round a Clirr bug
// So rather than invoke the parent code, we do it here
@Deprecated
protected Socket _openDataConnection_(int command, String arg)
throws IOException {
@Deprecated protected Socket _openDataConnection_(int command, String arg) throws IOException {
return _openDataConnection_(FTPCommand.getCommand(command), arg);
}
/**
* Returns a socket of the data connection.
* Wrapped as an {@link SSLSocket}, which carries out handshake processing.
*
* @param command The textual representation of the FTP command to send.
* @param arg The arguments to the FTP command.
* If this parameter is set to null, then the command is sent with
@ -621,9 +643,7 @@ public class FTPSClient extends FTPClient {
* @see FTPClient#_openDataConnection_(int, String)
* @since 3.2
*/
@Override
protected Socket _openDataConnection_(String command, String arg)
throws IOException {
@Override protected Socket _openDataConnection_(String command, String arg) throws IOException {
Socket socket = super._openDataConnection_(command, arg);
_prepareDataSocket_(socket);
if (socket instanceof SSLSocket) {
@ -655,12 +675,12 @@ public class FTPSClient extends FTPClient {
* Called by {@link #_openDataConnection_(int, String)} immediately
* after creating the socket.
* The default implementation is a no-op
*
* @param socket the socket to set up
* @throws IOException on error
* @since 3.1
*/
protected void _prepareDataSocket_(Socket socket)
throws IOException {
protected void _prepareDataSocket_(Socket socket) throws IOException {
}
/**
@ -686,22 +706,23 @@ public class FTPSClient extends FTPClient {
/**
* Get the currently configured {@link HostnameVerifier}.
* The verifier is only used on client mode connections.
*
* @return A HostnameVerifier instance.
* @since 3.4
*/
public HostnameVerifier getHostnameVerifier()
{
public HostnameVerifier getHostnameVerifier() {
return hostnameVerifier;
}
/**
* Override the default {@link HostnameVerifier} to use.
* The verifier is only used on client mode connections.
* @param newHostnameVerifier The HostnameVerifier implementation to set or <code>null</code> to disable.
*
* @param newHostnameVerifier The HostnameVerifier implementation to set or <code>null</code> to
* disable.
* @since 3.4
*/
public void setHostnameVerifier(HostnameVerifier newHostnameVerifier)
{
public void setHostnameVerifier(HostnameVerifier newHostnameVerifier) {
hostnameVerifier = newHostnameVerifier;
}
@ -714,8 +735,7 @@ public class FTPSClient extends FTPClient {
* @return True if enabled, false if not.
* @since 3.4
*/
public boolean isEndpointCheckingEnabled()
{
public boolean isEndpointCheckingEnabled() {
return tlsEndpointChecking;
}
@ -725,11 +745,11 @@ public class FTPSClient extends FTPClient {
*
* This check is only performed on client mode connections.
*
* @param enable Enable automatic endpoint identification checking using the HTTPS algorithm on Java 1.7+.
* @param enable Enable automatic endpoint identification checking using the HTTPS algorithm on
* Java 1.7+.
* @since 3.4
*/
public void setEndpointCheckingEnabled(boolean enable)
{
public void setEndpointCheckingEnabled(boolean enable) {
tlsEndpointChecking = enable;
}
@ -740,12 +760,11 @@ public class FTPSClient extends FTPClient {
* Calls {@code setSocketFactory(null)} and {@code setServerSocketFactory(null)}
* to reset the factories that may have been changed during the session,
* e.g. by {@link #execPROT(String)}
*
* @throws IOException If an error occurs while disconnecting.
* @since 3.0
*/
@Override
public void disconnect() throws IOException
{
@Override public void disconnect() throws IOException {
super.disconnect();
if (plainSocket != null) {
plainSocket.close();
@ -756,48 +775,46 @@ public class FTPSClient extends FTPClient {
/**
* Send the AUTH command with the specified mechanism.
*
* @param mechanism The mechanism name to send with the command.
* @return server reply.
* @throws IOException If an I/O error occurs while sending
* the command.
* @since 3.0
*/
public int execAUTH(String mechanism) throws IOException
{
public int execAUTH(String mechanism) throws IOException {
return sendCommand(CMD_AUTH, mechanism);
}
/**
* Send the ADAT command with the specified authentication data.
*
* @param data The data to send with the command.
* @return server reply.
* @throws IOException If an I/O error occurs while sending
* the command.
* @since 3.0
*/
public int execADAT(byte[] data) throws IOException
{
if (data != null)
{
public int execADAT(byte[] data) throws IOException {
if (data != null) {
return sendCommand(CMD_ADAT, Base64.encodeBase64StringUnChunked(data));
}
else
{
} else {
return sendCommand(CMD_ADAT);
}
}
/**
* Send the CCC command to the server.
* The CCC (Clear Command Channel) command causes the underlying {@link SSLSocket} instance to be assigned
* The CCC (Clear Command Channel) command causes the underlying {@link SSLSocket} instance to be
* assigned
* to a plain {@link Socket} instances
*
* @return server reply.
* @throws IOException If an I/O error occurs while sending
* the command.
* @since 3.0
*/
public int execCCC() throws IOException
{
public int execCCC() throws IOException {
int repCode = sendCommand(CMD_CCC);
// This will be performed by sendCommand(String, String)
// if (FTPReply.isPositiveCompletion(repCode)) {
@ -815,72 +832,63 @@ public class FTPSClient extends FTPClient {
/**
* Send the MIC command with the specified data.
*
* @param data The data to send with the command.
* @return server reply.
* @throws IOException If an I/O error occurs while sending
* the command.
* @since 3.0
*/
public int execMIC(byte[] data) throws IOException
{
if (data != null)
{
public int execMIC(byte[] data) throws IOException {
if (data != null) {
return sendCommand(CMD_MIC, Base64.encodeBase64StringUnChunked(data));
}
else
{
} else {
return sendCommand(CMD_MIC, ""); // perhaps "=" or just sendCommand(String)?
}
}
/**
* Send the CONF command with the specified data.
*
* @param data The data to send with the command.
* @return server reply.
* @throws IOException If an I/O error occurs while sending
* the command.
* @since 3.0
*/
public int execCONF(byte[] data) throws IOException
{
if (data != null)
{
public int execCONF(byte[] data) throws IOException {
if (data != null) {
return sendCommand(CMD_CONF, Base64.encodeBase64StringUnChunked(data));
}
else
{
} else {
return sendCommand(CMD_CONF, ""); // perhaps "=" or just sendCommand(String)?
}
}
/**
* Send the ENC command with the specified data.
*
* @param data The data to send with the command.
* @return server reply.
* @throws IOException If an I/O error occurs while sending
* the command.
* @since 3.0
*/
public int execENC(byte[] data) throws IOException
{
if (data != null)
{
public int execENC(byte[] data) throws IOException {
if (data != null) {
return sendCommand(CMD_ENC, Base64.encodeBase64StringUnChunked(data));
}
else
{
} else {
return sendCommand(CMD_ENC, ""); // perhaps "=" or just sendCommand(String)?
}
}
/**
* Parses the given ADAT response line and base64-decodes the data.
*
* @param reply The ADAT reply to parse.
* @return the data in the reply, base64-decoded.
* @since 3.0
*/
public byte[] parseADATReply(String reply)
{
public byte[] parseADATReply(String reply) {
if (reply == null) {
return null;
} else {
@ -890,6 +898,7 @@ public class FTPSClient extends FTPClient {
/**
* Extract the data from a reply with a prefix, e.g. PBSZ=1234 => 1234
*
* @param prefix the prefix to find
* @param reply where to find the prefix
* @return the remainder of the string after the prefix, or null if the prefix was not present.
@ -906,20 +915,15 @@ public class FTPSClient extends FTPClient {
// DEPRECATED - for API compatibility only - DO NOT USE
/** @deprecated - not used - may be removed in a future release */
@Deprecated
public static String KEYSTORE_ALGORITHM;
@Deprecated public static String KEYSTORE_ALGORITHM;
/** @deprecated - not used - may be removed in a future release */
@Deprecated
public static String TRUSTSTORE_ALGORITHM;
@Deprecated public static String TRUSTSTORE_ALGORITHM;
/** @deprecated - not used - may be removed in a future release */
@Deprecated
public static String PROVIDER;
@Deprecated public static String PROVIDER;
/** @deprecated - not used - may be removed in a future release */
@Deprecated
public static String STORE_TYPE;
@Deprecated public static String STORE_TYPE;
}
/* kate: indent-width 4; replace-tabs on; */

@ -19,11 +19,11 @@ package org.apache.commons.net.ftp;
/**
* FTPS-specific commands.
*
* @since 2.0
* @deprecated 3.0 DO NOT USE
*/
@Deprecated
public final class FTPSCommand {
@Deprecated public final class FTPSCommand {
public static final int AUTH = 0;
public static final int ADAT = 1;
public static final int PBSZ = 2;

@ -27,6 +27,7 @@ import javax.net.ssl.SSLServerSocket;
/**
* Server socket factory for FTPS connections.
*
* @since 2.2
*/
public class FTPSServerSocketFactory extends ServerSocketFactory {
@ -39,23 +40,20 @@ public class FTPSServerSocketFactory extends ServerSocketFactory {
}
// Override the default superclass method
@Override
public ServerSocket createServerSocket() throws IOException {
@Override public ServerSocket createServerSocket() throws IOException {
return init(this.context.getServerSocketFactory().createServerSocket());
}
@Override
public ServerSocket createServerSocket(int port) throws IOException {
@Override public ServerSocket createServerSocket(int port) throws IOException {
return init(this.context.getServerSocketFactory().createServerSocket(port));
}
@Override
public ServerSocket createServerSocket(int port, int backlog) throws IOException {
@Override public ServerSocket createServerSocket(int port, int backlog) throws IOException {
return init(this.context.getServerSocketFactory().createServerSocket(port, backlog));
}
@Override
public ServerSocket createServerSocket(int port, int backlog, InetAddress ifAddress) throws IOException {
@Override public ServerSocket createServerSocket(int port, int backlog, InetAddress ifAddress)
throws IOException {
return init(this.context.getServerSocketFactory().createServerSocket(port, backlog, ifAddress));
}

@ -26,7 +26,6 @@ import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
/**
*
* Implementation of org.apache.commons.net.SocketFactory
*
* @since 2.0
@ -40,18 +39,16 @@ public class FTPSSocketFactory extends SocketFactory {
}
// Override the default implementation
@Override
public Socket createSocket() throws IOException{
@Override public Socket createSocket() throws IOException {
return this.context.getSocketFactory().createSocket();
}
@Override
public Socket createSocket(String address, int port) throws UnknownHostException, IOException {
@Override public Socket createSocket(String address, int port)
throws UnknownHostException, IOException {
return this.context.getSocketFactory().createSocket(address, port);
}
@Override
public Socket createSocket(InetAddress address, int port) throws IOException {
@Override public Socket createSocket(InetAddress address, int port) throws IOException {
return this.context.getSocketFactory().createSocket(address, port);
}
@ -62,51 +59,58 @@ public class FTPSSocketFactory extends SocketFactory {
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
throws IOException {
return this.context.getSocketFactory().createSocket(address, port, localAddress, localPort);
}
// DEPRECATED METHODS - for API compatibility only - DO NOT USE
/** @param port the port
/**
* @param port the port
* @return the socket
* @throws IOException on error
* @deprecated (2.2) use {@link FTPSServerSocketFactory#createServerSocket(int) instead} */
@Deprecated
public java.net.ServerSocket createServerSocket(int port) throws IOException {
* @deprecated (2.2) use {@link FTPSServerSocketFactory#createServerSocket(int) instead}
*/
@Deprecated public java.net.ServerSocket createServerSocket(int port) throws IOException {
return this.init(this.context.getServerSocketFactory().createServerSocket(port));
}
/** @param port the port
/**
* @param port the port
* @param backlog the backlog
* @return the socket
* @throws IOException on error
* @deprecated (2.2) use {@link FTPSServerSocketFactory#createServerSocket(int, int) instead} */
@Deprecated
public java.net.ServerSocket createServerSocket(int port, int backlog) throws IOException {
* @deprecated (2.2) use {@link FTPSServerSocketFactory#createServerSocket(int, int) instead}
*/
@Deprecated public java.net.ServerSocket createServerSocket(int port, int backlog)
throws IOException {
return this.init(this.context.getServerSocketFactory().createServerSocket(port, backlog));
}
/** @param port the port
/**
* @param port the port
* @param backlog the backlog
* @param ifAddress the interface
* @return the socket
* @throws IOException on error
* @deprecated (2.2) use {@link FTPSServerSocketFactory#createServerSocket(int, int, InetAddress) instead} */
@Deprecated
public java.net.ServerSocket createServerSocket(int port, int backlog, InetAddress ifAddress) throws IOException {
return this.init(this.context.getServerSocketFactory().createServerSocket(port, backlog, ifAddress));
* @deprecated (2.2) use {@link FTPSServerSocketFactory#createServerSocket(int, int, InetAddress)
* instead}
*/
@Deprecated public java.net.ServerSocket createServerSocket(int port, int backlog,
InetAddress ifAddress) throws IOException {
return this.init(
this.context.getServerSocketFactory().createServerSocket(port, backlog, ifAddress));
}
/** @param socket the socket
/**
* @param socket the socket
* @return the socket
* @throws IOException on error
* @deprecated (2.2) use {@link FTPSServerSocketFactory#init(java.net.ServerSocket)} */
@Deprecated
public java.net.ServerSocket init(java.net.ServerSocket socket) throws IOException {
* @deprecated (2.2) use {@link FTPSServerSocketFactory#init(java.net.ServerSocket)}
*/
@Deprecated public java.net.ServerSocket init(java.net.ServerSocket socket) throws IOException {
((javax.net.ssl.SSLServerSocket) socket).setUseClientMode(true);
return socket;
}
}

@ -24,37 +24,30 @@ import javax.net.ssl.X509TrustManager;
/**
* Do not use.
*
* @since 2.0
* @deprecated 3.0 use
* {@link org.apache.commons.net.util.TrustManagerUtils#getValidateServerCertificateTrustManager()
* TrustManagerUtils#getValidateServerCertificateTrustManager()} instead
*/
@Deprecated
public class FTPSTrustManager implements X509TrustManager
{
@Deprecated public class FTPSTrustManager implements X509TrustManager {
private static final X509Certificate[] EMPTY_X509CERTIFICATE_ARRAY = new X509Certificate[] {};
/**
* No-op
*/
@Override
public void checkClientTrusted(X509Certificate[] certificates, String authType)
{
@Override public void checkClientTrusted(X509Certificate[] certificates, String authType) {
return;
}
@Override
public void checkServerTrusted(X509Certificate[] certificates, String authType) throws CertificateException
{
for (X509Certificate certificate : certificates)
{
@Override public void checkServerTrusted(X509Certificate[] certificates, String authType)
throws CertificateException {
for (X509Certificate certificate : certificates) {
certificate.checkValidity();
}
}
@Override
public X509Certificate[] getAcceptedIssuers()
{
@Override public X509Certificate[] getAcceptedIssuers() {
return EMPTY_X509CERTIFICATE_ARRAY;
}
}

@ -0,0 +1,33 @@
/*
* 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 org.apache.commons.net.ftp;
import org.apache.commons.net.io.CopyStreamListener;
/**
* Created by AriaL on 2017/9/26.
* ftp 上传文件流事件监听
*/
public interface OnFtpInputStreamListener {
/**
* {@link CopyStreamListener#bytesTransferred(long, int, long)}
*
* @param totalBytesTransferred 已经上传的文件长度
* @param bytesTransferred 上传byte长度
*/
void onFtpInputStream(FTPClient client, long totalBytesTransferred, int bytesTransferred,
long streamSize);
}

@ -28,37 +28,27 @@ import org.apache.commons.net.ftp.FTPFileEntryParserImpl;
* If the cached parser wont match due to the server changed the dirstyle,
* a new matching parser will be searched.
*/
public class CompositeFileEntryParser extends FTPFileEntryParserImpl
{
public class CompositeFileEntryParser extends FTPFileEntryParserImpl {
private final FTPFileEntryParser[] ftpFileEntryParsers;
private FTPFileEntryParser cachedFtpFileEntryParser;
public CompositeFileEntryParser(FTPFileEntryParser[] ftpFileEntryParsers)
{
public CompositeFileEntryParser(FTPFileEntryParser[] ftpFileEntryParsers) {
super();
this.cachedFtpFileEntryParser = null;
this.ftpFileEntryParsers = ftpFileEntryParsers;
}
@Override
public FTPFile parseFTPEntry(String listEntry)
{
if (cachedFtpFileEntryParser != null)
{
@Override public FTPFile parseFTPEntry(String listEntry) {
if (cachedFtpFileEntryParser != null) {
FTPFile matched = cachedFtpFileEntryParser.parseFTPEntry(listEntry);
if (matched != null)
{
if (matched != null) {
return matched;
}
}
else
{
for (FTPFileEntryParser ftpFileEntryParser : ftpFileEntryParsers)
{
} else {
for (FTPFileEntryParser ftpFileEntryParser : ftpFileEntryParsers) {
FTPFile matched = ftpFileEntryParser.parseFTPEntry(listEntry);
if (matched != null)
{
if (matched != null) {
cachedFtpFileEntryParser = ftpFileEntryParser;
return matched;
}

@ -23,7 +23,6 @@ import java.util.Calendar;
import org.apache.commons.net.ftp.Configurable;
import org.apache.commons.net.ftp.FTPClientConfig;
/**
* <p>
* This abstract class implements the common timestamp parsing
@ -38,34 +37,33 @@ import org.apache.commons.net.ftp.FTPClientConfig;
*
* @since 1.4
*/
public abstract class ConfigurableFTPFileEntryParserImpl
extends RegexFTPFileEntryParserImpl
implements Configurable
{
public abstract class ConfigurableFTPFileEntryParserImpl extends RegexFTPFileEntryParserImpl
implements Configurable {
private final FTPTimestampParser timestampParser;
/**
* constructor for this abstract class.
*
* @param regex Regular expression used main parsing of the
* file listing.
*/
public ConfigurableFTPFileEntryParserImpl(String regex)
{
public ConfigurableFTPFileEntryParserImpl(String regex) {
super(regex);
this.timestampParser = new FTPTimestampParserImpl();
}
/**
* constructor for this abstract class.
*
* @param regex Regular expression used main parsing of the
* file listing.
* @param flags the flags to apply, see
* {@link java.util.regex.Pattern#compile(String, int) Pattern#compile(String, int)}. Use 0 for none.
* {@link java.util.regex.Pattern#compile(String, int) Pattern#compile(String, int)}. Use 0 for
* none.
* @since 3.4
*/
public ConfigurableFTPFileEntryParserImpl(String regex, int flags)
{
public ConfigurableFTPFileEntryParserImpl(String regex, int flags) {
super(regex, flags);
this.timestampParser = new FTPTimestampParserImpl();
}
@ -85,7 +83,6 @@ implements Configurable
return this.timestampParser.parseTimestamp(timestampStr);
}
/**
* Implementation of the {@link Configurable Configurable}
* interface. Configures this parser by delegating to the
@ -98,9 +95,7 @@ implements Configurable
* If it is null, a default configuration defined by
* each concrete subclass is used instead.
*/
@Override
public void configure(FTPClientConfig config)
{
@Override public void configure(FTPClientConfig config) {
if (this.timestampParser instanceof Configurable) {
FTPClientConfig defaultCfg = getDefaultConfiguration();
if (config != null) {
@ -122,6 +117,7 @@ implements Configurable
* a default configuration to be used when that subclass is
* instantiated without a {@link FTPClientConfig FTPClientConfig}
* parameter being specified.
*
* @return the default configuration for the subclass.
*/
protected abstract FTPClientConfig getDefaultConfiguration();

@ -23,7 +23,6 @@ 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
@ -34,14 +33,14 @@ import org.apache.commons.net.ftp.FTPFileEntryParser;
* @see org.apache.commons.net.ftp.FTPClient#listFiles
* @see org.apache.commons.net.ftp.FTPClient#setParserFactory
*/
public class DefaultFTPFileEntryParserFactory
implements FTPFileEntryParserFactory
{
public class DefaultFTPFileEntryParserFactory implements FTPFileEntryParserFactory {
// Match a plain Java Identifier
private static final String JAVA_IDENTIFIER = "\\p{javaJavaIdentifierStart}(\\p{javaJavaIdentifierPart})*";
private static final String JAVA_IDENTIFIER =
"\\p{javaJavaIdentifierStart}(\\p{javaJavaIdentifierPart})*";
// Match a qualified name, e.g. a.b.c.Name - but don't allow the default package as that would allow "VMS"/"UNIX" etc.
private static final String JAVA_QUALIFIED_NAME = "("+JAVA_IDENTIFIER+"\\.)+"+JAVA_IDENTIFIER;
private static final String JAVA_QUALIFIED_NAME =
"(" + JAVA_IDENTIFIER + "\\.)+" + JAVA_IDENTIFIER;
// Create the pattern, as it will be reused many times
private static final Pattern JAVA_QUALIFIED_NAME_PATTERN = Pattern.compile(JAVA_QUALIFIED_NAME);
@ -85,9 +84,7 @@ public class DefaultFTPFileEntryParserFactory
* the supplied key into an FTPFileEntryParser.
* @see FTPFileEntryParser
*/
@Override
public FTPFileEntryParser createFileEntryParser(String key)
{
@Override public FTPFileEntryParser createFileEntryParser(String key) {
if (key == null) {
throw new ParserInitializationException("Parser key cannot be null");
}
@ -100,8 +97,7 @@ public class DefaultFTPFileEntryParserFactory
// Is the key a possible class name?
if (JAVA_QUALIFIED_NAME_PATTERN.matcher(key).matches()) {
try
{
try {
Class<?> parserClass = Class.forName(key);
try {
parser = (FTPFileEntryParser) parserClass.newInstance();
@ -121,52 +117,32 @@ public class DefaultFTPFileEntryParserFactory
if (parser == null) { // Now try for aliases
String ukey = key.toUpperCase(java.util.Locale.ENGLISH);
if (ukey.indexOf(FTPClientConfig.SYST_UNIX_TRIM_LEADING) >= 0)
{
if (ukey.indexOf(FTPClientConfig.SYST_UNIX_TRIM_LEADING) >= 0) {
parser = new UnixFTPEntryParser(config, true);
}
// must check this after SYST_UNIX_TRIM_LEADING as it is a substring of it
else if (ukey.indexOf(FTPClientConfig.SYST_UNIX) >= 0)
{
else if (ukey.indexOf(FTPClientConfig.SYST_UNIX) >= 0) {
parser = new UnixFTPEntryParser(config, false);
}
else if (ukey.indexOf(FTPClientConfig.SYST_VMS) >= 0)
{
} else if (ukey.indexOf(FTPClientConfig.SYST_VMS) >= 0) {
parser = new VMSVersioningFTPEntryParser(config);
}
else if (ukey.indexOf(FTPClientConfig.SYST_NT) >= 0)
{
} else if (ukey.indexOf(FTPClientConfig.SYST_NT) >= 0) {
parser = createNTFTPEntryParser(config);
}
else if (ukey.indexOf(FTPClientConfig.SYST_OS2) >= 0)
{
} else if (ukey.indexOf(FTPClientConfig.SYST_OS2) >= 0) {
parser = new OS2FTPEntryParser(config);
}
else if (ukey.indexOf(FTPClientConfig.SYST_OS400) >= 0 ||
ukey.indexOf(FTPClientConfig.SYST_AS400) >= 0)
{
} else if (ukey.indexOf(FTPClientConfig.SYST_OS400) >= 0
|| ukey.indexOf(FTPClientConfig.SYST_AS400) >= 0) {
parser = createOS400FTPEntryParser(config);
}
else if (ukey.indexOf(FTPClientConfig.SYST_MVS) >= 0)
{
} else if (ukey.indexOf(FTPClientConfig.SYST_MVS) >= 0) {
parser = new MVSFTPEntryParser(); // Does not currently support config parameter
}
else if (ukey.indexOf(FTPClientConfig.SYST_NETWARE) >= 0)
{
} else if (ukey.indexOf(FTPClientConfig.SYST_NETWARE) >= 0) {
parser = new NetwareFTPEntryParser(config);
}
else if (ukey.indexOf(FTPClientConfig.SYST_MACOS_PETER) >= 0)
{
} else if (ukey.indexOf(FTPClientConfig.SYST_MACOS_PETER) >= 0) {
parser = new MacOsPeterFTPEntryParser(config);
}
else if (ukey.indexOf(FTPClientConfig.SYST_L8) >= 0)
{
} else if (ukey.indexOf(FTPClientConfig.SYST_L8) >= 0) {
// L8 normally means Unix, but move it to the end for some L8 systems that aren't.
// This check should be last!
parser = new UnixFTPEntryParser(config);
}
else
{
} else {
throw new ParserInitializationException("Unknown parser type: " + key);
}
}
@ -189,31 +165,25 @@ public class DefaultFTPFileEntryParserFactory
* where the user knows that the server uses a non-default configuration
* and knows what that configuration is.
* </p>
*
* @param config A {@link FTPClientConfig FTPClientConfig}
* used to configure the parser created
*
* @return the @link FTPFileEntryParser FTPFileEntryParser} so created.
* @throws ParserInitializationException
* Thrown on any exception in instantiation
* @throws ParserInitializationException Thrown on any exception in instantiation
* @throws NullPointerException if {@code config} is {@code null}
* @since 1.4
*/
@Override
public FTPFileEntryParser createFileEntryParser(FTPClientConfig config)
throws ParserInitializationException
{
@Override public FTPFileEntryParser createFileEntryParser(FTPClientConfig config)
throws ParserInitializationException {
String key = config.getServerSystemKey();
return createFileEntryParser(key, config);
}
public FTPFileEntryParser createUnixFTPEntryParser()
{
public FTPFileEntryParser createUnixFTPEntryParser() {
return new UnixFTPEntryParser();
}
public FTPFileEntryParser createVMSVersioningFTPEntryParser()
{
public FTPFileEntryParser createVMSVersioningFTPEntryParser() {
return new VMSVersioningFTPEntryParser();
}
@ -221,8 +191,7 @@ public class DefaultFTPFileEntryParserFactory
return new NetwareFTPEntryParser();
}
public FTPFileEntryParser createNTFTPEntryParser()
{
public FTPFileEntryParser createNTFTPEntryParser() {
return createNTFTPEntryParser(null);
}
@ -230,34 +199,29 @@ public class DefaultFTPFileEntryParserFactory
* Creates an NT FTP parser: if the config exists, and the system key equals
* {@link FTPClientConfig.SYST_NT} then a plain {@link NTFTPEntryParser} is used,
* otherwise a composite of {@link NTFTPEntryParser} and {@link UnixFTPEntryParser} is used.
*
* @param config the config to use, may be {@code null}
* @return the parser
*/
private FTPFileEntryParser createNTFTPEntryParser(FTPClientConfig config)
{
if (config != null && FTPClientConfig.SYST_NT.equals(
config.getServerSystemKey()))
{
private FTPFileEntryParser createNTFTPEntryParser(FTPClientConfig config) {
if (config != null && FTPClientConfig.SYST_NT.equals(config.getServerSystemKey())) {
return new NTFTPEntryParser(config);
} else {
// clone the config as it may be changed by the parsers (NET-602)
final FTPClientConfig config2 = (config != null) ? new FTPClientConfig(config) : null;
return new CompositeFileEntryParser(new FTPFileEntryParser[]
{
new NTFTPEntryParser(config),
new UnixFTPEntryParser(config2,
config2 != null && FTPClientConfig.SYST_UNIX_TRIM_LEADING.equals(config2.getServerSystemKey()))
return new CompositeFileEntryParser(new FTPFileEntryParser[] {
new NTFTPEntryParser(config), new UnixFTPEntryParser(config2,
config2 != null && FTPClientConfig.SYST_UNIX_TRIM_LEADING.equals(
config2.getServerSystemKey()))
});
}
}
public FTPFileEntryParser createOS2FTPEntryParser()
{
public FTPFileEntryParser createOS2FTPEntryParser() {
return new OS2FTPEntryParser();
}
public FTPFileEntryParser createOS400FTPEntryParser()
{
public FTPFileEntryParser createOS400FTPEntryParser() {
return createOS400FTPEntryParser(null);
}
@ -265,31 +229,26 @@ public class DefaultFTPFileEntryParserFactory
* Creates an OS400 FTP parser: if the config exists, and the system key equals
* {@link FTPClientConfig.SYST_OS400} then a plain {@link OS400FTPEntryParser} is used,
* otherwise a composite of {@link OS400FTPEntryParser} and {@link UnixFTPEntryParser} is used.
*
* @param config the config to use, may be {@code null}
* @return the parser
*/
private FTPFileEntryParser createOS400FTPEntryParser(FTPClientConfig config)
{
if (config != null &&
FTPClientConfig.SYST_OS400.equals(config.getServerSystemKey()))
{
private FTPFileEntryParser createOS400FTPEntryParser(FTPClientConfig config) {
if (config != null && FTPClientConfig.SYST_OS400.equals(config.getServerSystemKey())) {
return new OS400FTPEntryParser(config);
} else {
// clone the config as it may be changed by the parsers (NET-602)
final FTPClientConfig config2 = (config != null) ? new FTPClientConfig(config) : null;
return new CompositeFileEntryParser(new FTPFileEntryParser[]
{
new OS400FTPEntryParser(config),
new UnixFTPEntryParser(config2,
config2 != null && FTPClientConfig.SYST_UNIX_TRIM_LEADING.equals(config2.getServerSystemKey()))
return new CompositeFileEntryParser(new FTPFileEntryParser[] {
new OS400FTPEntryParser(config), new UnixFTPEntryParser(config2,
config2 != null && FTPClientConfig.SYST_UNIX_TRIM_LEADING.equals(
config2.getServerSystemKey()))
});
}
}
public FTPFileEntryParser createMVSEntryParser()
{
public FTPFileEntryParser createMVSEntryParser() {
return new MVSFTPEntryParser();
}
}

@ -16,6 +16,7 @@
*/
package org.apache.commons.net.ftp.parser;
import java.util.Calendar;
import org.apache.commons.net.ftp.FTPFile;
@ -29,19 +30,18 @@ import org.apache.commons.net.ftp.FTPFile;
* DefaultFTPParserFactory by classname. It will not be chosen
* by the autodetection scheme.
* </B>
*
* @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
*/
public class EnterpriseUnixFTPEntryParser extends RegexFTPFileEntryParserImpl
{
public class EnterpriseUnixFTPEntryParser extends RegexFTPFileEntryParserImpl {
/**
* months abbreviations looked for by this parser. Also used
* to determine <b>which</b> month has been matched by the parser.
*/
private static final String MONTHS =
"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)";
private static final String MONTHS = "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)";
/**
* this is the regular expression used by this parser.
@ -49,15 +49,23 @@ public class EnterpriseUnixFTPEntryParser extends RegexFTPFileEntryParserImpl
private static final String REGEX =
"(([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])"
+ "([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z]))"
+ "(\\S*)\\s*" // 12
+ "(\\S+)\\s*" // 13
+ "(\\S*)\\s*" // 14 user
+ "(\\d*)\\s*" // 15 group
+ "(\\d*)\\s*" // 16 filesize
+ MONTHS // 17 month
+ "\\s*" // TODO should the space be optional?
+ "(\\S*)\\s*"
// 12
+ "(\\S+)\\s*"
// 13
+ "(\\S*)\\s*"
// 14 user
+ "(\\d*)\\s*"
// 15 group
+ "(\\d*)\\s*"
// 16 filesize
+ MONTHS
// 17 month
+ "\\s*"
// TODO should the space be optional?
// TODO \\d* should be \\d? surely ? Otherwise 01111 is allowed
+ "((?:[012]\\d*)|(?:3[01]))\\s*" // 18 date [012]\d* or 3[01]
+ "((?:[012]\\d*)|(?:3[01]))\\s*"
// 18 date [012]\d* or 3[01]
+ "((\\d\\d\\d\\d)|((?:[01]\\d)|(?:2[0123])):([012345]\\d))\\s"
// 20 \d\d\d\d = year OR
// 21 [01]\d or 2[0123] hour + ':'
@ -66,10 +74,8 @@ public class EnterpriseUnixFTPEntryParser extends RegexFTPFileEntryParserImpl
/**
* The sole constructor for a EnterpriseUnixFTPEntryParser object.
*
*/
public EnterpriseUnixFTPEntryParser()
{
public EnterpriseUnixFTPEntryParser() {
super(REGEX);
}
@ -83,15 +89,12 @@ public class EnterpriseUnixFTPEntryParser extends RegexFTPFileEntryParserImpl
* @param entry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
@Override
public FTPFile parseFTPEntry(String entry)
{
@Override public FTPFile parseFTPEntry(String entry) {
FTPFile file = new FTPFile();
file.setRawListing(entry);
if (matches(entry))
{
if (matches(entry)) {
String usr = group(14);
String grp = group(15);
String filesize = group(16);
@ -105,12 +108,9 @@ public class EnterpriseUnixFTPEntryParser extends RegexFTPFileEntryParserImpl
file.setType(FTPFile.FILE_TYPE);
file.setUser(usr);
file.setGroup(grp);
try
{
try {
file.setSize(Long.parseLong(filesize));
}
catch (NumberFormatException e)
{
} catch (NumberFormatException e) {
// intentionally do nothing
}
@ -123,25 +123,20 @@ public class EnterpriseUnixFTPEntryParser extends RegexFTPFileEntryParserImpl
int pos = MONTHS.indexOf(mo);
int month = pos / 4;
final int missingUnit; // the first missing unit
try
{
try {
if (yr != null)
{
if (yr != null) {
// it's a year; there are no hours and minutes
cal.set(Calendar.YEAR, Integer.parseInt(yr));
missingUnit = Calendar.HOUR_OF_DAY;
}
else
{
} else {
// it must be hour/minute or we wouldn't have matched
missingUnit = Calendar.SECOND;
int year = cal.get(Calendar.YEAR);
// if the month we're reading is greater than now, it must
// be last year
if (cal.get(Calendar.MONTH) < month)
{
if (cal.get(Calendar.MONTH) < month) {
year--;
}
cal.set(Calendar.YEAR, year);
@ -152,9 +147,7 @@ public class EnterpriseUnixFTPEntryParser extends RegexFTPFileEntryParserImpl
cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(da));
cal.clear(missingUnit);
file.setTimestamp(cal);
}
catch (NumberFormatException e)
{
} catch (NumberFormatException e) {
// do nothing, date will be uninitialized
}
file.setName(name);

@ -16,15 +16,16 @@
*/
package org.apache.commons.net.ftp.parser;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFileEntryParser;
/**
* The interface describes a factory for creating FTPFileEntryParsers.
*
* @since 1.2
*/
public interface FTPFileEntryParserFactory
{
public interface FTPFileEntryParserFactory {
/**
* Implementation should be a method that decodes the
* supplied key and creates an object implementing the
@ -32,13 +33,10 @@ public interface FTPFileEntryParserFactory
*
* @param key A string that somehow identifies an
* FTPFileEntryParser to be created.
*
* @return the FTPFileEntryParser created.
* @throws ParserInitializationException
* Thrown on any exception in instantiation
* @throws ParserInitializationException Thrown on any exception in instantiation
*/
public FTPFileEntryParser createFileEntryParser(String key)
throws ParserInitializationException;
public FTPFileEntryParser createFileEntryParser(String key) throws ParserInitializationException;
/**
* <p>
@ -56,13 +54,10 @@ public interface FTPFileEntryParserFactory
*
* @param config A {@link FTPClientConfig FTPClientConfig}
* used to configure the parser created
*
* @return the @link FTPFileEntryParser FTPFileEntryParser} so created.
* @throws ParserInitializationException
* Thrown on any exception in instantiation
* @throws ParserInitializationException Thrown on any exception in instantiation
* @since 1.4
*/
public FTPFileEntryParser createFileEntryParser(FTPClientConfig config)
throws ParserInitializationException;
}

@ -23,6 +23,7 @@ import java.util.Calendar;
/**
* This interface specifies the concept of parsing an FTP server's
* timestamp.
*
* @since 1.4
*/
public interface FTPTimestampParser {
@ -40,6 +41,7 @@ public interface FTPTimestampParser {
* Parses the supplied datestamp parameter. This parameter typically would
* have been pulled from a longer FTP listing via the regular expression
* mechanism
*
* @param timestampStr - the timestamp portion of the FTP directory listing
* to be parsed
* @return a <code>java.util.Calendar</code> object initialized to the date
@ -48,5 +50,4 @@ public interface FTPTimestampParser {
* the implementor can parse the input.
*/
public Calendar parseTimestamp(String timestampStr) throws ParseException;
}

@ -36,10 +36,7 @@ import org.apache.commons.net.ftp.FTPClientConfig;
* @see ConfigurableFTPFileEntryParserImpl
* @since 1.4
*/
public class FTPTimestampParserImpl implements
FTPTimestampParser, Configurable
{
public class FTPTimestampParserImpl implements FTPTimestampParser, Configurable {
/** The date format for all dates, except possibly recent dates. Assumed to include the year. */
private SimpleDateFormat defaultDateFormat;
@ -66,13 +63,9 @@ public class FTPTimestampParserImpl implements
* e.g. for MINUTE it would clear MILLISECOND and SECOND
*/
private static final int[] CALENDAR_UNITS = {
Calendar.MILLISECOND,
Calendar.SECOND,
Calendar.MINUTE,
Calendar.HOUR_OF_DAY,
Calendar.DAY_OF_MONTH,
Calendar.MONTH,
Calendar.YEAR};
Calendar.MILLISECOND, Calendar.SECOND, Calendar.MINUTE, Calendar.HOUR_OF_DAY,
Calendar.DAY_OF_MONTH, Calendar.MONTH, Calendar.YEAR
};
/*
* Return the index to the array representing the least significant
@ -159,13 +152,11 @@ public class FTPTimestampParserImpl implements
*
* This method assumes that the server time is the same as the local time.
*
* @see FTPTimestampParserImpl#parseTimestamp(String, Calendar)
*
* @param timestampStr The timestamp to be parsed
* @return a Calendar with the parsed timestamp
* @see FTPTimestampParserImpl#parseTimestamp(String, Calendar)
*/
@Override
public Calendar parseTimestamp(String timestampStr) throws ParseException {
@Override public Calendar parseTimestamp(String timestampStr) throws ParseException {
Calendar now = Calendar.getInstance();
return parseTimestamp(timestampStr, now);
}
@ -179,11 +170,11 @@ public class FTPTimestampParserImpl implements
* This method allows a {@link Calendar} instance to be passed in which represents the
* current (system) time.
*
* @see FTPTimestampParser#parseTimestamp(String)
* @param timestampStr The timestamp to be parsed
* @param serverTime The current time for the server
* @return the calendar
* @throws ParseException if timestamp cannot be parsed
* @see FTPTimestampParser#parseTimestamp(String)
* @since 1.5
*/
public Calendar parseTimestamp(String timestampStr, Calendar serverTime) throws ParseException {
@ -240,10 +231,10 @@ public class FTPTimestampParserImpl implements
if (parsed != null && pp.getIndex() == timestampStr.length()) {
working.setTime(parsed);
} else {
throw new ParseException(
"Timestamp '"+timestampStr+"' could not be parsed using a server time of "
+serverTime.getTime().toString(),
pp.getErrorIndex());
throw new ParseException("Timestamp '"
+ timestampStr
+ "' could not be parsed using a server time of "
+ serverTime.getTime().toString(), pp.getErrorIndex());
}
setPrecision(defaultDateSmallestUnitIndex, working);
return working;
@ -255,12 +246,14 @@ public class FTPTimestampParserImpl implements
public SimpleDateFormat getDefaultDateFormat() {
return defaultDateFormat;
}
/**
* @return Returns the defaultDateFormat pattern string.
*/
public String getDefaultDateFormatString() {
return defaultDateFormat.toPattern();
}
/**
* @param format The defaultDateFormat to be set.
* @param dfs the symbols to use (may be null)
@ -278,18 +271,21 @@ public class FTPTimestampParserImpl implements
}
this.defaultDateSmallestUnitIndex = getEntry(this.defaultDateFormat);
}
/**
* @return Returns the recentDateFormat.
*/
public SimpleDateFormat getRecentDateFormat() {
return recentDateFormat;
}
/**
* @return Returns the recentDateFormat.
*/
public String getRecentDateFormatString() {
return recentDateFormat.toPattern();
}
/**
* @param format The recentDateFormat to set.
* @param dfs the symbols to use (may be null)
@ -316,16 +312,17 @@ public class FTPTimestampParserImpl implements
return defaultDateFormat.getDateFormatSymbols().getShortMonths();
}
/**
* @return Returns the serverTimeZone used by this parser.
*/
public TimeZone getServerTimeZone() {
return this.defaultDateFormat.getTimeZone();
}
/**
* sets a TimeZone represented by the supplied ID string into all
* of the parsers used by this server.
*
* @param serverTimeZone Time Id java.util.TimeZone id used by
* the ftp server. If null the client's local time zone is assumed.
*/
@ -358,13 +355,13 @@ public class FTPTimestampParserImpl implements
* to parse timestamps.</li>
* <li>otherwise use default English month names</li>
* </ul><p>
* Finally if a {@link org.apache.commons.net.ftp.FTPClientConfig#setServerTimeZoneId(String) serverTimeZoneId}
* Finally if a {@link org.apache.commons.net.ftp.FTPClientConfig#setServerTimeZoneId(String)
* serverTimeZoneId}
* has been supplied via the config, set that into all date formats that have
* been configured.
* </p>
*/
@Override
public void configure(FTPClientConfig config) {
@Override public void configure(FTPClientConfig config) {
DateFormatSymbols dfs = null;
String languageCode = config.getServerLanguageCode();
@ -377,7 +374,6 @@ public class FTPTimestampParserImpl implements
dfs = FTPClientConfig.lookupDateFormatSymbols("en");
}
String recentFormatString = config.getRecentDateFormatStr();
setRecentDateFormat(recentFormatString, dfs);
@ -391,12 +387,14 @@ public class FTPTimestampParserImpl implements
this.lenientFutureDates = config.isLenientFutureDates();
}
/**
* @return Returns the lenientFutureDates.
*/
boolean isLenientFutureDates() {
return lenientFutureDates;
}
/**
* @param lenientFutureDates The lenientFutureDates to set.
*/

@ -16,6 +16,7 @@
*/
package org.apache.commons.net.ftp.parser;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
@ -54,12 +55,12 @@ import org.apache.commons.net.ftp.FTPFileEntryParserImpl;
*
* @since 3.0
*/
public class MLSxEntryParser extends FTPFileEntryParserImpl
{
public class MLSxEntryParser extends FTPFileEntryParserImpl {
// This class is immutable, so a single instance can be shared.
private static final MLSxEntryParser PARSER = new MLSxEntryParser();
private static final HashMap<String, Integer> TYPE_TO_INT = new HashMap<String, Integer>();
static {
TYPE_TO_INT.put("file", Integer.valueOf(FTPFile.FILE_TYPE));
TYPE_TO_INT.put("cdir", Integer.valueOf(FTPFile.DIRECTORY_TYPE)); // listed directory
@ -68,9 +69,7 @@ public class MLSxEntryParser extends FTPFileEntryParserImpl
}
private static int UNIX_GROUPS[] = { // Groups in order of mode digits
FTPFile.USER_ACCESS,
FTPFile.GROUP_ACCESS,
FTPFile.WORLD_ACCESS,
FTPFile.USER_ACCESS, FTPFile.GROUP_ACCESS, FTPFile.WORLD_ACCESS,
};
private static int UNIX_PERMS[][] = { // perm bits, broken down by octal int value
@ -88,13 +87,11 @@ public class MLSxEntryParser extends FTPFileEntryParserImpl
* Create the parser for MSLT and MSLD listing entries
* This class is immutable, so one can use {@link #getInstance()} instead.
*/
public MLSxEntryParser()
{
public MLSxEntryParser() {
super();
}
@Override
public FTPFile parseFTPEntry(String entry) {
@Override public FTPFile parseFTPEntry(String entry) {
if (entry.startsWith(" ")) {// leading space means no facts are present
if (entry.length() > 1) { // is there a path name?
FTPFile file = new FTPFile();
@ -104,7 +101,6 @@ public class MLSxEntryParser extends FTPFileEntryParserImpl
} else {
return null; // Invalid - no pathname
}
}
String parts[] = entry.split(" ", 2); // Path may contain space
if (parts.length != 2 || parts[1].length() == 0) {
@ -135,26 +131,22 @@ public class MLSxEntryParser extends FTPFileEntryParserImpl
String valueLowerCase = factvalue.toLowerCase(Locale.ENGLISH);
if ("size".equals(factname)) {
file.setSize(Long.parseLong(factvalue));
}
else if ("sizd".equals(factname)) { // Directory size
} else if ("sizd".equals(factname)) { // Directory size
file.setSize(Long.parseLong(factvalue));
}
else if ("modify".equals(factname)) {
} else if ("modify".equals(factname)) {
final Calendar parsed = parseGMTdateTime(factvalue);
if (parsed == null) {
return null;
}
file.setTimestamp(parsed);
}
else if ("type".equals(factname)) {
} else if ("type".equals(factname)) {
Integer intType = TYPE_TO_INT.get(valueLowerCase);
if (intType == null) {
file.setType(FTPFile.UNKNOWN_TYPE);
} else {
file.setType(intType.intValue());
}
}
else if (factname.startsWith("unix.")) {
} else if (factname.startsWith("unix.")) {
String unixfact = factname.substring("unix.".length()).toLowerCase(Locale.ENGLISH);
if ("group".equals(unixfact)) {
file.setGroup(factvalue);

@ -99,8 +99,7 @@ public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
* 1 2 3 4
* </pre>
*/
static final String JES_LEVEL_1_LIST_REGEX =
"(\\S+)\\s+" + // job name ignored
static final String JES_LEVEL_1_LIST_REGEX = "(\\S+)\\s+" + // job name ignored
"(\\S+)\\s+" + // job number
"(\\S+)\\s+" + // job status (OUTPUT,INPUT,ACTIVE)
"(\\S+)\\s+" + // number of spool files
@ -142,8 +141,7 @@ public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
* </pre>
*/
static final String JES_LEVEL_2_LIST_REGEX =
"(\\S+)\\s+" + // job name ignored
static final String JES_LEVEL_2_LIST_REGEX = "(\\S+)\\s+" + // job name ignored
"(\\S+)\\s+" + // job number
"(\\S+)\\s+" + // owner ignored
"(\\S+)\\s+" + // job status (OUTPUT,INPUT,ACTIVE) ignored
@ -240,7 +238,6 @@ public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
/**
* The sole constructor for a MVSFTPEntryParser object.
*
*/
public MVSFTPEntryParser() {
super(""); // note the regex is set in preParse.
@ -254,12 +251,10 @@ public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
* <code> null </code> is returned. Otherwise a <code> FTPFile </code>
* instance representing the file is returned.
*
* @param entry
* A line of text from the file listing
* @param entry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
@Override
public FTPFile parseFTPEntry(String entry) {
@Override public FTPFile parseFTPEntry(String entry) {
boolean isParsed = false;
FTPFile f = new FTPFile();
@ -305,8 +300,7 @@ public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
* a tape archive. These entries is currently not supported by this parser.
* A null value is returned.
*
* @param file
* will be updated with Name, Type, Timestamp if parsed.
* @param file will be updated with Name, Type, Timestamp if parsed.
* @param entry zosDirectoryEntry
* @return true: entry was parsed, false: entry was not parsed.
*/
@ -320,12 +314,10 @@ public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
// DSORG
if ("PS".equals(dsorg)) {
file.setType(FTPFile.FILE_TYPE);
}
else if ("PO".equals(dsorg) || "PO-E".equals(dsorg)) {
} else if ("PO".equals(dsorg) || "PO-E".equals(dsorg)) {
// regex already ruled out anything other than PO or PO-E
file.setType(FTPFile.DIRECTORY_TYPE);
}
else {
} else {
return false;
}
@ -356,8 +348,7 @@ public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
* [9] Id: User id for last update
* </pre>
*
* @param file
* will be updated with Name, Type and Timestamp if parsed.
* @param file will be updated with Name, Type and Timestamp if parsed.
* @param entry zosDirectoryEntry
* @return true: entry was parsed, false: entry was not parsed.
*/
@ -387,8 +378,6 @@ public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
* safe context, for example from a memberlist, where the regex for some
* reason fails. Then just assign the name field of FTPFile.
*
* @param file
* @param entry
* @return true if the entry string is non-null and non-empty
*/
private boolean parseSimpleEntry(FTPFile file, String entry) {
@ -405,8 +394,6 @@ public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
/**
* Parse the entry as a standard unix file. Using the UnixFTPEntryParser.
*
* @param file
* @param entry
* @return true: entry is parsed, false: entry could not be parsed.
*/
private boolean parseUnixList(FTPFile file, String entry) {
@ -433,8 +420,7 @@ public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
* [5] The string "Spool Files"
* </pre>
*
* @param file
* will be updated with Name, Type and Timestamp if parsed.
* @param file will be updated with Name, Type and Timestamp if parsed.
* @param entry zosDirectoryEntry
* @return true: entry was parsed, false: entry was not parsed.
*/
@ -471,8 +457,7 @@ public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
* [6] The rest
* </pre>
*
* @param file
* will be updated with Name, Type and Timestamp if parsed.
* @param file will be updated with Name, Type and Timestamp if parsed.
* @param entry zosDirectoryEntry
* @return true: entry was parsed, false: entry was not parsed.
*/
@ -497,10 +482,10 @@ public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
* z/OS-MVS File lists
* z/OS-MVS Member lists
* unix file lists
*
* @since 2.0
*/
@Override
public List<String> preParse(List<String> orig) {
@Override public List<String> preParse(List<String> orig) {
// simply remove the header line. Composite logic will take care of the
// two different types of
// list in short order.
@ -536,6 +521,7 @@ public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
/**
* Explicitly set the type of listing being processed.
*
* @param type The listing type.
*/
void setType(int type) {
@ -545,10 +531,7 @@ public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
/*
* @return
*/
@Override
protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(FTPClientConfig.SYST_MVS,
DEFAULT_DATE_FORMAT, null);
@Override protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(FTPClientConfig.SYST_MVS, DEFAULT_DATE_FORMAT, null);
}
}

@ -16,6 +16,7 @@
*/
package org.apache.commons.net.ftp.parser;
import java.text.ParseException;
import org.apache.commons.net.ftp.FTPClientConfig;
@ -28,14 +29,11 @@ import org.apache.commons.net.ftp.FTPFile;
* @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
* @since 3.1
*/
public class MacOsPeterFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
{
public class MacOsPeterFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
static final String DEFAULT_DATE_FORMAT
= "MMM d yyyy"; //Nov 9 2001
static final String DEFAULT_DATE_FORMAT = "MMM d yyyy"; //Nov 9 2001
static final String DEFAULT_RECENT_DATE_FORMAT
= "MMM d HH:mm"; //Nov 9 20:06
static final String DEFAULT_RECENT_DATE_FORMAT = "MMM d HH:mm"; //Nov 9 20:06
/**
* this is the regular expression used by this parser.
@ -57,15 +55,18 @@ public class MacOsPeterFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
* state)
* e z/OS external link bit
*/
private static final String REGEX =
"([bcdelfmpSs-])" // type (1)
+ "(((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-])))\\+?\\s+" // permission
private static final String REGEX = "([bcdelfmpSs-])"
// type (1)
+ "(((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-])))\\+?\\s+"
// permission
+ "("
+ "(folder\\s+)"
+ "|"
+ "((\\d+)\\s+(\\d+)\\s+)" // resource size & data size
+ "((\\d+)\\s+(\\d+)\\s+)"
// resource size & data size
+ ")"
+ "(\\d+)\\s+" // size
+ "(\\d+)\\s+"
// size
/*
* numeric or standard format date:
* yyyy-mm-dd (expecting hh:mm to follow)
@ -83,17 +84,15 @@ public class MacOsPeterFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
+ "(\\S*)(\\s*.*)"; // the rest
/**
* The default constructor for a UnixFTPEntryParser object.
*
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen
* under normal conditions. It it is seen, this is a sign that
* <code>REGEX</code> is not a valid regular expression.
*/
public MacOsPeterFTPEntryParser()
{
public MacOsPeterFTPEntryParser() {
this(null);
}
@ -103,14 +102,13 @@ public class MacOsPeterFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
*
* @param config The {@link FTPClientConfig configuration} object used to
* configure this parser.
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen
* under normal conditions. It it is seen, this is a sign that
* <code>REGEX</code> is not a valid regular expression.
* @since 1.4
*/
public MacOsPeterFTPEntryParser(FTPClientConfig config)
{
public MacOsPeterFTPEntryParser(FTPClientConfig config) {
super(REGEX);
configure(config);
}
@ -125,15 +123,13 @@ public class MacOsPeterFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
* @param entry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
@Override
public FTPFile parseFTPEntry(String entry) {
@Override public FTPFile parseFTPEntry(String entry) {
FTPFile file = new FTPFile();
file.setRawListing(entry);
int type;
boolean isDevice = false;
if (matches(entry))
{
if (matches(entry)) {
String typeStr = group(1);
String hardLinkCount = "0";
String usr = null;
@ -143,12 +139,9 @@ public class MacOsPeterFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
String name = group(23);
String endtoken = group(24);
try
{
try {
file.setTimestamp(super.parseTimestamp(datestr));
}
catch (ParseException e)
{
} catch (ParseException e) {
// intentionally do nothing
}
@ -156,8 +149,7 @@ public class MacOsPeterFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
// 'translucent' filesystems, of which a 'union' filesystem is one.
// bcdelfmpSs-
switch (typeStr.charAt(0))
{
switch (typeStr.charAt(0)) {
case 'd':
type = FTPFile.DIRECTORY_TYPE;
break;
@ -183,33 +175,23 @@ public class MacOsPeterFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
file.setType(type);
int g = 4;
for (int access = 0; access < 3; access++, g += 4)
{
for (int access = 0; access < 3; access++, g += 4) {
// Use != '-' to avoid having to check for suid and sticky bits
file.setPermission(access, FTPFile.READ_PERMISSION,
(!group(g).equals("-")));
file.setPermission(access, FTPFile.WRITE_PERMISSION,
(!group(g + 1).equals("-")));
file.setPermission(access, FTPFile.READ_PERMISSION, (!group(g).equals("-")));
file.setPermission(access, FTPFile.WRITE_PERMISSION, (!group(g + 1).equals("-")));
String execPerm = group(g + 2);
if (!execPerm.equals("-") && !Character.isUpperCase(execPerm.charAt(0)))
{
if (!execPerm.equals("-") && !Character.isUpperCase(execPerm.charAt(0))) {
file.setPermission(access, FTPFile.EXECUTE_PERMISSION, true);
}
else
{
} else {
file.setPermission(access, FTPFile.EXECUTE_PERMISSION, false);
}
}
if (!isDevice)
{
try
{
if (!isDevice) {
try {
file.setHardLinkCount(Integer.parseInt(hardLinkCount));
}
catch (NumberFormatException e)
{
} catch (NumberFormatException e) {
// intentionally do nothing
}
}
@ -217,42 +199,29 @@ public class MacOsPeterFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
file.setUser(usr);
file.setGroup(grp);
try
{
try {
file.setSize(Long.parseLong(filesize));
}
catch (NumberFormatException e)
{
} catch (NumberFormatException e) {
// intentionally do nothing
}
if (null == endtoken)
{
if (null == endtoken) {
file.setName(name);
}
else
{
} else {
// oddball cases like symbolic links, file names
// with spaces in them.
name += endtoken;
if (type == FTPFile.SYMBOLIC_LINK_TYPE)
{
if (type == FTPFile.SYMBOLIC_LINK_TYPE) {
int end = name.indexOf(" -> ");
// Give up if no link indicator is present
if (end == -1)
{
if (end == -1) {
file.setName(name);
}
else
{
} else {
file.setName(name.substring(0, end));
file.setLink(name.substring(end + 4));
}
}
else
{
} else {
file.setName(name);
}
}
@ -265,14 +234,11 @@ public class MacOsPeterFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
* Defines a default configuration to be used when this class is
* instantiated without a {@link FTPClientConfig FTPClientConfig}
* parameter being specified.
*
* @return the default configuration for this parser.
*/
@Override
protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(
FTPClientConfig.SYST_UNIX,
DEFAULT_DATE_FORMAT,
@Override protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(FTPClientConfig.SYST_UNIX, DEFAULT_DATE_FORMAT,
DEFAULT_RECENT_DATE_FORMAT);
}
}

@ -16,6 +16,7 @@
*/
package org.apache.commons.net.ftp.parser;
import java.text.ParseException;
import java.util.regex.Pattern;
@ -29,14 +30,11 @@ import org.apache.commons.net.ftp.FTPFile;
* @version $Id: NTFTPEntryParser.java 1752660 2016-07-14 13:25:39Z sebb $
* @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
*/
public class NTFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
{
public class NTFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
private static final String DEFAULT_DATE_FORMAT
= "MM-dd-yy hh:mma"; //11-09-01 12:30PM
private static final String DEFAULT_DATE_FORMAT = "MM-dd-yy hh:mma"; //11-09-01 12:30PM
private static final String DEFAULT_DATE_FORMAT2
= "MM-dd-yy kk:mm"; //11-09-01 18:30
private static final String DEFAULT_DATE_FORMAT2 = "MM-dd-yy kk:mm"; //11-09-01 18:30
private final FTPTimestampParser timestampParser;
@ -51,13 +49,12 @@ public class NTFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
/**
* The sole constructor for an NTFTPEntryParser object.
*
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen
* under normal conditions. It it is seen, this is a sign that
* <code>REGEX</code> is not a valid regular expression.
*/
public NTFTPEntryParser()
{
public NTFTPEntryParser() {
this(null);
}
@ -67,20 +64,17 @@ public class NTFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
*
* @param config The {@link FTPClientConfig configuration} object used to
* configure this parser.
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen
* under normal conditions. It it is seen, this is a sign that
* <code>REGEX</code> is not a valid regular expression.
* @since 1.4
*/
public NTFTPEntryParser(FTPClientConfig config)
{
public NTFTPEntryParser(FTPClientConfig config) {
super(REGEX, Pattern.DOTALL);
configure(config);
FTPClientConfig config2 = new FTPClientConfig(
FTPClientConfig.SYST_NT,
DEFAULT_DATE_FORMAT2,
null);
FTPClientConfig config2 =
new FTPClientConfig(FTPClientConfig.SYST_NT, DEFAULT_DATE_FORMAT2, null);
config2.setDefaultDateFormatStr(DEFAULT_DATE_FORMAT2);
this.timestampParser = new FTPTimestampParserImpl();
((Configurable) this.timestampParser).configure(config2);
@ -96,52 +90,37 @@ public class NTFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
* @param entry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
@Override
public FTPFile parseFTPEntry(String entry)
{
@Override public FTPFile parseFTPEntry(String entry) {
FTPFile f = new FTPFile();
f.setRawListing(entry);
if (matches(entry))
{
if (matches(entry)) {
String datestr = group(1) + " " + group(2);
String dirString = group(3);
String size = group(4);
String name = group(5);
try
{
try {
f.setTimestamp(super.parseTimestamp(datestr));
}
catch (ParseException e)
{
} catch (ParseException e) {
// parsing fails, try the other date format
try
{
try {
f.setTimestamp(timestampParser.parseTimestamp(datestr));
}
catch (ParseException e2)
{
} catch (ParseException e2) {
// intentionally do nothing
}
}
if (null == name || name.equals(".") || name.equals(".."))
{
if (null == name || name.equals(".") || name.equals("..")) {
return (null);
}
f.setName(name);
if ("<DIR>".equals(dirString))
{
if ("<DIR>".equals(dirString)) {
f.setType(FTPFile.DIRECTORY_TYPE);
f.setSize(0);
}
else
{
} else {
f.setType(FTPFile.FILE_TYPE);
if (null != size)
{
if (null != size) {
f.setSize(Long.parseLong(size));
}
}
@ -154,14 +133,10 @@ public class NTFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
* Defines a default configuration to be used when this class is
* instantiated without a {@link FTPClientConfig FTPClientConfig}
* parameter being specified.
*
* @return the default configuration for this parser.
*/
@Override
public FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(
FTPClientConfig.SYST_NT,
DEFAULT_DATE_FORMAT,
null);
@Override public FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(FTPClientConfig.SYST_NT, DEFAULT_DATE_FORMAT, null);
}
}

@ -23,14 +23,15 @@ 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
* Implementation of FTPFileEntryParser and FTPFileListParser for Netware Systems. Note that some of
* the proprietary
* extensions for Novell-specific operations are not supported. See
* <a href="http://www.novell.com/documentation/nw65/index.html?page=/documentation/nw65/ftp_enu/data/fbhbgcfa.html">
* http://www.novell.com/documentation/nw65/index.html?page=/documentation/nw65/ftp_enu/data/fbhbgcfa.html</a>
* for more details.
*
* @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
* @version $Id: NetwareFTPEntryParser.java 1752660 2016-07-14 13:25:39Z sebb $
* @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
* @since 1.5
*/
public class NetwareFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
@ -58,8 +59,8 @@ public class NetwareFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
/**
* The default constructor for a NetwareFTPEntryParser object.
*
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen
* under normal conditions. It it is seen, this is a sign that
* <code>REGEX</code> is not a valid regular expression.
*/
@ -73,8 +74,8 @@ public class NetwareFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
*
* @param config The {@link FTPClientConfig configuration} object used to
* configure this parser.
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen
* under normal conditions. It it is seen, this is a sign that
* <code>REGEX</code> is not a valid regular expression.
* @since 1.4
@ -96,11 +97,13 @@ public class NetwareFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
* <li><b>S</b> - Supervisor; All rights.
* <li><b>R</b> - Read; Right to open and read or execute.
* <li><b>W</b> - Write; Right to open and modify.
* <li><b>C</b> - Create; Right to create; when assigned to a file, allows a deleted file to be recovered.
* <li><b>C</b> - Create; Right to create; when assigned to a file, allows a deleted file to be
* recovered.
* <li><b>E</b> - Erase; Right to delete.
* <li><b>M</b> - Modify; Right to rename a file and to change attributes.
* <li><b>F</b> - File Scan; Right to see directory or file listings.
* <li><b>A</b> - Access Control; Right to modify trustee assignments and the Inherited Rights Mask.
* <li><b>A</b> - Access Control; Right to modify trustee assignments and the Inherited Rights
* Mask.
* </ul>
*
* See
@ -111,8 +114,7 @@ public class NetwareFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
* @param entry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
@Override
public FTPFile parseFTPEntry(String entry) {
@Override public FTPFile parseFTPEntry(String entry) {
FTPFile f = new FTPFile();
if (matches(entry)) {
@ -148,30 +150,26 @@ public class NetwareFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
// Now set the permissions (or at least a subset thereof - full permissions would probably require
// subclassing FTPFile and adding extra metainformation there)
if (attrib.indexOf("R") != -1) {
f.setPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION,
true);
f.setPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION, true);
}
if (attrib.indexOf("W") != -1) {
f.setPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION,
true);
f.setPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION, true);
}
return (f);
}
return null;
}
/**
* Defines a default configuration to be used when this class is
* instantiated without a {@link FTPClientConfig FTPClientConfig}
* parameter being specified.
*
* @return the default configuration for this parser.
*/
@Override
protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(FTPClientConfig.SYST_NETWARE,
DEFAULT_DATE_FORMAT, DEFAULT_RECENT_DATE_FORMAT);
@Override protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(FTPClientConfig.SYST_NETWARE, DEFAULT_DATE_FORMAT,
DEFAULT_RECENT_DATE_FORMAT);
}
}

@ -16,6 +16,7 @@
*/
package org.apache.commons.net.ftp.parser;
import java.text.ParseException;
import org.apache.commons.net.ftp.FTPClientConfig;
@ -31,13 +32,11 @@ public class OS2FTPEntryParser extends ConfigurableFTPFileEntryParserImpl
{
private static final String DEFAULT_DATE_FORMAT
= "MM-dd-yy HH:mm"; //11-09-01 12:30
private static final String DEFAULT_DATE_FORMAT = "MM-dd-yy HH:mm"; //11-09-01 12:30
/**
* this is the regular expression used by this parser.
*/
private static final String REGEX =
"\\s*([0-9]+)\\s*"
private static final String REGEX = "\\s*([0-9]+)\\s*"
+ "(\\s+|[A-Z]+)\\s*"
+ "(DIR|\\s+)\\s*"
+ "(\\S+)\\s+(\\S+)\\s+" /* date stuff */
@ -46,13 +45,12 @@ public class OS2FTPEntryParser extends ConfigurableFTPFileEntryParserImpl
/**
* The default constructor for a OS2FTPEntryParser object.
*
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen
* under normal conditions. It it is seen, this is a sign that
* <code>REGEX</code> is not a valid regular expression.
*/
public OS2FTPEntryParser()
{
public OS2FTPEntryParser() {
this(null);
}
@ -62,14 +60,13 @@ public class OS2FTPEntryParser extends ConfigurableFTPFileEntryParserImpl
*
* @param config The {@link FTPClientConfig configuration} object used to
* configure this parser.
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen
* under normal conditions. It it is seen, this is a sign that
* <code>REGEX</code> is not a valid regular expression.
* @since 1.4
*/
public OS2FTPEntryParser(FTPClientConfig config)
{
public OS2FTPEntryParser(FTPClientConfig config) {
super(REGEX);
configure(config);
}
@ -84,39 +81,28 @@ public class OS2FTPEntryParser extends ConfigurableFTPFileEntryParserImpl
* @param entry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
@Override
public FTPFile parseFTPEntry(String entry)
{
@Override public FTPFile parseFTPEntry(String entry) {
FTPFile f = new FTPFile();
if (matches(entry))
{
if (matches(entry)) {
String size = group(1);
String attrib = group(2);
String dirString = group(3);
String datestr = group(4) + " " + group(5);
String name = group(6);
try
{
try {
f.setTimestamp(super.parseTimestamp(datestr));
}
catch (ParseException e)
{
} catch (ParseException e) {
// intentionally do nothing
}
//is it a DIR or a file
if (dirString.trim().equals("DIR") || attrib.trim().equals("DIR"))
{
if (dirString.trim().equals("DIR") || attrib.trim().equals("DIR")) {
f.setType(FTPFile.DIRECTORY_TYPE);
}
else
{
} else {
f.setType(FTPFile.FILE_TYPE);
}
//set the name
f.setName(name.trim());
@ -126,21 +112,16 @@ public class OS2FTPEntryParser extends ConfigurableFTPFileEntryParserImpl
return (f);
}
return null;
}
/**
* Defines a default configuration to be used when this class is
* instantiated without a {@link FTPClientConfig FTPClientConfig}
* parameter being specified.
*
* @return the default configuration for this parser.
*/
@Override
protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(
FTPClientConfig.SYST_OS2,
DEFAULT_DATE_FORMAT,
null);
@Override protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(FTPClientConfig.SYST_OS2, DEFAULT_DATE_FORMAT, null);
}
}

@ -165,9 +165,12 @@ import org.apache.commons.net.ftp.FTPFile;
*
* [echo] Downloading members of a file:
* [ftp] getting files
* [ftp] transferring RUN.MBR to C:\workspaces\rdp_080\workspace\ANT - FTP\i5-downloads-file\RUN.MBR
* [ftp] transferring RUNNER.MBR to C:\workspaces\rdp_080\workspace\ANT - FTP\i5-downloads-file\RUNNER.MBR
* [ftp] transferring RUNNERBND.MBR to C:\workspaces\rdp_080\workspace\ANT - FTP\i5-downloads-file\RUNNERBND.MBR
* [ftp] transferring RUN.MBR to C:\workspaces\rdp_080\workspace\ANT -
* FTP\i5-downloads-file\RUN.MBR
* [ftp] transferring RUNNER.MBR to C:\workspaces\rdp_080\workspace\ANT -
* FTP\i5-downloads-file\RUNNER.MBR
* [ftp] transferring RUNNERBND.MBR to C:\workspaces\rdp_080\workspace\ANT -
* FTP\i5-downloads-file\RUNNERBND.MBR
* [ftp] 3 files retrieved
*
*
@ -196,12 +199,18 @@ import org.apache.commons.net.ftp.FTPFile;
*
* [echo] Downloading members of all files of a library:
* [ftp] getting files
* [ftp] transferring RPGUNIT1.FILE\RUN.MBR to C:\work\rdp_080\space\ANT - FTP\i5-downloads\RPGUNIT1.FILE\RUN.MBR
* [ftp] transferring RPGUNIT1.FILE\RUNRMT.MBR to C:\work\rdp_080\space\ANT - FTP\i5-downloads\RPGUNIT1.FILE\RUNRMT.MBR
* [ftp] transferring RPGUNITT1.FILE\RUNT.MBR to C:\work\rdp_080\space\ANT - FTP\i5-downloads\RPGUNITT1.FILE\RUNT.MBR
* [ftp] transferring RPGUNITY1.FILE\RUN.MBR to C:\work\rdp_080\space\ANT - FTP\i5-downloads\RPGUNITY1.FILE\RUN.MBR
* [ftp] transferring RPGUNITY1.FILE\RUNNER.MBR to C:\work\rdp_080\space\ANT - FTP\i5-downloads\RPGUNITY1.FILE\RUNNER.MBR
* [ftp] transferring RPGUNITY1.FILE\RUNNERBND.MBR to C:\work\rdp_080\space\ANT - FTP\i5-downloads\RPGUNITY1.FILE\RUNNERBND.MBR
* [ftp] transferring RPGUNIT1.FILE\RUN.MBR to C:\work\rdp_080\space\ANT -
* FTP\i5-downloads\RPGUNIT1.FILE\RUN.MBR
* [ftp] transferring RPGUNIT1.FILE\RUNRMT.MBR to C:\work\rdp_080\space\ANT -
* FTP\i5-downloads\RPGUNIT1.FILE\RUNRMT.MBR
* [ftp] transferring RPGUNITT1.FILE\RUNT.MBR to C:\work\rdp_080\space\ANT -
* FTP\i5-downloads\RPGUNITT1.FILE\RUNT.MBR
* [ftp] transferring RPGUNITY1.FILE\RUN.MBR to C:\work\rdp_080\space\ANT -
* FTP\i5-downloads\RPGUNITY1.FILE\RUN.MBR
* [ftp] transferring RPGUNITY1.FILE\RUNNER.MBR to C:\work\rdp_080\space\ANT -
* FTP\i5-downloads\RPGUNITY1.FILE\RUNNER.MBR
* [ftp] transferring RPGUNITY1.FILE\RUNNERBND.MBR to C:\work\rdp_080\space\ANT -
* FTP\i5-downloads\RPGUNITY1.FILE\RUNNERBND.MBR
* [ftp] 6 files retrieved
*
*
@ -231,31 +240,24 @@ import org.apache.commons.net.ftp.FTPFile;
*
* </pre>
*/
public class OS400FTPEntryParser extends ConfigurableFTPFileEntryParserImpl
{
private static final String DEFAULT_DATE_FORMAT
= "yy/MM/dd HH:mm:ss"; //01/11/09 12:30:24
public class OS400FTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
private static final String DEFAULT_DATE_FORMAT = "yy/MM/dd HH:mm:ss"; //01/11/09 12:30:24
private static final String REGEX =
"(\\S+)\\s+" // user
private static final String REGEX = "(\\S+)\\s+" // user
+ "(?:(\\d+)\\s+)?" // size, empty for members
+ "(?:(\\S+)\\s+(\\S+)\\s+)?" // date stuff, empty for members
+ "(\\*STMF|\\*DIR|\\*FILE|\\*MEM)\\s+" // *STMF/*DIR/*FILE/*MEM
+ "(?:(\\S+)\\s*)?"; // filename, missing, when CWD is a *FILE
/**
* The default constructor for a OS400FTPEntryParser object.
*
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen
* under normal conditions. It it is seen, this is a sign that
* <code>REGEX</code> is not a valid regular expression.
*/
public OS400FTPEntryParser()
{
public OS400FTPEntryParser() {
this(null);
}
@ -265,34 +267,28 @@ public class OS400FTPEntryParser extends ConfigurableFTPFileEntryParserImpl
*
* @param config The {@link FTPClientConfig configuration} object used to
* configure this parser.
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen
* under normal conditions. It it is seen, this is a sign that
* <code>REGEX</code> is not a valid regular expression.
* @since 1.4
*/
public OS400FTPEntryParser(FTPClientConfig config)
{
public OS400FTPEntryParser(FTPClientConfig config) {
super(REGEX);
configure(config);
}
@Override
public FTPFile parseFTPEntry(String entry)
{
@Override public FTPFile parseFTPEntry(String entry) {
FTPFile file = new FTPFile();
file.setRawListing(entry);
int type;
if (matches(entry))
{
if (matches(entry)) {
String usr = group(1);
String filesize = group(2);
String datestr = "";
if (!isNullOrEmpty(group(3)) || !isNullOrEmpty(group(4)))
{
if (!isNullOrEmpty(group(3)) || !isNullOrEmpty(group(4))) {
datestr = group(3) + " " + group(4);
}
String typeStr = group(5);
@ -300,34 +296,23 @@ public class OS400FTPEntryParser extends ConfigurableFTPFileEntryParserImpl
boolean mustScanForPathSeparator = true;
try
{
try {
file.setTimestamp(super.parseTimestamp(datestr));
}
catch (ParseException e)
{
} catch (ParseException e) {
// intentionally do nothing
}
if (typeStr.equalsIgnoreCase("*STMF"))
{
if (typeStr.equalsIgnoreCase("*STMF")) {
type = FTPFile.FILE_TYPE;
if (isNullOrEmpty(filesize) || isNullOrEmpty(name))
{
if (isNullOrEmpty(filesize) || isNullOrEmpty(name)) {
return null;
}
}
else if (typeStr.equalsIgnoreCase("*DIR"))
{
} else if (typeStr.equalsIgnoreCase("*DIR")) {
type = FTPFile.DIRECTORY_TYPE;
if (isNullOrEmpty(filesize) || isNullOrEmpty(name))
{
if (isNullOrEmpty(filesize) || isNullOrEmpty(name)) {
return null;
}
}
else if (typeStr.equalsIgnoreCase("*FILE"))
{
} else if (typeStr.equalsIgnoreCase("*FILE")) {
// File, defines the structure of the data (columns of a row)
// but the data is stored in one or more members. Typically a
// source file contains multiple members whereas it is
@ -335,27 +320,20 @@ public class OS400FTPEntryParser extends ConfigurableFTPFileEntryParserImpl
// file.
// Save files are a special type of files which are used
// to save objects, e.g. for backups.
if (name != null && name.toUpperCase().endsWith(".SAVF"))
{
if (name != null && name.toUpperCase().endsWith(".SAVF")) {
mustScanForPathSeparator = false;
type = FTPFile.FILE_TYPE;
}
else
{
} else {
return null;
}
}
else if (typeStr.equalsIgnoreCase("*MEM"))
{
} else if (typeStr.equalsIgnoreCase("*MEM")) {
mustScanForPathSeparator = false;
type = FTPFile.FILE_TYPE;
if (isNullOrEmpty(name))
{
if (isNullOrEmpty(name)) {
return null;
}
if (!(isNullOrEmpty(filesize) && isNullOrEmpty(datestr)))
{
if (!(isNullOrEmpty(filesize) && isNullOrEmpty(datestr))) {
return null;
}
@ -365,9 +343,7 @@ public class OS400FTPEntryParser extends ConfigurableFTPFileEntryParserImpl
// use the separator of the FTP server, which is a forward
// slash in case of an AS/400.
name = name.replace('/', File.separatorChar);
}
else
{
} else {
type = FTPFile.UNKNOWN_TYPE;
}
@ -375,24 +351,18 @@ public class OS400FTPEntryParser extends ConfigurableFTPFileEntryParserImpl
file.setUser(usr);
try
{
try {
file.setSize(Long.parseLong(filesize));
}
catch (NumberFormatException e)
{
} catch (NumberFormatException e) {
// intentionally do nothing
}
if (name.endsWith("/"))
{
if (name.endsWith("/")) {
name = name.substring(0, name.length() - 1);
}
if (mustScanForPathSeparator)
{
if (mustScanForPathSeparator) {
int pos = name.lastIndexOf('/');
if (pos > -1)
{
if (pos > -1) {
name = name.substring(pos + 1);
}
}
@ -405,7 +375,6 @@ public class OS400FTPEntryParser extends ConfigurableFTPFileEntryParserImpl
}
/**
*
* @param string String value that is checked for <code>null</code>
* or empty.
* @return <code>true</code> for <code>null</code> or empty values,
@ -422,14 +391,10 @@ public class OS400FTPEntryParser extends ConfigurableFTPFileEntryParserImpl
* Defines a default configuration to be used when this class is
* instantiated without a {@link FTPClientConfig FTPClientConfig}
* parameter being specified.
*
* @return the default configuration for this parser.
*/
@Override
protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(
FTPClientConfig.SYST_OS400,
DEFAULT_DATE_FORMAT,
null);
@Override protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(FTPClientConfig.SYST_OS400, DEFAULT_DATE_FORMAT, null);
}
}

@ -54,9 +54,7 @@ public class ParserInitializationException extends RuntimeException {
* @return the root cause of this exception being thrown
* @deprecated use {@link #getCause()} instead
*/
@Deprecated
public Throwable getRootCause() {
@Deprecated public Throwable getRootCause() {
return super.getCause();
}
}

@ -15,7 +15,6 @@
* limitations under the License.
*/
package org.apache.commons.net.ftp.parser;
import java.util.regex.MatchResult;
@ -32,8 +31,7 @@ import org.apache.commons.net.ftp.FTPFileEntryParserImpl;
*
* This is the base class for all regular expression based FTPFileEntryParser classes
*/
public abstract class RegexFTPFileEntryParserImpl extends
FTPFileEntryParserImpl {
public abstract class RegexFTPFileEntryParserImpl extends FTPFileEntryParserImpl {
/**
* internal pattern the matcher tries to match, representing a file
* entry
@ -57,9 +55,8 @@ public abstract class RegexFTPFileEntryParserImpl extends
*
* @param regex The regular expression with which this object is
* initialized.
*
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen in
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen in
* normal conditions. It it is seen, this is a sign that a subclass has
* been created with a bad regular expression. Since the parser must be
* created before use, this means that any bad parser subclasses created
@ -77,9 +74,8 @@ public abstract class RegexFTPFileEntryParserImpl extends
* @param regex The regular expression with which this object is
* initialized.
* @param flags the flags to apply, see {@link Pattern#compile(String, int)}. Use 0 for none.
*
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen in
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen in
* normal conditions. It it is seen, this is a sign that a subclass has
* been created with a bad regular expression. Since the parser must be
* created before use, this means that any bad parser subclasses created
@ -126,7 +122,6 @@ public abstract class RegexFTPFileEntryParserImpl extends
* method.
*
* @param matchnum match group number to be retrieved
*
* @return the content of the <code>matchnum'th</code> group of the internal
* match or null if this method is called without a match having
* been made.
@ -148,8 +143,10 @@ public abstract class RegexFTPFileEntryParserImpl extends
public String getGroupsAsString() {
StringBuilder b = new StringBuilder();
for (int i = 1; i <= this.result.groupCount(); i++) {
b.append(i).append(") ").append(this.result.group(i)).append(
System.getProperty("line.separator"));
b.append(i)
.append(") ")
.append(this.result.group(i))
.append(System.getProperty("line.separator"));
}
return b.toString();
}
@ -157,25 +154,26 @@ public abstract class RegexFTPFileEntryParserImpl extends
/**
* Alter the current regular expression being utilised for entry parsing
* and create a new {@link Pattern} instance.
*
* @param regex The new regular expression
* @return true
* @since 2.0
* @throws IllegalArgumentException if the regex cannot be compiled
* @since 2.0
*/
public boolean setRegex(final String regex) {
compileRegex(regex, 0);
return true;
}
/**
* Alter the current regular expression being utilised for entry parsing
* and create a new {@link Pattern} instance.
*
* @param regex The new regular expression
* @param flags the flags to apply, see {@link Pattern#compile(String, int)}. Use 0 for none.
* @return true
* @since 3.4
* @throws IllegalArgumentException if the regex cannot be compiled
* @since 3.4
*/
public boolean setRegex(final String regex, final int flags) {
compileRegex(regex, flags);

@ -16,6 +16,7 @@
*/
package org.apache.commons.net.ftp.parser;
import java.text.ParseException;
import java.util.List;
import java.util.ListIterator;
@ -30,31 +31,28 @@ import org.apache.commons.net.ftp.FTPFile;
* This class is based on the logic of Daniel Savarese's
* DefaultFTPListParser, but adapted to use regular expressions and to fit the
* 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)
*/
public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
{
public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
static final String DEFAULT_DATE_FORMAT
= "MMM d yyyy"; //Nov 9 2001
static final String DEFAULT_DATE_FORMAT = "MMM d yyyy"; //Nov 9 2001
static final String DEFAULT_RECENT_DATE_FORMAT
= "MMM d HH:mm"; //Nov 9 20:06
static final String DEFAULT_RECENT_DATE_FORMAT = "MMM d HH:mm"; //Nov 9 20:06
static final String NUMERIC_DATE_FORMAT
= "yyyy-MM-dd HH:mm"; //2001-11-09 20:06
static final String NUMERIC_DATE_FORMAT = "yyyy-MM-dd HH:mm"; //2001-11-09 20:06
// Suffixes used in Japanese listings after the numeric values
private static final String JA_MONTH = "\u6708";
private static final String JA_DAY = "\u65e5";
private static final String JA_YEAR = "\u5e74";
private static final String DEFAULT_DATE_FORMAT_JA
= "M'" + JA_MONTH + "' d'" + JA_DAY + "' yyyy'" + JA_YEAR + "'"; //6月 3日 2003年
private static final String DEFAULT_DATE_FORMAT_JA =
"M'" + JA_MONTH + "' d'" + JA_DAY + "' yyyy'" + JA_YEAR + "'"; //6月 3日 2003年
private static final String DEFAULT_RECENT_DATE_FORMAT_JA
= "M'" + JA_MONTH + "' d'" + JA_DAY + "' HH:mm"; //8月 17日 20:10
private static final String DEFAULT_RECENT_DATE_FORMAT_JA =
"M'" + JA_MONTH + "' d'" + JA_DAY + "' HH:mm"; //8月 17日 20:10
/**
* Some Linux distributions are now shipping an FTP server which formats
@ -69,10 +67,7 @@ public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
* Steve Cohen - 2005-04-17
*/
public static final FTPClientConfig NUMERIC_DATE_CONFIG =
new FTPClientConfig(
FTPClientConfig.SYST_UNIX,
NUMERIC_DATE_FORMAT,
null);
new FTPClientConfig(FTPClientConfig.SYST_UNIX, NUMERIC_DATE_FORMAT, null);
/**
* this is the regular expression used by this parser.
@ -99,8 +94,7 @@ public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
* this is not allowed for here as does not appear to be shown by FTP servers
* {@code @} file has extended attributes
*/
private static final String REGEX =
"([bcdelfmpSs-])" // file type
private static final String REGEX = "([bcdelfmpSs-])" // file type
+ "(((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-])))\\+?" // permissions
+ "\\s*" // separator TODO why allow it to be omitted??
@ -124,13 +118,10 @@ public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
* diacritics (e.g. umlaut) in some abbreviations.
* Japanese uses numeric day and month with suffixes to distinguish them
* [d]dXX [d]dZZ
*/
+ "("+
"(?:\\d+[-/]\\d+[-/]\\d+)" + // yyyy-mm-dd
*/ + "(" + "(?:\\d+[-/]\\d+[-/]\\d+)" + // yyyy-mm-dd
"|(?:\\S{3}\\s+\\d{1,2})" + // MMM [d]d
"|(?:\\d{1,2}\\s+\\S{3})" + // [d]d MMM
"|(?:\\d{1,2}" + JA_MONTH + "\\s+\\d{1,2}" + JA_DAY + ")"+
")"
"|(?:\\d{1,2}" + JA_MONTH + "\\s+\\d{1,2}" + JA_DAY + ")" + ")"
+ "\\s+" // separator
@ -138,14 +129,12 @@ public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
year (for non-recent standard format) - yyyy
or time (for numeric or recent standard format) [h]h:mm
or Japanese year - yyyyXX
*/
+ "((?:\\d+(?::\\d+)?)|(?:\\d{4}" + JA_YEAR + "))" // (20)
*/ + "((?:\\d+(?::\\d+)?)|(?:\\d{4}" + JA_YEAR + "))" // (20)
+ "\\s" // separator
+ "(.*)"; // the rest (21)
// if true, leading spaces are trimmed from file names
// this was the case for the original implementation
final boolean trimLeadingSpaces; // package protected for access from test code
@ -153,13 +142,12 @@ public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
/**
* The default constructor for a UnixFTPEntryParser object.
*
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen
* under normal conditions. It it is seen, this is a sign that
* <code>REGEX</code> is not a valid regular expression.
*/
public UnixFTPEntryParser()
{
public UnixFTPEntryParser() {
this(null);
}
@ -169,14 +157,13 @@ public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
*
* @param config The {@link FTPClientConfig configuration} object used to
* configure this parser.
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen
* under normal conditions. It it is seen, this is a sign that
* <code>REGEX</code> is not a valid regular expression.
* @since 1.4
*/
public UnixFTPEntryParser(FTPClientConfig config)
{
public UnixFTPEntryParser(FTPClientConfig config) {
this(config, false);
}
@ -187,14 +174,13 @@ public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
* @param config The {@link FTPClientConfig configuration} object used to
* configure this parser.
* @param trimLeadingSpaces if {@code true}, trim leading spaces from file names
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen
* under normal conditions. It it is seen, this is a sign that
* <code>REGEX</code> is not a valid regular expression.
* @since 3.4
*/
public UnixFTPEntryParser(FTPClientConfig config, boolean trimLeadingSpaces)
{
public UnixFTPEntryParser(FTPClientConfig config, boolean trimLeadingSpaces) {
super(REGEX);
configure(config);
this.trimLeadingSpaces = trimLeadingSpaces;
@ -203,8 +189,7 @@ public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
/**
* Preparse the list to discard "total nnn" lines
*/
@Override
public List<String> preParse(List<String> original) {
@Override public List<String> preParse(List<String> original) {
ListIterator<String> iter = original.listIterator();
while (iter.hasNext()) {
String entry = iter.next();
@ -225,15 +210,13 @@ public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
* @param entry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
@Override
public FTPFile parseFTPEntry(String entry) {
@Override public FTPFile parseFTPEntry(String entry) {
FTPFile file = new FTPFile();
file.setRawListing(entry);
int type;
boolean isDevice = false;
if (matches(entry))
{
if (matches(entry)) {
String typeStr = group(1);
String hardLinkCount = group(15);
String usr = group(16);
@ -245,19 +228,16 @@ public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
name = name.replaceFirst("^\\s+", "");
}
try
{
try {
if (group(19).contains(JA_MONTH)) { // special processing for Japanese format
FTPTimestampParserImpl jaParser = new FTPTimestampParserImpl();
jaParser.configure(new FTPClientConfig(
FTPClientConfig.SYST_UNIX, DEFAULT_DATE_FORMAT_JA, DEFAULT_RECENT_DATE_FORMAT_JA));
jaParser.configure(new FTPClientConfig(FTPClientConfig.SYST_UNIX, DEFAULT_DATE_FORMAT_JA,
DEFAULT_RECENT_DATE_FORMAT_JA));
file.setTimestamp(jaParser.parseTimestamp(datestr));
} else {
file.setTimestamp(super.parseTimestamp(datestr));
}
}
catch (ParseException e)
{
} catch (ParseException e) {
// intentionally do nothing
}
@ -265,8 +245,7 @@ public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
// 'translucent' filesystems, of which a 'union' filesystem is one.
// bcdelfmpSs-
switch (typeStr.charAt(0))
{
switch (typeStr.charAt(0)) {
case 'd':
type = FTPFile.DIRECTORY_TYPE;
break;
@ -292,33 +271,23 @@ public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
file.setType(type);
int g = 4;
for (int access = 0; access < 3; access++, g += 4)
{
for (int access = 0; access < 3; access++, g += 4) {
// Use != '-' to avoid having to check for suid and sticky bits
file.setPermission(access, FTPFile.READ_PERMISSION,
(!group(g).equals("-")));
file.setPermission(access, FTPFile.WRITE_PERMISSION,
(!group(g + 1).equals("-")));
file.setPermission(access, FTPFile.READ_PERMISSION, (!group(g).equals("-")));
file.setPermission(access, FTPFile.WRITE_PERMISSION, (!group(g + 1).equals("-")));
String execPerm = group(g + 2);
if (!execPerm.equals("-") && !Character.isUpperCase(execPerm.charAt(0)))
{
if (!execPerm.equals("-") && !Character.isUpperCase(execPerm.charAt(0))) {
file.setPermission(access, FTPFile.EXECUTE_PERMISSION, true);
}
else
{
} else {
file.setPermission(access, FTPFile.EXECUTE_PERMISSION, false);
}
}
if (!isDevice)
{
try
{
if (!isDevice) {
try {
file.setHardLinkCount(Integer.parseInt(hardLinkCount));
}
catch (NumberFormatException e)
{
} catch (NumberFormatException e) {
// intentionally do nothing
}
}
@ -326,35 +295,25 @@ public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
file.setUser(usr);
file.setGroup(grp);
try
{
try {
file.setSize(Long.parseLong(filesize));
}
catch (NumberFormatException e)
{
} catch (NumberFormatException e) {
// intentionally do nothing
}
// oddball cases like symbolic links, file names
// with spaces in them.
if (type == FTPFile.SYMBOLIC_LINK_TYPE)
{
if (type == FTPFile.SYMBOLIC_LINK_TYPE) {
int end = name.indexOf(" -> ");
// Give up if no link indicator is present
if (end == -1)
{
if (end == -1) {
file.setName(name);
}
else
{
} else {
file.setName(name.substring(0, end));
file.setLink(name.substring(end + 4));
}
}
else
{
} else {
file.setName(name);
}
return file;
@ -366,14 +325,11 @@ public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
* Defines a default configuration to be used when this class is
* instantiated without a {@link FTPClientConfig FTPClientConfig}
* parameter being specified.
*
* @return the default configuration for this parser.
*/
@Override
protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(
FTPClientConfig.SYST_UNIX,
DEFAULT_DATE_FORMAT,
@Override protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(FTPClientConfig.SYST_UNIX, DEFAULT_DATE_FORMAT,
DEFAULT_RECENT_DATE_FORMAT);
}
}

@ -16,6 +16,7 @@
*/
package org.apache.commons.net.ftp.parser;
import java.io.BufferedReader;
import java.io.IOException;
import java.text.ParseException;
@ -28,9 +29,12 @@ import org.apache.commons.net.ftp.FTPFile;
* Implementation FTPFileEntryParser and FTPFileListParser for VMS Systems.
* This is a sample of VMS LIST output
*
* "1-JUN.LIS;1 9/9 2-JUN-1998 07:32:04 [GROUP,OWNER] (RWED,RWED,RWED,RE)",
* "1-JUN.LIS;2 9/9 2-JUN-1998 07:32:04 [GROUP,OWNER] (RWED,RWED,RWED,RE)",
* "DATA.DIR;1 1/9 2-JUN-1998 07:32:04 [GROUP,OWNER] (RWED,RWED,RWED,RE)",
* "1-JUN.LIS;1 9/9 2-JUN-1998 07:32:04 [GROUP,OWNER]
* (RWED,RWED,RWED,RE)",
* "1-JUN.LIS;2 9/9 2-JUN-1998 07:32:04 [GROUP,OWNER]
* (RWED,RWED,RWED,RE)",
* "DATA.DIR;1 1/9 2-JUN-1998 07:32:04 [GROUP,OWNER]
* (RWED,RWED,RWED,RE)",
* <P><B>
* Note: VMSFTPEntryParser can only be instantiated through the
* DefaultFTPParserFactory by classname. It will not be chosen
@ -39,15 +43,12 @@ import org.apache.commons.net.ftp.FTPFile;
* <P>
*
* @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
*/
public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
{
public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
private static final String DEFAULT_DATE_FORMAT
= "d-MMM-yyyy HH:mm:ss"; //9-NOV-2001 12:30:24
private static final String DEFAULT_DATE_FORMAT = "d-MMM-yyyy HH:mm:ss"; //9-NOV-2001 12:30:24
/**
* this is the regular expression used by this parser.
@ -57,21 +58,19 @@ public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
+ "(\\d+)/\\d+\\s*" //2 size/allocated
+ "(\\S+)\\s+(\\S+)\\s+" //3+4 date and time
+ "\\[(([0-9$A-Za-z_]+)|([0-9$A-Za-z_]+),([0-9$a-zA-Z_]+))\\]?\\s*" //5(6,7,8) owner
+ "\\([a-zA-Z]*,([a-zA-Z]*),([a-zA-Z]*),([a-zA-Z]*)\\)"; //9,10,11 Permissions (O,G,W)
+ "\\([a-zA-Z]*,([a-zA-Z]*),([a-zA-Z]*),([a-zA-Z]*)\\)";
//9,10,11 Permissions (O,G,W)
// TODO - perhaps restrict permissions to [RWED]* ?
/**
* Constructor for a VMSFTPEntryParser object.
*
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen
* under normal conditions. It it is seen, this is a sign that
* <code>REGEX</code> is not a valid regular expression.
*/
public VMSFTPEntryParser()
{
public VMSFTPEntryParser() {
this(null);
}
@ -81,14 +80,13 @@ public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
*
* @param config The {@link FTPClientConfig configuration} object used to
* configure this parser.
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen
* under normal conditions. It it is seen, this is a sign that
* <code>REGEX</code> is not a valid regular expression.
* @since 1.4
*/
public VMSFTPEntryParser(FTPClientConfig config)
{
public VMSFTPEntryParser(FTPClientConfig config) {
super(REGEX);
configure(config);
}
@ -103,14 +101,11 @@ public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
* @param entry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
@Override
public FTPFile parseFTPEntry(String entry)
{
@Override public FTPFile parseFTPEntry(String entry) {
//one block in VMS equals 512 bytes
long longBlock = 512;
if (matches(entry))
{
if (matches(entry)) {
FTPFile f = new FTPFile();
f.setRawListing(entry);
String name = group(1);
@ -121,16 +116,12 @@ public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
permissions[0] = group(9);
permissions[1] = group(10);
permissions[2] = group(11);
try
{
try {
f.setTimestamp(super.parseTimestamp(datestr));
}
catch (ParseException e)
{
} catch (ParseException e) {
// intentionally do nothing
}
String grp;
String user;
StringTokenizer t = new StringTokenizer(owner, ",");
@ -148,22 +139,16 @@ public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
user = null;
}
if (name.lastIndexOf(".DIR") != -1)
{
if (name.lastIndexOf(".DIR") != -1) {
f.setType(FTPFile.DIRECTORY_TYPE);
}
else
{
} else {
f.setType(FTPFile.FILE_TYPE);
}
//set FTPFile name
//Check also for versions to be returned or not
if (isVersioning())
{
if (isVersioning()) {
f.setName(name);
}
else
{
} else {
name = name.substring(0, name.lastIndexOf(";"));
f.setName(name);
}
@ -181,8 +166,7 @@ public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
//R (read) W (write) E (execute) D (delete)
//iterate for OWNER GROUP WORLD permissions
for (int access = 0; access < 3; access++)
{
for (int access = 0; access < 3; access++) {
String permission = permissions[access];
f.setPermission(access, FTPFile.READ_PERMISSION, permission.indexOf('R') >= 0);
@ -195,7 +179,6 @@ public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
return null;
}
/**
* Reads the next entry using the supplied BufferedReader object up to
* whatever delemits one entry from the next. This parser cannot use
@ -204,25 +187,20 @@ public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
*
* @param reader The BufferedReader object from which entries are to be
* read.
*
* @return A string representing the next ftp entry or null if none found.
* @throws IOException thrown on any IO Error reading from the reader.
*/
@Override
public String readNextEntry(BufferedReader reader) throws IOException
{
@Override public String readNextEntry(BufferedReader reader) throws IOException {
String line = reader.readLine();
StringBuilder entry = new StringBuilder();
while (line != null)
{
while (line != null) {
if (line.startsWith("Directory") || line.startsWith("Total")) {
line = reader.readLine();
continue;
}
entry.append(line);
if (line.trim().endsWith(")"))
{
if (line.trim().endsWith(")")) {
break;
}
line = reader.readLine();
@ -238,32 +216,29 @@ public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
* Defines a default configuration to be used when this class is
* instantiated without a {@link FTPClientConfig FTPClientConfig}
* parameter being specified.
*
* @return the default configuration for this parser.
*/
@Override
protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(
FTPClientConfig.SYST_VMS,
DEFAULT_DATE_FORMAT,
null);
@Override protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(FTPClientConfig.SYST_VMS, DEFAULT_DATE_FORMAT, null);
}
// DEPRECATED METHODS - for API compatibility only - DO NOT USE
/**
* DO NOT USE
*
* @param listStream the stream
* @return the array of files
* @throws IOException on error
* @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);
@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);
engine.readServerList(listStream, null);
return engine.getFiles();
}
}
/* Emacs configuration

@ -34,32 +34,31 @@ import org.apache.commons.net.ftp.FTPClientConfig;
*
* This is a sample of VMS LIST output
*
* "1-JUN.LIS;1 9/9 2-JUN-1998 07:32:04 [GROUP,OWNER] (RWED,RWED,RWED,RE)",
* "1-JUN.LIS;2 9/9 2-JUN-1998 07:32:04 [GROUP,OWNER] (RWED,RWED,RWED,RE)",
* "DATA.DIR;1 1/9 2-JUN-1998 07:32:04 [GROUP,OWNER] (RWED,RWED,RWED,RE)",
* "1-JUN.LIS;1 9/9 2-JUN-1998 07:32:04 [GROUP,OWNER]
* (RWED,RWED,RWED,RE)",
* "1-JUN.LIS;2 9/9 2-JUN-1998 07:32:04 [GROUP,OWNER]
* (RWED,RWED,RWED,RE)",
* "DATA.DIR;1 1/9 2-JUN-1998 07:32:04 [GROUP,OWNER]
* (RWED,RWED,RWED,RE)",
* <P>
*
* @version $Id: VMSVersioningFTPEntryParser.java 1747119 2016-06-07 02:22:24Z ggregory $
*
* @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
*/
public class VMSVersioningFTPEntryParser extends VMSFTPEntryParser
{
public class VMSVersioningFTPEntryParser extends VMSFTPEntryParser {
private final Pattern _preparse_pattern_;
private static final String PRE_PARSE_REGEX =
"(.*?);([0-9]+)\\s*.*";
private static final String PRE_PARSE_REGEX = "(.*?);([0-9]+)\\s*.*";
/**
* Constructor for a VMSFTPEntryParser object.
*
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen
* under normal conditions. It it is seen, this is a sign that
* <code>REGEX</code> is not a valid regular expression.
*/
public VMSVersioningFTPEntryParser()
{
public VMSVersioningFTPEntryParser() {
this(null);
}
@ -69,27 +68,21 @@ public class VMSVersioningFTPEntryParser extends VMSFTPEntryParser
*
* @param config The {@link FTPClientConfig configuration} object used to
* configure this parser.
* @throws IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* @throws IllegalArgumentException Thrown if the regular expression is unparseable. Should not
* be seen
* under normal conditions. It it is seen, this is a sign that
* <code>REGEX</code> is not a valid regular expression.
* @since 1.4
*/
public VMSVersioningFTPEntryParser(FTPClientConfig config)
{
public VMSVersioningFTPEntryParser(FTPClientConfig config) {
super();
configure(config);
try
{
try {
//_preparse_matcher_ = new Perl5Matcher();
_preparse_pattern_ = Pattern.compile(PRE_PARSE_REGEX);
} catch (PatternSyntaxException pse) {
throw new IllegalArgumentException("Unparseable regex supplied: " + PRE_PARSE_REGEX);
}
catch (PatternSyntaxException pse)
{
throw new IllegalArgumentException (
"Unparseable regex supplied: " + PRE_PARSE_REGEX);
}
}
/**
@ -98,11 +91,9 @@ public class VMSVersioningFTPEntryParser extends VMSFTPEntryParser
* multiple files with the same name to remove the duplicates ..
*
* @param original Original list
*
* @return Original list purged of duplicates
*/
@Override
public List<String> preParse(List<String> original) {
@Override public List<String> preParse(List<String> original) {
HashMap<String, Integer> existingEntries = new HashMap<String, Integer>();
ListIterator<String> iter = original.listIterator();
while (iter.hasNext()) {
@ -123,7 +114,6 @@ public class VMSVersioningFTPEntryParser extends VMSFTPEntryParser
}
existingEntries.put(name, nv);
}
}
// we've now removed all entries less than with less than the largest
// version number for each name that were listed after the largest.
@ -145,17 +135,13 @@ public class VMSVersioningFTPEntryParser extends VMSFTPEntryParser
}
}
}
}
return original;
}
@Override
protected boolean isVersioning() {
@Override protected boolean isVersioning() {
return true;
}
}
/* Emacs configuration

@ -28,18 +28,17 @@ import java.io.Reader;
*
* @since 3.0
*/
public final class CRLFLineReader extends BufferedReader
{
public final class CRLFLineReader extends BufferedReader {
private static final char LF = '\n';
private static final char CR = '\r';
/**
* Creates a CRLFLineReader that wraps an existing Reader
* input source.
*
* @param reader The Reader input source.
*/
public CRLFLineReader(Reader reader)
{
public CRLFLineReader(Reader reader) {
super(reader);
}
@ -47,16 +46,15 @@ public final class CRLFLineReader extends BufferedReader
* Read a line of text.
* A line is considered to be terminated by carriage return followed immediately by a linefeed.
* This contrasts with BufferedReader which also allows other combinations.
*
* @since 3.0
*/
@Override
public String readLine() throws IOException {
@Override public String readLine() throws IOException {
StringBuilder sb = new StringBuilder();
int intch;
boolean prevWasCR = false;
synchronized (lock) { // make thread-safe (hopefully!)
while((intch = read()) != -1)
{
while ((intch = read()) != -1) {
if (prevWasCR && intch == LF) {
return sb.substring(0, sb.length() - 1);
}

@ -32,21 +32,18 @@ import org.apache.commons.net.util.ListenerList;
* reasons and also because multiple listeners cannot be registered given
* that the methods are static.
*
*
* @version $Id: CopyStreamAdapter.java 1741829 2016-05-01 00:24:44Z sebb $
* @see CopyStreamEvent
* @see CopyStreamListener
* @see Util
* @version $Id: CopyStreamAdapter.java 1741829 2016-05-01 00:24:44Z sebb $
*/
public class CopyStreamAdapter implements CopyStreamListener
{
public class CopyStreamAdapter implements CopyStreamListener {
private final ListenerList internalListeners;
/**
* Creates a new copyStreamAdapter.
*/
public CopyStreamAdapter()
{
public CopyStreamAdapter() {
internalListeners = new ListenerList();
}
@ -57,14 +54,12 @@ public class CopyStreamAdapter implements CopyStreamListener
* transferred in the last write. The CopyStreamAdapater will relay
* the event to all of its registered listeners, listing itself as the
* source of the event.
*
* @param event The CopyStreamEvent fired by the copying of a block of
* bytes.
*/
@Override
public void bytesTransferred(CopyStreamEvent event)
{
for (EventListener listener : internalListeners)
{
@Override public void bytesTransferred(CopyStreamEvent event) {
for (EventListener listener : internalListeners) {
((CopyStreamListener) (listener)).bytesTransferred(event);
}
}
@ -76,6 +71,7 @@ public class CopyStreamAdapter implements CopyStreamListener
* transfer. The CopyStreamAdapater will create a CopyStreamEvent
* from the arguments and relay the event to all of its registered
* listeners, listing itself as the source of the event.
*
* @param totalBytesTransferred The total number of bytes transferred
* so far by the copy operation.
* @param bytesTransferred The number of bytes copied by the most recent
@ -84,14 +80,11 @@ public class CopyStreamAdapter implements CopyStreamListener
* This may be equal to CopyStreamEvent.UNKNOWN_STREAM_SIZE if
* the size is unknown.
*/
@Override
public void bytesTransferred(long totalBytesTransferred,
int bytesTransferred, long streamSize)
{
for (EventListener listener : internalListeners)
{
((CopyStreamListener) (listener)).bytesTransferred(
totalBytesTransferred, bytesTransferred, streamSize);
@Override public void bytesTransferred(long totalBytesTransferred, int bytesTransferred,
long streamSize) {
for (EventListener listener : internalListeners) {
((CopyStreamListener) (listener)).bytesTransferred(totalBytesTransferred, bytesTransferred,
streamSize);
}
}
@ -99,20 +92,20 @@ public class CopyStreamAdapter implements CopyStreamListener
* Registers a CopyStreamListener to receive CopyStreamEvents.
* Although this method is not declared to be synchronized, it is
* implemented in a thread safe manner.
*
* @param listener The CopyStreamlistener to register.
*/
public void addCopyStreamListener(CopyStreamListener listener)
{
public void addCopyStreamListener(CopyStreamListener listener) {
internalListeners.addListener(listener);
}
/**
* Unregisters a CopyStreamListener. Although this method is not
* synchronized, it is implemented in a thread safe manner.
*
* @param listener The CopyStreamlistener to unregister.
*/
public void removeCopyStreamListener(CopyStreamListener listener)
{
public void removeCopyStreamListener(CopyStreamListener listener) {
internalListeners.removeListener(listener);
}
}

@ -25,14 +25,12 @@ import java.util.EventObject;
* transferred by the write triggering the event as well as the total
* number of bytes transferred so far by the copy operation.
*
*
* @version $Id: CopyStreamEvent.java 1652801 2015-01-18 17:10:05Z sebb $
* @see CopyStreamListener
* @see CopyStreamAdapter
* @see Util
* @version $Id: CopyStreamEvent.java 1652801 2015-01-18 17:10:05Z sebb $
*/
public class CopyStreamEvent extends EventObject
{
public class CopyStreamEvent extends EventObject {
private static final long serialVersionUID = -964927635655051867L;
/**
@ -46,6 +44,7 @@ public class CopyStreamEvent extends EventObject
/**
* Creates a new CopyStreamEvent instance.
*
* @param source The source of the event.
* @param totalBytesTransferred The total number of bytes transferred so
* far during a copy operation.
@ -55,9 +54,8 @@ public class CopyStreamEvent extends EventObject
* This may be set to <code>UNKNOWN_STREAM_SIZE</code> if the
* size is unknown.
*/
public CopyStreamEvent(Object source, long totalBytesTransferred,
int bytesTransferred, long streamSize)
{
public CopyStreamEvent(Object source, long totalBytesTransferred, int bytesTransferred,
long streamSize) {
super(source);
this.bytesTransferred = bytesTransferred;
this.totalBytesTransferred = totalBytesTransferred;
@ -67,22 +65,22 @@ public class CopyStreamEvent extends EventObject
/**
* Returns the number of bytes transferred by the write that triggered
* the event.
*
* @return The number of bytes transferred by the write that triggered
* the vent.
*/
public int getBytesTransferred()
{
public int getBytesTransferred() {
return bytesTransferred;
}
/**
* Returns the total number of bytes transferred so far by the copy
* operation.
*
* @return The total number of bytes transferred so far by the copy
* operation.
*/
public long getTotalBytesTransferred()
{
public long getTotalBytesTransferred() {
return totalBytesTransferred;
}
@ -90,22 +88,26 @@ public class CopyStreamEvent extends EventObject
* Returns the size of the stream being copied.
* This may be set to <code>UNKNOWN_STREAM_SIZE</code> if the
* size is unknown.
*
* @return The size of the stream being copied.
*/
public long getStreamSize()
{
public long getStreamSize() {
return streamSize;
}
/**
* @since 3.0
*/
@Override
public String toString(){
return getClass().getName() + "[source=" + source
+ ", total=" + totalBytesTransferred
+ ", bytes=" + bytesTransferred
+ ", size=" + streamSize
@Override public String toString() {
return getClass().getName()
+ "[source="
+ source
+ ", total="
+ totalBytesTransferred
+ ", bytes="
+ bytesTransferred
+ ", size="
+ streamSize
+ "]";
}
}

@ -24,26 +24,24 @@ import java.io.IOException;
* copyStream() methods. It stores the number of bytes confirmed to
* have been transferred before an I/O error as well as the IOException
* responsible for the failure of a copy operation.
* @see Util
*
* @version $Id: CopyStreamException.java 1299238 2012-03-10 17:12:28Z sebb $
* @see Util
*/
public class CopyStreamException extends IOException
{
public class CopyStreamException extends IOException {
private static final long serialVersionUID = -2602899129433221532L;
private final long totalBytesTransferred;
/**
* Creates a new CopyStreamException instance.
*
* @param message A message describing the error.
* @param bytesTransferred The total number of bytes transferred before
* an exception was thrown in a copy operation.
* @param exception The IOException thrown during a copy operation.
*/
public CopyStreamException(String message,
long bytesTransferred,
IOException exception)
{
public CopyStreamException(String message, long bytesTransferred, IOException exception) {
super(message);
initCause(exception); // merge this into super() call once we need 1.6+
totalBytesTransferred = bytesTransferred;
@ -52,20 +50,20 @@ public class CopyStreamException extends IOException
/**
* Returns the total number of bytes confirmed to have
* been transferred by a failed copy operation.
*
* @return The total number of bytes confirmed to have
* been transferred by a failed copy operation.
*/
public long getTotalBytesTransferred()
{
public long getTotalBytesTransferred() {
return totalBytesTransferred;
}
/**
* Returns the IOException responsible for the failure of a copy operation.
*
* @return The IOException responsible for the failure of a copy operation.
*/
public IOException getIOException()
{
public IOException getIOException() {
return (IOException) getCause(); // cast is OK because it was initialised with an IOException
}
}

@ -33,30 +33,29 @@ import java.util.EventListener;
* JavaBean event model, which is why the hooks have been included from the
* beginning.
*
*
* @version $Id: CopyStreamListener.java 1652801 2015-01-18 17:10:05Z sebb $
* @see CopyStreamEvent
* @see CopyStreamAdapter
* @see Util
* @version $Id: CopyStreamListener.java 1652801 2015-01-18 17:10:05Z sebb $
*/
public interface CopyStreamListener extends EventListener
{
public interface CopyStreamListener extends EventListener {
/**
* This method is invoked by a CopyStreamEvent source after copying
* a block of bytes from a stream. The CopyStreamEvent will contain
* the total number of bytes transferred so far and the number of bytes
* transferred in the last write.
*
* @param event The CopyStreamEvent fired by the copying of a block of
* bytes.
*/
public void bytesTransferred(CopyStreamEvent event);
/**
* This method is not part of the JavaBeans model and is used by the
* static methods in the org.apache.commons.io.Util class for efficiency.
* It is invoked after a block of bytes to inform the listener of the
* transfer.
*
* @param totalBytesTransferred The total number of bytes transferred
* so far by the copy operation.
* @param bytesTransferred The number of bytes copied by the most recent

@ -35,10 +35,10 @@ import java.io.Reader;
* Note: versions since 3.0 extend BufferedReader rather than Reader,
* and no longer change the CRLF into the local EOL. Also only DOT CR LF
* acts as EOF.
*
* @version $Id: DotTerminatedMessageReader.java 1747119 2016-06-07 02:22:24Z ggregory $
*/
public final class DotTerminatedMessageReader extends BufferedReader
{
public final class DotTerminatedMessageReader extends BufferedReader {
private static final char LF = '\n';
private static final char CR = '\r';
private static final int DOT = '.';
@ -50,10 +50,10 @@ public final class DotTerminatedMessageReader extends BufferedReader
/**
* Creates a DotTerminatedMessageReader that wraps an existing Reader
* input source.
*
* @param reader The Reader input source containing the message.
*/
public DotTerminatedMessageReader(Reader reader)
{
public DotTerminatedMessageReader(Reader reader) {
super(reader);
// Assumes input is at start of message
atBeginning = true;
@ -67,13 +67,13 @@ public final class DotTerminatedMessageReader extends BufferedReader
* the message properly (removing doubled dots and so on). All of
* this is transparent to the programmer and is only mentioned for
* completeness.
*
* @return The next character in the message. Returns -1 if the end of the
* message has been reached.
* @throws IOException If an error occurs while reading the underlying
* stream.
*/
@Override
public int read() throws IOException {
@Override public int read() throws IOException {
synchronized (lock) {
if (eof) {
return -1; // Don't allow read past EOF
@ -132,20 +132,18 @@ public final class DotTerminatedMessageReader extends BufferedReader
}
}
/**
* Reads the next characters from the message into an array and
* returns the number of characters read. Returns -1 if the end of the
* message has been reached.
*
* @param buffer The character array in which to store the characters.
* @return The number of characters read. Returns -1 if the
* end of the message has been reached.
* @throws IOException If an error occurs in reading the underlying
* stream.
*/
@Override
public int read(char[] buffer) throws IOException
{
@Override public int read(char[] buffer) throws IOException {
return read(buffer, 0, buffer.length);
}
@ -154,6 +152,7 @@ public final class DotTerminatedMessageReader extends BufferedReader
* returns the number of characters read. Returns -1 if the end of the
* message has been reached. The characters are stored in the array
* starting from the given offset and up to the length specified.
*
* @param buffer The character array in which to store the characters.
* @param offset The offset into the array at which to start storing
* characters.
@ -163,28 +162,21 @@ public final class DotTerminatedMessageReader extends BufferedReader
* @throws IOException If an error occurs in reading the underlying
* stream.
*/
@Override
public int read(char[] buffer, int offset, int length) throws IOException
{
if (length < 1)
{
@Override public int read(char[] buffer, int offset, int length) throws IOException {
if (length < 1) {
return 0;
}
int ch;
synchronized (lock)
{
if ((ch = read()) == -1)
{
synchronized (lock) {
if ((ch = read()) == -1) {
return -1;
}
int off = offset;
do
{
do {
buffer[offset++] = (char) ch;
}
while (--length > 0 && (ch = read()) != -1);
} while (--length > 0 && (ch = read()) != -1);
return (offset - off);
}
@ -201,18 +193,14 @@ public final class DotTerminatedMessageReader extends BufferedReader
* for communicating with the server. If you do not fully read
* a message, you MUST close it, otherwise your program will likely
* hang or behave improperly.
*
* @throws IOException If an error occurs while reading the
* underlying stream.
*/
@Override
public void close() throws IOException
{
synchronized (lock)
{
if (!eof)
{
while (read() != -1)
{
@Override public void close() throws IOException {
synchronized (lock) {
if (!eof) {
while (read() != -1) {
// read to EOF
}
}
@ -225,15 +213,14 @@ public final class DotTerminatedMessageReader extends BufferedReader
* Read a line of text.
* A line is considered to be terminated by carriage return followed immediately by a linefeed.
* This contrasts with BufferedReader which also allows other combinations.
*
* @since 3.0
*/
@Override
public String readLine() throws IOException {
@Override public String readLine() throws IOException {
StringBuilder sb = new StringBuilder();
int intch;
synchronized (lock) { // make thread-safe (hopefully!)
while((intch = read()) != -1)
{
while ((intch = read()) != -1) {
if (intch == LF && atBeginning) {
return sb.substring(0, sb.length() - 1);
}

@ -36,8 +36,7 @@ import java.io.Writer;
*
***/
public final class DotTerminatedMessageWriter extends Writer
{
public final class DotTerminatedMessageWriter extends Writer {
private static final int __NOTHING_SPECIAL_STATE = 0;
private static final int __LAST_WAS_CR_STATE = 1;
private static final int __LAST_WAS_NL_STATE = 2;
@ -45,21 +44,18 @@ public final class DotTerminatedMessageWriter extends Writer
private int __state;
private Writer __output;
/***
* Creates a DotTerminatedMessageWriter that wraps an existing Writer
* output destination.
*
* @param output The Writer output destination to write the message.
***/
public DotTerminatedMessageWriter(Writer output)
{
public DotTerminatedMessageWriter(Writer output) {
super(output);
__output = output;
__state = __NOTHING_SPECIAL_STATE;
}
/***
* Writes a character to the output. Note that a call to this method
* may result in multiple writes to the underling Writer in order to
@ -71,13 +67,9 @@ public final class DotTerminatedMessageWriter extends Writer
* @throws IOException If an error occurs while writing to the
* underlying output.
***/
@Override
public void write(int ch) throws IOException
{
synchronized (lock)
{
switch (ch)
{
@Override public void write(int ch) throws IOException {
synchronized (lock) {
switch (ch) {
case '\r':
__state = __LAST_WAS_CR_STATE;
__output.write('\r');
@ -103,7 +95,6 @@ public final class DotTerminatedMessageWriter extends Writer
}
}
/***
* Writes a number of characters from a character array to the output
* starting from a given offset.
@ -114,18 +105,14 @@ public final class DotTerminatedMessageWriter extends Writer
* @throws IOException If an error occurs while writing to the underlying
* output.
***/
@Override
public void write(char[] buffer, int offset, int length) throws IOException
{
synchronized (lock)
{
@Override public void write(char[] buffer, int offset, int length) throws IOException {
synchronized (lock) {
while (length-- > 0) {
write(buffer[offset++]);
}
}
}
/***
* Writes a character array to the output.
*
@ -133,13 +120,10 @@ public final class DotTerminatedMessageWriter extends Writer
* @throws IOException If an error occurs while writing to the underlying
* output.
***/
@Override
public void write(char[] buffer) throws IOException
{
@Override public void write(char[] buffer) throws IOException {
write(buffer, 0, buffer.length);
}
/***
* Writes a String to the output.
*
@ -147,13 +131,10 @@ public final class DotTerminatedMessageWriter extends Writer
* @throws IOException If an error occurs while writing to the underlying
* output.
***/
@Override
public void write(String string) throws IOException
{
@Override public void write(String string) throws IOException {
write(string.toCharArray());
}
/***
* Writes part of a String to the output starting from a given offset.
*
@ -163,29 +144,22 @@ public final class DotTerminatedMessageWriter extends Writer
* @throws IOException If an error occurs while writing to the underlying
* output.
***/
@Override
public void write(String string, int offset, int length) throws IOException
{
@Override public void write(String string, int offset, int length) throws IOException {
write(string.toCharArray(), offset, length);
}
/***
* Flushes the underlying output, writing all buffered output.
*
* @throws IOException If an error occurs while writing to the underlying
* output.
***/
@Override
public void flush() throws IOException
{
synchronized (lock)
{
@Override public void flush() throws IOException {
synchronized (lock) {
__output.flush();
}
}
/***
* Flushes the underlying output, writing all buffered output, but doesn't
* actually close the underlying stream. The underlying stream may still
@ -194,11 +168,8 @@ public final class DotTerminatedMessageWriter extends Writer
* @throws IOException If an error occurs while writing to the underlying
* output or closing the Writer.
***/
@Override
public void close() throws IOException
{
synchronized (lock)
{
@Override public void close() throws IOException {
synchronized (lock) {
if (__output == null) {
return;
}
@ -215,5 +186,4 @@ public final class DotTerminatedMessageWriter extends Writer
__output = null;
}
}
}

@ -32,8 +32,7 @@ import java.io.UnsupportedEncodingException;
*
***/
public final class FromNetASCIIInputStream extends PushbackInputStream
{
public final class FromNetASCIIInputStream extends PushbackInputStream {
static final boolean _noConversionRequired;
static final String _lineSeparator;
static final byte[] _lineSeparatorBytes;
@ -59,8 +58,7 @@ public final class FromNetASCIIInputStream extends PushbackInputStream
* @return True if the NETASCII line separator differs from the local
* system line separator, false if they are the same.
***/
public static final boolean isConversionRequired()
{
public static final boolean isConversionRequired() {
return !_noConversionRequired;
}
@ -69,30 +67,23 @@ public final class FromNetASCIIInputStream extends PushbackInputStream
* InputStream.
* @param input the stream to wrap
***/
public FromNetASCIIInputStream(InputStream input)
{
public FromNetASCIIInputStream(InputStream input) {
super(input, _lineSeparatorBytes.length + 1);
}
private int __read() throws IOException
{
private int __read() throws IOException {
int ch;
ch = super.read();
if (ch == '\r')
{
if (ch == '\r') {
ch = super.read();
if (ch == '\n')
{
if (ch == '\n') {
unread(_lineSeparatorBytes);
ch = super.read();
// This is a kluge for read(byte[], ...) to read the right amount
--__length;
}
else
{
} else {
if (ch != -1) {
unread(ch);
}
@ -103,7 +94,6 @@ public final class FromNetASCIIInputStream extends PushbackInputStream
return ch;
}
/***
* Reads and returns the next byte in the stream. If the end of the
* message has been reached, returns -1. Note that a call to this method
@ -117,9 +107,7 @@ public final class FromNetASCIIInputStream extends PushbackInputStream
* @throws IOException If an error occurs while reading the underlying
* stream.
***/
@Override
public int read() throws IOException
{
@Override public int read() throws IOException {
if (_noConversionRequired) {
return super.read();
}
@ -127,7 +115,6 @@ public final class FromNetASCIIInputStream extends PushbackInputStream
return __read();
}
/***
* Reads the next number of bytes from the stream into an array and
* returns the number of bytes read. Returns -1 if the end of the
@ -139,13 +126,10 @@ public final class FromNetASCIIInputStream extends PushbackInputStream
* @throws IOException If an error occurs in reading the underlying
* stream.
***/
@Override
public int read(byte buffer[]) throws IOException
{
@Override public int read(byte buffer[]) throws IOException {
return read(buffer, 0, buffer.length);
}
/***
* Reads the next number of bytes from the stream into an array and returns
* the number of bytes read. Returns -1 if the end of the
@ -160,9 +144,7 @@ public final class FromNetASCIIInputStream extends PushbackInputStream
* @throws IOException If an error occurs while reading the underlying
* stream.
***/
@Override
public int read(byte buffer[], int offset, int length) throws IOException
{
@Override public int read(byte buffer[], int offset, int length) throws IOException {
if (_noConversionRequired) {
return super.read(buffer, offset, length);
}
@ -182,26 +164,22 @@ public final class FromNetASCIIInputStream extends PushbackInputStream
__length = 1;
}
if ((ch = __read()) == -1) {
return -1;
}
off = offset;
do
{
do {
buffer[offset++] = (byte) ch;
}
while (--__length > 0 && (ch = __read()) != -1);
} while (--__length > 0 && (ch = __read()) != -1);
return (offset - off);
}
// PushbackInputStream in JDK 1.1.3 returns the wrong thing
// TODO - can we delete this override now?
/***
* Returns the number of bytes that can be read without blocking EXCEPT
* when newline conversions have to be made somewhere within the
@ -209,13 +187,10 @@ public final class FromNetASCIIInputStream extends PushbackInputStream
* rely on the value returned by this method if you are trying to avoid
* blocking.
***/
@Override
public int available() throws IOException
{
@Override public int available() throws IOException {
if (in == null) {
throw new IOException("Stream closed");
}
return (buf.length - pos) + in.available();
}
}

@ -36,8 +36,7 @@ import java.io.OutputStream;
*
***/
public final class FromNetASCIIOutputStream extends FilterOutputStream
{
public final class FromNetASCIIOutputStream extends FilterOutputStream {
private boolean __lastWasCR;
/***
@ -46,24 +45,19 @@ public final class FromNetASCIIOutputStream extends FilterOutputStream
*
* @param output The OutputStream to wrap.
***/
public FromNetASCIIOutputStream(OutputStream output)
{
public FromNetASCIIOutputStream(OutputStream output) {
super(output);
__lastWasCR = false;
}
private void __write(int ch) throws IOException
{
switch (ch)
{
private void __write(int ch) throws IOException {
switch (ch) {
case '\r':
__lastWasCR = true;
// Don't write anything. We need to see if next one is linefeed
break;
case '\n':
if (__lastWasCR)
{
if (__lastWasCR) {
out.write(FromNetASCIIInputStream._lineSeparatorBytes);
__lastWasCR = false;
break;
@ -72,8 +66,7 @@ public final class FromNetASCIIOutputStream extends FilterOutputStream
out.write('\n');
break;
default:
if (__lastWasCR)
{
if (__lastWasCR) {
out.write('\r');
__lastWasCR = false;
}
@ -82,7 +75,6 @@ public final class FromNetASCIIOutputStream extends FilterOutputStream
}
}
/***
* Writes a byte to the stream. Note that a call to this method
* might not actually write a byte to the underlying stream until a
@ -95,12 +87,8 @@ public final class FromNetASCIIOutputStream extends FilterOutputStream
* @throws IOException If an error occurs while writing to the underlying
* stream.
***/
@Override
public synchronized void write(int ch)
throws IOException
{
if (FromNetASCIIInputStream._noConversionRequired)
{
@Override public synchronized void write(int ch) throws IOException {
if (FromNetASCIIInputStream._noConversionRequired) {
out.write(ch);
return;
}
@ -108,7 +96,6 @@ public final class FromNetASCIIOutputStream extends FilterOutputStream
__write(ch);
}
/***
* Writes a byte array to the stream.
*
@ -116,14 +103,10 @@ public final class FromNetASCIIOutputStream extends FilterOutputStream
* @throws IOException If an error occurs while writing to the underlying
* stream.
***/
@Override
public synchronized void write(byte buffer[])
throws IOException
{
@Override public synchronized void write(byte buffer[]) throws IOException {
write(buffer, 0, buffer.length);
}
/***
* Writes a number of bytes from a byte array to the stream starting from
* a given offset.
@ -134,12 +117,9 @@ public final class FromNetASCIIOutputStream extends FilterOutputStream
* @throws IOException If an error occurs while writing to the underlying
* stream.
***/
@Override
public synchronized void write(byte buffer[], int offset, int length)
throws IOException
{
if (FromNetASCIIInputStream._noConversionRequired)
{
@Override public synchronized void write(byte buffer[], int offset, int length)
throws IOException {
if (FromNetASCIIInputStream._noConversionRequired) {
// FilterOutputStream method is very slow.
//super.write(buffer, offset, length);
out.write(buffer, offset, length);
@ -151,18 +131,13 @@ public final class FromNetASCIIOutputStream extends FilterOutputStream
}
}
/***
* Closes the stream, writing all pending data.
*
* @throws IOException If an error occurs while closing the stream.
***/
@Override
public synchronized void close()
throws IOException
{
if (FromNetASCIIInputStream._noConversionRequired)
{
@Override public synchronized void close() throws IOException {
if (FromNetASCIIInputStream._noConversionRequired) {
super.close();
return;
}

@ -34,8 +34,7 @@ import java.net.Socket;
* @see SocketOutputStream
***/
public class SocketInputStream extends FilterInputStream
{
public class SocketInputStream extends FilterInputStream {
private final Socket __socket;
/***
@ -46,8 +45,7 @@ public class SocketInputStream extends FilterInputStream
* @param socket The socket to close on closing the stream.
* @param stream The input stream to wrap.
***/
public SocketInputStream(Socket socket, InputStream stream)
{
public SocketInputStream(Socket socket, InputStream stream) {
super(stream);
__socket = socket;
}
@ -59,9 +57,7 @@ public class SocketInputStream extends FilterInputStream
* @throws IOException If there is an error in closing the stream
* or socket.
***/
@Override
public void close() throws IOException
{
@Override public void close() throws IOException {
super.close();
__socket.close();
}

@ -34,8 +34,7 @@ import java.net.Socket;
* @see SocketInputStream
***/
public class SocketOutputStream extends FilterOutputStream
{
public class SocketOutputStream extends FilterOutputStream {
private final Socket __socket;
/***
@ -46,13 +45,11 @@ public class SocketOutputStream extends FilterOutputStream
* @param socket The socket to close on closing the stream.
* @param stream The input stream to wrap.
***/
public SocketOutputStream(Socket socket, OutputStream stream)
{
public SocketOutputStream(Socket socket, OutputStream stream) {
super(stream);
__socket = socket;
}
/***
* Writes a number of bytes from a byte array to the stream starting from
* a given offset. This method bypasses the equivalent method in
@ -65,13 +62,10 @@ public class SocketOutputStream extends FilterOutputStream
* @throws IOException If an error occurs while writing to the underlying
* stream.
***/
@Override
public void write(byte buffer[], int offset, int length) throws IOException
{
@Override public void write(byte buffer[], int offset, int length) throws IOException {
out.write(buffer, offset, length);
}
/***
* Closes the stream and immediately afterward closes the referenced
* socket.
@ -79,9 +73,7 @@ public class SocketOutputStream extends FilterOutputStream
* @throws IOException If there is an error in closing the stream
* or socket.
***/
@Override
public void close() throws IOException
{
@Override public void close() throws IOException {
super.close();
__socket.close();
}

@ -32,8 +32,7 @@ import java.io.InputStream;
*
***/
public final class ToNetASCIIInputStream extends FilterInputStream
{
public final class ToNetASCIIInputStream extends FilterInputStream {
private static final int __NOTHING_SPECIAL = 0;
private static final int __LAST_WAS_CR = 1;
private static final int __LAST_WAS_NL = 2;
@ -45,13 +44,11 @@ public final class ToNetASCIIInputStream extends FilterInputStream
*
* @param input The InputStream to wrap.
***/
public ToNetASCIIInputStream(InputStream input)
{
public ToNetASCIIInputStream(InputStream input) {
super(input);
__status = __NOTHING_SPECIAL;
}
/***
* Reads and returns the next byte in the stream. If the end of the
* message has been reached, returns -1.
@ -61,27 +58,22 @@ public final class ToNetASCIIInputStream extends FilterInputStream
* @throws IOException If an error occurs while reading the underlying
* stream.
***/
@Override
public int read() throws IOException
{
@Override public int read() throws IOException {
int ch;
if (__status == __LAST_WAS_NL)
{
if (__status == __LAST_WAS_NL) {
__status = __NOTHING_SPECIAL;
return '\n';
}
ch = in.read();
switch (ch)
{
switch (ch) {
case '\r':
__status = __LAST_WAS_CR;
return '\r';
case '\n':
if (__status != __LAST_WAS_CR)
{
if (__status != __LAST_WAS_CR) {
__status = __LAST_WAS_NL;
return '\r';
}
@ -94,7 +86,6 @@ public final class ToNetASCIIInputStream extends FilterInputStream
//return ch;
}
/***
* Reads the next number of bytes from the stream into an array and
* returns the number of bytes read. Returns -1 if the end of the
@ -106,13 +97,10 @@ public final class ToNetASCIIInputStream extends FilterInputStream
* @throws IOException If an error occurs in reading the underlying
* stream.
***/
@Override
public int read(byte buffer[]) throws IOException
{
@Override public int read(byte buffer[]) throws IOException {
return read(buffer, 0, buffer.length);
}
/***
* Reads the next number of bytes from the stream into an array and returns
* the number of bytes read. Returns -1 if the end of the
@ -127,9 +115,7 @@ public final class ToNetASCIIInputStream extends FilterInputStream
* @throws IOException If an error occurs while reading the underlying
* stream.
***/
@Override
public int read(byte buffer[], int offset, int length) throws IOException
{
@Override public int read(byte buffer[], int offset, int length) throws IOException {
int ch, off;
if (length < 1) {
@ -153,25 +139,19 @@ public final class ToNetASCIIInputStream extends FilterInputStream
off = offset;
do
{
do {
buffer[offset++] = (byte) ch;
}
while (--length > 0 && (ch = read()) != -1);
} while (--length > 0 && (ch = read()) != -1);
return (offset - off);
}
/*** Returns false. Mark is not supported. ***/
@Override
public boolean markSupported()
{
@Override public boolean markSupported() {
return false;
}
@Override
public int available() throws IOException
{
@Override public int available() throws IOException {
int result;
result = in.available();

@ -32,8 +32,7 @@ import java.io.OutputStream;
*
***/
public final class ToNetASCIIOutputStream extends FilterOutputStream
{
public final class ToNetASCIIOutputStream extends FilterOutputStream {
private boolean __lastWasCR;
/***
@ -42,13 +41,11 @@ public final class ToNetASCIIOutputStream extends FilterOutputStream
*
* @param output The OutputStream to wrap.
***/
public ToNetASCIIOutputStream(OutputStream output)
{
public ToNetASCIIOutputStream(OutputStream output) {
super(output);
__lastWasCR = false;
}
/***
* Writes a byte to the stream. Note that a call to this method
* may result in multiple writes to the underlying input stream in order
@ -60,12 +57,8 @@ public final class ToNetASCIIOutputStream extends FilterOutputStream
* @throws IOException If an error occurs while writing to the underlying
* stream.
***/
@Override
public synchronized void write(int ch)
throws IOException
{
switch (ch)
{
@Override public synchronized void write(int ch) throws IOException {
switch (ch) {
case '\r':
__lastWasCR = true;
out.write('\r');
@ -82,7 +75,6 @@ public final class ToNetASCIIOutputStream extends FilterOutputStream
}
}
/***
* Writes a byte array to the stream.
*
@ -90,14 +82,10 @@ public final class ToNetASCIIOutputStream extends FilterOutputStream
* @throws IOException If an error occurs while writing to the underlying
* stream.
***/
@Override
public synchronized void write(byte buffer[])
throws IOException
{
@Override public synchronized void write(byte buffer[]) throws IOException {
write(buffer, 0, buffer.length);
}
/***
* Writes a number of bytes from a byte array to the stream starting from
* a given offset.
@ -108,13 +96,10 @@ public final class ToNetASCIIOutputStream extends FilterOutputStream
* @throws IOException If an error occurs while writing to the underlying
* stream.
***/
@Override
public synchronized void write(byte buffer[], int offset, int length)
throws IOException
{
@Override public synchronized void write(byte buffer[], int offset, int length)
throws IOException {
while (length-- > 0) {
write(buffer[offset++]);
}
}
}

@ -35,8 +35,7 @@ import java.net.Socket;
* @see CopyStreamAdapter
***/
public final class Util
{
public final class Util {
/**
* The default buffer size ({@value}) used by
* {@link #copyStream copyStream } and {@link #copyReader copyReader}
@ -45,9 +44,8 @@ public final class Util
public static final int DEFAULT_COPY_BUFFER_SIZE = 1024;
// Cannot be instantiated
private Util()
{ }
private Util() {
}
/***
* Copies the contents of an InputStream to an OutputStream using a
@ -87,25 +85,18 @@ public final class Util
* the CopyStreamException getTotalBytesTransferred() and
* getIOException() methods.
***/
public static final long copyStream(InputStream source, OutputStream dest,
int bufferSize, long streamSize,
CopyStreamListener listener,
boolean flush)
throws CopyStreamException
{
public static final long copyStream(InputStream source, OutputStream dest, int bufferSize,
long streamSize, CopyStreamListener listener, boolean flush) throws CopyStreamException {
int numBytes;
long total = 0;
byte[] buffer = new byte[bufferSize > 0 ? bufferSize : DEFAULT_COPY_BUFFER_SIZE];
try
{
while ((numBytes = source.read(buffer)) != -1)
{
try {
while ((numBytes = source.read(buffer)) != -1) {
// Technically, some read(byte[]) methods may return 0 and we cannot
// accept that as an indication of EOF.
if (numBytes == 0)
{
if (numBytes == 0) {
int singleByte = source.read();
if (singleByte < 0) {
break;
@ -130,11 +121,8 @@ public final class Util
listener.bytesTransferred(total, numBytes, streamSize);
}
}
}
catch (IOException e)
{
throw new CopyStreamException("IOException caught while copying.",
total, e);
} catch (IOException e) {
throw new CopyStreamException("IOException caught while copying.", total, e);
}
return total;
@ -175,16 +163,11 @@ public final class Util
* the CopyStreamException getTotalBytesTransferred() and
* getIOException() methods.
***/
public static final long copyStream(InputStream source, OutputStream dest,
int bufferSize, long streamSize,
CopyStreamListener listener)
throws CopyStreamException
{
return copyStream(source, dest, bufferSize, streamSize, listener,
true);
public static final long copyStream(InputStream source, OutputStream dest, int bufferSize,
long streamSize, CopyStreamListener listener) throws CopyStreamException {
return copyStream(source, dest, bufferSize, streamSize, listener, true);
}
/***
* Copies the contents of an InputStream to an OutputStream using a
* copy buffer of a given size. The contents of the InputStream are
@ -207,15 +190,11 @@ public final class Util
* the CopyStreamException getTotalBytesTransferred() and
* getIOException() methods.
***/
public static final long copyStream(InputStream source, OutputStream dest,
int bufferSize)
throws CopyStreamException
{
return copyStream(source, dest, bufferSize,
CopyStreamEvent.UNKNOWN_STREAM_SIZE, null);
public static final long copyStream(InputStream source, OutputStream dest, int bufferSize)
throws CopyStreamException {
return copyStream(source, dest, bufferSize, CopyStreamEvent.UNKNOWN_STREAM_SIZE, null);
}
/***
* Same as <code> copyStream(source, dest, DEFAULT_COPY_BUFFER_SIZE); </code>
* @param source where to copy from
@ -224,12 +203,10 @@ public final class Util
* @throws CopyStreamException on error
***/
public static final long copyStream(InputStream source, OutputStream dest)
throws CopyStreamException
{
throws CopyStreamException {
return copyStream(source, dest, DEFAULT_COPY_BUFFER_SIZE);
}
/***
* Copies the contents of a Reader to a Writer using a
* copy buffer of a given size and notifies the provided
@ -263,23 +240,17 @@ public final class Util
* the CopyStreamException getTotalBytesTransferred() and
* getIOException() methods.
***/
public static final long copyReader(Reader source, Writer dest,
int bufferSize, long streamSize,
CopyStreamListener listener)
throws CopyStreamException
{
public static final long copyReader(Reader source, Writer dest, int bufferSize, long streamSize,
CopyStreamListener listener) throws CopyStreamException {
int numChars;
long total = 0;
char[] buffer = new char[bufferSize > 0 ? bufferSize : DEFAULT_COPY_BUFFER_SIZE];
try
{
while ((numChars = source.read(buffer)) != -1)
{
try {
while ((numChars = source.read(buffer)) != -1) {
// Technically, some read(char[]) methods may return 0 and we cannot
// accept that as an indication of EOF.
if (numChars == 0)
{
if (numChars == 0) {
int singleChar = source.read();
if (singleChar < 0) {
break;
@ -300,17 +271,13 @@ public final class Util
listener.bytesTransferred(total, numChars, streamSize);
}
}
}
catch (IOException e)
{
throw new CopyStreamException("IOException caught while copying.",
total, e);
} catch (IOException e) {
throw new CopyStreamException("IOException caught while copying.", total, e);
}
return total;
}
/***
* Copies the contents of a Reader to a Writer using a
* copy buffer of a given size. The contents of the Reader are
@ -332,15 +299,11 @@ public final class Util
* the CopyStreamException getTotalBytesTransferred() and
* getIOException() methods.
***/
public static final long copyReader(Reader source, Writer dest,
int bufferSize)
throws CopyStreamException
{
return copyReader(source, dest, bufferSize,
CopyStreamEvent.UNKNOWN_STREAM_SIZE, null);
public static final long copyReader(Reader source, Writer dest, int bufferSize)
throws CopyStreamException {
return copyReader(source, dest, bufferSize, CopyStreamEvent.UNKNOWN_STREAM_SIZE, null);
}
/***
* Same as <code> copyReader(source, dest, DEFAULT_COPY_BUFFER_SIZE); </code>
* @param source where to copy from
@ -348,9 +311,7 @@ public final class Util
* @return number of bytes copied
* @throws CopyStreamException on error
***/
public static final long copyReader(Reader source, Writer dest)
throws CopyStreamException
{
public static final long copyReader(Reader source, Writer dest) throws CopyStreamException {
return copyReader(source, dest, DEFAULT_COPY_BUFFER_SIZE);
}

@ -20,31 +20,34 @@ package org.apache.commons.net.util;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
/**
* Provides Base64 encoding and decoding as defined by RFC 2045.
*
* <p>
* This class implements section <cite>6.8. Base64 Content-Transfer-Encoding</cite> from RFC 2045 <cite>Multipurpose
* Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies</cite> by Freed and Borenstein.
* This class implements section <cite>6.8. Base64 Content-Transfer-Encoding</cite> from RFC 2045
* <cite>Multipurpose
* Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies</cite> by Freed and
* Borenstein.
* </p>
* <p>
* The class can be parameterized in the following manner with various constructors:
* <ul>
* <li>URL-safe mode: Default off.</li>
* <li>Line length: Default 76. Line length that aren't multiples of 4 will still essentially end up being multiples of
* <li>Line length: Default 76. Line length that aren't multiples of 4 will still essentially end up
* being multiples of
* 4 in the encoded data.
* <li>Line separator: Default is CRLF ("\r\n")</li>
* </ul>
* <p>
* Since this class operates directly on byte streams, and not character streams, it is hard-coded to only encode/decode
* character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8, etc).
* Since this class operates directly on byte streams, and not character streams, it is hard-coded
* to only encode/decode
* character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1,
* Windows-1252, UTF-8, etc).
* </p>
*
* @version $Id: Base64.java 1697293 2015-08-24 01:01:00Z sebb $
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
* @since 2.2
* @version $Id: Base64.java 1697293 2015-08-24 01:01:00Z sebb $
*/
public class Base64 {
private static final int DEFAULT_BUFFER_RESIZE_FACTOR = 2;
@ -55,7 +58,8 @@ public class Base64 {
* Chunk size per RFC 2045 section 6.8.
*
* <p>
* The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any
* The {@value} character limit does not count the trailing CRLF, but counts all other characters,
* including any
* equal signs.
* </p>
*
@ -73,18 +77,18 @@ public class Base64 {
private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
/**
* This array is a lookup table that translates 6-bit positive integer index values into their "Base64 Alphabet"
* This array is a lookup table that translates 6-bit positive integer index values into their
* "Base64 Alphabet"
* equivalents as specified in Table 1 of RFC 2045.
*
* Thanks to "commons" project in ws.apache.org for this code.
* http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
*/
private static final byte[] STANDARD_ENCODE_TABLE = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4',
'5', '6', '7', '8', '9', '+', '/'
};
/**
@ -93,11 +97,10 @@ public class Base64 {
* This table is only used when the Base64's mode is set to URL-SAFE.
*/
private static final byte[] URL_SAFE_ENCODE_TABLE = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4',
'5', '6', '7', '8', '9', '-', '_'
};
/**
@ -106,24 +109,27 @@ public class Base64 {
private static final byte PAD = '=';
/**
* This array is a lookup table that translates Unicode characters drawn from the "Base64 Alphabet" (as specified in
* Table 1 of RFC 2045) into their 6-bit positive integer equivalents. Characters that are not in the Base64
* This array is a lookup table that translates Unicode characters drawn from the "Base64
* Alphabet" (as specified in
* Table 1 of RFC 2045) into their 6-bit positive integer equivalents. Characters that are not in
* the Base64
* alphabet but fall within the bounds of the array are translated to -1.
*
* Note: '+' and '-' both decode to 62. '/' and '_' both decode to 63. This means decoder seamlessly handles both
* URL_SAFE and STANDARD base64. (The encoder, on the other hand, needs to know ahead of time what to emit).
* Note: '+' and '-' both decode to 62. '/' and '_' both decode to 63. This means decoder
* seamlessly handles both
* URL_SAFE and STANDARD base64. (The encoder, on the other hand, needs to know ahead of time what
* to emit).
*
* Thanks to "commons" project in ws.apache.org for this code.
* http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
*/
private static final byte[] DECODE_TABLE = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, 52, 53, 54,
55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62,
-1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1,
63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
47, 48, 49, 50, 51
};
/** Mask used to extract 6 bits, used when encoding */
@ -137,14 +143,17 @@ public class Base64 {
// some state be preserved between calls of encode() and decode().
/**
* Encode table to use: either STANDARD or URL_SAFE. Note: the DECODE_TABLE above remains static because it is able
* to decode both STANDARD and URL_SAFE streams, but the encodeTable must be a member variable so we can switch
* Encode table to use: either STANDARD or URL_SAFE. Note: the DECODE_TABLE above remains static
* because it is able
* to decode both STANDARD and URL_SAFE streams, but the encodeTable must be a member variable so
* we can switch
* between the two modes.
*/
private final byte[] encodeTable;
/**
* Line length for encoding. Not used when decoding. A value of zero or less implies no chunking of the base64
* Line length for encoding. Not used when decoding. A value of zero or less implies no chunking
* of the base64
* encoded data.
*/
private final int lineLength;
@ -155,13 +164,15 @@ public class Base64 {
private final byte[] lineSeparator;
/**
* Convenience variable to help us determine when our buffer is going to run out of room and needs resizing.
* Convenience variable to help us determine when our buffer is going to run out of room and needs
* resizing.
* <code>decodeSize = 3 + lineSeparator.length;</code>
*/
private final int decodeSize;
/**
* Convenience variable to help us determine when our buffer is going to run out of room and needs resizing.
* Convenience variable to help us determine when our buffer is going to run out of room and needs
* resizing.
* <code>encodeSize = 4 + lineSeparator.length;</code>
*/
private final int encodeSize;
@ -182,25 +193,29 @@ public class Base64 {
private int readPos;
/**
* Variable tracks how many characters have been written to the current line. Only used when encoding. We use it to
* Variable tracks how many characters have been written to the current line. Only used when
* encoding. We use it to
* make sure each encoded line never goes beyond lineLength (if lineLength > 0).
*/
private int currentLinePos;
/**
* Writes to the buffer only occur after every 3 reads when encoding, an every 4 reads when decoding. This variable
* Writes to the buffer only occur after every 3 reads when encoding, an every 4 reads when
* decoding. This variable
* helps track that.
*/
private int modulus;
/**
* Boolean flag to indicate the EOF has been reached. Once EOF has been reached, this Base64 object becomes useless,
* Boolean flag to indicate the EOF has been reached. Once EOF has been reached, this Base64
* object becomes useless,
* and must be thrown away.
*/
private boolean eof;
/**
* Place holder for the 3 bytes we're dealing with for our base64 logic. Bitwise operations store and extract the
* Place holder for the 3 bytes we're dealing with for our base64 logic. Bitwise operations store
* and extract the
* base64 encoding or decoding from this variable.
*/
private int x;
@ -208,7 +223,8 @@ public class Base64 {
/**
* Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
* <p>
* When encoding the line length is 76, the line separator is CRLF, and the encoding table is STANDARD_ENCODE_TABLE.
* When encoding the line length is 76, the line separator is CRLF, and the encoding table is
* STANDARD_ENCODE_TABLE.
* </p>
*
* <p>
@ -222,15 +238,16 @@ public class Base64 {
/**
* Creates a Base64 codec used for decoding (all modes) and encoding in the given URL-safe mode.
* <p>
* When encoding the line length is 76, the line separator is CRLF, and the encoding table is STANDARD_ENCODE_TABLE.
* When encoding the line length is 76, the line separator is CRLF, and the encoding table is
* STANDARD_ENCODE_TABLE.
* </p>
*
* <p>
* When decoding all variants are supported.
* </p>
*
* @param urlSafe
* if <code>true</code>, URL-safe encoding is used. In most cases this should be set to
* @param urlSafe if <code>true</code>, URL-safe encoding is used. In most cases this should be
* set to
* <code>false</code>.
* @since 1.4
*/
@ -241,19 +258,22 @@ public class Base64 {
/**
* Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
* <p>
* When encoding the line length is given in the constructor, the line separator is CRLF, and the encoding table is
* When encoding the line length is given in the constructor, the line separator is CRLF, and the
* encoding table is
* STANDARD_ENCODE_TABLE.
* </p>
* <p>
* Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data.
* Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in
* the encoded data.
* </p>
* <p>
* When decoding all variants are supported.
* </p>
*
* @param lineLength
* Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 4).
* If {@code lineLength <= 0}, then the output will not be divided into lines (chunks). Ignored when decoding.
* @param lineLength Each line of encoded data will be at most of the given length (rounded down
* to nearest multiple of 4).
* If {@code lineLength <= 0}, then the output will not be divided into lines (chunks). Ignored
* when decoding.
* @since 1.4
*/
public Base64(int lineLength) {
@ -263,23 +283,25 @@ public class Base64 {
/**
* Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
* <p>
* When encoding the line length and line separator are given in the constructor, and the encoding table is
* When encoding the line length and line separator are given in the constructor, and the encoding
* table is
* STANDARD_ENCODE_TABLE.
* </p>
* <p>
* Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data.
* Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in
* the encoded data.
* </p>
* <p>
* When decoding all variants are supported.
* </p>
*
* @param lineLength
* Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 4).
* If {@code lineLength <= 0}, then the output will not be divided into lines (chunks). Ignored when decoding.
* @param lineSeparator
* Each line of encoded data will end with this sequence of bytes.
* @throws IllegalArgumentException
* Thrown when the provided lineSeparator included some base64 characters.
* @param lineLength Each line of encoded data will be at most of the given length (rounded down
* to nearest multiple of 4).
* If {@code lineLength <= 0}, then the output will not be divided into lines (chunks). Ignored
* when decoding.
* @param lineSeparator Each line of encoded data will end with this sequence of bytes.
* @throws IllegalArgumentException Thrown when the provided lineSeparator included some base64
* characters.
* @since 1.4
*/
public Base64(int lineLength, byte[] lineSeparator) {
@ -289,26 +311,28 @@ public class Base64 {
/**
* Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
* <p>
* When encoding the line length and line separator are given in the constructor, and the encoding table is
* When encoding the line length and line separator are given in the constructor, and the encoding
* table is
* STANDARD_ENCODE_TABLE.
* </p>
* <p>
* Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data.
* Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in
* the encoded data.
* </p>
* <p>
* When decoding all variants are supported.
* </p>
*
* @param lineLength
* Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 4).
* If {@code lineLength <= 0}, then the output will not be divided into lines (chunks). Ignored when decoding.
* @param lineSeparator
* Each line of encoded data will end with this sequence of bytes.
* @param urlSafe
* Instead of emitting '+' and '/' we emit '-' and '_' respectively. urlSafe is only applied to encode
* @param lineLength Each line of encoded data will be at most of the given length (rounded down
* to nearest multiple of 4).
* If {@code lineLength <= 0}, then the output will not be divided into lines (chunks). Ignored
* when decoding.
* @param lineSeparator Each line of encoded data will end with this sequence of bytes.
* @param urlSafe Instead of emitting '+' and '/' we emit '-' and '_' respectively. urlSafe is
* only applied to encode
* operations. Decoding seamlessly handles both modes.
* @throws IllegalArgumentException
* The provided lineSeparator included some base64 characters. That's not going to work!
* @throws IllegalArgumentException The provided lineSeparator included some base64 characters.
* That's not going to work!
* @since 1.4
*/
public Base64(int lineLength, byte[] lineSeparator, boolean urlSafe) {
@ -327,7 +351,8 @@ public class Base64 {
this.decodeSize = this.encodeSize - 1;
if (containsBase64Byte(lineSeparator)) {
String sep = newStringUtf8(lineSeparator);
throw new IllegalArgumentException("lineSeperator must not contain base64 characters: [" + sep + "]");
throw new IllegalArgumentException(
"lineSeperator must not contain base64 characters: [" + sep + "]");
}
this.encodeTable = urlSafe ? URL_SAFE_ENCODE_TABLE : STANDARD_ENCODE_TABLE;
}
@ -374,15 +399,14 @@ public class Base64 {
}
/**
* Extracts buffered data into the provided byte[] array, starting at position bPos, up to a maximum of bAvail
* Extracts buffered data into the provided byte[] array, starting at position bPos, up to a
* maximum of bAvail
* bytes. Returns how many bytes were actually extracted.
*
* @param b
* byte[] array to extract the buffered data into.
* @param bPos
* position in byte[] array to start extraction at.
* @param bAvail
* amount of bytes we're allowed to extract. We may extract fewer (if fewer are available).
* @param b byte[] array to extract the buffered data into.
* @param bPos position in byte[] array to start extraction at.
* @param bAvail amount of bytes we're allowed to extract. We may extract fewer (if fewer are
* available).
* @return The number of bytes successfully extracted into the provided byte[] array.
*/
int readResults(byte[] b, int bPos, int bAvail) {
@ -405,15 +429,14 @@ public class Base64 {
}
/**
* Sets the streaming buffer. This is a small optimization where we try to buffer directly to the consumer's output
* array for one round (if the consumer calls this method first) instead of starting our own buffer.
* Sets the streaming buffer. This is a small optimization where we try to buffer directly to the
* consumer's output
* array for one round (if the consumer calls this method first) instead of starting our own
* buffer.
*
* @param out
* byte[] array to buffer directly to.
* @param outPos
* Position to start buffering into.
* @param outAvail
* Amount of bytes available for direct buffering.
* @param out byte[] array to buffer directly to.
* @param outPos Position to start buffering into.
* @param outAvail Amount of bytes available for direct buffering.
*/
void setInitialBuffer(byte[] out, int outPos, int outAvail) {
// We can re-use consumer's original output array under
@ -427,8 +450,10 @@ public class Base64 {
/**
* <p>
* Encodes all of the provided data, starting at inPos, for inAvail bytes. Must be called at least twice: once with
* the data to encode, and once with inAvail set to "-1" to alert encoder that EOF has been reached, so flush last
* Encodes all of the provided data, starting at inPos, for inAvail bytes. Must be called at least
* twice: once with
* the data to encode, and once with inAvail set to "-1" to alert encoder that EOF has been
* reached, so flush last
* remaining bytes (if not multiple of 3).
* </p>
* <p>
@ -436,12 +461,9 @@ public class Base64 {
* http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
* </p>
*
* @param in
* byte[] array of binary data to base64 encode.
* @param inPos
* Position to start reading data from.
* @param inAvail
* Amount of bytes available from input for encoding.
* @param in byte[] array of binary data to base64 encode.
* @param inPos Position to start reading data from.
* @param inAvail Amount of bytes available from input for encoding.
*/
void encode(byte[] in, int inPos, int inAvail) {
if (eof) {
@ -510,13 +532,17 @@ public class Base64 {
/**
* <p>
* Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at least twice: once
* with the data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been reached. The "-1"
* Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at
* least twice: once
* with the data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been
* reached. The "-1"
* call is not necessary when decoding, but it doesn't hurt, either.
* </p>
* <p>
* Ignores all non-base64 characters. This is how chunked (e.g. 76 character) data is handled, since CR and LF are
* silently ignored, but has implications for other bytes, too. This method subscribes to the garbage-in,
* Ignores all non-base64 characters. This is how chunked (e.g. 76 character) data is handled,
* since CR and LF are
* silently ignored, but has implications for other bytes, too. This method subscribes to the
* garbage-in,
* garbage-out philosophy: it will not check the provided data for validity.
* </p>
* <p>
@ -524,12 +550,9 @@ public class Base64 {
* http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
* </p>
*
* @param in
* byte[] array of ascii data to base64 decode.
* @param inPos
* Position to start reading data from.
* @param inAvail
* Amount of bytes available from input for encoding.
* @param in byte[] array of ascii data to base64 decode.
* @param inPos Position to start reading data from.
* @param inAvail Amount of bytes available from input for encoding.
*/
void decode(byte[] in, int inPos, int inAvail) {
if (eof) {
@ -586,9 +609,9 @@ public class Base64 {
/**
* Returns whether or not the <code>octet</code> is in the base 64 alphabet.
*
* @param octet
* The value to test
* @return <code>true</code> if the value is defined in the the base 64 alphabet, <code>false</code> otherwise.
* @param octet The value to test
* @return <code>true</code> if the value is defined in the the base 64 alphabet,
* <code>false</code> otherwise.
* @since 1.4
*/
public static boolean isBase64(byte octet) {
@ -596,12 +619,13 @@ public class Base64 {
}
/**
* Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. Currently the
* Tests a given byte array to see if it contains only valid characters within the Base64
* alphabet. Currently the
* method treats whitespace as valid.
*
* @param arrayOctet
* byte array to test
* @return <code>true</code> if all bytes are valid characters in the Base64 alphabet or if the byte array is empty;
* @param arrayOctet byte array to test
* @return <code>true</code> if all bytes are valid characters in the Base64 alphabet or if the
* byte array is empty;
* false, otherwise
*/
public static boolean isArrayByteBase64(byte[] arrayOctet) {
@ -614,15 +638,15 @@ public class Base64 {
}
/**
* Tests a given byte array to see if it contains only valid characters within the Base64 alphabet.
* Tests a given byte array to see if it contains only valid characters within the Base64
* alphabet.
*
* @param arrayOctet
* byte array to test
* @return <code>true</code> if any byte is a valid character in the Base64 alphabet; false herwise
* @param arrayOctet byte array to test
* @return <code>true</code> if any byte is a valid character in the Base64 alphabet; false
* herwise
*/
private static boolean containsBase64Byte(byte[] arrayOctet) {
for (byte element : arrayOctet)
{
for (byte element : arrayOctet) {
if (isBase64(element)) {
return true;
}
@ -633,8 +657,7 @@ public class Base64 {
/**
* Encodes binary data using the base64 algorithm but does not chunk the output.
*
* @param binaryData
* binary data to encode
* @param binaryData binary data to encode
* @return byte[] containing Base64 characters in their UTF-8 representation.
*/
public static byte[] encodeBase64(byte[] binaryData) {
@ -646,8 +669,7 @@ public class Base64 {
* <p>
* For a non-chunking version, see {@link #encodeBase64StringUnChunked(byte[])}.
*
* @param binaryData
* binary data to encode
* @param binaryData binary data to encode
* @return String containing Base64 characters.
* @since 1.4
*/
@ -660,8 +682,7 @@ public class Base64 {
* <p>
* For a chunking version, see {@link #encodeBase64String(byte[])}.
*
* @param binaryData
* binary data to encode
* @param binaryData binary data to encode
* @return String containing Base64 characters.
* @since 3.2
*/
@ -672,8 +693,7 @@ public class Base64 {
/**
* Encodes binary data using the base64 algorithm.
*
* @param binaryData
* binary data to encode
* @param binaryData binary data to encode
* @param useChunking whether to split the output into chunks
* @return String containing Base64 characters.
* @since 3.2
@ -683,11 +703,11 @@ public class Base64 {
}
/**
* Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The
* Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the
* output. The
* url-safe variation emits - and _ instead of + and / characters.
*
* @param binaryData
* binary data to encode
* @param binaryData binary data to encode
* @return byte[] containing Base64 characters in their UTF-8 representation.
* @since 1.4
*/
@ -696,11 +716,11 @@ public class Base64 {
}
/**
* Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The
* Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the
* output. The
* url-safe variation emits - and _ instead of + and / characters.
*
* @param binaryData
* binary data to encode
* @param binaryData binary data to encode
* @return String containing Base64 characters
* @since 1.4
*/
@ -709,10 +729,10 @@ public class Base64 {
}
/**
* Encodes binary data using the base64 algorithm and chunks the encoded output into 76 character blocks
* Encodes binary data using the base64 algorithm and chunks the encoded output into 76 character
* blocks
*
* @param binaryData
* binary data to encode
* @param binaryData binary data to encode
* @return Base64 characters chunked in 76 character blocks
*/
public static byte[] encodeBase64Chunked(byte[] binaryData) {
@ -722,8 +742,7 @@ public class Base64 {
/**
* Decodes a String containing containing characters in the Base64 alphabet.
*
* @param pArray
* A String containing Base64 character data
* @param pArray A String containing Base64 character data
* @return a byte array containing binary data
* @since 1.4
*/
@ -742,8 +761,7 @@ public class Base64 {
/**
* Decodes a byte[] containing containing characters in the Base64 alphabet.
*
* @param pArray
* A byte array containing Base64 character data
* @param pArray A byte array containing Base64 character data
* @return a byte array containing binary data
*/
public byte[] decode(byte[] pArray) {
@ -769,32 +787,32 @@ public class Base64 {
}
/**
* Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks.
* Encodes binary data using the base64 algorithm, optionally chunking the output into 76
* character blocks.
*
* @param binaryData
* Array containing binary data to encode.
* @param isChunked
* if <code>true</code> this encoder will chunk the base64 output into 76 character blocks
* @param binaryData Array containing binary data to encode.
* @param isChunked if <code>true</code> this encoder will chunk the base64 output into 76
* character blocks
* @return Base64-encoded data.
* @throws IllegalArgumentException
* Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE}
* @throws IllegalArgumentException Thrown when the input array needs an output array bigger than
* {@link Integer#MAX_VALUE}
*/
public static byte[] encodeBase64(byte[] binaryData, boolean isChunked) {
return encodeBase64(binaryData, isChunked, false);
}
/**
* Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks.
* Encodes binary data using the base64 algorithm, optionally chunking the output into 76
* character blocks.
*
* @param binaryData
* Array containing binary data to encode.
* @param isChunked
* if <code>true</code> this encoder will chunk the base64 output into 76 character blocks
* @param urlSafe
* if <code>true</code> this encoder will emit - and _ instead of the usual + and / characters.
* @param binaryData Array containing binary data to encode.
* @param isChunked if <code>true</code> this encoder will chunk the base64 output into 76
* character blocks
* @param urlSafe if <code>true</code> this encoder will emit - and _ instead of the usual + and /
* characters.
* @return Base64-encoded data.
* @throws IllegalArgumentException
* Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE}
* @throws IllegalArgumentException Thrown when the input array needs an output array bigger than
* {@link Integer#MAX_VALUE}
* @since 1.4
*/
public static byte[] encodeBase64(byte[] binaryData, boolean isChunked, boolean urlSafe) {
@ -802,32 +820,33 @@ public class Base64 {
}
/**
* Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks.
* Encodes binary data using the base64 algorithm, optionally chunking the output into 76
* character blocks.
*
* @param binaryData
* Array containing binary data to encode.
* @param isChunked
* if <code>true</code> this encoder will chunk the base64 output into 76 character blocks
* @param urlSafe
* if <code>true</code> this encoder will emit - and _ instead of the usual + and / characters.
* @param maxResultSize
* The maximum result size to accept.
* @param binaryData Array containing binary data to encode.
* @param isChunked if <code>true</code> this encoder will chunk the base64 output into 76
* character blocks
* @param urlSafe if <code>true</code> this encoder will emit - and _ instead of the usual + and /
* characters.
* @param maxResultSize The maximum result size to accept.
* @return Base64-encoded data.
* @throws IllegalArgumentException
* Thrown when the input array needs an output array bigger than maxResultSize
* @throws IllegalArgumentException Thrown when the input array needs an output array bigger than
* maxResultSize
* @since 1.4
*/
public static byte[] encodeBase64(byte[] binaryData, boolean isChunked, boolean urlSafe, int maxResultSize) {
public static byte[] encodeBase64(byte[] binaryData, boolean isChunked, boolean urlSafe,
int maxResultSize) {
if (binaryData == null || binaryData.length == 0) {
return binaryData;
}
long len = getEncodeLength(binaryData, isChunked ? CHUNK_SIZE : 0, isChunked ? CHUNK_SEPARATOR : EMPTY_BYTE_ARRAY);
long len = getEncodeLength(binaryData, isChunked ? CHUNK_SIZE : 0,
isChunked ? CHUNK_SEPARATOR : EMPTY_BYTE_ARRAY);
if (len > maxResultSize) {
throw new IllegalArgumentException("Input array too big, the output array would be bigger (" +
len +
") than the specified maxium size of " +
maxResultSize);
throw new IllegalArgumentException("Input array too big, the output array would be bigger ("
+ len
+ ") than the specified maxium size of "
+ maxResultSize);
}
Base64 b64 = isChunked ? new Base64(urlSafe) : new Base64(0, CHUNK_SEPARATOR, urlSafe);
@ -837,8 +856,7 @@ public class Base64 {
/**
* Decodes a Base64 String into octets
*
* @param base64String
* String containing Base64 data
* @param base64String String containing Base64 data
* @return Array containing decoded data.
* @since 1.4
*/
@ -849,21 +867,17 @@ public class Base64 {
/**
* Decodes Base64 data into octets
*
* @param base64Data
* Byte array containing Base64 data
* @param base64Data Byte array containing Base64 data
* @return Array containing decoded data.
*/
public static byte[] decodeBase64(byte[] base64Data) {
return new Base64().decode(base64Data);
}
/**
* Checks if a byte value is whitespace or not.
*
* @param byteToCheck
* the byte to check
* @param byteToCheck the byte to check
* @return true if byte is whitespace, false otherwise
*/
private static boolean isWhiteSpace(byte byteToCheck) {
@ -879,10 +893,10 @@ public class Base64 {
}
/**
* Encodes a byte[] containing binary data, into a String containing characters in the Base64 alphabet.
* Encodes a byte[] containing binary data, into a String containing characters in the Base64
* alphabet.
*
* @param pArray
* a byte array containing binary data
* @param pArray a byte array containing binary data
* @return A String containing only Base64 character data
* @since 1.4
*/
@ -901,10 +915,10 @@ public class Base64 {
}
/**
* Encodes a byte[] containing binary data, into a byte[] containing characters in the Base64 alphabet.
* Encodes a byte[] containing binary data, into a byte[] containing characters in the Base64
* alphabet.
*
* @param pArray
* a byte array containing binary data
* @param pArray a byte array containing binary data
* @return A byte array containing only Base64 character data
*/
public byte[] encode(byte[] pArray) {
@ -938,7 +952,6 @@ public class Base64 {
* @param chunkSize line-length of the output (<= 0 means no chunking) between each
* chunkSeparator (e.g. CRLF).
* @param chunkSeparator the sequence of bytes used to separate chunks of output (e.g. CRLF).
*
* @return amount of space needed to encoded the supplied array. Returns
* a long since a max-len array will require Integer.MAX_VALUE + 33%.
*/
@ -962,11 +975,11 @@ public class Base64 {
}
// Implementation of integer encoding used for crypto
/**
* Decodes a byte64-encoded integer according to crypto standards such as W3C's XML-Signature
*
* @param pArray
* a byte array containing base64 character data
* @param pArray a byte array containing base64 character data
* @return A BigInteger
* @since 1.4
*/
@ -977,11 +990,9 @@ public class Base64 {
/**
* Encodes to a byte64-encoded integer according to crypto standards such as W3C's XML-Signature
*
* @param bigInt
* a BigInteger
* @param bigInt a BigInteger
* @return A byte array containing base64 character data
* @throws NullPointerException
* if null is passed in
* @throws NullPointerException if null is passed in
* @since 1.4
*/
public static byte[] encodeInteger(BigInteger bigInt) {
@ -994,8 +1005,7 @@ public class Base64 {
/**
* Returns a byte-array representation of a <code>BigInteger</code> without sign bit.
*
* @param bigInt
* <code>BigInteger</code> to be converted
* @param bigInt <code>BigInteger</code> to be converted
* @return a byte array representation of the BigInteger parameter
*/
static byte[] toIntegerBytes(BigInteger bigInt) {

@ -29,8 +29,8 @@ public class Charsets {
/**
* Returns a charset object for the given charset name.
*
* @param charsetName
* The name of the requested charset; may be a canonical name, an alias, or null. If null, return the
* @param charsetName The name of the requested charset; may be a canonical name, an alias, or
* null. If null, return the
* default charset.
* @return A charset object for the named charset
*/
@ -41,11 +41,10 @@ public class Charsets {
/**
* Returns a charset object for the given charset name.
*
* @param charsetName
* The name of the requested charset; may be a canonical name, an alias, or null.
* @param charsetName The name of the requested charset; may be a canonical name, an alias, or
* null.
* If null, return the default charset.
* @param defaultCharsetName the charset name to use if the requested charset is null
*
* @return A charset object for the named charset
*/
public static Charset toCharset(String charsetName, String defaultCharsetName) {

@ -75,15 +75,16 @@ public final class KeyManagerUtils {
* Does not handle server keys.
*
* @param ks the keystore to use
* @param keyAlias the alias of the key to use, may be {@code null} in which case the first key entry alias is used
* @param keyAlias the alias of the key to use, may be {@code null} in which case the first key
* entry alias is used
* @param keyPass the password of the key to use
* @return the customised KeyManager
* @throws GeneralSecurityException if there is a problem creating the keystore
*/
public static KeyManager createClientKeyManager(KeyStore ks, String keyAlias, String keyPass)
throws GeneralSecurityException
{
ClientKeyStore cks = new ClientKeyStore(ks, keyAlias != null ? keyAlias : findAlias(ks), keyPass);
throws GeneralSecurityException {
ClientKeyStore cks =
new ClientKeyStore(ks, keyAlias != null ? keyAlias : findAlias(ks), keyPass);
return new X509KeyManager(cks);
}
@ -94,16 +95,16 @@ public final class KeyManagerUtils {
* @param storeType the type of the keyStore, e.g. "JKS"
* @param storePath the path to the keyStore
* @param storePass the keyStore password
* @param keyAlias the alias of the key to use, may be {@code null} in which case the first key entry alias is used
* @param keyAlias the alias of the key to use, may be {@code null} in which case the first key
* entry alias is used
* @param keyPass the password of the key to use
* @return the customised KeyManager
* @throws GeneralSecurityException if there is a problem creating the keystore
* @throws IOException if there is a problem creating the keystore
*/
public static KeyManager createClientKeyManager(
String storeType, File storePath, String storePass, String keyAlias, String keyPass)
throws IOException, GeneralSecurityException
{
public static KeyManager createClientKeyManager(String storeType, File storePath,
String storePass, String keyAlias, String keyPass)
throws IOException, GeneralSecurityException {
KeyStore ks = loadStore(storeType, storePath, storePass);
return createClientKeyManager(ks, keyAlias, keyPass);
}
@ -115,14 +116,14 @@ public final class KeyManagerUtils {
*
* @param storePath the path to the keyStore
* @param storePass the keyStore password
* @param keyAlias the alias of the key to use, may be {@code null} in which case the first key entry alias is used
* @param keyAlias the alias of the key to use, may be {@code null} in which case the first key
* entry alias is used
* @return the customised KeyManager
* @throws IOException if there is a problem creating the keystore
* @throws GeneralSecurityException if there is a problem creating the keystore
*/
public static KeyManager createClientKeyManager(File storePath, String storePass, String keyAlias)
throws IOException, GeneralSecurityException
{
throws IOException, GeneralSecurityException {
return createClientKeyManager(DEFAULT_STORE_TYPE, storePath, storePass, keyAlias, storePass);
}
@ -139,8 +140,7 @@ public final class KeyManagerUtils {
* @throws GeneralSecurityException if there is a problem creating the keystore
*/
public static KeyManager createClientKeyManager(File storePath, String storePass)
throws IOException, GeneralSecurityException
{
throws IOException, GeneralSecurityException {
return createClientKeyManager(DEFAULT_STORE_TYPE, storePath, storePass, null, storePass);
}
@ -174,8 +174,7 @@ public final class KeyManagerUtils {
private final PrivateKey key;
private final String keyAlias;
ClientKeyStore(KeyStore ks, String keyAlias, String keyPass) throws GeneralSecurityException
{
ClientKeyStore(KeyStore ks, String keyAlias, String keyPass) throws GeneralSecurityException {
this.keyAlias = keyAlias;
this.key = (PrivateKey) ks.getKey(this.keyAlias, keyPass.toCharArray());
Certificate[] certs = ks.getCertificateChain(this.keyAlias);
@ -208,39 +207,31 @@ public final class KeyManagerUtils {
}
// Call sequence: 1
@Override
public String chooseClientAlias(String[] keyType, Principal[] issuers,
@Override public String chooseClientAlias(String[] keyType, Principal[] issuers,
Socket socket) {
return keyStore.getAlias();
}
// Call sequence: 2
@Override
public X509Certificate[] getCertificateChain(String alias) {
@Override public X509Certificate[] getCertificateChain(String alias) {
return keyStore.getCertificateChain();
}
@Override
public String[] getClientAliases(String keyType, Principal[] issuers) {
@Override public String[] getClientAliases(String keyType, Principal[] issuers) {
return new String[] { keyStore.getAlias() };
}
// Call sequence: 3
@Override
public PrivateKey getPrivateKey(String alias) {
@Override public PrivateKey getPrivateKey(String alias) {
return keyStore.getPrivateKey();
}
@Override
public String[] getServerAliases(String keyType, Principal[] issuers) {
@Override public String[] getServerAliases(String keyType, Principal[] issuers) {
return null;
}
@Override
public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
@Override public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
return null;
}
}
}

@ -25,29 +25,24 @@ import java.util.concurrent.CopyOnWriteArrayList;
/**
*/
public class ListenerList implements Serializable, Iterable<EventListener>
{
public class ListenerList implements Serializable, Iterable<EventListener> {
private static final long serialVersionUID = -1934227607974228213L;
private final CopyOnWriteArrayList<EventListener> __listeners;
public ListenerList()
{
public ListenerList() {
__listeners = new CopyOnWriteArrayList<EventListener>();
}
public void addListener(EventListener listener)
{
public void addListener(EventListener listener) {
__listeners.add(listener);
}
public void removeListener(EventListener listener)
{
public void removeListener(EventListener listener) {
__listeners.remove(listener);
}
public int getListenerCount()
{
public int getListenerCount() {
return __listeners.size();
}
@ -58,9 +53,7 @@ public class ListenerList implements Serializable, Iterable<EventListener>
* @since 2.0
* TODO Check that this is a good defensive strategy
*/
@Override
public Iterator<EventListener> iterator() {
@Override public Iterator<EventListener> iterator() {
return __listeners.iterator();
}
}

@ -26,6 +26,7 @@ import javax.net.ssl.TrustManager;
/**
* General utilities for SSLContext.
*
* @since 3.0
*/
public class SSLContextUtils {
@ -36,29 +37,32 @@ public class SSLContextUtils {
/**
* Create and initialise an SSLContext.
*
* @param protocol the protocol used to instatiate the context
* @param keyManager the key manager, may be {@code null}
* @param trustManager the trust manager, may be {@code null}
* @return the initialised context.
* @throws IOException this is used to wrap any {@link GeneralSecurityException} that occurs
*/
public static SSLContext createSSLContext(String protocol, KeyManager keyManager, TrustManager trustManager)
throws IOException {
return createSSLContext(protocol,
keyManager == null ? null : new KeyManager[] { keyManager },
public static SSLContext createSSLContext(String protocol, KeyManager keyManager,
TrustManager trustManager) throws IOException {
return createSSLContext(protocol, keyManager == null ? null : new KeyManager[] { keyManager },
trustManager == null ? null : new TrustManager[] { trustManager });
}
/**
* Create and initialise an SSLContext.
*
* @param protocol the protocol used to instatiate the context
* @param keyManagers the array of key managers, may be {@code null} but array entries must not be {@code null}
* @param trustManagers the array of trust managers, may be {@code null} but array entries must not be {@code null}
* @param keyManagers the array of key managers, may be {@code null} but array entries must not be
* {@code null}
* @param trustManagers the array of trust managers, may be {@code null} but array entries must
* not be {@code null}
* @return the initialised context.
* @throws IOException this is used to wrap any {@link GeneralSecurityException} that occurs
*/
public static SSLContext createSSLContext(String protocol, KeyManager[] keyManagers, TrustManager[] trustManagers)
throws IOException {
public static SSLContext createSSLContext(String protocol, KeyManager[] keyManagers,
TrustManager[] trustManagers) throws IOException {
SSLContext ctx;
try {
ctx = SSLContext.getInstance(protocol);

@ -25,6 +25,7 @@ import javax.net.ssl.SSLSocket;
/**
* General utilities for SSLSocket.
*
* @since 3.4
*/
public class SSLSocketUtils {
@ -34,16 +35,20 @@ public class SSLSocketUtils {
/**
* Enable the HTTPS endpoint identification algorithm on an SSLSocket.
*
* @param socket the SSL socket
* @return {@code true} on success (this is only supported on Java 1.7+)
*/
public static boolean enableEndpointNameVerification(SSLSocket socket) {
try {
Class<?> cls = Class.forName("javax.net.ssl.SSLParameters");
Method setEndpointIdentificationAlgorithm = cls.getDeclaredMethod("setEndpointIdentificationAlgorithm", String.class);
Method setEndpointIdentificationAlgorithm =
cls.getDeclaredMethod("setEndpointIdentificationAlgorithm", String.class);
Method getSSLParameters = SSLSocket.class.getDeclaredMethod("getSSLParameters");
Method setSSLParameters = SSLSocket.class.getDeclaredMethod("setSSLParameters", cls);
if (setEndpointIdentificationAlgorithm != null && getSSLParameters != null && setSSLParameters != null) {
if (setEndpointIdentificationAlgorithm != null
&& getSSLParameters != null
&& setSSLParameters != null) {
Object sslParams = getSSLParameters.invoke(socket);
if (sslParams != null) {
setEndpointIdentificationAlgorithm.invoke(sslParams, "HTTPS");

@ -21,6 +21,7 @@ import java.util.regex.Pattern;
/**
* A class that performs some subnet calculations given a network address and a subnet mask.
*
* @see "http://www.faqs.org/rfcs/rfc1519.html"
* @since 2.0
*/
@ -40,9 +41,9 @@ public class SubnetUtils {
/** Whether the broadcast/network address are included in host count */
private boolean inclusiveHostCount = false;
/**
* Constructor that takes a CIDR-notation string, e.g. "192.168.0.1/16"
*
* @param cidrNotation A CIDR-notation string, e.g. "192.168.0.1/16"
* @throws IllegalArgumentException if the parameter is invalid,
* i.e. does not match n.n.n.n/m where n=1-3 decimal digits, m = 1-3 decimal digits in range 1-32
@ -53,6 +54,7 @@ public class SubnetUtils {
/**
* Constructor that takes a dotted decimal address and a dotted decimal mask.
*
* @param address An IP address, e.g. "192.168.0.1"
* @param mask A dotted decimal netmask e.g. "255.255.0.0"
* @throws IllegalArgumentException if the address or mask is invalid,
@ -62,12 +64,12 @@ public class SubnetUtils {
calculate(toCidrNotation(address, mask));
}
/**
* Returns <code>true</code> if the return value of {@link SubnetInfo#getAddressCount()}
* includes the network and broadcast addresses.
* @since 2.2
*
* @return true if the hostcount includes the network and broadcast addresses
* @since 2.2
*/
public boolean isInclusiveHostCount() {
return inclusiveHostCount;
@ -76,6 +78,7 @@ public class SubnetUtils {
/**
* Set to <code>true</code> if you want the return value of {@link SubnetInfo#getAddressCount()}
* to include the network and broadcast addresses.
*
* @param inclusiveHostCount true if network and broadcast addresses are to be included
* @since 2.2
*/
@ -83,41 +86,56 @@ public class SubnetUtils {
this.inclusiveHostCount = inclusiveHostCount;
}
/**
* Convenience container for subnet summary information.
*
*/
public final class SubnetInfo {
/* Mask to convert unsigned int to a long (i.e. keep 32 bits) */
private static final long UNSIGNED_INT_MASK = 0x0FFFFFFFFL;
private SubnetInfo() {}
private SubnetInfo() {
}
private int netmask() {
return netmask;
}
private int network() {
return network;
}
private int address() {
return address;
}
private int netmask() { return netmask; }
private int network() { return network; }
private int address() { return address; }
private int broadcast() { return broadcast; }
private int broadcast() {
return broadcast;
}
// long versions of the values (as unsigned int) which are more suitable for range checking
private long networkLong() { return network & UNSIGNED_INT_MASK; }
private long broadcastLong(){ return broadcast & UNSIGNED_INT_MASK; }
private long networkLong() {
return network & UNSIGNED_INT_MASK;
}
private long broadcastLong() {
return broadcast & UNSIGNED_INT_MASK;
}
private int low() {
return (isInclusiveHostCount() ? network() :
broadcastLong() - networkLong() > 1 ? network() + 1 : 0);
return (isInclusiveHostCount() ? network()
: broadcastLong() - networkLong() > 1 ? network() + 1 : 0);
}
private int high() {
return (isInclusiveHostCount() ? broadcast() :
broadcastLong() - networkLong() > 1 ? broadcast() -1 : 0);
return (isInclusiveHostCount() ? broadcast()
: broadcastLong() - networkLong() > 1 ? broadcast() - 1 : 0);
}
/**
* Returns true if the parameter <code>address</code> is in the
* range of usable endpoint addresses for this subnet. This excludes the
* network and broadcast adresses.
*
* @param address A dot-delimited IPv4 address, e.g. "192.168.0.1"
* @return True if in range, false otherwise
*/
@ -126,7 +144,6 @@ public class SubnetUtils {
}
/**
*
* @param address the address to check
* @return true if it is in range
* @since 3.4 (made public)
@ -177,12 +194,12 @@ public class SubnetUtils {
/**
* Get the count of available addresses.
* Will be zero for CIDR/31 and CIDR/32 if the inclusive flag is false.
*
* @return the count of addresses, may be zero.
* @throws RuntimeException if the correct count is greater than {@code Integer.MAX_VALUE}
* @deprecated (3.4) use {@link #getAddressCountLong()} instead
*/
@Deprecated
public int getAddressCount() {
@Deprecated public int getAddressCount() {
long countLong = getAddressCountLong();
if (countLong > Integer.MAX_VALUE) {
throw new RuntimeException("Count is larger than an integer: " + countLong);
@ -194,6 +211,7 @@ public class SubnetUtils {
/**
* Get the count of available addresses.
* Will be zero for CIDR/31 and CIDR/32 if the inclusive flag is false.
*
* @return the count of addresses, may be zero.
* @since 3.4
*/
@ -209,10 +227,7 @@ public class SubnetUtils {
}
public String getCidrSignature() {
return toCidrNotation(
format(toArray(address())),
format(toArray(netmask()))
);
return toCidrNotation(format(toArray(address())), format(toArray(netmask())));
}
public String[] getAllAddresses() {
@ -229,27 +244,44 @@ public class SubnetUtils {
/**
* {@inheritDoc}
*
* @since 2.2
*/
@Override
public String toString() {
@Override public String toString() {
final StringBuilder buf = new StringBuilder();
buf.append("CIDR Signature:\t[").append(getCidrSignature()).append("]")
.append(" Netmask: [").append(getNetmask()).append("]\n")
.append("Network:\t[").append(getNetworkAddress()).append("]\n")
.append("Broadcast:\t[").append(getBroadcastAddress()).append("]\n")
.append("First Address:\t[").append(getLowAddress()).append("]\n")
.append("Last Address:\t[").append(getHighAddress()).append("]\n")
.append("# Addresses:\t[").append(getAddressCount()).append("]\n");
buf.append("CIDR Signature:\t[")
.append(getCidrSignature())
.append("]")
.append(" Netmask: [")
.append(getNetmask())
.append("]\n")
.append("Network:\t[")
.append(getNetworkAddress())
.append("]\n")
.append("Broadcast:\t[")
.append(getBroadcastAddress())
.append("]\n")
.append("First Address:\t[")
.append(getLowAddress())
.append("]\n")
.append("Last Address:\t[")
.append(getHighAddress())
.append("]\n")
.append("# Addresses:\t[")
.append(getAddressCount())
.append("]\n");
return buf.toString();
}
}
/**
* Return a {@link SubnetInfo} instance that contains subnet-specific statistics
*
* @return new instance
*/
public final SubnetInfo getInfo() { return new SubnetInfo(); }
public final SubnetInfo getInfo() {
return new SubnetInfo();
}
/*
* Initialize the internal fields from the supplied CIDR mask
@ -336,7 +368,8 @@ public class SubnetUtils {
return value;
}
throw new IllegalArgumentException("Value [" + value + "] not in range ["+begin+","+end+"]");
throw new IllegalArgumentException(
"Value [" + value + "] not in range [" + begin + "," + end + "]");
}
/*

@ -30,8 +30,7 @@ import javax.net.ssl.X509TrustManager;
*
* @since 3.0
*/
public final class TrustManagerUtils
{
public final class TrustManagerUtils {
private static final X509Certificate[] EMPTY_X509CERTIFICATE_ARRAY = new X509Certificate[] {};
private static class TrustManager implements X509TrustManager {
@ -45,19 +44,14 @@ public final class TrustManagerUtils
/**
* Never generates a CertificateException.
*/
@Override
public void checkClientTrusted(X509Certificate[] certificates, String authType)
{
@Override public void checkClientTrusted(X509Certificate[] certificates, String authType) {
return;
}
@Override
public void checkServerTrusted(X509Certificate[] certificates, String authType)
throws CertificateException
{
@Override public void checkServerTrusted(X509Certificate[] certificates, String authType)
throws CertificateException {
if (checkServerValidity) {
for (X509Certificate certificate : certificates)
{
for (X509Certificate certificate : certificates) {
certificate.checkValidity();
}
}
@ -66,9 +60,7 @@ public final class TrustManagerUtils
/**
* @return an empty array of certificates
*/
@Override
public X509Certificate[] getAcceptedIssuers()
{
@Override public X509Certificate[] getAcceptedIssuers() {
return EMPTY_X509CERTIFICATE_ARRAY;
}
}
@ -100,18 +92,19 @@ public final class TrustManagerUtils
* Return the default TrustManager provided by the JVM.
* <p>
* 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(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], * java.security.SecureRandom)
* SSLContext#init(KeyManager[], TrustManager[], SecureRandom)}
* when the TrustManager parameter is set to {@code null}
*
* @param keyStore the KeyStore to use, may be {@code null}
* @return the default TrustManager
* @throws GeneralSecurityException if an error occurs
*/
public static X509TrustManager getDefaultTrustManager(KeyStore keyStore) throws GeneralSecurityException {
public static X509TrustManager getDefaultTrustManager(KeyStore keyStore)
throws GeneralSecurityException {
String defaultAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory instance = TrustManagerFactory.getInstance(defaultAlgorithm);
instance.init(keyStore);
return (X509TrustManager) instance.getTrustManagers()[0];
}
}

@ -35,7 +35,7 @@ import java.io.File;
* Ftp下载测试
*/
public class FtpDownloadActivity extends BaseActivity<ActivityFtpDownloadBinding> {
private final String URL = "ftp://172.18.104.147:21/haha/ftp_test.apk";
private final String URL = "ftp://172.18.104.229:21/haha/测试ss123/ftp_test.apk";
@Override protected void init(Bundle savedInstanceState) {
super.init(savedInstanceState);

@ -34,8 +34,8 @@ import com.arialyy.simple.databinding.ActivityFtpUploadBinding;
* Ftp 文件上传demo
*/
public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
private final String FILE_PATH = "/mnt/sdcard/成都.mp3";
private final String URL = "ftp://172.18.104.229:21/upload/测试";
private final String FILE_PATH = "/mnt/sdcard/Download/jd.jpg";
private final String URL = "ftp://192.168.1.9:21/upload/测试";
@Override protected void init(Bundle savedInstanceState) {
setTile("FTP 文件上传");

Loading…
Cancel
Save