Package railo.runtime.tag

Source Code of railo.runtime.tag.Ftp

package railo.runtime.tag;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import railo.commons.io.IOUtil;
import railo.commons.io.res.Resource;
import railo.commons.io.res.util.ResourceUtil;
import railo.runtime.exp.ApplicationException;
import railo.runtime.exp.PageException;
import railo.runtime.ext.tag.TagImpl;
import railo.runtime.net.ftp.FTPConnection;
import railo.runtime.net.ftp.FTPConnectionImpl;
import railo.runtime.net.ftp.FTPConstant;
import railo.runtime.net.ftp.FTPPath;
import railo.runtime.net.ftp.FTPPool;
import railo.runtime.op.Caster;
import railo.runtime.type.Collection.Key;
import railo.runtime.type.KeyImpl;
import railo.runtime.type.QueryImpl;
import railo.runtime.type.Struct;
import railo.runtime.type.StructImpl;
import railo.runtime.type.dt.DateTimeImpl;
import railo.runtime.type.util.ListUtil;

/**
*
* Lets users implement File Transfer Protocol (FTP) operations.
*
*
*
**/
public final class Ftp extends TagImpl {
   
    private static final String ASCCI_EXT_LIST="txt;htm;html;cfm;cfml;shtm;shtml;css;asp;asa";

  private static final Key SUCCEEDED = KeyImpl.intern("succeeded");
  private static final Key ERROR_CODE = KeyImpl.intern("errorCode");
  private static final Key ERROR_TEXT = KeyImpl.intern("errorText");
  private static final Key RETURN_VALUE = KeyImpl.intern("returnValue");
  private static final Key CFFTP = KeyImpl.intern("cfftp");
  /*private static final Key  = KeyImpl.getInstance();
  private static final Key  = KeyImpl.getInstance();
  private static final Key  = KeyImpl.getInstance();
  private static final Key  = KeyImpl.getInstance();
  private static final Key  = KeyImpl.getInstance();
  private static final Key  = KeyImpl.getInstance();*/
 
    private FTPPool pool;

  private String action;
  private String username;
  private String password;
  private String server;
  private int timeout=30;
  private int port=21;
  private String connectionName;
  private int retrycount=1;
  private int count=0;
  private boolean stoponerror=true;
  private boolean passive;
  private String name;
  private String directory;
  private String ASCIIExtensionList=ASCCI_EXT_LIST;
  private short transferMode=FTPConstant.TRANSFER_MODE_AUTO;
  private String remotefile;
  private String localfile;
  private boolean failifexists=true;
  private String existing;
  private String _new;
    private String item;
    private String result;

    private String proxyserver;
  private int proxyport=80;
  private String proxyuser;
  private String proxypassword="";
 
  //private Struct cfftp=new StructImpl();

    @Override
  public void release()  {
    super.release();
    this.pool=null;
   
    this.action=null;
    this.username=null;
    this.password=null;
    this.server=null;
    this.timeout=30;
    this.port=21;
    this.connectionName=null;
    this.proxyserver=null;
    this.proxyport=80;
    this.proxyuser=null;
    this.proxypassword="";
    this.retrycount=1;
    this.count=0;
    this.stoponerror=true;
    this.passive=false;
    this.name=null;
    this.directory=null;
    this.ASCIIExtensionList=ASCCI_EXT_LIST;
    this.transferMode=FTPConstant.TRANSFER_MODE_AUTO;
    this.remotefile=null;
    this.localfile=null;
    this.failifexists=true;
    this.existing=null;
    this._new=null;
    this.item=null;
        this.result=null;
  }

  /**
   * sets the attribute action
   * @param action
   */
  public void setAction(String action) {
    this.action=action.trim().toLowerCase();
  }

  @Override
  public int doStartTag()  {
    return SKIP_BODY;
  }

