com.panet.imeta.job.entries.getpop.JobEntryGetPOP.java Source code

Java tutorial

Introduction

Here is the source code for com.panet.imeta.job.entries.getpop.JobEntryGetPOP.java

Source

/* Copyright (c) 2007 Pentaho Corporation.  All rights reserved. 
 * This software was developed by Pentaho Corporation and is provided under the terms 
 * of the GNU Lesser General Public License, Version 2.1. You may not use 
 * this file except in compliance with the license. If you need a copy of the license, 
 * please go to http://www.gnu.org/licenses/lgpl-2.1.txt. The Original Code is Pentaho 
 * Data Integration.  The Initial Developer is Pentaho Corporation.
 *
 * Software distributed under the GNU Lesser Public License is distributed on an "AS IS" 
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or  implied. Please refer to 
 * the license for the specific language governing your rights and limitations.*/

package com.panet.imeta.job.entries.getpop;

import static com.panet.imeta.job.entry.validator.AbstractFileValidator.putVariableSpace;
import static com.panet.imeta.job.entry.validator.AndValidator.putValidators;
import static com.panet.imeta.job.entry.validator.JobEntryValidatorUtils.andValidator;
import static com.panet.imeta.job.entry.validator.JobEntryValidatorUtils.fileExistsValidator;
import static com.panet.imeta.job.entry.validator.JobEntryValidatorUtils.integerValidator;
import static com.panet.imeta.job.entry.validator.JobEntryValidatorUtils.notBlankValidator;
import static com.panet.imeta.job.entry.validator.JobEntryValidatorUtils.notNullValidator;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.mail.Folder;
import javax.mail.Header;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.URLName;
import javax.mail.internet.MimeUtility;

import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileType;
import org.w3c.dom.Node;

import com.panet.imeta.cluster.SlaveServer;
import com.panet.imeta.core.CheckResultInterface;
import com.panet.imeta.core.Const;
import com.panet.imeta.core.Result;
import com.panet.imeta.core.database.DatabaseMeta;
import com.panet.imeta.core.encryption.Encr;
import com.panet.imeta.core.exception.KettleDatabaseException;
import com.panet.imeta.core.exception.KettleException;
import com.panet.imeta.core.exception.KettleXMLException;
import com.panet.imeta.core.logging.LogWriter;
import com.panet.imeta.core.util.StringUtil;
import com.panet.imeta.core.vfs.KettleVFS;
import com.panet.imeta.core.xml.XMLHandler;
import com.panet.imeta.job.Job;
import com.panet.imeta.job.JobEntryType;
import com.panet.imeta.job.JobMeta;
import com.panet.imeta.job.entry.JobEntryBase;
import com.panet.imeta.job.entry.JobEntryInterface;
import com.panet.imeta.job.entry.validator.ValidatorContext;
import com.panet.imeta.repository.Repository;
import com.panet.imeta.resource.ResourceEntry;
import com.panet.imeta.resource.ResourceReference;
import com.panet.imeta.resource.ResourceEntry.ResourceType;
import com.panet.imeta.shared.SharedObjectInterface;
import com.sun.mail.pop3.POP3SSLStore;

/**
 * This defines an get pop job entry.
 *
 * @author Samatar
 * @since 01-03-2007
 *
 */

public class JobEntryGetPOP extends JobEntryBase implements Cloneable, JobEntryInterface {
    private String servername;

    private String username;

    private String password;

    private boolean usessl;

    private String sslport;

    private String outputdirectory;

    private String filenamepattern;

    private String firstmails;

    public int retrievemails;

    private boolean delete;

    public JobEntryGetPOP(String n) {
        super(n, ""); //$NON-NLS-1$
        servername = null;
        username = null;
        password = null;
        usessl = false;
        sslport = "995"; //$NON-NLS-1$
        outputdirectory = null;
        filenamepattern = null;
        retrievemails = 0;
        firstmails = null;
        delete = false;

        setID(-1L);
        setJobEntryType(JobEntryType.GET_POP);
    }

    public JobEntryGetPOP() {
        this(""); //$NON-NLS-1$
    }

    public JobEntryGetPOP(JobEntryBase jeb) {
        super(jeb);
    }

    public Object clone() {
        JobEntryGetPOP je = (JobEntryGetPOP) super.clone();
        return je;
    }

