BrazilUtils API

E lá se vai um programador e começa a surgir um gerente de projetos :XD:

Ironlynx…

Boa Douglas!!!Eu tb vou me acostumar a testar…
Beleza Renato, mas se não fosse pedir muito, vc tem a lógica disso?
A do 2 por 5 tem no guj, se não tiver depois eu procuro no google mesmo.Valeu! :thumbup:

Valeu Renato!Só agora vi suas PM!!!
Vou dar uma boa lida naquilo e repassar ao Rafael! :thumbup:

Os fontes tão aqui, mas infelizmente em Delphi, não em Java (humm… é… humm… :roll: )

Pessoal, após instalar o Eclipse M6 e começar a usar as novas funcionalidades do 5.0 eu tô igual criança com brinquedo novo. Depois que refiz a classe TipoLogradouro como enum percebi que poderia fazer o mesmo para as Unidades da federação (UF). Antes eu tinha 27 classes (uma por uf) mais umas 3 ou 4 (interfaces etc). Troquei TODAS por uma única classe UF que é um enum com todas as mesmas propriedades das antigas. A nova é bem mais elegante para criaço~, pois não precisa gerar exceções por que só é possível criar umas das 27 possibilidades do enum, ou null.
Estou fazendo uma tb para os formatos do telefone e pensei se seria possível fazer para Inscrição Estadual, que também são 27 classes. Essas últimas acho que não é possível pois cada uma tem um método de validação diferente. No caso da UF o que muda á só sigla, nome e IE. Se alguém tiver uma idéia de como fazer uma redução semelhante nas Inscrições Estaduais eu agradeço.
Segue a classe nova de UF:

package org.brazilutils.br.endereco;

import java.util.EnumSet;

import org.brazilutils.br.ie.AbstractInscricaoEstadual;
import org.brazilutils.br.ie.InscricaoEstadualAC;
import org.brazilutils.br.ie.InscricaoEstadualAL;
import org.brazilutils.br.ie.InscricaoEstadualAM;
import org.brazilutils.br.ie.InscricaoEstadualAP;
import org.brazilutils.br.ie.InscricaoEstadualBA;
import org.brazilutils.br.ie.InscricaoEstadualCE;
import org.brazilutils.br.ie.InscricaoEstadualDF;
import org.brazilutils.br.ie.InscricaoEstadualES;
import org.brazilutils.br.ie.InscricaoEstadualGO;
import org.brazilutils.br.ie.InscricaoEstadualMA;
import org.brazilutils.br.ie.InscricaoEstadualMG;
import org.brazilutils.br.ie.InscricaoEstadualMS;
import org.brazilutils.br.ie.InscricaoEstadualMT;
import org.brazilutils.br.ie.InscricaoEstadualPA;
import org.brazilutils.br.ie.InscricaoEstadualPB;
import org.brazilutils.br.ie.InscricaoEstadualPE;
import org.brazilutils.br.ie.InscricaoEstadualPI;
import org.brazilutils.br.ie.InscricaoEstadualPR;
import org.brazilutils.br.ie.InscricaoEstadualRJ;
import org.brazilutils.br.ie.InscricaoEstadualRN;
import org.brazilutils.br.ie.InscricaoEstadualRO;
import org.brazilutils.br.ie.InscricaoEstadualRR;
import org.brazilutils.br.ie.InscricaoEstadualRS;
import org.brazilutils.br.ie.InscricaoEstadualSC;
import org.brazilutils.br.ie.InscricaoEstadualSE;
import org.brazilutils.br.ie.InscricaoEstadualSP;
import org.brazilutils.br.ie.InscricaoEstadualTO;


/**
 * @author Douglas Siviotti
 *
 */