  @Override
  public int doEndTag() throws PageException  {
      pool=pageContext.getFTPPool();
      FTPClient client = null;
     
     
      // retries
      do {
        try {
          if(action.equals("open")) client=actionOpen();
          else if(action.equals("close")) client=actionClose();
          else if(action.equals("changedir")) client=actionChangeDir();
          else if(action.equals("createdir")) client=actionCreateDir();
          else if(action.equals("listdir")) client=actionListDir();
          else if(action.equals("removedir")) client=actionRemoveDir();
          else if(action.equals("getfile")) client=actionGetFile();
          else if(action.equals("putfile")) client=actionPutFile();
          else if(action.equals("rename")) client=actionRename();
          else if(action.equals("remove")) client=actionRemove();
          else if(action.equals("getcurrentdir")) client=actionGetCurrentDir();
          else if(action.equals("getcurrenturl")) client=actionGetCurrentURL();
          else if(action.equals("existsdir")) client=actionExistsDir();
          else if(action.equals("existsfile")) client=actionExistsFile();
          else if(action.equals("exists")) client=actionExists();
          //else if(action.equals("copy")) client=actionCopy();
         
          
          else throw new ApplicationException(
                  "attribute action has an invalid value ["+action+"]",
                  "valid values are [open,close,listDir,createDir,removeDir,changeDir,getCurrentDir," +
                  "getCurrentURL,existsFile,existsDir,exists,getFile,putFile,rename,remove]");

        }
        catch(IOException ioe) {
            if(count++<retrycount)continue;
            throw Caster.toPageException(ioe);
        }
   
        if(client==null || !checkCompletion(client))break;
      }while(true);
     
    return EVAL_PAGE;
  }

    /**
     * check if a file or directory exists
     * @return FTPCLient
     * @throws PageException
     * @throws IOException
     */
    private FTPClient actionExists() throws PageException, IOException {
        required("item",item);

        FTPClient client = getClient();
        FTPFile file=existsFile(client,item,false);
        Struct cfftp = writeCfftp(client);

        cfftp.setEL(RETURN_VALUE,Caster.toBoolean(file!=null));
        cfftp.setEL(SUCCEEDED,Boolean.TRUE);
       
        return client;
    }

    /**
     * check if a directory exists or not
     * @return FTPCLient
     * @throws PageException
     * @throws IOException
     */
    private FTPClient actionExistsDir() throws PageException, IOException {
      required("directory",directory);

      FTPClient client = getClient();
      boolean res = existsDir(client,directory);
        Struct cfftp = writeCfftp(client);

        cfftp.setEL(RETURN_VALUE,Caster.toBoolean(res));
        cfftp.setEL(SUCCEEDED,Boolean.TRUE);
       
        stoponerror=false;
        return client;
     
      /*FTPClient client = pool.get(createConnection());
        FTPFile file=existsFile(client,directory);
        Struct cfftp = writeCfftp(client);

        cfftp.setEL(RETURN_VALUE,Caster.toBoolean(file!=null && file.isDirectory()));
        cfftp.setEL(SUCCEEDED,Boolean.TRUE);
       
        stoponerror=false;
        return client;*/
    }

    /**
     * check if a file exists or not
     * @return FTPCLient
     * @throws IOException
     * @throws PageException
     */
    private FTPClient actionExistsFile() throws PageException, IOException {
        required("remotefile",remotefile);

        FTPClient client = getClient();
        FTPFile file=existsFile(client,remotefile,true);
       
        Struct cfftp = writeCfftp(client);

        cfftp.setEL(RETURN_VALUE,Caster.toBoolean(file!=null && file.isFile()));
        cfftp.setEL(SUCCEEDED,Boolean.TRUE);
       
        stoponerror=false;
        return client;
   
   
   
    }

   
   
 
    /* *
     * check if file or directory exists if it exists return FTPFile otherwise null
     * @param client
     * @param strPath
     * @return FTPFile or null
     * @throws IOException
     * @throws PageException
     * /
    private FTPFile exists(FTPClient client, String strPath) throws PageException, IOException {
        strPath=strPath.trim();
       
        // get parent path
        FTPPath path=new FTPPath(client.printWorkingDirectory(),strPath);
        String name=path.getName();
        print.out("path:"+name);
       
        // when directory
        FTPFile[] files=null;
        try {
            files = client.listFiles(path.getPath());
        } catch (IOException e) {}
       
        if(files!=null) {
            for(int i=0;i<files.length;i++) {
                if(files[i].getName().equalsIgnoreCase(name)) {
                    return files[i];
                }
            }
           
        }
        return null;
    }*/
   
