Doubt about threads

0

I have two classes.

One has thread for downloading email attachments and the other has thread for converting files xml to csv .

I gave a start in these two threads to another classe . The% of% of emails have to wait for new emails and the other thread has to convert the files that have a folder inside the project, and if any new ones come through the thread that downloads attachments, it also has to convert this file.

Any tips on how I can do this?

I have thread and everything is ready. But I do not know how to organize them so that what I want to work out.

threads

obs: This is a class for reading e-mails and downloading attachments to the computer. The code would have to stay on a thread that would either stay running directly or run according to some stipulated time to receive new files.

public class LeitorEmail {
    // pasta onde os arquivos XML serão salvos
    public static final String pastaXML = "arquivos-xml";
    public static final String imap = "imaps"; 
    // endereço do servidor de hospedagem do gmail 
    public static final String host = "imap.gmail.com"; 
    // porta para acessar o gmail
    public static final int porta = 993; 
    // arquivo de mensagens do e-mail
    public static final String arquivoMSG = "Inbox"; 
    // e-mail de onde os arquivos serão pegos
    public static final String login = "[email protected]"; 
    // senha
    public static final String senha = "xxxxxxxxx"; 
    // pasta onde ficam os arquivos dentro do e-mail
    public static final String pastaPrincipal = "Inbox"; 

    private Store store = null;
    private Folder folder = null;
    private Message message = null;
    private Message[] messages = null;
    private Object msgObj = null;
    private String sender = null;
    private String subject = null;
    private Multipart multipart = null;
    private Part part = null;
    private String contentType = null;

    public LeitorEmail() throws MessagingException {
        processMail();
    }

    /**
     * Processa o e-mail
     * 
     */
    public void processMail() throws MessagingException {
        try {
            store = conexaoServidorEMail();
            folder = getPastaCaixaEntrada(store);
            messages = folder.getMessages();

            for (int messageNumber = 0; messageNumber < messages.length; messageNumber++) {
                message = messages[messageNumber];
                msgObj = message.getContent();

                // Determine o tipo de email
                if (msgObj instanceof Multipart) {

                    subject = message.getSubject();
                    multipart = (Multipart) message.getContent();

                    for (int i = 0; i < multipart.getCount(); i++) {

                        part = multipart.getBodyPart(i);
                        // pegando um tipo do conteúdo
                        contentType = part.getContentType();

                        String fileName2 = part.getFileName();
                        if(fileName2 != null) {
                            System.out.println(messageNumber + " " + fileName2 + " | " + message.getSubject());
                        }
                        fileName2 = null;
                        // teste para saber o tipo de conteúdo (PDF, PLAIN TEXT, XML...)
                        //System.out.println("content type: " + contentType);
                        //System.out.println();

                        // Tela do conteúdo
                        if (contentType.startsWith("text/plain")) {
                            System.out.println("É só um e-mail comum... :|");
                        } else {
                            // TASK: FIXME 
                            // validação XML
                            if (contentType.startsWith("TEXT/XML") && validarXML(part) == true){
                                System.out.println("*************************************************************************************************************");
                                System.out.println("                                          Salvando arquivo...                                                ");
                                salvarArquivo(part);
                                System.out.println("                                          Arquivo Salvo! :3                                                  ");
                                System.out.println("*************************************************************************************************************");
                            }
//                          String fileName = part.getFileName();
//                          @SuppressWarnings("unused")
//                          Message[] mensagensXML = separaMensagensXML(i, fileName);

                        }
                    }
                } else {
                    sender = ((InternetAddress) message.getFrom()[0]).getPersonal();
                    if (sender == null) {
                        sender = ((InternetAddress) message.getFrom()[0]).getAddress();
                    }
                    // Get the subject information
                    subject = message.getSubject();
                }
            }
            // Fecha a pasta
            folder.close(true);
            // Histório de mensagens
            store.close();
            System.out.println("Terminado");
        } catch (AuthenticationFailedException e) {
            store.close();
            e.printStackTrace();
        } catch (FolderClosedException e) {
            store.close();
            e.printStackTrace();
        } catch (FolderNotFoundException e) {
            store.close();
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            store.close();
            e.printStackTrace();
        } catch (ReadOnlyFolderException e) {
            store.close();
            e.printStackTrace();
        } catch (StoreClosedException e) {
            store.close();
            e.printStackTrace();
        } catch (Exception e) {
            store.close();
            e.printStackTrace();
        }
    }