public enum UF {
    AC("Acre", new InscricaoEstadualAC()),
    AL("Alagoas", new InscricaoEstadualAL()),
    AM("Amazonas", new InscricaoEstadualAM()),
    AP("Amapá", new InscricaoEstadualAP()),
    BA("Bahia", new InscricaoEstadualBA()),
    CE("Ceará", new InscricaoEstadualCE()),
    DF("Distrito Federal", new InscricaoEstadualDF()),
    ES("ESpírito Santo", new InscricaoEstadualES()),
    GO("Goiás", new InscricaoEstadualGO()),
    MA("Maranhão", new InscricaoEstadualMA()),
    MG("Minas Gerais", new InscricaoEstadualMG()),
    MS("Mato Grosso do Sul", new InscricaoEstadualMS()),
    MT("Mato Grosso", new InscricaoEstadualMT()),
    PA("Pará", new InscricaoEstadualPA()),
    PB("Paraíba", new InscricaoEstadualPB()),
    PE("Pernambuco", new InscricaoEstadualPE()),
    PI("Piauí", new InscricaoEstadualPI()),
    PR("Paraná", new InscricaoEstadualPR()),
    RJ("Rio de Janeiro", new InscricaoEstadualRJ()),
    RN("Rio Grande do Norte", new InscricaoEstadualRN()),
    RO("Rondônia", new InscricaoEstadualRO()),
    RR("Roraima", new InscricaoEstadualRR()),
    RS("Rio Grande do Sul", new InscricaoEstadualRS()),
    SC("Santa Catarina", new InscricaoEstadualSC()),
    SE("Sergipe", new InscricaoEstadualSE()),
    SP("São Paulo", new InscricaoEstadualSP()),
    TO("Tocantins", new InscricaoEstadualTO())
    ;
	/**Create a UF from a String.
	 * @param uf The UF abbreviature as String
	 * @return The Uf 
	 */
	public static UF getUf(String uf){
		String upper = uf.toUpperCase();
		for (UF u: EnumSet.range
				(UF.AC, UF.TO)){
				String s = u.name().toUpperCase(); 
				if (upper.equals(s)) return u;
			}				
		
		return null;
	}
	// PRIVATE
	private AbstractInscricaoEstadual inscricaoEstadual;
	private String ufName;
	private UF(String ufName, AbstractInscricaoEstadual ie){
		this.ufName = ufName;
		this.inscricaoEstadual = ie;
	}
	// PUBLIC
	/**
	 * @return Returns the inscricaoEstadual.
	 */
	public AbstractInscricaoEstadual getInscricaoEstadual() {
		return inscricaoEstadual;
	}
	/**
	 * @return Returns the Uf Name.
	 */
	public String getName() {
		return ufName;
	}
	/**Returns the abbreviature. Returns name() method value.
	 * @return Returns the abbreviature.
	 */
	public String getAbbreviature(){
		return name();
	}
}

Aliás, matei o pacote UF e coloquei ela no pacote endereco junto com o CEp que tinha ficado sozinho no pacote. Vou escrever uns testes amanhã e dou retorno.

WTF! :shock:
Caramba!!!Nunca usei essa feature do Tiger!!!
Isso parece aquelas estruturas em C…
Parece poupar um bando de constantes em interface tb, mas qual é o custo disso???
Cadê o nosso PM Web?(CeeeeVêeee!!!)

Me lembra o BD em Haskell…

“Parece aquelas estruturas em C” - nao parecem, SAO as enums do C, soh que com umas frescurinhas a mais :slight_smile:

Nao se preocupe com o custo - elas sao soh classes, no fim das contas (passe um javap numa enum pra ver exatamente o que acontece, ou leia a spec ;))

Pessoal. Estou pensando em renomear o pacote cpfcnpj para id para colocar ali classes de identidade, Pis e coisas assim. O que vocês acham, devo renomear o cpfcnpj e por tudo junto ou criar um pacote id novo?

Aproveitando… Fiz uma verificação de CEP a partir da UF com base nas regiões definidas pelo Correio. Se você tem um cep e uma UF dá pra saber se aquele cep pode ou não estar em um determinado estado. Segue a classe de teste:

package org.brazilutils.test;

import org.brazilutils.br.endereco.Cep;
import org.brazilutils.br.endereco.UF;

import junit.framework.TestCase;

public class CepUfTest extends TestCase {
	/**CEP and UF check
	 * @throws Exception
	 */
	public void test3() throws Exception{
		Cep cepSP1 = new Cep("01.234.567"); // SP
		Cep cepSP2 = new Cep("11.234-567"); // SP
		Cep cepRJ = new Cep("21.021-380");  // RJ
		Cep cepRS = new Cep("91.021-380");  // RS
		UF rj = UF.RJ; // first digit 2
		UF sp = UF.SP; // first digit 0|1
		UF rs = UF.RS; // first digit 9
		// RJ 
		assertTrue(rj.cepMatches(cepSP1.toString()) == false);
		assertTrue(rj.cepMatches(cepSP2.toString()) == false);
		assertTrue(rj.cepMatches(cepRJ.toString()) == true);
		assertTrue(rj.cepMatches(cepRS.toString()) == false);
		// SP
		assertTrue(sp.cepMatches(cepSP1.toString()) == true);
		assertTrue(sp.cepMatches(cepSP2.toString()) == true);
		assertTrue(sp.cepMatches(cepRJ.toString()) == false);
		assertTrue(sp.cepMatches(cepRS.toString()) == false);
		// RS
		assertTrue(rs.cepMatches(cepSP1.toString()) == false);
		assertTrue(rs.cepMatches(cepSP2.toString()) == false);
		assertTrue(rs.cepMatches(cepRJ.toString()) == false);
		assertTrue(rs.cepMatches(cepRS.toString()) == true);
	}

}