    private FTPFile existsFile(FTPClient client, String strPath,boolean isFile) throws PageException, IOException {
        strPath=strPath.trim();
        if(strPath.equals("/")) {
            FTPFile file= new FTPFile();
            file.setName("/");
            file.setType(FTPFile.DIRECTORY_TYPE);
            return file;
        }
       
        // get parent path
        FTPPath path=new FTPPath(client.printWorkingDirectory(),strPath);
        String p=path.getPath();
        String n=path.getName();

        strPath=p;
        if("//".equals(p))strPath="/";
        if(isFile)strPath+=n;
       
        // when directory
        FTPFile[] files=null;
        try {
      files = client.listFiles(strPath);
    } catch (IOException e) {}
       
        if(files!=null) {
            for(int i=0;i<files.length;i++) {
              if(files[i].getName().equalsIgnoreCase(n)) {
                    return files[i];
                }
            }
           
        }
        return null;
    }
   
    private boolean existsDir(FTPClient client, String strPath) throws PageException, IOException {
        strPath=strPath.trim();
       
        // get parent path
        FTPPath path=new FTPPath(client.printWorkingDirectory(),strPath);
        String p=path.getPath();
        String n=path.getName();

        strPath=p+""+n;
        if("//".equals(p))strPath="/"+n;
        if(!strPath.endsWith("/"))strPath+="/";
       
        String pwd = client.printWorkingDirectory();
        boolean rc = client.changeWorkingDirectory(directory);
        client.changeWorkingDirectory(pwd);
        return rc;
    }

    /**
     * removes a file on the server
     * @return FTPCLient
     * @throws IOException
     * @throws PageException
     */
    private FTPClient actionRemove() throws IOException, PageException {
        required("item",item);
        FTPClient client = getClient();
        client.deleteFile(item);
        writeCfftp(client);
       
        return client;
    }

    /**
     * rename a file on the server
     * @return FTPCLient
     * @throws PageException
     * @throws IOException
     */
    private FTPClient actionRename() throws PageException, IOException {
        required("existing",existing);
        required("new",_new);
       
        FTPClient client = getClient();
    client.rename(existing,_new);
        writeCfftp(client);
       
        return client;
    }

    /**
     * copy a local file to server
     * @return FTPClient
     * @throws IOException
     * @throws PageException
     */
    private FTPClient actionPutFile() throws IOException, PageException  {
        required("remotefile",remotefile);
        required("localfile",localfile);
       
    FTPClient client = getClient();
    Resource local=ResourceUtil.toResourceExisting(pageContext ,localfile);//new File(localfile);
    //  if(failifexists && local.exists()) throw new ApplicationException("File ["+local+"] already exist, if you want to overwrite, set attribute failIfExists to false");
    InputStream is=null;
   
        try {
          is=IOUtil.toBufferedInputStream(local.getInputStream());
          client.setFileType(getType(local));
            client.storeFile(remotefile,is);
        }
        finally {
          IOUtil.closeEL(is);
        }
        writeCfftp(client);
       
        return client;
    }

    /**
     * gets a file from server and copy it local
     * @return FTPCLient
     * @throws PageException
     * @throws IOException
     */
    private FTPClient actionGetFile() throws PageException, IOException {
        required("remotefile",remotefile);
        required("localfile",localfile);
   
       
    FTPClient client = getClient();
    Resource local=ResourceUtil.toResourceExistingParent(pageContext ,localfile);//new File(localfile);
        pageContext.getConfig().getSecurityManager().checkFileLocation(local);
    if(failifexists && local.exists()) throw new ApplicationException("File ["+local+"] already exist, if you want to overwrite, set attribute failIfExists to false");
    OutputStream fos=null;
        client.setFileType(getType(local));
        try {
          fos=IOUtil.toBufferedOutputStream(local.getOutputStream());
            client.retrieveFile(remotefile,fos);
        }
        finally {
          IOUtil.closeEL(fos);
        }
        writeCfftp(client);
       
        return client;
    }