    /**
     * Recebe o anexo e valida se é um XML, se sim ele salva o arquivo em uma
     * pasta
     * 
     * @param part
     * @return
     * @throws MessagingException
     * @throws IOException
     */
    private boolean validarXML(Part part) throws MessagingException, IOException {
        String fileName = part.getFileName();
        if (fileName != null) {
            int tamanhoString = fileName.length() - 3;
            if (fileName.substring(tamanhoString).equals("xml")) {
                return true;
            } 
        }
        return false;
    }


    /**
     * @author Waffle-Chan
     * @Data 26.01.2017
     * @Função Salva o arquivo em uma pasta
     * 
     */
    private void salvarArquivo(Part part) throws IOException, MessagingException {  
        // variável que armazena o caminho da pasta onde o arquivo será salvo de acordo com o tipo dele
        String caminhoPasta = "";

        // vai para a pasta
        caminhoPasta = pastaXML;
        System.out.println(caminhoPasta + part.getFileName());

        // O arquivo é aberto em uma FileOutputStream . Caso o arquivo não exista, ele é criado. (neste caso, é criado)
        FileOutputStream fos = new FileOutputStream(caminhoPasta + part.getFileName());
        // É criado um ObjectOutputStream a partir da stream anterior.
        ObjectOutputStream stream = new ObjectOutputStream(fos);
        // o objeto "obj" recebe o conteúdo do arquivo xml vindo do e-mail
        Object obj = part.getContent();
        // teste: verificar se o arquivo está vindo completo do e-mail
        //System.out.println(part.getContent());

        try {
            // Ao escrever no ObjectOutputStream, os dados são enviados por meio da FileOutputStream para o arquivo físico.
            stream.writeObject(obj);
            // Por fim, a stream é fechada.
            stream.close();
        } catch (Exception e){
            System.out.println("Error: " + e);
        } 
    }

    /**
     * Acessa a Caixa de Entrada (Inbox)
     * 
     * @param store
     * @return
     * @throws MessagingException
     */
    private Folder getPastaCaixaEntrada(Store store) throws MessagingException {
        Folder folder;
        // pego a pasta principal (Ibox) do e-mail
        folder = store.getFolder(pastaPrincipal);
        // abro a pasta para leitura/escrita, conforme o que será utilizado
        folder.open(Folder.READ_WRITE);
        // retorno a caixa de entrada
        return folder;
    }

    /**
     * Autenticação e conexão com o Servidor de e-mail
     * 
     * @return
     * @throws NoSuchProviderException
     * @throws MessagingException
     */
    private Store conexaoServidorEMail() throws NoSuchProviderException, MessagingException {
        Session session;
        Store store;
        Properties prop = new Properties();
        session = Session.getInstance(prop);
        URLName url = new URLName(imap, host, porta, arquivoMSG, login, senha);
        store = session.getStore(url);
        store.connect();

        return store;
    }
}

LeitorEmail

obs: here it was inside a thread, but since I could not do what I wanted, I ended up getting it ...

public class ServicoEmail {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    @SuppressWarnings("unused") 
    LeitorEmail leitor =null; 
    try { 
        leitor = new LeitorEmail(); 
    } catch (MessagingException e) { 
        e.printStackTrace(); 
    }
}

}

classe para executar o LeitorEmail

obs: le an XML file and converts to CSV. This thread would have to be running for the files that are in the directory and if another file appears inside it, it would have to run again for this new file. As you can see I've already left the code inside a thread ...