    public String getXML() {
        StringBuffer retval = new StringBuffer(200);

        retval.append(super.getXML());
        retval.append("      ").append(XMLHandler.addTagValue("servername", servername)); //$NON-NLS-1$ //$NON-NLS-2$
        retval.append("      ").append(XMLHandler.addTagValue("username", username)); //$NON-NLS-1$ //$NON-NLS-2$
        retval.append("      ") //$NON-NLS-1$
                .append(XMLHandler.addTagValue("password", Encr.encryptPasswordIfNotUsingVariables(password))); //$NON-NLS-1$
        retval.append("      ").append(XMLHandler.addTagValue("usessl", usessl)); //$NON-NLS-1$ //$NON-NLS-2$
        retval.append("      ").append(XMLHandler.addTagValue("sslport", sslport)); //$NON-NLS-1$ //$NON-NLS-2$
        retval.append("      ").append(XMLHandler.addTagValue("outputdirectory", outputdirectory)); //$NON-NLS-1$ //$NON-NLS-2$
        retval.append("      ").append(XMLHandler.addTagValue("filenamepattern", filenamepattern)); //$NON-NLS-1$ //$NON-NLS-2$
        retval.append("      ").append(XMLHandler.addTagValue("retrievemails", retrievemails)); //$NON-NLS-1$ //$NON-NLS-2$
        retval.append("      ").append(XMLHandler.addTagValue("firstmails", firstmails)); //$NON-NLS-1$ //$NON-NLS-2$
        retval.append("      ").append(XMLHandler.addTagValue("delete", delete)); //$NON-NLS-1$ //$NON-NLS-2$

        return retval.toString();
    }

    public void loadXML(Node entrynode, List<DatabaseMeta> databases, List<SlaveServer> slaveServers,
            Repository rep) throws KettleXMLException {
        try {
            super.loadXML(entrynode, databases, slaveServers);
            servername = XMLHandler.getTagValue(entrynode, "servername"); //$NON-NLS-1$
            username = XMLHandler.getTagValue(entrynode, "username"); //$NON-NLS-1$
            password = Encr.decryptPasswordOptionallyEncrypted(XMLHandler.getTagValue(entrynode, "password"));
            usessl = "Y".equalsIgnoreCase(XMLHandler.getTagValue(entrynode, "usessl")); //$NON-NLS-1$ //$NON-NLS-2$
            sslport = XMLHandler.getTagValue(entrynode, "sslport"); //$NON-NLS-1$
            outputdirectory = XMLHandler.getTagValue(entrynode, "outputdirectory"); //$NON-NLS-1$
            filenamepattern = XMLHandler.getTagValue(entrynode, "filenamepattern"); //$NON-NLS-1$
            retrievemails = Const.toInt(XMLHandler.getTagValue(entrynode, "retrievemails"), -1); //$NON-NLS-1$
            firstmails = XMLHandler.getTagValue(entrynode, "firstmails"); //$NON-NLS-1$
            delete = "Y".equalsIgnoreCase(XMLHandler.getTagValue(entrynode, "delete")); //$NON-NLS-1$ //$NON-NLS-2$
        } catch (KettleXMLException xe) {
            throw new KettleXMLException(Messages.getString("JobEntryGetPOP.UnableToLoadFromXml"), xe); //$NON-NLS-1$
        }
    }

    public void setInfo(Map<String, String[]> p, String id, List<? extends SharedObjectInterface> databases) {
        // TODO Auto-generated method stub
        servername = JobEntryBase.parameterToString(p.get(id + ".servername"));
        username = JobEntryBase.parameterToString(p.get(id + ".username"));
        password = JobEntryBase.parameterToString(p.get(id + ".password"));
        usessl = JobEntryBase.parameterToBoolean(p.get(id + ".usessl"));
        sslport = JobEntryBase.parameterToString(p.get(id + ".sslport"));
        outputdirectory = JobEntryBase.parameterToString(p.get(id + ".outputdirectory"));
        filenamepattern = JobEntryBase.parameterToString(p.get(id + ".filenamepattern"));
        retrievemails = JobEntryBase.parameterToInt(p.get(id + ".retrievemails"));
        firstmails = JobEntryBase.parameterToString(p.get(id + ".firstmails"));
        delete = JobEntryBase.parameterToBoolean(p.get(id + ".delete"));
    }