    /**
     * get url of the working directory
     * @return FTPCLient
     * @throws IOException
     * @throws PageException
     */
    private FTPClient actionGetCurrentURL() throws PageException, IOException {
        FTPClient client = getClient();
        String pwd=client.printWorkingDirectory();
        Struct cfftp = writeCfftp(client);
        cfftp.setEL("returnValue","ftp://"+client.getRemoteAddress().getHostName()+pwd);
        return client;
    }

    /**
     * get path from the working directory
     * @return FTPCLient
     * @throws IOException
     * @throws PageException
     */
    private FTPClient actionGetCurrentDir() throws PageException, IOException {
        FTPClient client = getClient();
        String pwd=client.printWorkingDirectory();
        Struct cfftp = writeCfftp(client);
        cfftp.setEL("returnValue",pwd);
        return client;
    }

    /**
     * change working directory
     * @return FTPCLient
     * @throws IOException
     * @throws PageException
     */
    private FTPClient actionChangeDir() throws IOException, PageException {
        required("directory",directory);

        FTPClient client = getClient();
        client.changeWorkingDirectory(directory);
        writeCfftp(client);
        return client;
    }

    private FTPClient getClient() throws PageException, IOException {
      return pool.get(_createConnection());
  }

  /**
     * removes a remote directory on server
     * @return FTPCLient
     * @throws IOException
     * @throws PageException
     */
    private FTPClient actionRemoveDir() throws IOException, PageException {
        required("directory",directory);

        FTPClient client = getClient();
        client.removeDirectory(directory);
        writeCfftp(client);
        return client;
    }

    /**
     * create a remote directory
     * @return FTPCLient
     * @throws IOException
     * @throws PageException
     */
    private FTPClient actionCreateDir() throws IOException, PageException {
        required("directory",directory);

        FTPClient client = getClient();
        client.makeDirectory(directory);
        writeCfftp(client);
        return client;
    }

    /**
     * List data of a ftp connection
     * @return FTPCLient
     * @throws PageException
     * @throws IOException
     */
    private FTPClient actionListDir() throws PageException, IOException {
        required("name",name);
        required("directory",directory);
       
        FTPClient client = getClient();
        FTPFile[] files = client.listFiles(directory);
        if(files==null)files=new FTPFile[0];
       
        String[] cols = new String[]{"attributes","isdirectory","lastmodified","length","mode","name",
                "path","url","type","raw"};
        String[] types = new String[]{"VARCHAR","BOOLEAN","DATE","DOUBLE","VARCHAR","VARCHAR",
                "VARCHAR","VARCHAR","VARCHAR","VARCHAR"};
       
        railo.runtime.type.Query query=new QueryImpl(cols,types,0,"query");
       
        // translate directory path for display
        if(directory.length()==0)directory="/";
        else if(directory.startsWith("./"))directory=directory.substring(1);
        else if(directory.charAt(0)!='/')directory='/'+directory;
        if(directory.charAt(directory.length()-1)!='/')directory=directory+'/';
               
        pageContext.setVariable(name,query);
        int row=0;
        for(int i=0;i<files.length;i++) {
            FTPFile file = files[i];
            if(file.getName().equals(".") || file.getName().equals("..")) continue;
            query.addRow();
            row++;
            query.setAt("attributes",row,"");
            query.setAt("isdirectory",row,Caster.toBoolean(file.isDirectory()));
            query.setAt("lastmodified",row,new DateTimeImpl(file.getTimestamp()));
            query.setAt("length",row,Caster.toDouble(file.getSize()));
            query.setAt("mode",row,FTPConstant.getPermissionASInteger(file));
            query.setAt("type",row,FTPConstant.getTypeAsString(file.getType()));
            //query.setAt("permission",row,FTPConstant.getPermissionASInteger(file));
            query.setAt("raw",row,file.getRawListing());
            query.setAt("name",row,file.getName());
            query.setAt("path",row,directory+file.getName());
            query.setAt("url",row,"ftp://"+client.getRemoteAddress().getHostName()+""+directory+file.getName());
        }
        writeCfftp(client);
        return client;
    }