public class ServicoCSV implements Runnable {
    /** DECLARAÇÃO DE VARIÁVEIS DA CLASSE **/
    // variável utilizada para modificar o nome do arquivo gerado
    public static int num = 0;
    // variável utilizada para armazenar o caminho do arquivo de schema
    static String schema = null;
    // 
    static Leitor.LeitorXML arq;
    // crio um objeto da classe ConversorXMl
    static Conversor.ConversorXML conversor = new Conversor.ConversorXML();
    // variável auxiliar
    static int i;
    // variável utilizada para pegar os arquivos do diretório 
    static File arquivosXML[];
    // 
    static File diretorioArqXML;
    static File diretorioArqXMLPos;

    public void run() {
        /** INICIALIZAÇÃO DE VARIÁVEIS **/
        diretorioArqXML = new File("arquivos-xml");
        // diretorioArqXMLPos = new File ("arquivos-xml");
        // armazeno os arquivos em um vetor de arquivos
        arquivosXML = diretorioArqXML.listFiles();
        // inicializo o contador em 0
        i = 0;

        // enquanto o contador for menor do que o número de arquivos dentro do diretório de arquivos 
        while (i < diretorioArqXML.listFiles().length) {
            // se houver um esquema para o arquivo XML
            if(schemaSource!=null){
                System.out.println (i + " - " + arquivosXML[i].toString());
                //cria o leitor XML para cada arquivo XML no array testando consistencia contra o schema
                arq = new Leitor.LeitorXML(true,schema, arquivosXML[i].toString());
                i++;
            }else{
                //cria o leitor XML para cada arquivo XML no array
                arq = new Leitor.LeitorXML(false, schema, arquivosXML[i].toString());
            }
            try {
                arq.guardaEstruturaXML(arq.doc.getChildNodes());
                arq.ConfereLancamentosXML();

                // chamando os métodos que estão em EscritorXML 
                escritor.converteVetorParaCSV(arq);
            } catch (Exception e){
                System.out.println("Exception: " + e);
            }

            // incrementando num para passar para o próximo arquivo
            num ++;
        }
    
asked by anonymous 27.01.2017 / 16:38

1 answer

0

WatchService

You can create a WatchService to notify you always event occurs in the directory you are watching. Example:

public class WatchServiceTest {

    public static void main(String[] args) throws IOException, InterruptedException {

        WatchService watcher = FileSystems.getDefault().newWatchService();
        Path dir = Paths.get("C:/Caminho/da/pasta/que/voce/quer/acompanhar");
        //Aqui você registra os tipos de evento que quer acompanhar
        //Nesse exemplo, eu coloquei para ser notificado sempre 
        //que um arquivo for criado
        dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);

        WatchKey watchKey = null;
        while (true) {
            watchKey = watcher.poll(10, TimeUnit.MINUTES);
            if(watchKey != null) {
                watchKey.pollEvents().stream().forEach(event -> System.out.println(event.context()));
            }
            watchKey.reset();
        }
    }
}

Here a more complete guide.

Observer

Another option is to use the Observer project pattern. Simple example with your code:

Create an interface that represents the action that should be performed when the event of your interest occurs:

public interface ArquivoCriadoListener {

    public void acao(String caminho);
}

Modify your class LeitorEmail so you can register them:

public class LeitorEmail {

    private final List<ArquivoCriadoListener> listeners = new ArrayList<>();

    //Seus outros atributos

    public LeitorEmail(List<ArquivoCriadoListener> listeners) throws MessagingException {
        this.listeners.addAll(listeners);
        processMail();
    }

    //Seus outros métodos

    //Altere esse método para que ele execute os listeners sempre que o arquivo for salvo
    private void salvarArquivo(Part part) throws IOException, MessagingException {
        //O resto do código que você usa para salvar o aquivo

        // O nome do seu arquivo
        String nomeDoArquivo = ...;

        listeners.forEach(a -> a.acao(nomeDoArquivo));
    }
}

Your class ServicoCSV :

public class ServicoCSV implements ArquivoCriadoListener {

    @Override
    public void acao(String caminho) {
        File file = new File(caminho);
        //aqui você implementa o método de converter o arquivo
    }

}

Your ServicoEmail :

public class ServicoEmail {

    public static void main(String[] args) throws MessagingException {
        new LeitorEmail(Arrays.asList(new ServicoCSV()));
    }
}
    
30.01.2017 / 19:40