    public void loadRep(Repository rep, long id_jobentry, List<DatabaseMeta> databases,
            List<SlaveServer> slaveServers) throws KettleException {
        try {
            super.loadRep(rep, id_jobentry, databases, slaveServers);
            servername = rep.getJobEntryAttributeString(id_jobentry, "servername"); //$NON-NLS-1$
            username = rep.getJobEntryAttributeString(id_jobentry, "username"); //$NON-NLS-1$
            password = Encr
                    .decryptPasswordOptionallyEncrypted(rep.getJobEntryAttributeString(id_jobentry, "password"));

            usessl = rep.getJobEntryAttributeBoolean(id_jobentry, "usessl"); //$NON-NLS-1$
            int intSSLPort = (int) rep.getJobEntryAttributeInteger(id_jobentry, "sslport"); //$NON-NLS-1$
            sslport = rep.getJobEntryAttributeString(id_jobentry, "sslport"); // backward compatible. //$NON-NLS-1$
            if (intSSLPort > 0 && Const.isEmpty(sslport))
                sslport = Integer.toString(intSSLPort);

            outputdirectory = rep.getJobEntryAttributeString(id_jobentry, "outputdirectory"); //$NON-NLS-1$
            filenamepattern = rep.getJobEntryAttributeString(id_jobentry, "filenamepattern"); //$NON-NLS-1$
            retrievemails = (int) rep.getJobEntryAttributeInteger(id_jobentry, "retrievemails"); //$NON-NLS-1$
            firstmails = rep.getJobEntryAttributeString(id_jobentry, "firstmails"); //$NON-NLS-1$
            delete = rep.getJobEntryAttributeBoolean(id_jobentry, "delete"); //$NON-NLS-1$
        } catch (KettleException dbe) {
            throw new KettleException(
                    Messages.getString("JobEntryGetPOP.UnableToLoadFromRepo", String.valueOf(id_jobentry)), dbe); //$NON-NLS-1$
        }
    }

    public void saveRep(Repository rep, long id_job) throws KettleException {
        try {
            super.saveRep(rep, id_job);

            rep.saveJobEntryAttribute(id_job, getID(), "servername", servername); //$NON-NLS-1$
            rep.saveJobEntryAttribute(id_job, getID(), "username", username); //$NON-NLS-1$
            rep.saveJobEntryAttribute(id_job, getID(), "password", //$NON-NLS-1$
                    Encr.encryptPasswordIfNotUsingVariables(password));
            rep.saveJobEntryAttribute(id_job, getID(), "usessl", usessl); //$NON-NLS-1$
            rep.saveJobEntryAttribute(id_job, getID(), "sslport", sslport); //$NON-NLS-1$
            rep.saveJobEntryAttribute(id_job, getID(), "outputdirectory", outputdirectory); //$NON-NLS-1$
            rep.saveJobEntryAttribute(id_job, getID(), "filenamepattern", filenamepattern); //$NON-NLS-1$
            rep.saveJobEntryAttribute(id_job, getID(), "retrievemails", retrievemails); //$NON-NLS-1$
            rep.saveJobEntryAttribute(id_job, getID(), "firstmails", firstmails); //$NON-NLS-1$
            rep.saveJobEntryAttribute(id_job, getID(), "delete", delete); //$NON-NLS-1$
        } catch (KettleDatabaseException dbe) {
            throw new KettleException(
                    Messages.getString("JobEntryGetPOP.UnableToSaveToRepo", String.valueOf(id_job)), dbe); //$NON-NLS-1$
        }
    }

    public String getSSLPort() {
        return sslport;
    }

    public String getRealSSLPort() {
        return environmentSubstitute(getSSLPort());
    }

    public void setSSLPort(String sslport) {
        this.sslport = sslport;
    }

    public void setFirstMails(String firstmails) {
        this.firstmails = firstmails;
    }

    public String getFirstMails() {
        return firstmails;
    }

    public String getRealFirstMails() {
        return environmentSubstitute(getFirstMails());
    }

    public void setServerName(String servername) {
        this.servername = servername;
    }

    public String getServerName() {
        return servername;
    }

    public void setUserName(String username) {
        this.username = username;
    }

    public String getUserName() {
        return username;
    }

    public void setOutputDirectory(String outputdirectory) {
        this.outputdirectory = outputdirectory;
    }