    /** 
     * Opens a FTP Connection
     * @return FTPCLinet
     * @throws IOException
     * @throws PageException
     */
    private FTPClient actionOpen() throws IOException, PageException {
        required("server",server);
        required("username",username);
        required("password",password);
       
       
        FTPClient client = getClient();
        writeCfftp(client);
        return client;
    }

    /**
     * close a existing ftp connection
     * @return FTPCLient
     * @throws PageException
     */
    private FTPClient actionClose() throws PageException {
        FTPConnection conn = _createConnection();
        FTPClient client = pool.remove(conn);
       
        Struct cfftp = writeCfftp(client);
        cfftp.setEL("succeeded",Caster.toBoolean(client!=null));
        return client;
    }

  /**
   * throw a error if the value is empty (null)
     * @param attributeName
     * @param atttributValue
   * @throws ApplicationException
     */
    private void required(String attributeName, String atttributValue) throws ApplicationException {
        if(atttributValue==null)
            throw new ApplicationException(
                    "invalid attribute constelation for the tag ftp",
                    "attribute ["+attributeName+"] is required, if action is ["+action+"]");
    }

    /**
     * writes cfftp variable
     * @param client
     * @return FTPCLient
     * @throws PageException
     */
    private Struct writeCfftp(FTPClient client) throws PageException  {
        Struct cfftp=new StructImpl();
        if(result==null)pageContext.variablesScope().setEL(CFFTP,cfftp);
        else pageContext.setVariable(result,cfftp);
        if(client==null) {
            cfftp.setEL(SUCCEEDED,Boolean.FALSE);
            cfftp.setEL(ERROR_CODE,new Double(-1));
            cfftp.setEL(ERROR_TEXT,"");
            cfftp.setEL(RETURN_VALUE,"");
            return cfftp;
        }
        int repCode = client.getReplyCode();
        String repStr=client.getReplyString();
        cfftp.setEL(ERROR_CODE,new Double(repCode));
        cfftp.setEL(ERROR_TEXT,repStr);
       
        cfftp.setEL(SUCCEEDED,Caster.toBoolean(FTPReply.isPositiveCompletion(repCode)));
        cfftp.setEL(RETURN_VALUE,repStr);
        return cfftp;
    }

    /**
     * check completion status of the client
     * @param client
     * @return FTPCLient
     * @throws ApplicationException
     */
    private boolean checkCompletion(FTPClient client) throws ApplicationException {
        boolean  isPositiveCompletion=FTPReply.isPositiveCompletion(client.getReplyCode());
        if(isPositiveCompletion) return false;
        if(count++<retrycount) return true;
        if(stoponerror){
          throw new railo.runtime.exp.FTPException(action,client);
        }
       
        return false;
    }
   
    /**
     * get FTP. ... _FILE_TYPE
     * @param file
     * @return type
     */
    private int getType(Resource file) {
        if(transferMode==FTPConstant.TRANSFER_MODE_BINARY) return FTP.BINARY_FILE_TYPE;
        else if(transferMode==FTPConstant.TRANSFER_MODE_ASCCI) return FTP.ASCII_FILE_TYPE;
        else {
            String ext=ResourceUtil.getExtension(file,null);
            if(ext==null || ListUtil.listContainsNoCase(ASCIIExtensionList,ext,";")==-1)
                return FTP.BINARY_FILE_TYPE;
              return FTP.ASCII_FILE_TYPE;
        }
    }
   
    /**
     * @return return a new FTP Connection Object
     */
    private FTPConnection _createConnection() {
     
        return new FTPConnectionImpl(connectionName,server,username,password,port,timeout,transferMode,passive,proxyserver,proxyport,proxyuser,proxypassword);
    }
   
