修复FTP上传文件不完整的bug,尝试处理ftp 断点续传上传
This commit is contained in:
@@ -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("> ");
|
||||
}
|
||||
@@ -161,7 +151,7 @@ public class PrintCommandListener implements ProtocolCommandListener
|
||||
final String IMAP_LOGIN = "LOGIN";
|
||||
if (IMAP_LOGIN.equalsIgnoreCase(cmd)) { // IMAP
|
||||
String msg = event.getMessage();
|
||||
msg=msg.substring(0, msg.indexOf(IMAP_LOGIN)+IMAP_LOGIN.length());
|
||||
msg = msg.substring(0, msg.indexOf(IMAP_LOGIN) + IMAP_LOGIN.length());
|
||||
__writer.print(msg);
|
||||
__writer.println(" *******"); // Don't bother with EOL marker for this!
|
||||
} else {
|
||||
@@ -174,14 +164,14 @@ public class PrintCommandListener implements ProtocolCommandListener
|
||||
__writer.flush();
|
||||
}
|
||||
|
||||
private String getPrintableString(String msg){
|
||||
private String getPrintableString(String msg) {
|
||||
if (__eolMarker == 0) {
|
||||
return msg;
|
||||
}
|
||||
int pos = msg.indexOf(SocketClient.NETASCII_EOL);
|
||||
if (pos > 0) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(msg.substring(0,pos));
|
||||
sb.append(msg.substring(0, pos));
|
||||
sb.append(__eolMarker);
|
||||
sb.append(msg.substring(pos));
|
||||
return sb.toString();
|
||||
@@ -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,15 +61,13 @@ 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)
|
||||
{
|
||||
((ProtocolCommandListener)listener).protocolCommandSent(event);
|
||||
for (EventListener listener : __listeners) {
|
||||
((ProtocolCommandListener) listener).protocolCommandSent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,14 +84,12 @@ 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)
|
||||
{
|
||||
((ProtocolCommandListener)listener).protocolReplyReceived(event);
|
||||
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_);
|
||||
@@ -329,7 +315,7 @@ public abstract class SocketClient
|
||||
}
|
||||
|
||||
private void closeQuietly(Socket socket) {
|
||||
if (socket != null){
|
||||
if (socket != null) {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
@@ -338,8 +324,8 @@ public abstract class SocketClient
|
||||
}
|
||||
}
|
||||
|
||||
private void closeQuietly(Closeable close){
|
||||
if (close != null){
|
||||
private void closeQuietly(Closeable close) {
|
||||
if (close != null) {
|
||||
try {
|
||||
close.close();
|
||||
} catch (IOException e) {
|
||||
@@ -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(){
|
||||
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,16 +477,18 @@ public abstract class SocketClient
|
||||
|
||||
/**
|
||||
* Get the current sendBuffer size
|
||||
*
|
||||
* @return the size, or -1 if not initialised
|
||||
* @since 3.0
|
||||
*/
|
||||
protected int getSendBufferSize(){
|
||||
protected int getSendBufferSize() {
|
||||
return sendBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,22 +499,23 @@ public abstract class SocketClient
|
||||
|
||||
/**
|
||||
* Get the current receivedBuffer size
|
||||
*
|
||||
* @return the size, or -1 if not initialised
|
||||
* @since 3.0
|
||||
*/
|
||||
protected int getReceiveBufferSize(){
|
||||
protected int getReceiveBufferSize() {
|
||||
return receiveBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@@ -810,7 +792,7 @@ public abstract class SocketClient
|
||||
/**
|
||||
* Create the CommandSupport instance if required
|
||||
*/
|
||||
protected void createCommandSupport(){
|
||||
protected void createCommandSupport() {
|
||||
__commandSupport = new ProtocolCommandSupport(this);
|
||||
}
|
||||
|
||||
@@ -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,18 +356,16 @@ 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 +"'");
|
||||
throw new MalformedServerReplyException("Truncated server reply: '" + line + "'");
|
||||
} else if (sep != ' ') {
|
||||
throw new MalformedServerReplyException("Invalid server reply: '" + line +"'");
|
||||
throw new MalformedServerReplyException("Invalid server reply: '" + line + "'");
|
||||
}
|
||||
}
|
||||
} else if (isStrictReplyParsing()) {
|
||||
throw new MalformedServerReplyException("Truncated server reply: '" + line +"'");
|
||||
throw new MalformedServerReplyException("Truncated server reply: '" + line + "'");
|
||||
}
|
||||
|
||||
if (reportReply) {
|
||||
@@ -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_}.
|
||||
@@ -410,14 +396,12 @@ 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()));
|
||||
if (socketIsReader == null) {
|
||||
_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 {
|
||||
try{
|
||||
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.
|
||||
@@ -618,7 +587,7 @@ public class FTP extends SocketClient
|
||||
* command or receiving the server reply.
|
||||
* @since 3.3
|
||||
*/
|
||||
public int sendCommand(FTPCmd command) throws IOException{
|
||||
public int sendCommand(FTPCmd command) throws IOException {
|
||||
return sendCommand(command, null);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -644,7 +613,7 @@ public class FTP extends SocketClient
|
||||
* command or receiving the server reply.
|
||||
* @since 3.3
|
||||
*/
|
||||
public int sendCommand(FTPCmd command, String args) throws IOException{
|
||||
public int sendCommand(FTPCmd command, String args) throws IOException {
|
||||
return sendCommand(command.getCommand(), args);
|
||||
}
|
||||
|
||||
@@ -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_;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -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,18 +359,17 @@ 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);
|
||||
LANGUAGE_CODE_MAP.put("de",Locale.GERMAN);
|
||||
LANGUAGE_CODE_MAP.put("it",Locale.ITALIAN);
|
||||
LANGUAGE_CODE_MAP.put("de", Locale.GERMAN);
|
||||
LANGUAGE_CODE_MAP.put("it", Locale.ITALIAN);
|
||||
LANGUAGE_CODE_MAP.put("es", new Locale("es", "", "")); // spanish
|
||||
LANGUAGE_CODE_MAP.put("pt", new Locale("pt", "", "")); // portuguese
|
||||
LANGUAGE_CODE_MAP.put("da", new Locale("da", "", "")); // danish
|
||||
@@ -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í|jún|júl|ágú|sep|okt|nó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,19 +623,19 @@ 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) {
|
||||
return new DateFormatSymbols((Locale) lang);
|
||||
} else if (lang instanceof String){
|
||||
} else if (lang instanceof String) {
|
||||
return getDateFormatSymbols((String) lang);
|
||||
}
|
||||
}
|
||||
@@ -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,15 +662,14 @@ 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;
|
||||
while(st.hasMoreTokens()) {
|
||||
while (st.hasMoreTokens()) {
|
||||
months[pos++] = st.nextToken();
|
||||
}
|
||||
months[pos]="";
|
||||
months[pos] = "";
|
||||
return months;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -19,50 +19,10 @@
|
||||
package org.apache.commons.net.ftp;
|
||||
|
||||
/**
|
||||
* @since 3.3
|
||||
* @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;
|
||||
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]";
|
||||
@@ -472,7 +429,7 @@ public class FTPFile implements Serializable
|
||||
if (timestamp != null) {
|
||||
if (timezone != null) {
|
||||
TimeZone newZone = TimeZone.getTimeZone(timezone);
|
||||
if (!newZone.equals(timestamp.getTimeZone())){
|
||||
if (!newZone.equals(timestamp.getTimeZone())) {
|
||||
Date original = timestamp.getTime();
|
||||
Calendar newStamp = Calendar.getInstance(newZone);
|
||||
newStamp.setTime(original);
|
||||
@@ -501,8 +458,8 @@ public class FTPFile implements Serializable
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private char formatType(){
|
||||
switch(_type) {
|
||||
private char formatType() {
|
||||
switch (_type) {
|
||||
case FILE_TYPE:
|
||||
return '-';
|
||||
case DIRECTORY_TYPE:
|
||||
@@ -514,7 +471,7 @@ public class FTPFile implements Serializable
|
||||
}
|
||||
}
|
||||
|
||||
private String permissionToString(int access ){
|
||||
private String permissionToString(int access) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (hasPermission(access, READ_PERMISSION)) {
|
||||
sb.append('r');
|
||||
|
@@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -43,7 +43,7 @@ public class FTPHTTPClient extends FTPClient {
|
||||
private final String proxyUsername;
|
||||
private final String proxyPassword;
|
||||
|
||||
private static final byte[] CRLF={'\r', '\n'};
|
||||
private static final byte[] CRLF = { '\r', '\n' };
|
||||
private final Base64 base64 = new Base64();
|
||||
|
||||
private String tunnelHost; // Save the host when setting up a tunnel (needed for EPSV)
|
||||
@@ -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,17 +129,16 @@ public class FTPHTTPClient extends FTPClient {
|
||||
Reader socketIsReader;
|
||||
try {
|
||||
socketIsReader = tunnelHandshake(host, port, _input_, _output_);
|
||||
}
|
||||
catch (Exception e) {
|
||||
IOException ioe = new IOException("Could not connect to " + host+ " using port " + port);
|
||||
} catch (Exception e) {
|
||||
IOException ioe = new IOException("Could not connect to " + host + " using port " + port);
|
||||
ioe.initCause(e);
|
||||
throw ioe;
|
||||
}
|
||||
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
|
||||
@@ -224,7 +212,7 @@ public class FTPListParseEngine {
|
||||
if (temp == null && saveUnparseableEntries) {
|
||||
temp = new FTPFile(entry);
|
||||
}
|
||||
tmpResults.add(0,temp);
|
||||
tmpResults.add(0, temp);
|
||||
count--;
|
||||
}
|
||||
return tmpResults.toArray(new FTPFile[tmpResults.size()]);
|
||||
@@ -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
|
||||
@@ -274,12 +260,11 @@ public class FTPListParseEngine {
|
||||
if (temp == null && saveUnparseableEntries) {
|
||||
temp = new FTPFile(entry);
|
||||
}
|
||||
if (filter.accept(temp)){
|
||||
if (filter.accept(temp)) {
|
||||
tmpResults.add(temp);
|
||||
}
|
||||
}
|
||||
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,23 +45,24 @@ 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
|
||||
*/
|
||||
public class FTPSClient extends FTPClient {
|
||||
|
||||
// From http://www.iana.org/assignments/port-numbers
|
||||
// From http://www.iana.org/assignments/port-numbers
|
||||
|
||||
// ftps-data 989/tcp ftp protocol, data, over TLS/SSL
|
||||
// ftps-data 989/udp ftp protocol, data, over TLS/SSL
|
||||
// ftps 990/tcp ftp protocol, control, over TLS/SSL
|
||||
// ftps 990/udp ftp protocol, control, over TLS/SSL
|
||||
// ftps-data 989/tcp ftp protocol, data, over TLS/SSL
|
||||
// ftps-data 989/udp ftp protocol, data, over TLS/SSL
|
||||
// ftps 990/tcp ftp protocol, control, over TLS/SSL
|
||||
// ftps 990/udp ftp protocol, control, over TLS/SSL
|
||||
|
||||
public static final int DEFAULT_FTPS_DATA_PORT = 989;
|
||||
public static final int DEFAULT_FTPS_PORT = 990;
|
||||
|
||||
/** The value that I can set in PROT command (C = Clear, P = Protected) */
|
||||
private static final String[] PROT_COMMAND_VALUE = {"C","E","S","P"};
|
||||
private static final String[] PROT_COMMAND_VALUE = { "C", "E", "S", "P" };
|
||||
/** Default PROT Command */
|
||||
private static final String DEFAULT_PROT = "C";
|
||||
/** Default secure socket protocol name, i.e. TLS */
|
||||
@@ -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,21 +342,24 @@ 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.
|
||||
*/
|
||||
public boolean getEnableSessionCreation() {
|
||||
if (_socket_ instanceof SSLSocket) {
|
||||
return ((SSLSocket)_socket_).getEnableSessionCreation();
|
||||
return ((SSLSocket) _socket_).getEnableSessionCreation();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the socket to require client authentication.
|
||||
*
|
||||
* @param isNeedClientAuth The need client auth flag.
|
||||
*/
|
||||
public void setNeedClientAuth(boolean isNeedClientAuth) {
|
||||
@@ -355,12 +369,13 @@ 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.
|
||||
*/
|
||||
public boolean getNeedClientAuth() {
|
||||
if (_socket_ instanceof SSLSocket) {
|
||||
return ((SSLSocket)_socket_).getNeedClientAuth();
|
||||
return ((SSLSocket) _socket_).getNeedClientAuth();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -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,12 +394,13 @@ 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.
|
||||
*/
|
||||
public boolean getWantClientAuth() {
|
||||
if (_socket_ instanceof SSLSocket) {
|
||||
return ((SSLSocket)_socket_).getWantClientAuth();
|
||||
return ((SSLSocket) _socket_).getWantClientAuth();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -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,12 +419,13 @@ 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.
|
||||
*/
|
||||
public boolean getUseClientMode() {
|
||||
if (_socket_ instanceof SSLSocket) {
|
||||
return ((SSLSocket)_socket_).getUseClientMode();
|
||||
return ((SSLSocket) _socket_).getUseClientMode();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -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,11 +445,12 @@ 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() {
|
||||
if (_socket_ instanceof SSLSocket) {
|
||||
return ((SSLSocket)_socket_).getEnabledCipherSuites();
|
||||
return ((SSLSocket) _socket_).getEnabledCipherSuites();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -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,17 +470,19 @@ 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() {
|
||||
if (_socket_ instanceof SSLSocket) {
|
||||
return ((SSLSocket)_socket_).getEnabledProtocols();
|
||||
return ((SSLSocket) _socket_).getEnabledProtocols();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,13 +643,11 @@ 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) {
|
||||
SSLSocket sslSocket = (SSLSocket)socket;
|
||||
SSLSocket sslSocket = (SSLSocket) socket;
|
||||
|
||||
sslSocket.setUseClientMode(isClientMode);
|
||||
sslSocket.setEnableSessionCreation(isCreation);
|
||||
@@ -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,131 +775,120 @@ 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)) {
|
||||
// _socket_.close();
|
||||
// _socket_ = plainSocket;
|
||||
// _controlInput_ = new BufferedReader(
|
||||
// new InputStreamReader(
|
||||
// _socket_.getInputStream(), getControlEncoding()));
|
||||
// _controlOutput_ = new BufferedWriter(
|
||||
// new OutputStreamWriter(
|
||||
// _socket_.getOutputStream(), getControlEncoding()));
|
||||
// }
|
||||
// This will be performed by sendCommand(String, String)
|
||||
// if (FTPReply.isPositiveCompletion(repCode)) {
|
||||
// _socket_.close();
|
||||
// _socket_ = plainSocket;
|
||||
// _controlInput_ = new BufferedReader(
|
||||
// new InputStreamReader(
|
||||
// _socket_.getInputStream(), getControlEncoding()));
|
||||
// _controlOutput_ = new BufferedWriter(
|
||||
// new OutputStreamWriter(
|
||||
// _socket_.getOutputStream(), getControlEncoding()));
|
||||
// }
|
||||
return repCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -900,26 +909,21 @@ public class FTPSClient extends FTPClient {
|
||||
return null;
|
||||
}
|
||||
// N.B. Cannot use trim before substring as leading space would affect the offset.
|
||||
return reply.substring(idx+prefix.length()).trim();
|
||||
return reply.substring(idx + prefix.length()).trim();
|
||||
}
|
||||
|
||||
// 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;
|
||||
@@ -36,7 +36,7 @@ public final class FTPSCommand {
|
||||
public static final int DATA_CHANNEL_PROTECTION_LEVEL = PROT;
|
||||
public static final int CLEAR_COMMAND_CHANNEL = CCC;
|
||||
|
||||
private static final String[] _commands = {"AUTH","ADAT","PBSZ","PROT","CCC"};
|
||||
private static final String[] _commands = { "AUTH", "ADAT", "PBSZ", "PROT", "CCC" };
|
||||
|
||||
/**
|
||||
* Retrieve the FTPS command string corresponding to a specified
|
||||
|
@@ -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
|
||||
{
|
||||
private static final X509Certificate[] EMPTY_X509CERTIFICATE_ARRAY = new X509Certificate[]{};
|
||||
@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) {
|
||||
@@ -110,9 +105,9 @@ implements Configurable
|
||||
if (null == config.getRecentDateFormatStr()) {
|
||||
config.setRecentDateFormatStr(defaultCfg.getRecentDateFormatStr());
|
||||
}
|
||||
((Configurable)this.timestampParser).configure(config);
|
||||
((Configurable) this.timestampParser).configure(config);
|
||||
} else {
|
||||
((Configurable)this.timestampParser).configure(defaultCfg);
|
||||
((Configurable) this.timestampParser).configure(defaultCfg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,58 +117,38 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
if (parser instanceof Configurable) {
|
||||
((Configurable)parser).configure(config);
|
||||
((Configurable) parser).configure(config);
|
||||
}
|
||||
return parser;
|
||||
}
|
||||
@@ -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,16 +33,13 @@ 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>
|
||||
* <p>
|
||||
* Implementation should be a method that extracts
|
||||
* a key from the supplied {@link FTPClientConfig FTPClientConfig}
|
||||
* parameter and creates an object implementing the
|
||||
@@ -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
|
||||
@@ -83,11 +76,11 @@ public class FTPTimestampParserImpl implements
|
||||
if (dateFormat == null) {
|
||||
return 0;
|
||||
}
|
||||
final String FORMAT_CHARS="SsmHdM";
|
||||
final String FORMAT_CHARS = "SsmHdM";
|
||||
final String pattern = dateFormat.toPattern();
|
||||
for(char ch : FORMAT_CHARS.toCharArray()) {
|
||||
if (pattern.indexOf(ch) != -1){ // found the character
|
||||
switch(ch) {
|
||||
for (char ch : FORMAT_CHARS.toCharArray()) {
|
||||
if (pattern.indexOf(ch) != -1) { // found the character
|
||||
switch (ch) {
|
||||
case 'S':
|
||||
return indexOf(Calendar.MILLISECOND);
|
||||
case 's':
|
||||
@@ -111,7 +104,7 @@ public class FTPTimestampParserImpl implements
|
||||
*/
|
||||
private static int indexOf(int calendarUnit) {
|
||||
int i;
|
||||
for(i = 0; i <CALENDAR_UNITS.length; i++) {
|
||||
for (i = 0; i < CALENDAR_UNITS.length; i++) {
|
||||
if (calendarUnit == CALENDAR_UNITS[i]) {
|
||||
return i;
|
||||
}
|
||||
@@ -128,12 +121,12 @@ public class FTPTimestampParserImpl implements
|
||||
if (index <= 0) { // e.g. MILLISECONDS
|
||||
return;
|
||||
}
|
||||
final int field = CALENDAR_UNITS[index-1];
|
||||
final int field = CALENDAR_UNITS[index - 1];
|
||||
// Just in case the analysis is wrong, stop clearing if
|
||||
// field value is not the default.
|
||||
final int value = working.get(field);
|
||||
if (value != 0) { // don't reset if it has a value
|
||||
// new Throwable("Unexpected value "+value).printStackTrace(); // DEBUG
|
||||
// new Throwable("Unexpected value "+value).printStackTrace(); // DEBUG
|
||||
} else {
|
||||
working.clear(field); // reset just the required field
|
||||
}
|
||||
@@ -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,33 +69,29 @@ 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
|
||||
/* 0 */ {},
|
||||
/* 1 */ {FTPFile.EXECUTE_PERMISSION},
|
||||
/* 2 */ {FTPFile.WRITE_PERMISSION},
|
||||
/* 3 */ {FTPFile.EXECUTE_PERMISSION, FTPFile.WRITE_PERMISSION},
|
||||
/* 4 */ {FTPFile.READ_PERMISSION},
|
||||
/* 5 */ {FTPFile.READ_PERMISSION, FTPFile.EXECUTE_PERMISSION},
|
||||
/* 6 */ {FTPFile.READ_PERMISSION, FTPFile.WRITE_PERMISSION},
|
||||
/* 7 */ {FTPFile.READ_PERMISSION, FTPFile.WRITE_PERMISSION, FTPFile.EXECUTE_PERMISSION},
|
||||
/* 1 */ { FTPFile.EXECUTE_PERMISSION },
|
||||
/* 2 */ { FTPFile.WRITE_PERMISSION },
|
||||
/* 3 */ { FTPFile.EXECUTE_PERMISSION, FTPFile.WRITE_PERMISSION },
|
||||
/* 4 */ { FTPFile.READ_PERMISSION },
|
||||
/* 5 */ { FTPFile.READ_PERMISSION, FTPFile.EXECUTE_PERMISSION },
|
||||
/* 6 */ { FTPFile.READ_PERMISSION, FTPFile.WRITE_PERMISSION },
|
||||
/* 7 */ { FTPFile.READ_PERMISSION, FTPFile.WRITE_PERMISSION, FTPFile.EXECUTE_PERMISSION },
|
||||
};
|
||||
|
||||
/**
|
||||
* 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,9 +101,8 @@ public class MLSxEntryParser extends FTPFileEntryParserImpl
|
||||
} else {
|
||||
return null; // Invalid - no pathname
|
||||
}
|
||||
|
||||
}
|
||||
String parts[] = entry.split(" ",2); // Path may contain space
|
||||
String parts[] = entry.split(" ", 2); // Path may contain space
|
||||
if (parts.length != 2 || parts[1].length() == 0) {
|
||||
return null; // no space found or no file name
|
||||
}
|
||||
@@ -119,11 +115,11 @@ public class MLSxEntryParser extends FTPFileEntryParserImpl
|
||||
file.setName(parts[1]);
|
||||
String[] facts = factList.split(";");
|
||||
boolean hasUnixMode = parts[0].toLowerCase(Locale.ENGLISH).contains("unix.mode=");
|
||||
for(String fact : facts) {
|
||||
String []factparts = fact.split("=", -1); // Don't drop empty values
|
||||
// Sample missing permission
|
||||
// drwx------ 2 mirror mirror 4096 Mar 13 2010 subversion
|
||||
// modify=20100313224553;perm=;type=dir;unique=811U282598;UNIX.group=500;UNIX.mode=0700;UNIX.owner=500; subversion
|
||||
for (String fact : facts) {
|
||||
String[] factparts = fact.split("=", -1); // Don't drop empty values
|
||||
// Sample missing permission
|
||||
// drwx------ 2 mirror mirror 4096 Mar 13 2010 subversion
|
||||
// modify=20100313224553;perm=;type=dir;unique=811U282598;UNIX.group=500;UNIX.mode=0700;UNIX.owner=500; subversion
|
||||
if (factparts.length != 2) {
|
||||
return null; // invalid - there was no "=" sign
|
||||
}
|
||||
@@ -135,37 +131,33 @@ 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)){
|
||||
if ("group".equals(unixfact)) {
|
||||
file.setGroup(factvalue);
|
||||
} else if ("owner".equals(unixfact)){
|
||||
} else if ("owner".equals(unixfact)) {
|
||||
file.setUser(factvalue);
|
||||
} else if ("mode".equals(unixfact)){ // e.g. 0[1]755
|
||||
int off = factvalue.length()-3; // only parse last 3 digits
|
||||
for(int i=0; i < 3; i++){
|
||||
int ch = factvalue.charAt(off+i)-'0';
|
||||
} else if ("mode".equals(unixfact)) { // e.g. 0[1]755
|
||||
int off = factvalue.length() - 3; // only parse last 3 digits
|
||||
for (int i = 0; i < 3; i++) {
|
||||
int ch = factvalue.charAt(off + i) - '0';
|
||||
if (ch >= 0 && ch <= 7) { // Check it's valid octal
|
||||
for(int p : UNIX_PERMS[ch]) {
|
||||
for (int p : UNIX_PERMS[ch]) {
|
||||
file.setPermission(UNIX_GROUPS[i], p, true);
|
||||
}
|
||||
} else {
|
||||
@@ -191,7 +183,7 @@ public class MLSxEntryParser extends FTPFileEntryParserImpl
|
||||
public static Calendar parseGMTdateTime(String timestamp) {
|
||||
final SimpleDateFormat sdf;
|
||||
final boolean hasMillis;
|
||||
if (timestamp.contains(".")){
|
||||
if (timestamp.contains(".")) {
|
||||
sdf = new SimpleDateFormat("yyyyMMddHHmmss.SSS");
|
||||
hasMillis = true;
|
||||
} else {
|
||||
@@ -219,7 +211,7 @@ public class MLSxEntryParser extends FTPFileEntryParserImpl
|
||||
// pvals = "a" / "c" / "d" / "e" / "f" /
|
||||
// "l" / "m" / "p" / "r" / "w"
|
||||
private void doUnixPerms(FTPFile file, String valueLowerCase) {
|
||||
for(char c : valueLowerCase.toCharArray()) {
|
||||
for (char c : valueLowerCase.toCharArray()) {
|
||||
// TODO these are mostly just guesses at present
|
||||
switch (c) {
|
||||
case 'a': // (file) may APPEnd
|
||||
|
@@ -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) {
|
||||
@@ -431,10 +418,9 @@ public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
|
||||
* [3] Job status (INPUT,ACTIVE,OUTPUT)
|
||||
* [4] Number of sysout files
|
||||
* [5] The string "Spool Files"
|
||||
*</pre>
|
||||
* </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,23 +64,20 @@ 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);
|
||||
((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))
|
||||
{
|
||||
String datestr = group(1)+" "+group(2);
|
||||
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 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,69 +267,52 @@ 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)))
|
||||
{
|
||||
datestr = group(3)+" "+group(4);
|
||||
if (!isNullOrEmpty(group(3)) || !isNullOrEmpty(group(4))) {
|
||||
datestr = group(3) + " " + group(4);
|
||||
}
|
||||
String typeStr = group(5);
|
||||
String name = group(6);
|
||||
|
||||
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,9 +94,8 @@ 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
|
||||
+"(((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-])))\\+?" // permissions
|
||||
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.
|
||||
@@ -55,23 +56,21 @@ public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
|
||||
private static final String REGEX =
|
||||
"(.*?;[0-9]+)\\s*" //1 file and version
|
||||
+ "(\\d+)/\\d+\\s*" //2 size/allocated
|
||||
+"(\\S+)\\s+(\\S+)\\s+" //3+4 date and time
|
||||
+ "(\\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,34 +101,27 @@ 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);
|
||||
String size = group(2);
|
||||
String datestr = group(3)+" "+group(4);
|
||||
String datestr = group(3) + " " + group(4);
|
||||
String owner = group(5);
|
||||
String permissions[] = new String[3];
|
||||
permissions[0]= group(9);
|
||||
permissions[1]= group(10);
|
||||
permissions[2]= group(11);
|
||||
try
|
||||
{
|
||||
permissions[0] = group(9);
|
||||
permissions[1] = group(10);
|
||||
permissions[2] = group(11);
|
||||
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,13 +166,12 @@ 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);
|
||||
f.setPermission(access, FTPFile.WRITE_PERMISSION, permission.indexOf('W')>=0);
|
||||
f.setPermission(access, FTPFile.EXECUTE_PERMISSION, permission.indexOf('E')>=0);
|
||||
f.setPermission(access, FTPFile.READ_PERMISSION, permission.indexOf('R') >= 0);
|
||||
f.setPermission(access, FTPFile.WRITE_PERMISSION, permission.indexOf('W') >= 0);
|
||||
f.setPermission(access, FTPFile.EXECUTE_PERMISSION, permission.indexOf('E') >= 0);
|
||||
}
|
||||
|
||||
return f;
|
||||
@@ -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,18 +46,17 @@ 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)
|
||||
{
|
||||
synchronized (lock) { // make thread-safe (hopefully!)
|
||||
while ((intch = read()) != -1) {
|
||||
if (prevWasCR && intch == LF) {
|
||||
return sb.substring(0, sb.length()-1);
|
||||
return sb.substring(0, sb.length() - 1);
|
||||
}
|
||||
if (intch == CR) {
|
||||
prevWasCR = true;
|
||||
|
@@ -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,17 +213,16 @@ 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)
|
||||
{
|
||||
synchronized (lock) { // make thread-safe (hopefully!)
|
||||
while ((intch = read()) != -1) {
|
||||
if (intch == LF && atBeginning) {
|
||||
return sb.substring(0, sb.length()-1);
|
||||
return sb.substring(0, sb.length() - 1);
|
||||
}
|
||||
sb.append((char) intch);
|
||||
}
|
||||
|
@@ -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,24 +67,20 @@ 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');
|
||||
return ;
|
||||
return;
|
||||
case '\n':
|
||||
if (__state != __LAST_WAS_CR_STATE) {
|
||||
__output.write('\r');
|
||||
}
|
||||
__output.write('\n');
|
||||
__state = __LAST_WAS_NL_STATE;
|
||||
return ;
|
||||
return;
|
||||
case '.':
|
||||
// Double the dot at the beginning of a line
|
||||
if (__state == __LAST_WAS_NL_STATE) {
|
||||
@@ -98,12 +90,11 @@ public final class DotTerminatedMessageWriter extends Writer
|
||||
default:
|
||||
__state = __NOTHING_SPECIAL_STATE;
|
||||
__output.write(ch);
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* 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,13 +168,10 @@ 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 ;
|
||||
return;
|
||||
}
|
||||
|
||||
if (__state == __LAST_WAS_CR_STATE) {
|
||||
@@ -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;
|
||||
@@ -44,7 +43,7 @@ public final class FromNetASCIIInputStream extends PushbackInputStream
|
||||
try {
|
||||
_lineSeparatorBytes = _lineSeparator.getBytes("US-ASCII");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException("Broken JVM - cannot find US-ASCII charset!",e);
|
||||
throw new RuntimeException("Broken JVM - cannot find US-ASCII charset!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
buffer[offset++] = (byte)ch;
|
||||
}
|
||||
while (--__length > 0 && (ch = __read()) != -1);
|
||||
|
||||
do {
|
||||
buffer[offset++] = (byte) ch;
|
||||
} 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,20 +87,15 @@ 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 ;
|
||||
return;
|
||||
}
|
||||
|
||||
__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,16 +117,13 @@ 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);
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
while (length-- > 0) {
|
||||
@@ -151,20 +131,15 @@ 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 ;
|
||||
return;
|
||||
}
|
||||
|
||||
if (__lastWasCR) {
|
||||
|
@@ -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
|
||||
{
|
||||
buffer[offset++] = (byte)ch;
|
||||
}
|
||||
while (--length > 0 && (ch = read()) != -1);
|
||||
do {
|
||||
buffer[offset++] = (byte) ch;
|
||||
} 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,16 +57,12 @@ 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');
|
||||
return ;
|
||||
return;
|
||||
case '\n':
|
||||
if (!__lastWasCR) {
|
||||
out.write('\r');
|
||||
@@ -78,11 +71,10 @@ public final class ToNetASCIIOutputStream extends FilterOutputStream
|
||||
default:
|
||||
__lastWasCR = false;
|
||||
out.write(ch);
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* 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,31 +85,24 @@ 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;
|
||||
}
|
||||
dest.write(singleByte);
|
||||
if(flush) {
|
||||
if (flush) {
|
||||
dest.flush();
|
||||
}
|
||||
++total;
|
||||
@@ -122,7 +113,7 @@ public final class Util
|
||||
}
|
||||
|
||||
dest.write(buffer, 0, numBytes);
|
||||
if(flush) {
|
||||
if (flush) {
|
||||
dest.flush();
|
||||
}
|
||||
total += numBytes;
|
||||
@@ -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>
|
||||
*
|
||||
@@ -68,23 +72,23 @@ public class Base64 {
|
||||
*
|
||||
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 2.1</a>
|
||||
*/
|
||||
private static final byte[] CHUNK_SEPARATOR = {'\r', '\n'};
|
||||
private static final byte[] CHUNK_SEPARATOR = { '\r', '\n' };
|
||||
|
||||
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) {
|
||||
@@ -455,7 +477,7 @@ public class Base64 {
|
||||
resizeBuffer();
|
||||
}
|
||||
switch (modulus) {
|
||||
case 1 :
|
||||
case 1:
|
||||
buffer[pos++] = encodeTable[(x >> 2) & MASK_6BITS];
|
||||
buffer[pos++] = encodeTable[(x << 4) & MASK_6BITS];
|
||||
// URL-SAFE skips the padding to further reduce size.
|
||||
@@ -465,7 +487,7 @@ public class Base64 {
|
||||
}
|
||||
break;
|
||||
|
||||
case 2 :
|
||||
case 2:
|
||||
buffer[pos++] = encodeTable[(x >> 10) & MASK_6BITS];
|
||||
buffer[pos++] = encodeTable[(x >> 4) & MASK_6BITS];
|
||||
buffer[pos++] = encodeTable[(x << 2) & MASK_6BITS];
|
||||
@@ -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) {
|
||||
@@ -569,11 +592,11 @@ public class Base64 {
|
||||
if (eof && modulus != 0) {
|
||||
x = x << 6;
|
||||
switch (modulus) {
|
||||
case 2 :
|
||||
case 2:
|
||||
x = x << 6;
|
||||
buffer[pos++] = (byte) ((x >> 16) & MASK_8BITS);
|
||||
break;
|
||||
case 3 :
|
||||
case 3:
|
||||
buffer[pos++] = (byte) ((x >> 16) & MASK_8BITS);
|
||||
buffer[pos++] = (byte) ((x >> 8) & MASK_8BITS);
|
||||
break;
|
||||
@@ -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,40 +867,36 @@ 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) {
|
||||
switch (byteToCheck) {
|
||||
case ' ' :
|
||||
case '\n' :
|
||||
case '\r' :
|
||||
case '\t' :
|
||||
case ' ':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '\t':
|
||||
return true;
|
||||
default :
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
|
@@ -66,7 +66,7 @@ public final class KeyManagerUtils {
|
||||
|
||||
private static final String DEFAULT_STORE_TYPE = KeyStore.getDefaultType();
|
||||
|
||||
private KeyManagerUtils(){
|
||||
private KeyManagerUtils() {
|
||||
// Not instantiable
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ public final class KeyManagerUtils {
|
||||
|
||||
private static String findAlias(KeyStore ks) throws KeyStoreException {
|
||||
Enumeration<String> e = ks.aliases();
|
||||
while(e.hasMoreElements()) {
|
||||
while (e.hasMoreElements()) {
|
||||
String entry = e.nextElement();
|
||||
if (ks.isKeyEntry(entry)) {
|
||||
return entry;
|
||||
@@ -174,13 +174,12 @@ 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);
|
||||
X509Certificate[] X509certs = new X509Certificate[certs.length];
|
||||
for (int i=0; i < certs.length; i++) {
|
||||
for (int i = 0; i < certs.length; i++) {
|
||||
X509certs[i] = (X509Certificate) certs[i];
|
||||
}
|
||||
this.certChain = X509certs;
|
||||
@@ -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) {
|
||||
return new String[]{ keyStore.getAlias()};
|
||||
@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 broadcast() { return broadcast; }
|
||||
private int netmask() {
|
||||
return netmask;
|
||||
}
|
||||
|
||||
private int network() {
|
||||
return network;
|
||||
}
|
||||
|
||||
private int address() {
|
||||
return address;
|
||||
}
|
||||
|
||||
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,23 +194,24 @@ 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);
|
||||
}
|
||||
// N.B. cannot be negative
|
||||
return (int)countLong;
|
||||
return (int) countLong;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
@@ -221,7 +236,7 @@ public class SubnetUtils {
|
||||
if (ct == 0) {
|
||||
return addresses;
|
||||
}
|
||||
for (int add = low(), j=0; add <= high(); ++add, ++j) {
|
||||
for (int add = low(), j = 0; add <= high(); ++add, ++j) {
|
||||
addresses[j] = format(toArray(add));
|
||||
}
|
||||
return addresses;
|
||||
@@ -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
|
||||
@@ -296,7 +328,7 @@ public class SubnetUtils {
|
||||
int addr = 0;
|
||||
for (int i = 1; i <= 4; ++i) {
|
||||
int n = (rangeCheck(Integer.parseInt(matcher.group(i)), 0, 255));
|
||||
addr |= ((n & 0xff) << 8*(4-i));
|
||||
addr |= ((n & 0xff) << 8 * (4 - i));
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
@@ -307,7 +339,7 @@ public class SubnetUtils {
|
||||
private int[] toArray(int val) {
|
||||
int ret[] = new int[4];
|
||||
for (int j = 3; j >= 0; --j) {
|
||||
ret[j] |= ((val >>> 8*(3-j)) & (0xff));
|
||||
ret[j] |= ((val >>> 8 * (3 - j)) & (0xff));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -317,7 +349,7 @@ public class SubnetUtils {
|
||||
*/
|
||||
private String format(int[] octets) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
for (int i =0; i < octets.length; ++i){
|
||||
for (int i = 0; i < octets.length; ++i) {
|
||||
str.append(octets[i]);
|
||||
if (i != octets.length - 1) {
|
||||
str.append(".");
|
||||
@@ -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,9 +30,8 @@ import javax.net.ssl.X509TrustManager;
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
public final class TrustManagerUtils
|
||||
{
|
||||
private static final X509Certificate[] EMPTY_X509CERTIFICATE_ARRAY = new X509Certificate[]{};
|
||||
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,23 +60,21 @@ public final class TrustManagerUtils
|
||||
/**
|
||||
* @return an empty array of certificates
|
||||
*/
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers()
|
||||
{
|
||||
@Override public X509Certificate[] getAcceptedIssuers() {
|
||||
return EMPTY_X509CERTIFICATE_ARRAY;
|
||||
}
|
||||
}
|
||||
|
||||
private static final X509TrustManager ACCEPT_ALL=new TrustManager(false);
|
||||
private static final X509TrustManager ACCEPT_ALL = new TrustManager(false);
|
||||
|
||||
private static final X509TrustManager CHECK_SERVER_VALIDITY=new TrustManager(true);
|
||||
private static final X509TrustManager CHECK_SERVER_VALIDITY = new TrustManager(true);
|
||||
|
||||
/**
|
||||
* Generate a TrustManager that performs no checks.
|
||||
*
|
||||
* @return the TrustManager
|
||||
*/
|
||||
public static X509TrustManager getAcceptAllTrustManager(){
|
||||
public static X509TrustManager getAcceptAllTrustManager() {
|
||||
return ACCEPT_ALL;
|
||||
}
|
||||
|
||||
@@ -92,7 +84,7 @@ public final class TrustManagerUtils
|
||||
*
|
||||
* @return the validating TrustManager
|
||||
*/
|
||||
public static X509TrustManager getValidateServerCertificateTrustManager(){
|
||||
public static X509TrustManager getValidateServerCertificateTrustManager() {
|
||||
return CHECK_SERVER_VALIDITY;
|
||||
}
|
||||
|
||||
@@ -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 文件上传");
|
||||
|
Reference in New Issue
Block a user