    public void setFilenamePattern(String filenamepattern) {
        this.filenamepattern = filenamepattern;
    }

    public String getFilenamePattern() {
        return filenamepattern;
    }

    public String getOutputDirectory() {
        return outputdirectory;
    }

    public String getRealOutputDirectory() {
        return environmentSubstitute(getOutputDirectory());
    }

    public String getRealFilenamePattern() {
        return environmentSubstitute(getFilenamePattern());
    }

    public String getRealUsername() {
        return environmentSubstitute(getUserName());
    }

    public String getRealServername() {
        return environmentSubstitute(getServerName());
    }

    /**
     * @return Returns the password.
     */
    public String getPassword() {
        return password;
    }

    public String getRealPassword() {
        return environmentSubstitute(getPassword());
    }

    /**
     * @param delete The delete to set.
     */
    public void setDelete(boolean delete) {
        this.delete = delete;
    }

    /**
     * @return Returns the delete.
     */
    public boolean getDelete() {
        return delete;
    }

    /**
     * @param usessl The usessl to set.
     */
    public void setUseSSL(boolean usessl) {
        this.usessl = usessl;
    }

    /**
     * @return Returns the usessl.
     */
    public boolean getUseSSL() {
        return usessl;
    }

    /**
     * @param password The password to set.
     */
    public void setPassword(String password) {
        this.password = password;
    }