    /**
     * @param password The password to set.
     */
    public void setPassword(String password) {
        this.password = password;
    }
    /**
     * @param username The username to set.
     */
    public void setUsername(String username) {
        this.username = username;
    }
    /**
     * @param server The server to set.
     */
    public void setServer(String server) {
        this.server = server;
    }
    /**
     * @param timeout The timeout to set.
     */
    public void setTimeout(double timeout) {
        this.timeout = (int)timeout;
    }
    /**
     * @param port The port to set.
     */
    public void setPort(double port) {
        this.port = (int)port;
    }
    /**
     * @param connection The connection to set.
     */
    public void setConnection(String connection) {
        this.connectionName = connection;
    }
    /**
     * @param proxyserver The proxyserver to set.
     */
    public void setProxyserver(String proxyserver) {
        this.proxyserver = proxyserver;
    }
 
  /** set the value proxyport
  *  The port number on the proxy server from which the object is requested. Default is 80. When
  *   used with resolveURL, the URLs of retrieved documents that specify a port number are automatically
  *   resolved to preserve links in the retrieved document.
  * @param proxyport value to set
  **/
  public void setProxyport(double proxyport)  {
    this.proxyport=(int)proxyport;
  }

  /** set the value username
  *  When required by a proxy server, a valid username.
  * @param proxyuser value to set
  **/
  public void setProxyuser(String proxyuser)  {
    this.proxyuser=proxyuser;
  }

   
  /** set the value password
  *  When required by a proxy server, a valid password.
  * @param proxypassword value to set
  **/
  public void setProxypassword(String proxypassword)  {
    this.proxypassword=proxypassword;
  }

   
   
    /**
     * @param retrycount The retrycount to set.
     */
    public void setRetrycount(double retrycount) {
        this.retrycount = (int)retrycount;
    }
    /**
     * @param stoponerror The stoponerror to set.
     */
    public void setStoponerror(boolean stoponerror) {
        this.stoponerror = stoponerror;
    }
    /**
     * @param passive The passive to set.
     */
    public void setPassive(boolean passive) {
        this.passive = passive;
    }
    /**
     * @param directory The directory to set.
     */
    public void setDirectory(String directory) {
        this.directory = directory;
    }
    /**
     * @param name The name to set.
     */
    public void setName(String name) {
        this.name = name;
    }
    /**
     * @param extensionList The aSCIIExtensionList to set.
     */
    public void setAsciiextensionlist(String extensionList) {
        ASCIIExtensionList = extensionList.toLowerCase().trim();
    }
    /**
     * @param transferMode The transferMode to set.
     */
    public void setTransfermode(String transferMode) {
        transferMode=transferMode.toLowerCase().trim();
        if(transferMode.equals("binary"))this.transferMode=FTPConstant.TRANSFER_MODE_BINARY;
        else if(transferMode.equals("ascci"))this.transferMode=FTPConstant.TRANSFER_MODE_ASCCI;
        else this.transferMode=FTPConstant.TRANSFER_MODE_AUTO;
    }
   
    /**
     * @param localfile The localfile to set.
     */
    public void setLocalfile(String localfile) {
        this.localfile = localfile;
    }
    /**
     * @param remotefile The remotefile to set.
     */
    public void setRemotefile(String remotefile) {
        this.remotefile = remotefile;
    }
    /**
     * @param failifexists The failifexists to set.
     */
    public void setFailifexists(boolean failifexists) {
        this.failifexists = failifexists;
    }
    /**
     * @param _new The _new to set.
     */
    public void setNew(String _new) {
        this._new = _new;
    }
    /**
     * @param existing The existing to set.
     */
    public void setExisting(String existing) {
        this.existing = existing;
    }
    /**
     * @param item The item to set.
     */
    public void setItem(String item) {
        this.item = item;
    }

    /**
     * @param result The result to set.
     */
    public void setResult(String result) {
        this.result = result;
    }
}
TOP

Related Classes of railo.runtime.tag.Ftp

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.