Amanhã vou colocar o código no cvs, mas quem quiser tem aquele zip lá na página do projeto.

dsiviotti, test3() eh um nome de metodo ruim - ele nao diz o que vc ta testando… mais pra frente, num relatorio do JUnit, “3” nao vai te dizer nada sobre o teste que falhou :wink:

Que tal testCEPAceitaNumerosDeCEPValidosEmSP(), testCEPAceitaNumerosDeCEPValidosNoRJ(), testCEPAceitaNumerosDeCEPValidosNoRS(), e por ai vai?

Alias, pq assertTrue(… == true) e assertTrue(… == false) e nao assertTrue(…) e assertFalse(…) direto? :wink:

[quote=cv]
Alias, pq assertTrue(… == true) e assertTrue(… == false) e nao assertTrue(…) e assertFalse(…) direto? ;)[/quote]

Falou cv, nem sabia da existência do assertFalse(), tava usando true e false na comparação pra ficar mais legível, mas assertTrue/assertFalse fica melhor. :wink: Já está corrigido.

public class CepUfTest extends TestCase {
	/**CEP and UF check
	 * @throws Exception
	 */
	public void testUfValidaCep() throws Exception{
		Cep cepSP1 = new Cep("01.234.567"); // SP
		Cep cepSP2 = new Cep("11.234-567"); // SP
		Cep cepRJ = new Cep("21.021-380");  // RJ
		Cep cepRS = new Cep("91.021-380");  // RS
		UF rj = UF.RJ; // first digit 2
		UF sp = UF.SP; // first digit 0|1
		UF rs = UF.RS; // first digit 9
		// RJ 
		assertFalse(rj.cepMatches(cepSP1.toString()));
		assertFalse(rj.cepMatches(cepSP2.toString()));
		assertTrue(rj.cepMatches(cepRJ.toString()));
		assertFalse(rj.cepMatches(cepRS.toString()));
		// SP
		assertTrue(sp.cepMatches(cepSP1.toString()));
		assertTrue(sp.cepMatches(cepSP2.toString()));
		assertFalse(sp.cepMatches(cepRJ.toString()));
		assertFalse(sp.cepMatches(cepRS.toString()));
		// RS
		assertFalse(rs.cepMatches(cepSP1.toString()));
		assertFalse(rs.cepMatches(cepSP2.toString()));
		assertFalse(rs.cepMatches(cepRJ.toString()));
		assertTrue(rs.cepMatches(cepRS.toString()));
	}
}

Vou acertar os outros. Você memcionou testeCep…Rj, testCep…SP, acha necessário fazer um para cada UF? O mecanismo é basicamente o mesmo para todas usei 3 pra verificar se funcionava. O que muda é uma String passada como parâmetro para cada estado, ele testa o primeiro (os primeiros no futuro) caracteres e copara com esse parâmetro. Fazer 27 testes vai ser cruel.

Dei uma refinada na relação Cep/Uf. Agora um CEp sabe a qual Uf pertence através do método getUf() é possível determinar a UF de um CEP.

Cep cep = new Cep("21.021-380");
System.out.println(cep.getUf()); // a saída é RJ

Com isso dá pra validar um cep em um endereço que tenha uf.

Nos casos de AM, DF e GO as faixas não são contínuas, mas mesmo nestes já dá pra identificar a uf.

	public void testAmDfGoRange() throws Exception{
		// AM = 69000000 to 69299999 and 69400000 to 69899999
		Cep cepAM1 = new Cep("69.295-625"); // AM
		Cep cepAM2 = new Cep("69.355-625"); // RR !!!
		Cep cepAM3 = new Cep("69.455-625"); // AM
		Cep cepAM4 = new Cep("69.955-625"); // AC !!!
		assertTrue(cepAM1.getUf().equals(UF.AM));
		assertFalse(cepAM2.getUf().equals(UF.AM));
		assertTrue(cepAM2.getUf().equals(UF.RR));
		assertTrue(cepAM3.getUf().equals(UF.AM));
		assertFalse(cepAM4.getUf().equals(UF.AM));
		assertTrue(cepAM4.getUf().equals(UF.AC));
		// DF = 70000000 to 72799999 and 73000000 to 73699999
		// GO = 72800000 to 72999999 and 73700000 to 76799999
		Cep cepDF1 = new Cep("70.321.375");
		Cep cepDF2 = new Cep("73.621.375");
		Cep cepGO1 = new Cep("72.821.375");
		Cep cepGO2 = new Cep("73.721.375");
		assertTrue(cepDF1.getUf().equals(UF.DF));
		assertTrue(cepDF2.getUf().equals(UF.DF));
		assertTrue(cepGO1.getUf().equals(UF.GO));
		assertTrue(cepGO2.getUf().equals(UF.GO));	
	}

