/*
* Copyright (C) 2009 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.exoplatform.services.ftp.command;
import org.apache.commons.chain.Context;
import org.exoplatform.services.ftp.FtpConst;
import org.exoplatform.services.ftp.FtpContext;
import org.exoplatform.services.ftp.client.FtpClientSession;
import org.exoplatform.services.ftp.listcode.FtpFileInfo;
import org.exoplatform.services.ftp.listcode.FtpFileInfoImpl;
import org.exoplatform.services.ftp.listcode.FtpSystemCoder;
import org.exoplatform.services.ftp.listcode.FtpSystemCoderManager;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import java.io.IOException;
import java.util.ArrayList;
import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
/**
* Created by The eXo Platform SAS Author : Vitaly Guly <gavrik-vetal@ukr.net/mail.ru>
*
* @version $Id: $
*/
public abstract class FtpCommandImpl implements FtpCommand
{
private static Log log = ExoLogger.getLogger(FtpConst.FTP_PREFIX + "FtpCommandImpl");
protected boolean isNeedLogin = true;
protected String commandName = "";
public ThreadLocal<FtpClientSession> localClientSession = new ThreadLocal<FtpClientSession>();
public void reply(String replyString) throws IOException
{
clientSession().reply(replyString);
}
public boolean execute(Context context) throws Exception
{
localClientSession.set(((FtpContext)context).getFtpClientSession());
if (isNeedLogin)
{
if (!clientSession().isLogged())
{
reply(FtpConst.Replyes.REPLY_530);
return false;
}
}
String[] params = ((FtpContext)context).getParams();
run(params);
String cmdParams = null;
if (params.length > 1)
{
cmdParams = params[1];
}
clientSession().setPrevCommand(commandName);
clientSession().setPrevParams(cmdParams);
return true;
}
public abstract void run(String[] params) throws Exception;
public FtpClientSession clientSession()
{
return localClientSession.get();
}
public ArrayList<FtpFileInfo> getFileList(String resPath)
{
ArrayList<FtpFileInfo> files = new ArrayList<FtpFileInfo>();
FtpFileInfo fi = new FtpFileInfoImpl();
fi.setName(".");
files.add(fi);
fi = new FtpFileInfoImpl();
fi.setName("..");
files.add(fi);
ArrayList<String> newPath = clientSession().getFullPath(resPath);
try
{
if (newPath.size() == 0)
{
String[] workspaces = clientSession().getFtpServer().getRepository().getWorkspaceNames();
for (int i = 0; i < workspaces.length; i++)
{
FtpFileInfo fileInfo = new FtpFileInfoImpl();
fileInfo.setName(workspaces[i]);
files.add(fileInfo);
}
}
else
{
String repoPath = clientSession().getRepoPath(newPath);
Session curSession = clientSession().getSession(newPath.get(0));
Node parentNode = (Node)curSession.getItem(repoPath);
if (parentNode.isNodeType(FtpConst.NodeTypes.NT_FILE))
{
files.clear();
FtpFileInfoImpl fileInfo = new FtpFileInfoImpl();
fileInfo.initFromNode(parentNode);
files.add(fileInfo);
}
else
{
NodeIterator nodeIter = parentNode.getNodes();
while (nodeIter.hasNext())
{
Node curNode = nodeIter.nextNode();
FtpFileInfoImpl fileInfo = new FtpFileInfoImpl();
fileInfo.initFromNode(curNode);
files.add(fileInfo);
}
}
}
}
catch (RepositoryException rexc)
{
return null;
}
catch (Exception exc)
{
log.info("Unhandled exception. " + exc.getMessage(), exc);
return null;
}
return files;
}
public void removeResource(String resName) throws IOException
{
try
{
ArrayList<String> newPath = clientSession().getFullPath(resName);
Session curSession = clientSession().getSession(newPath.get(0));
String repoPath = clientSession().getRepoPath(newPath);
Node parentNode = (Node)curSession.getItem(repoPath);
parentNode.remove();
curSession.save();
reply(String.format(FtpConst.Replyes.REPLY_250, commandName));
return;
}
catch (PathNotFoundException pexc)
{
}
catch (NoSuchWorkspaceException wexc)
{
}
catch (Exception exc)
{
log.info("Unhandled exception. " + exc.getMessage(), exc);
}
reply(String.format(FtpConst.Replyes.REPLY_550, resName));
}
public void SendFileList(String[] params) throws IOException
{
String path = "";
if (params.length > 1)
{
path = params[1];
if (path.startsWith("-la"))
{
path = path.substring(3);
}
while (path.startsWith(" "))
{
path = path.substring(1);
}
}
ArrayList<FtpFileInfo> items = getFileList(path);
if (items == null)
{
reply(String.format(FtpConst.Replyes.REPLY_450, path));
return;
}
if (clientSession().getDataTransiver() == null)
{
reply(FtpConst.Replyes.REPLY_425);
return;
}
try
{
while (!clientSession().getDataTransiver().isConnected())
{
Thread.sleep(100);
}
}
catch (Exception exc)
{
log.info("Unhandled exception. " + exc.getMessage(), exc);
}
FtpSystemCoder systemCoder =
FtpSystemCoderManager.getSystemCoder(clientSession().getFtpServer().getConfiguration());
reply(FtpConst.Replyes.REPLY_125);
boolean isNeedExtendedInfo = (commandName.equals(FtpConst.Commands.CMD_LIST)) ? true : false;
try
{
String encoding = clientSession().getFtpServer().getConfiguration().getClientSideEncoding();
for (int i = 0; i < items.size(); i++)
{
FtpFileInfo curFileInfo = items.get(i);
String curSerialized = "";
if (isNeedExtendedInfo)
{
curSerialized = systemCoder.serializeFileInfo(curFileInfo);
}
else
{
curSerialized = curFileInfo.getName();
}
byte[] data = curSerialized.getBytes(encoding);
clientSession().getDataTransiver().getOutputStream().write(data);
clientSession().getDataTransiver().getOutputStream().write("\r\n".getBytes());
}
clientSession().closeDataTransiver();
}
catch (Exception exc)
{
log.info("Unhandled exception. " + exc.getMessage());
log.info("Data transmit failed.");
}
reply(FtpConst.Replyes.REPLY_226);
}
}