    @SuppressWarnings({ "unchecked" })
    public Result execute(Result previousResult, int nr, Repository rep, Job parentJob) {
        LogWriter log = LogWriter.getInstance();
        Result result = previousResult;
        result.setResult(false);
        result.setNrErrors(1);

        //Get system properties
        Properties prop = new Properties();
        prop.setProperty("mail.pop3s.rsetbeforequit", "true"); //$NON-NLS-1$ //$NON-NLS-2$
        prop.setProperty("mail.pop3.rsetbeforequit", "true"); //$NON-NLS-1$ //$NON-NLS-2$

        //Create session object
        Session sess = Session.getDefaultInstance(prop, null);
        sess.setDebug(true);

        FileObject fileObject = null;
        Store st = null;
        Folder f = null;
        try {
            int nbrmailtoretrieve = Const.toInt(firstmails, 0);
            String realOutputFolder = getRealOutputDirectory();
            fileObject = KettleVFS.getFileObject(realOutputFolder);

            // Check if output folder exists
            if (!fileObject.exists()) {
                log.logError(toString(),
                        Messages.getString("JobGetMailsFromPOP.FolderNotExists.Label", realOutputFolder)); //$NON-NLS-1$
            } else {
                if (fileObject.getType() == FileType.FOLDER) {
                    String host = getRealServername();
                    String user = getRealUsername();
                    String pwd = getRealPassword();

                    if (!getUseSSL()) {
                        //Create POP3 object
                        st = sess.getStore("pop3"); //$NON-NLS-1$

                        // Try to connect to the server
                        st.connect(host, user, pwd);
                    } else {
                        // Ssupports POP3 connection with SSL, the connection is established via SSL.

                        String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory"; //$NON-NLS-1$
                        prop.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY); //$NON-NLS-1$
                        prop.setProperty("mail.pop3.socketFactory.fallback", "false"); //$NON-NLS-1$ //$NON-NLS-2$
                        prop.setProperty("mail.pop3.port", getRealSSLPort()); //$NON-NLS-1$
                        prop.setProperty("mail.pop3.socketFactory.port", getRealSSLPort()); //$NON-NLS-1$

                        URLName url = new URLName("pop3", host, Const.toInt(getRealSSLPort(), 995), "", user, pwd); //$NON-NLS-1$ //$NON-NLS-2$
                        st = new POP3SSLStore(sess, url);
                        st.connect();
                    }
                    if (log.isDetailed())
                        log.logDetailed(toString(),
                                Messages.getString("JobGetMailsFromPOP.LoggedWithUser.Label") + user); //$NON-NLS-1$

                    //Open the INBOX FOLDER
                    // For POP3, the only folder available is the INBOX.
                    f = st.getFolder("INBOX"); //$NON-NLS-1$

                    if (f == null) {
                        log.logError(toString(), Messages.getString("JobGetMailsFromPOP.InvalidFolder.Label")); //$NON-NLS-1$

                    } else {
                        // Open folder
                        if (delete)
                            f.open(Folder.READ_WRITE);
                        else
                            f.open(Folder.READ_ONLY);

                        Message messageList[] = f.getMessages();
                        if (log.isDetailed()) {
                            log.logDetailed(toString(),
                                    Messages.getString("JobGetMailsFromPOP.TotalMessagesFolder.Label", f.getName(), //$NON-NLS-1$
                                            String.valueOf(messageList.length)));
                            log.logDetailed(toString(),
                                    Messages.getString("JobGetMailsFromPOP.TotalUnreadMessagesFolder.Label", //$NON-NLS-1$
                                            f.getName(), String.valueOf(f.getUnreadMessageCount())));
                        }
                        // Get emails
                        Message msg_list[] = getPOPMessages(f, retrievemails);

                        if (msg_list.length > 0) {
                            List<File> current_file_POP = new ArrayList<File>();
                            List<String> current_filepath_POP = new ArrayList<String>();
                            int nb_email_POP = 1;

                            String startpattern = "name"; //$NON-NLS-1$
                            if (!Const.isEmpty(getRealFilenamePattern())) {
                                startpattern = getRealFilenamePattern();
                            }

                            for (int i = 0; i < msg_list.length; i++) {
                                if ((nb_email_POP <= nbrmailtoretrieve && retrievemails == 2)
                                        || (retrievemails != 2)) {
                                    Message msg_POP = msg_list[i];
                                    if (log.isDetailed()) {
                                        log.logDetailed(toString(),
                                                Messages.getString("JobGetMailsFromPOP.EmailFrom.Label", //$NON-NLS-1$
                                                        msg_list[i].getFrom()[0].toString()));
                                        log.logDetailed(toString(), Messages.getString(
                                                "JobGetMailsFromPOP.EmailSubject.Label", msg_list[i].getSubject())); //$NON-NLS-1$
                                    }
                                    String localfilename_message = startpattern + "_" //$NON-NLS-1$
                                            + StringUtil.getFormattedDateTimeNow(true) + "_" + (i + 1) + ".mail"; //$NON-NLS-1$ //$NON-NLS-2$
                                    if (log.isDetailed())
                                        log.logDetailed(toString(), Messages.getString(
                                                "JobGetMailsFromPOP.LocalFilename.Label", localfilename_message)); //$NON-NLS-1$

                                    File filename_message = new File(realOutputFolder, localfilename_message);
                                    OutputStream os_filename = new FileOutputStream(filename_message);
                                    Enumeration<Header> enums_POP = msg_POP.getAllHeaders();
                                    while (enums_POP.hasMoreElements())

                                    {
                                        Header header_POP = enums_POP.nextElement();
                                        os_filename.write(new StringBuffer(header_POP.getName()).append(": ") //$NON-NLS-1$
                                                .append(header_POP.getValue()).append("\r\n").toString().getBytes()); //$NON-NLS-1$
                                    }
                                    os_filename.write("\r\n".getBytes()); //$NON-NLS-1$
                                    InputStream in_POP = msg_POP.getInputStream();
                                    byte[] buffer_POP = new byte[1024];
                                    int length_POP = 0;
                                    while ((length_POP = in_POP.read(buffer_POP, 0, 1024)) != -1) {
                                        os_filename.write(buffer_POP, 0, length_POP);

                                    }
                                    os_filename.close();
                                    nb_email_POP++;
                                    current_file_POP.add(filename_message);
                                    current_filepath_POP.add(filename_message.getPath());

                                    // Check attachments
                                    Object content = msg_POP.getContent();
                                    if (content instanceof Multipart) {
                                        handleMultipart(realOutputFolder, (Multipart) content);
                                    }

                                    // Check if mail has to be deleted
                                    if (delete) {
                                        if (log.isDetailed())
                                            log.logDetailed(toString(),
                                                    Messages.getString("JobGetMailsFromPOP.DeleteEmail.Label")); //$NON-NLS-1$
                                        msg_POP.setFlag(javax.mail.Flags.Flag.DELETED, true);
                                    }
                                }
                            }
                        }

                        result.setNrErrors(0);
                        result.setResult(true);
                    }

                } else {
                    log.logError(toString(),
                            Messages.getString("JobGetMailsFromPOP.Error.NotAFolder", realOutputFolder));
                }
            }
        } catch (NoSuchProviderException e) {
            log.logError(toString(), Messages.getString("JobEntryGetPOP.ProviderException", e.getMessage())); //$NON-NLS-1$
        } catch (MessagingException e) {
            log.logError(toString(), Messages.getString("JobEntryGetPOP.MessagingException", e.getMessage())); //$NON-NLS-1$
        } catch (Exception e) {
            log.logError(toString(), Messages.getString("JobEntryGetPOP.GeneralException", e.getMessage())); //$NON-NLS-1$
        } finally {
            if (fileObject != null) {
                try {
                    fileObject.close();
                } catch (IOException ex) {
                }
                ;
            }
            //close the folder, passing in a true value to expunge the deleted message
            try {
                if (f != null)
                    f.close(true);
                if (st != null)
                    st.close();
            } catch (Exception e) {
                log.logError(toString(), e.getMessage());
            }
            // free memory
            f = null;
            st = null;
            sess = null;
        }

