package pt.estgp.estgweb.web;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.log4j.Logger;
import pt.estgp.estgweb.domain.UserSession;
import pt.estgp.estgweb.domain.UserSessionImpl;
import pt.estgp.estgweb.utils.*;
import pt.estgp.estgweb.utils.Globals;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.SocketException;
import java.net.URL;
import java.util.HashMap;
/**
* @author Jorge
* @date 18/Jan/2009
* @time 18:35:11
*/
public class FtpServer
{
private static final 1.5.0/docs/api/java/util/logging/Logger.html">Logger logger =
1.5.0/docs/api/java/util/logging/Logger.html">Logger.
getLogger(FtpServer.
class);
private static HashMap
<String, FtpServer
> servers =
new HashMap
<String, FtpServer
>();
1.5.0/docs/api/java/lang/String.html">String host =
null;
int port =
21;
1.5.0/docs/api/java/lang/String.html">String username =
null;
1.5.0/docs/api/java/lang/String.html">String password =
null;
1.5.0/docs/api/java/lang/String.html">String errorMsg =
"";
public FtpServer
(1.5.0/docs/api/java/lang/String.html">String host,
int port
)
{
this.
host = host
;
if (port
> 0
)
this.
port = port
;
}
public FtpServer
(1.5.0/docs/api/java/lang/String.html">String host,
int port,
1.5.0/docs/api/java/lang/String.html">String username,
1.5.0/docs/api/java/lang/String.html">String password
)
{
this.
host = host
;
this.
port = port
;
this.
username = username
;
this.
password = password
;
}
public static FtpServer getFtpServerForCurrentUser
(1.5.0/docs/api/java/lang/String.html">String urlStr, HttpServletRequest request
) throws 1.5.0/docs/api/java/net/MalformedURLException.html">MalformedURLException
{
1.5.0/docs/api/java/net/URL.html">URL url =
new 1.5.0/docs/api/java/net/URL.html">URL(urlStr
);
int port = url.
getPort();
if (port
<= 0
)
port =
21;
1.5.0/docs/api/java/lang/String.html">String host = url.
getHost();
UserSession userSession = UserSessionProxy.
loadUserSessionFromRequest(request
);
1.5.0/docs/api/java/lang/String.html">String username = userSession.
getUsername();
1.5.0/docs/api/java/lang/String.html">String password =
((UserSessionImpl
)userSession
).
getUserPasswordInSession();
return new FtpServer
(host,port,username,password
);
}
private static final int FTP_TIMEOUT_SECONDS = pt.
estgp.
estgweb.
utils.
Globals.
FTP_TIMEOUT_SECONDS;
public static class Connector
implements 1.5.0/docs/api/java/lang/Runnable.html">Runnable
{
FTPClient ftp
;
1.5.0/docs/api/java/lang/String.html">String host
;
int port
;
public Connector
(FTPClient ftp,
1.5.0/docs/api/java/lang/String.html">String host,
int port
) {
this.
ftp = ftp
;
this.
host = host
;
this.
port = port
;
}
@
1.5.0/docs/api/java/lang/Override.html">Override
public void run
() {
try {
ftp.
connect(host, port
);
} catch (1.5.0/docs/api/java/io/IOException.html">IOException e
) {
logger.
error(e,e
);
}
}
}
public FtpClientWrapper getClientWrapperAutoReconnect
() throws 1.5.0/docs/api/java/io/IOException.html">IOException
{
return new FtpClientWrapper
(this,3
);
}
public FTPClient getClient
() throws 1.5.0/docs/api/java/io/IOException.html">IOException
{
errorMsg =
null;
Connector connector =
new Connector
(new MyFTPClient
(),host,port
);
logger.
info("CONNECTING... waiting " + FTP_TIMEOUT_SECONDS +
" seconds");
1.5.0/docs/api/java/lang/Thread.html">Thread t =
new 1.5.0/docs/api/java/lang/Thread.html">Thread(connector
);
t.
start();
try {
for(int i=
0;i
<FTP_TIMEOUT_SECONDS
;i++
)
{
1.5.0/docs/api/java/lang/Thread.html">Thread.
sleep(1000
);
if(!t.
isAlive())
{
if(connector.
ftp.
isConnected())
break;
}
}
if(!connector.
ftp.
isConnected())
{
errorMsg =
"errors.ftp.timeout";
logger.
info("Not Connected will interrupt");
t.
interrupt();
return null;
}
} catch (1.5.0/docs/api/java/lang/InterruptedException.html">InterruptedException e
) {
logger.
error(e,e
);
errorMsg =
"errors.ftp.interrupt";
}
if (username
!=
null && password
!=
null)
{
//connector.ftp.setDataTimeout(1000000000);
connector.
ftp.
setDataTimeout(10000
);
try {
//connector.ftp.setSoTimeout(1000000000);
connector.
ftp.
setSoTimeout(10000
);
} catch (1.5.0/docs/api/java/net/SocketException.html">SocketException e
) {
e.
printStackTrace();
}
//connector.ftp.setDefaultTimeout(1000000000);
connector.
ftp.
setDefaultTimeout(10000
);
if(connector.
ftp.
login(username,password
))
{
return connector.
ftp;
}
else
{
errorMsg =
"errors.ftp.no.permission";
logger.
warn("Cant login user: " + username
);
}
}
if(errorMsg ==
null)
errorMsg =
"errors.ftp.unknown.error";
return null;
/* estava assim
if (username != null)
ftp.user(username);
if (password != null)
ftp.pass(password);*/
//return ftp;
}
public 1.5.0/docs/api/java/lang/String.html">String getErrorMsg
() {
return errorMsg
;
}
public 1.5.0/docs/api/java/lang/String.html">String getHost
()
{
return host
;
}
public void setHost
(1.5.0/docs/api/java/lang/String.html">String host
)
{
this.
host = host
;
}
public int getPort
()
{
return port
;
}
public void setPort
(int port
)
{
this.
port = port
;
}
public 1.5.0/docs/api/java/lang/String.html">String getUsername
()
{
return username
;
}
public void setUsername
(1.5.0/docs/api/java/lang/String.html">String username
)
{
this.
username = username
;
}
public 1.5.0/docs/api/java/lang/String.html">String getPassword
()
{
return password
;
}
public void setPassword
(1.5.0/docs/api/java/lang/String.html">String password
)
{
this.
password = password
;
}
public static FtpServer getServer
(1.5.0/docs/api/java/lang/String.html">String urlStr,
1.5.0/docs/api/java/lang/String.html">String user,
1.5.0/docs/api/java/lang/String.html">String pass
)
{
FtpServer ftpServer = servers.
get(urlStr
);
if (ftpServer ==
null)
ftpServer = addServer
(urlStr, user, pass
);
return ftpServer
;
}
public static FtpServer getNewServer
(1.5.0/docs/api/java/lang/String.html">String urlStr,
1.5.0/docs/api/java/lang/String.html">String user,
1.5.0/docs/api/java/lang/String.html">String pass
)
{
try
{
1.5.0/docs/api/java/net/URL.html">URL url =
new 1.5.0/docs/api/java/net/URL.html">URL(urlStr
);
1.5.0/docs/api/java/lang/String.html">String host = url.
getHost();
int port = url.
getPort();
if (port
<= 0
)
port =
21;
logger.
info("Connecting to " + host +
"in port:" + port
);
return new FtpServer
(host, port, user, pass
);
}
catch (1.5.0/docs/api/java/net/MalformedURLException.html">MalformedURLException e
)
{
logger.
error(e, e
);
}
catch (1.5.0/docs/api/java/io/IOException.html">IOException e
)
{
logger.
error(e, e
);
}
return null;
}
/**
* Add a ftpServer to Cache
*
* @param urlStr to parse
* @param user username
* @param pass password
* @return ftpServer
*/
private static synchronized FtpServer addServer
(1.5.0/docs/api/java/lang/String.html">String urlStr,
1.5.0/docs/api/java/lang/String.html">String user,
1.5.0/docs/api/java/lang/String.html">String pass
)
{
try
{
1.5.0/docs/api/java/net/URL.html">URL url =
new 1.5.0/docs/api/java/net/URL.html">URL(urlStr
);
1.5.0/docs/api/java/lang/String.html">String host = url.
getHost();
int port = url.
getPort();
if (port
<= 0
)
port =
21;
logger.
info("Connecting to " + host +
" in port:" + port
);
FtpServer ftpServer =
new FtpServer
(host, port, user, pass
);
servers.
put(urlStr, ftpServer
);
return ftpServer
;
}
catch (1.5.0/docs/api/java/net/MalformedURLException.html">MalformedURLException e
)
{
logger.
error(e, e
);
}
catch (1.5.0/docs/api/java/io/IOException.html">IOException e
)
{
logger.
error(e, e
);
}
return null;
}
public static class FtpClientWrapper
{
FtpServer server
;
FTPClient client =
null;
private int restartTimes =
2;
private int tries =
0;
private 1.5.0/docs/api/java/lang/String.html">String lastWorkingDirectory =
"";
private int fileType
;
private int TIMEOUT_FILES = 1000
* 60;
public int getTIMEOUT_FILES
() {
return TIMEOUT_FILES
;
}
/**
* in miliseconds
* @param TIMEOUT_FILES
*/
public void setTIMEOUT_FILES
(int TIMEOUT_FILES
) {
this.
TIMEOUT_FILES = TIMEOUT_FILES
;
}
public FtpClientWrapper
(FtpServer server,
int restartTimesOnFail
) throws 1.5.0/docs/api/java/io/IOException.html">IOException {
this.
server = server
;
this.
restartTimes = restartTimesOnFail
;
client = server.
getClient();
client.
setDataTimeout(TIMEOUT_FILES
);
client.
setSoTimeout(10000
);
//client.setSoTimeout(TIMEOUT_FILES);
client.
setDefaultTimeout(10000
);
client.
enterLocalActiveMode();
}
/*public boolean changeWorkingDirectory(String pathname) throws IOException
{
return changeWorkingDirectory(pathname, false);
}*/
public boolean changeWorkingDirectory
(1.5.0/docs/api/java/lang/String.html">String pathname,
boolean absolute
) throws 1.5.0/docs/api/java/io/IOException.html">IOException
{
try{
tries++
;
boolean b = client.
changeWorkingDirectory(pathname
);
tries =
0;
if(b
)
{
if(absolute
)
lastWorkingDirectory = pathname
;
else
lastWorkingDirectory = lastWorkingDirectory +
"/" + pathname
;
}
return b
;
}
catch(1.5.0/docs/api/java/io/IOException.html">IOException e
)
{
if(tries
> restartTimes
)
{
tries =
0;
client = server.
getClient();
client.
setDataTimeout(TIMEOUT_FILES
);
client.
enterLocalActiveMode();
logger.
error("Restart exceed maximum restart times of " + restartTimes
);
throw e
;
}
else
{
logger.
warn("FTP Fail will try restart " + tries +
"º connection of " + restartTimes +
" error: " + e.
toString());
client = server.
getClient();
client.
setDataTimeout(TIMEOUT_FILES
);
client.
enterLocalActiveMode();
if(absolute
)
return changeWorkingDirectory
(pathname,
true);
else
{
client.
changeWorkingDirectory(lastWorkingDirectory
);
return changeWorkingDirectory
(pathname,
false);
}
}
}
}
public void changeToParentDirectory
() throws 1.5.0/docs/api/java/io/IOException.html">IOException
{
try{
tries++
;
boolean b = client.
changeToParentDirectory();
tries =
0;
if(b
)
{
lastWorkingDirectory = lastWorkingDirectory.
substring(0,lastWorkingDirectory.
indexOf("/"));
}
}
catch(1.5.0/docs/api/java/io/IOException.html">IOException e
)
{
if(tries
> restartTimes
)
{
tries =
0;
client = server.
getClient();
client.
setDataTimeout(TIMEOUT_FILES
);
logger.
error("Restart exceed maximum restart times of " + restartTimes
);
throw e
;
}
else
{
logger.
warn("FTP Fail will try restart " + tries +
"º connection of " + restartTimes +
" error: " + e.
toString());
client = server.
getClient();
client.
setDataTimeout(TIMEOUT_FILES
);
client.
changeWorkingDirectory(lastWorkingDirectory
);
changeToParentDirectory
();
}
}
}
public void enterLocalPassiveMode
() {
client.
enterLocalPassiveMode();
}
public void enterLocalActiveMode
() {
client.
enterLocalActiveMode();
}
public boolean storeFile
(1.5.0/docs/api/java/lang/String.html">String remote,
5+0%2Fdocs%2Fapi+InputStream">InputStream local
) throws 1.5.0/docs/api/java/io/IOException.html">IOException {
try{
tries++
;
boolean b = client.
storeFile(remote, local
);
tries =
0;
return b
;
}
catch(1.5.0/docs/api/java/io/IOException.html">IOException e
)
{
if(tries
> restartTimes
)
{
tries =
0;
client = server.
getClient();
client.
setDataTimeout(TIMEOUT_FILES
);
client.
enterLocalActiveMode();
logger.
error("Restart exceed maximum restart times of " + restartTimes
);
throw e
;
}
else
{
client = server.
getClient();
client.
setDataTimeout(TIMEOUT_FILES
);
client.
enterLocalActiveMode();
logger.
warn("FTP Fail will try restart " + tries +
"º connection of " + restartTimes +
" error: " + e.
toString());
return client.
storeFile(remote, local
);
}
}
}
public void close
() throws 1.5.0/docs/api/java/io/IOException.html">IOException {
client.
quit();
client.
disconnect();
}
public void reconnect
(boolean recoverWorkingDirectory
) throws 1.5.0/docs/api/java/io/IOException.html">IOException
{
close
();
client = server.
getClient();
if(recoverWorkingDirectory
)
client.
changeWorkingDirectory(lastWorkingDirectory
);
client.
enterLocalActiveMode();
}
public boolean logout
() throws 1.5.0/docs/api/java/io/IOException.html">IOException {
return client.
logout();
}
public boolean abort
() throws 1.5.0/docs/api/java/io/IOException.html">IOException {
return client.
abort();
}
public 1.5.0/docs/api/java/lang/String.html">String[] listNames
() throws 1.5.0/docs/api/java/io/IOException.html">IOException {
try{
tries++
;
1.5.0/docs/api/java/lang/String.html">String[] b = client.
listNames();
tries =
0;
return b
;
}
catch(1.5.0/docs/api/java/io/IOException.html">IOException e
)
{
if(tries
> restartTimes
)
{
tries =
0;
client = server.
getClient();
client.
setDataTimeout(TIMEOUT_FILES
);
client.
changeWorkingDirectory(lastWorkingDirectory
);
client.
enterLocalActiveMode();
logger.
error("Restart exceed maximum restart times of " + restartTimes
);
throw e
;
}
else
{
client = server.
getClient();
client.
setDataTimeout(TIMEOUT_FILES
);
client.
changeWorkingDirectory(lastWorkingDirectory
);
client.
enterLocalActiveMode();
logger.
warn("FTP Fail will try restart " + tries +
"º connection of " + restartTimes +
" error: " + e.
toString());
return client.
listNames();
}
}
}
public FTPFile
[] listFiles
() throws 1.5.0/docs/api/java/io/IOException.html">IOException {
try{
tries++
;
FTPFile
[] b = client.
listFiles();
tries =
0;
return b
;
}
catch(1.5.0/docs/api/java/io/IOException.html">IOException e
)
{
if(tries
> restartTimes
)
{
tries =
0;
client = server.
getClient();
client.
setDataTimeout(TIMEOUT_FILES
);
client.
changeWorkingDirectory(lastWorkingDirectory
);
client.
enterLocalActiveMode();
logger.
error("Restart exceed maximum restart times of " + restartTimes
);
throw e
;
}
else
{
client = server.
getClient();
client.
setDataTimeout(TIMEOUT_FILES
);
client.
changeWorkingDirectory(lastWorkingDirectory
);
client.
enterLocalActiveMode();
logger.
warn("FTP Fail will try restart " + tries +
"º connection of " + restartTimes +
" error: " + e.
toString());
return client.
listFiles();
}
}
}
/**Metodo que nao manda Escepção em caso de timeout da operação
* este metodo não é seguro pode estar em disconnect e nao deteta lendo 0 ficheiros sem dar erro*/
public FTPFile
[] listFiles
(1.5.0/docs/api/java/lang/String.html">String pathname
) throws 1.5.0/docs/api/java/io/IOException.html">IOException {
try{
tries++
;
FTPFile
[] b = client.
listFiles(pathname
);
if(!client.
isConnected())
throw new 1.5.0/docs/api/java/io/IOException.html">IOException("Client disconnected guessed by BACO");
tries =
0;
return b
;
}
catch(1.5.0/docs/api/java/io/IOException.html">IOException e
)
{
if(tries
> restartTimes
)
{
tries =
0;
client = server.
getClient();
client.
setDataTimeout(TIMEOUT_FILES
);
client.
changeWorkingDirectory(lastWorkingDirectory
);
client.
enterLocalActiveMode();
logger.
error("Restart exceed maximum restart times of " + restartTimes
);
throw e
;
}
else
{
client = server.
getClient();
client.
setDataTimeout(TIMEOUT_FILES
);
client.
changeWorkingDirectory(lastWorkingDirectory
);
client.
enterLocalActiveMode();
logger.
warn("FTP Fail will try restart " + tries +
"º connection of " + restartTimes +
" error: " + e.
toString());
return client.
listFiles(pathname
);
}
}
}
public FtpIsolatedInputStream retrieveAbsoluteFileStream
(1.5.0/docs/api/java/lang/String.html">String pathFile
) throws 1.5.0/docs/api/java/io/IOException.html">IOException
{
//String urlStr = "ftp://" + server.getUsername() + ":" + server.getPassword() + "@" + server.getHost() + "/" + URIUtil.encodePath(pathFile,"ISO-8859-1");
logger.
info("Retrieving: " + pathFile
);
//URL url = new URL(urlStr);
//return url.openStream();
return new FtpIsolatedInputStream
(pathFile,
true);
}
public FtpIsolatedInputStream retrieveFileStreamInCurrentFolder
(1.5.0/docs/api/java/lang/String.html">String name
) throws 1.5.0/docs/api/java/io/IOException.html">IOException
{
//FTPClient client = server.getClient();
//client.setDataTimeout(TIMEOUT_FILES);
//client.changeWorkingDirectory(lastWorkingDirectory);
logger.
info("Retrieving: " + name
);
return new FtpIsolatedInputStream
(name,
false);
}
public void setBufferSize
(int bufferSize
) {
client.
setBufferSize(bufferSize
);
}
public int getBufferSize
() {
return client.
getBufferSize();
}
public void setFileType
(int fileType
) throws 1.5.0/docs/api/java/io/IOException.html">IOException {
client.
setFileType(fileType
);
}
public void setDefaultFileType
() throws 1.5.0/docs/api/java/io/IOException.html">IOException {
client.
setFileType(FTP.
ASCII_FILE_TYPE);
}
public class FtpIsolatedInputStream
{
FTPClient clientIsolated
;
5+0%2Fdocs%2Fapi+InputStream">InputStream inputStream
;
public FtpIsolatedInputStream
(1.5.0/docs/api/java/lang/String.html">String file,
boolean absolute
) throws 1.5.0/docs/api/java/io/IOException.html">IOException
{
clientIsolated = server.
getClient();
clientIsolated.
setDataTimeout(TIMEOUT_FILES
);
clientIsolated.
setFileType(FTP.
BINARY_FILE_TYPE);
if(!absolute
)
{
clientIsolated.
changeWorkingDirectory(lastWorkingDirectory
);
}
inputStream = clientIsolated.
retrieveFileStream(file
);
}
public 5+0%2Fdocs%2Fapi+InputStream">InputStream getInputStream
() {
return inputStream
;
}
public void close
(){
try{
if(clientIsolated.
isConnected())
{
clientIsolated.
quit();
clientIsolated.
disconnect();
}
else
{
1.5.0/docs/api/java/lang/System.html">System.
out.
println("Client isolated already disconnect");
}
}catch(1.5.0/docs/api/java/lang/Throwable.html">Throwable e
)
{
logger.
error(e,e
);
}
}
}
}
public static final int FTP_DATA_STORE_TIMEOUT_SECONDS = Globals.
FTP_DATA_STORE_TIMEOUT_SECONDS;
public class MyFTPClient
extends FTPClient
implements 1.5.0/docs/api/java/lang/Runnable.html">Runnable
{
1.5.0/docs/api/java/lang/String.html">String remote =
"";
5+0%2Fdocs%2Fapi+InputStream">InputStream local =
null;
boolean storeResult =
false;
public void run
() {
try {
storeResult =
super.
storeFile(remote, local
);
} catch (1.5.0/docs/api/java/io/IOException.html">IOException e
) {
logger.
error(e,e
);
}
}
@
1.5.0/docs/api/java/lang/Override.html">Override
public boolean storeFile
(1.5.0/docs/api/java/lang/String.html">String remote,
5+0%2Fdocs%2Fapi+InputStream">InputStream local
) throws 1.5.0/docs/api/java/io/IOException.html">IOException
{
logger.
info("FTP store Timeout protection of " + FTP_DATA_STORE_TIMEOUT_SECONDS +
" seconds");
this.
remote = remote
;
this.
local = local
;
1.5.0/docs/api/java/lang/Thread.html">Thread t =
new 1.5.0/docs/api/java/lang/Thread.html">Thread(this);
t.
start();
try {
for(int i=
0;i
<FTP_DATA_STORE_TIMEOUT_SECONDS
;i++
)
{
1.5.0/docs/api/java/lang/Thread.html">Thread.
sleep(1000
);
if(!t.
isAlive())
{
break;
}
}
if(t.
isAlive())
{
logger.
info("Timeout expired will interrupt");
t.
interrupt();
return false;
}
} catch (1.5.0/docs/api/java/lang/InterruptedException.html">InterruptedException e
) {
logger.
error(e,e
);
}
return storeResult
;
}
}
}