Também estou com um probleminha.No meu caso,em relação ao pack metrics…

Tenho muitos métodos burros, do tipo:

public BigDecimal convertAtmToPsi(double atm){
		BigDecimal result = new BigDecimal(atm*14.6959643206788);
		return result;
	}

O que acaba gerando classes com mais de 1000linhas…
Para ficar mais enxuto eu pensei em algo do tipo:

public BigDecimal convertToPsi(double value,int scale){ for... if(i==scale){ PSI_CONSTANT=PSI_CONST[i]; } BigDecimal result = new BigDecimal(value * PSI_CONSTANT); return result; }
Onde scale seria o num de casas decimais.
assim, a única classe inchada seria uma interface “carregada” de constantes referentes a diferentes casas decimais.Sugestões???

Não tenho certeza se entendi o problema. Coloca um zip lá na página do projeto (não no CVS) e eu dou uma olhada.

ironlynx, esse lance das constantes eh legal, mas eh detalhe de implementacao e nao deve ser exposto na API publica - o melhor seria ter, por exemplo, ATM.toPSI() e PSI.toATM(). Dica: BigDecimal nao eh final, voce pode estender :wink:

Pessoal,

Acabei criando um pacote novo “id” e deixei o cpfcnpj como está. No pacote id terá as classes RG (Identidade), CNH(Habilitação), CTPS (Carteira Profissional), TítuloEleitoral, Placa (de carro) PisPasep e o que mais surgir desse tipo. Essas classes não tem obrigatoriamente validação, mas em geral sõ compostas por várias partes, assim acho que ficão bem juntas.

Sobre as placas de carro o enum UF já reconhece uma placa de carro sendo de uma ou outra UF através das três letras da placa. Segue a classe de teste:

package org.brazilutils.test;

import junit.framework.TestCase;

import org.brazilutils.br.endereco.UF;
import org.brazilutils.br.id.Placa;

public class TestPlaca extends TestCase {
	
	/**test formats
	 * @throws Exception
	 */
	public void testPlaca() throws Exception {
		Placa placa = new Placa("ABC-1234");
		assertTrue(placa.toString().equals("ABC-1234"));
		placa.setPlaca("LLL4321");
		assertTrue(placa.toString().equals("LLL-4321"));
		placa.setLetters("mmm"); // lower
		placa.setNumbers("5555");
		assertTrue(placa.toString().equals("MMM-5555"));
	}

	/**Test UF
	 * @throws Exception
	 */
	public void testPlacaUf() throws Exception {
		Placa placa = new Placa("ABC-1234"); // PR
		assertTrue(placa.getUf().equals(UF.PR));
		placa.setPlaca("LLL-2143"); // RJ
		assertTrue(placa.getUf().equals(UF.RJ));
		placa.setPlaca("ZZZ-2211"); // invalid - out of range
		assertTrue(placa.getUf() == null);
		placa.setPlaca("BEZ-1234"); // LAST PR
		assertTrue(placa.getUf().equals(UF.PR));
		placa.setPlaca("BFA-1234"); // FIRST SP
		assertTrue(placa.getUf().equals(UF.SP));		
	}
}

Não sei se tem grande utilidade mas como era igual ao CEP achei que devia implementar. As classes que citei antes do pacote ID estão só na estrutura, se alguém tiver algo já pronto ou alguma idéia será bem-vinda.

Cv, eu isolei por unidades físicas(Energy,Pressure,Force…), senão eu teria incontáveis classes…(centenas, ou mais…) por isso eu deixei o convertToItem…deixando em cada classe, suas unidades correspondentes.
Acho q não pesquei o lance do BigDecimal.Vc tah querendo dizer para eu flexibilizar para extender qdo necessário???(Dê exemplos…)
Tô procurando na API, mas não tô achando… tem algum método para eu pegar só a quantidade passada de dígitos depois da vírgula?

Boa Douglas!!!
EDITADO:Tava procurando em biginteger não ia achar mesmo… hauhauha
É só usar o setScale()! :wink:
Mas Cv, explane melhor a sua idéia…

Parece que o problema do número de linhas poderia ser resolvido desmembrando a classe Energy mesmo. Energy passa a ser um pacote e BTU, Cal, Erg etc viram classes desse pacote. Fica melhor para dar manutenção. Ao invés de Energy.convertBtuToCal() seria BTU.toCal(). Não sei se alcancei o problema mas acho dessa forma mais simplificado.
Ainda não tinha idéia do tamanho do pacote metrics, agora vejo que ele vai crescer bastante.

Opa pessoal…

Duas coisas:

  • Tem alguma classe responsável por converter números romanos em números de verdade? Senão, onde posso criar?

  • O que que há com o CVS? Baxei e tá com erro de compilação, alguem sabe?

VELO