Doubt about threads

Asked

Viewed 114 times

0

I have two classes.

One possesses a thread for the download of email attachments and the other has a thread for the conversion of files xml for csv.

I started those two threads in another classe. To thread of the emails have to be waiting for new emails and the other thread have to convert the files you have into a folder within the project, and if any new ones come through the thread that downloads the attachments, she also has to convert that file.

Any hint on how I can do this?

I have the threads and everything is ready. But I don’t know how to organize them so that what I want to work.

LeitorEmail

Obs: this is a class for reading emails and downloading attachments to the computer. The code would have to stay in a thread that remains running straight or runs 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;
    }
}

classe para executar o LeitorEmail

Obs: here was inside a thread, but as I could not do what I wanted, I ended up taking...

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(); 
    }
}

}

ServicoCSV

Obs: le an XML file and convert to CSV. This thread would have to run to the files that are in the directory and if another file appears inside it, it would have to run again to 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 ++;
        }
  • Put the code you already have ready, so we can help you to elaborate it

  • Without you putting the code you’ve already done, it’s hard to tell you what you have to do, what you have to change and what you have to leave as it is.

  • @Victor Stafusa I am not allowed to disclose all the code, but I tried to make it more complete.. = c thanks for the personal help!

1 answer

0


Watchservice

You can create a Watchservice to notify you whenever an event occurs in the directory you are observing. 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 project pattern Observer. Simple example with your code:

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

public interface ArquivoCriadoListener {
    
    public void acao(String caminho);
}

Modify your class LeitorEmail so that 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()));
    }
}
  • I’ll try that! Thank you so much for your help :3

Browser other questions tagged

You are not signed in. Login or sign up in order to post.