org.adempierelbr.util.WebServiceCep.java Source code

Java tutorial

Introduction

Here is the source code for org.adempierelbr.util.WebServiceCep.java

Source

/******************************************************************************
 * Product: ADempiereLBR - ADempiere Localization Brazil                      *
 * This program is free software; you can redistribute it and/or modify it    *
 * under the terms version 2 of the GNU General Public License as published   *
 * by the Free Software Foundation. This program 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 General Public License for more details.                       *
 * You should have received a copy of the GNU General Public License along    *
 * with this program; if not, write to the Free Software Foundation, Inc.,    *
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.                     *
 *****************************************************************************/
package org.adempierelbr.util;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * Ferramenta de busca de CEP, veja o mtodo {@link WebServiceCep#searchCep(String)} para
 * maiores informaes.
 * <BR>
 * <BR>Constroi um objeto {@link WebServiceCep} com os dados XML encapsulados, a partir
 * da chamada do mtodo estatico {@link WebServiceCep#searchCep(String)}.
 * <BR>
 * <BR>Objeto contem todas as informaes do XML, alm de informaes referente ao
 * resultado da pesquisa.
 * <BR>
 * <BR>Esta ferramente depende diretamente do pacote <tt>org.dom4j</tt> para fazer o 
 * parse dos arquivos XML. O pacote dom4j.jar pode ser encontrado em 
 * <a href="http://www.dom4j.org/dom4j-1.6.1/download.html" target="_blank">dom4j.org</a>
 * <BR>
 * <BR>Exemplo de uso:
 * <BR><tt>{@link WebServiceCep} cep = {@link WebServiceCep}.searchCep("13345-325");
 * 
 * <BR>//caso a busca ocorra bem, imprime os resultados.
 * <BR>if (cep.wasSuccessful()) {
 * <BR>&nbsp; &nbsp; System.out.println("Cep: "+cep.getCep());
 * <BR>&nbsp; &nbsp; System.out.println("Logradouro: "+cep.getLogradouroFull());
 * <BR>&nbsp; &nbsp; System.out.println("Bairro: "+cep.getBairro());
 * <BR>&nbsp; &nbsp; System.out.println("Cidade: "+
 *          cep.getCidade()+"/"+ cep.cep());
 * <BR>//caso haja problemas imprime o cdigo e msg de erro.
 * <BR>} else {
 * <BR>&nbsp; &nbsp; System.out.println("Erro nmero: " + cep.getResulCode());
 * <BR>&nbsp; &nbsp; System.out.println("Descrio do erro: " + cep.getResultText());
 * <BR>}
 * <BR></tt>
 * <BR>A resposta do console seria:
 * <BR><tt>
 * <BR>Cep: 13345325
 * <BR>Logradouro: Rua Cinco
 * <BR>Bairro: Jardim Rmulo Zoppi
 * <BR>Cidade: Indaiatuba/SP
 * <BR></tt>
 * <BR>Ultima reviso: 09/01/2009
 * @author Tomaz Lavieri
 */
public final class WebServiceCep {

    /* Classes Internas, que auxiliam na busca do CEP */
    /**
     * Enumeration para setar os parametros do XML, cada constante conhece o seu mtodo
     * correspondente, invocando a partir de um atalho comum
     * {@link Xml#setCep(String, WebServiceCep)}.
     * @author Tomaz Lavieri
     */
    private enum Xml {
        CIDADE {
            @Override
            public void setCep(String text, WebServiceCep webServiceCep) {
                webServiceCep.setCidade(text);
            }
        },
        BAIRRO {
            @Override
            public void setCep(String text, WebServiceCep webServiceCep) {
                webServiceCep.setBairro(text);
            }
        },
        TIPO_LOGRADOURO {
            @Override
            public void setCep(String text, WebServiceCep webServiceCep) {
                webServiceCep.setLogradouroType(text);
            }
        },
        LOGRADOURO {
            @Override
            public void setCep(String text, WebServiceCep webServiceCep) {
                webServiceCep.setLogradouro(text);
            }
        },
        RESULTADO {
            @Override
            public void setCep(String text, WebServiceCep webServiceCep) {
                webServiceCep.setResulCode(Integer.parseInt(text));
            }
        },
        RESULTADO_TXT {
            @Override
            public void setCep(String text, WebServiceCep webServiceCep) {
                webServiceCep.setResultText(text);
            }
        },
        UF {
            @Override
            public void setCep(String text, WebServiceCep webServiceCep) {
                webServiceCep.setUf(text);
            }
        };
        /**
         * Seta o texto enviado no parametro <tt>text</tt> no objeto
         * {@link WebServiceCep} no seu parametro correspondente. Cada constante do enum
         * conhece o seu parametro a passar.
         * @param text {@link String} contendo o texto a ser inserido.
         * @param webServiceCep {@link WebServiceCep} referencia do objeto para inserir
         *         o parametro text.
         */
        public abstract void setCep(String text, WebServiceCep webServiceCep);
    }

    /**
     * Classe utilitria apenas encapsula o Iterator de elements da root dentro de um
     * Iterable, para ser usado dentro de um for.
     * @see Iterable
     * @see Iterator
     * @author Tomaz Lavieri
     */
    private static final class IterableElement implements Iterable<Element> {
        private Iterator<Element> itr;

        @SuppressWarnings("unchecked")
        public IterableElement(Iterator<?> itr) {
            this.itr = (Iterator<Element>) itr;
        }

        public Iterator<Element> iterator() {
            return itr;
        }
    }

    /**
     * Classe contendo todos os Enums {@link Xml}.
     * Tem como finalidade, buscar um Enumeration especifico pelo seu nome.
     * @author Tomaz Lavieri
     */
    private static final class XmlEnums {
        private HashMap<String, Xml> enumsMap;

        /**
         * Cria um {@link XmlEnums}
         */
        public XmlEnums() {
            initializeEnums();
        }

        /**
         * Inicializa este objeto, guardando os enumerations em um {@link HashMap}
         */
        private void initializeEnums() {
            Xml[] enums = Xml.class.getEnumConstants();
            enumsMap = new HashMap<String, Xml>();
            for (int i = 0; i < enums.length; i++) {
                enumsMap.put(enums[i].name().toLowerCase(), enums[i]);
            }
        }

        /**
         * Busca um Enum {@link Xml} a partir do seu nome, a busca no  case sensitive,
         * portanto o nome pode ser escrito ignorando lowercases or uppercases.
         * @see Xml
         * @param xmlName {@link String} contendo o nome do enumeration {@link Xml}.
         * @return {@link Xml} correspondente ao nome enviado.
         */
        public Xml getXml(String xmlName) {
            return enumsMap.get(xmlName.toLowerCase());
        }
    }

    /* Mtodos e variaveis estaticas, responsveis pela busca do CEP */
    /**
     * Mascara para a string url de conexo, onde <tt>"%s"</tt>  substituido pelo valor
     * do cep. 
     */
    private static final String URL_STRING = "http://cep.republicavirtual.com.br/web_cep.php?cep=%s&formato=xml";

    /**
     * Carrega o Documento xml a partir do CEP enviado.
     * @param cep nmero do cep.
     * @return {@link Document} xml WebService do site Republic Virtual
     * @throws DocumentException Quando h problema na formao do documento XML.
     * @throws MalformedURLException Quando a h problema no link url.
     */
    private static Document getDocument(String cep) throws DocumentException, MalformedURLException {
        URL url = new URL(String.format(URL_STRING, cep));
        SAXReader reader = new SAXReader();
        Document document = reader.read(url);
        return document;
    }

    /**
     * Retorna o elemento principal (root) da arvore XML.
      * @param cep nmero do cep.
     * @return {@link Element} principal (root) da arvore XML.
      * @throws DocumentException Quando h problema na formao do documento XML.
      * @throws MalformedURLException Quando a h problema no link url.
     */
    private static Element getRootElement(String cep) throws DocumentException, MalformedURLException {
        return getDocument(cep).getRootElement();
    }

    /**
     * Encapsula os elementos XML dentro de um objeto
     * <tt>{@link Iterable}<{@link Element}></tt> podendo ser recuperados um a um dentro
     * de um for
     * <BR>
     * <BR>Por exemplo:
     * <BR><tt>for (Element e : getElements(cep)) {
     * <BR>//...
     * <BR>}
      * @param cep nmero do cep.
     * @return
      * @throws DocumentException Quando h problema na formao do documento XML.
      * @throws MalformedURLException Quando a h problema no link url.
     */
    private static IterableElement getElements(String cep) throws DocumentException, MalformedURLException {
        return new IterableElement(getRootElement(cep).elementIterator());
    }

    /**
     * Faz uma busca a partir do cep enviado, no site 
     * <a href="http://www.republicavirtual.com.br" 
     * target="_blank">republicavirtual.com.br</a>, retornando o resultado em um objeto
     * {@link WebServiceCep}.
     * <BR>
     * <BR>No se faz necessrio formataes, a string pode ser enviada em qualquer
     * formatao, pois s sero consideradas os primeiros 8 numeros da string.
     * <BR>Por Exemplo:
     * <BR>Uma <tt>{@link String} "14.568-910"</tt>  automaticamente passada para
     * <tt>"14568910"</tt>.
     * <BR>Uma <tt>{@link String} "1%4#5?55%16a8&910"</tt>  automaticamente passada para
     * <tt>"14555168"</tt>, s levando em conta os primeiros 8 nmeros.
     * @param   cep Nmero do cep a ser carregado. S sero considerados os primeiros 8 
     *          nmeros da {@link String} enviada. Todos os caracters no numricos sero
     *          removidos, e a string ser truncada caso seja maior que 8 caracters.
     * @return {@link WebServiceCep} contendo as informaes da pesquisa.
     */
    public static WebServiceCep searchCep(String cep) {
        cep = cep.replaceAll("\\D*", ""); //To numeric digits only
        if (cep.length() > 8)
            cep = cep.substring(0, 8);
        WebServiceCep loadCep = new WebServiceCep(cep);
        try {
            XmlEnums enums = new XmlEnums();
            for (Element e : getElements(cep))
                enums.getXml(e.getQualifiedName()).setCep(e.getText(), loadCep);
        } catch (DocumentException ex) {
            if (ex.getNestedException() != null
                    && ex.getNestedException() instanceof java.net.UnknownHostException) {
                loadCep.setResultText("Site no encontrado.");
                loadCep.setResulCode(-14);
            } else {
                loadCep.setResultText("No foi possivel ler o documento xml.");
                loadCep.setResulCode(-15);
            }
            loadCep.setExceptio(ex);
        } catch (MalformedURLException ex) {
            loadCep.setExceptio(ex);
            loadCep.setResultText("Erro na formao da url.");
            loadCep.setResulCode(-16);
        } catch (Exception ex) {
            loadCep.setExceptio(ex);
            loadCep.setResultText("Erro inesperado.");
            loadCep.setResulCode(-17);
        }
        return loadCep;
    }

    /* Campos internos de resultado da busca */

    private int resulCode = -1;
    private String resultText = "busca no realizada.";
    private String cep = null;
    private String bairro = null;
    private String cidade = null;
    private String logradouro = null;
    private String logradouroType = null;
    private String uf = null;
    private Exception exception;

    /**
     * Privado para que seja invocado apenas atravs de {@link #searchCep(String)}
     * @param cep
     */
    public WebServiceCep(String cep) {
        this.cep = cep;
    }

    /**
     * Excees lanadas pelo {@link #searchCep(String)}.
     * @param ex
     */
    private void setExceptio(Exception ex) {
        this.exception = ex;
    }
    /* PRIVATE mtodos set, usados pela classe Xml para setar o objeto CepWebService */

    private void setCidade(String cidade) {
        this.cidade = cidade;
    }

    private void setBairro(String bairro) {
        this.bairro = bairro;
    }

    private void setLogradouroType(String logradouroType) {
        this.logradouroType = logradouroType;
    }

    private void setLogradouro(String logradouro) {
        this.logradouro = logradouro;
    }

    private void setResulCode(int resultado) {
        this.resulCode = resultado;
    }

    private void setResultText(String resultado_txt) {
        this.resultText = resultado_txt;
    }

    private void setUf(String uf) {
        this.uf = uf;
    }

    /* PUBLIC mtodos get e is, usado para acessar o objeto aps carregado. */
    /**
     * Informa o cdigo do resultado da pesquisa.
     * <BR>Cdigos conhecidos:
     * <BR><tt>-1</tt> : busca no realizada
     * <BR><tt>0</tt> : cep no encontrado
     * <BR><tt>1</tt> : cep econtrado
     * <BR><tt>-14</tt> : Site no encontrado (pode ser por problemas na internet).
     * <BR><tt>-15</tt> : No foi possivel ler o documento xml
     * <BR><tt>-16</tt> : Erro na formao da url
     * <BR><tt>-17</tt> : Erro inesperado
     * 
     * 
     * @return <tt>int</tt> Cdigo do resultado.
     */
    public int getResulCode() {
        return resulCode;
    }

    /**
     * Informao textual sobre o resultado da pesquisa
     * @return {@link String} contendo a descrio do resultado da pesquisa.
     */
    public String getResultText() {
        return resultText;
    }

    /**
     * Informa se o cep foi encontrado com sucesso.
     * @return   <tt>true</tt> - caso a pesquisa ache um resultado no banco.
     *          <BR><tt>false</tt> - caso haja falhas, ou o cep enviado no esteja 
     *          cadastrado.
     */
    public boolean wasSuccessful() {
        return (resulCode == 1 && exception == null);
    }

    /**
     * Informa se no existe o cep cadastrado.
     * @return   <tt>true</tt> - Caso o cep no tenha cido encontrado.
     *          <BR><tt>false</tt> - Caso haja falhas, ou caso o cep esteja cadastrado.
     */
    public boolean isCepNotFound() {
        return (resulCode == 0);
    }

    /**
     * Informa se houve falhas na busca do cep
     * @return   <tt>true</tt> - Caso ocorra falhas
     *          <BR><tt>false</tt> - Caso no haja falhas.
     */
    public boolean hasException() {
        return (exception != null);
    }

    /**
     * Pega a exceo que ocorreu durante a busca, retorna null caso no haja excees.
     * @return   <tt>{@link Exception}</tt> - Caso ocorra falhas
     *          <BR><tt>null</tt> - Caso no haja falhas.
     */
    public Exception getException() {
        return exception;
    }

    /**
     * Informa o bairro
     * @return {@link String} contendo o nome bairro
     */
    public String getBairro() {
        return bairro;
    }

    /**
     * Informa a cidade
     * @return {@link String} contendo o nome da Cidade
     */
    public String getCidade() {
        return cidade;
    }

    /**
     * Informa a Unidade Federativa
     * @return {@link String} contendo o nome da Unidade Federativa
     */
    public String getUf() {
        return uf;
    }

    /**
     * Informa o logradouro.
     * @return {@link String} contendo o nome do Logradouro
     */
    public String getLogradouro() {
        return logradouro;
    }

    /**
     * Informa o logradouro junto com o tipo de logradouro.
     * @return {@link String} contendo o tipo de Logradouro + nome do Logradouro.
     */
    public String getLogradouroFull() {
        return (logradouro == null || logradouroType == null) ? null : logradouroType + " " + logradouro;
    }

    /**
     * Informa o tipo do logradouro.
     * @return {@link String} contendo o tipo de logradouuro.
     */
    public String getLogradouroType() {
        return logradouroType;
    }

    /**
     * Informa o cep.
     * @return {@link String} contendo o cep.
     */
    public String getCep() {
        return cep;
    }
}