        return result;
    }

    public static void handleMultipart(String foldername, Multipart multipart)
            throws MessagingException, IOException {
        for (int i = 0, n = multipart.getCount(); i < n; i++) {
            handlePart(foldername, multipart.getBodyPart(i));
        }
    }

    public static void handlePart(String foldername, Part part) throws MessagingException, IOException {
        String disposition = part.getDisposition();
        // String contentType = part.getContentType();

        if ((disposition != null)
                && (disposition.equalsIgnoreCase(Part.ATTACHMENT) || disposition.equalsIgnoreCase(Part.INLINE))) {
            saveFile(foldername, MimeUtility.decodeText(part.getFileName()), part.getInputStream());
        }
    }

    public static void saveFile(String foldername, String filename, InputStream input) throws IOException {

        // LogWriter log = LogWriter.getInstance();

        if (filename == null) {
            filename = File.createTempFile("xx", ".out").getName(); //$NON-NLS-1$ //$NON-NLS-2$
        }
        // Do no overwrite existing file
        File file = new File(foldername, filename);
        for (int i = 0; file.exists(); i++) {
            file = new File(foldername, filename + i);
        }
        FileOutputStream fos = new FileOutputStream(file);
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        BufferedInputStream bis = new BufferedInputStream(input);
        int aByte;
        while ((aByte = bis.read()) != -1) {
            bos.write(aByte);
        }

        bos.flush();
        bos.close();
        bis.close();
    }

    public boolean evaluates() {
        return true;
    }

    public Message[] getPOPMessages(Folder folder, int retrievemails) throws Exception {
        // Get  messages ..
        try {
            int unreadMsgs = folder.getUnreadMessageCount();
            Message msgsAll[] = folder.getMessages();
            int msgCount = msgsAll.length;

            if (retrievemails == 1) {
                Message msgsUnread[] = folder.getMessages(msgCount - unreadMsgs + 1, msgCount);
                return (msgsUnread);

            } else {
                return (msgsAll);
            }
        }

        catch (Exception e) {
            return null;
        }

    }

    public void check(List<CheckResultInterface> remarks, JobMeta jobMeta) {
        andValidator().validate(this, "serverName", remarks, putValidators(notBlankValidator())); //$NON-NLS-1$
        andValidator().validate(this, "userName", remarks, putValidators(notBlankValidator())); //$NON-NLS-1$
        andValidator().validate(this, "password", remarks, putValidators(notNullValidator())); //$NON-NLS-1$

        ValidatorContext ctx = new ValidatorContext();
        putVariableSpace(ctx, getVariables());
        putValidators(ctx, notBlankValidator(), fileExistsValidator());
        andValidator().validate(this, "outputDirectory", remarks, ctx);//$NON-NLS-1$

        andValidator().validate(this, "SSLPort", remarks, putValidators(integerValidator())); //$NON-NLS-1$
    }

    public List<ResourceReference> getResourceDependencies(JobMeta jobMeta) {
        List<ResourceReference> references = super.getResourceDependencies(jobMeta);
        if (!Const.isEmpty(servername)) {
            String realServername = jobMeta.environmentSubstitute(servername);
            ResourceReference reference = new ResourceReference(this);
            reference.getEntries().add(new ResourceEntry(realServername, ResourceType.SERVER));
            references.add(reference);
        }
        return references;
    }
}