BrazilUtils 0.2

Vc pode mudar os nomes dos pacotes. Que seja TerritorialUnit , tudo bem. Unidades Federativas são consideradas TU pela ISO, então é só isso que interessa. O que as UF não são é estados. Mas ninguem está chamado state … então acho que tá tudo ok.

Na realidade os pacotes não interessam muito. Eu coloquei em BR porque é experimental. O que interessa ai é a estrutura em arvore que permite que o endereço seja formado por campos e estes campos variem de pais para pais ou dentro do propio pais.
Isto é muito esperimental e é uma alternativa ao modelo que estava sendo usado que é muito engessado ao brasil e até duvido que funcione em todo o brasil.

O que é o onlineconversion ??

Desculpe, eu achei que vc usava o CSV e o eclipse (que tem uma ferramenta de comparação de codigo). Da proxima vez eu aviso, se bem que não mexi nos pacotes existentes, excepto no UF.

[quote] O que interessa ai é a estrutura em arvore que permite que o endereço seja formado por campos e estes campos variem de pais para pais ou dentro do propio pais.
Isto é muito esperimental e é uma alternativa ao modelo que estava sendo usado que é muito engessado ao brasil e até duvido que funcione em todo o brasil.[/quote]
Saquei. :smiley:

É o maior site de conversões da net(claro q em tempos de google…), é um “mero” conversor.Mas indispensável quando necessário…

Eu uso Eclipse(3.3M5), mas não sei pq cargas d´agua eu não consigo me conectar ao CVS! :evil:
Aquele exemplo do CVS q vc tinha me mandado era antigo pacas…acho que o pessoal tinha esquecido de atualizar aquela parte(eu tava mandando em packs separados)!Vamos atualizar isso!

Apenas para demonstrar a utilidade de ferramentas específicas para melhorar o código-fonte sob vários aspectos, como FindBugs, PMD, Checkstyle, vejam a thread Cleaning up SwingX? . 8)

Sérgio, seu código vai para a nossa incubadora, assim vc pode desenvolvê-lo como bem entender, e quando opessoal tiver testado bastante, pode vir a se tornar estável.Rafael, explica aqui a idéia da incubadora.

[size=9]Ok, Ctrl+C / Ctrl+V do meu blog, sobre a incubadora.[/size]

A biblioteca BrazilUtils visa aumentar a qualidade e produtividade de programadores que precisem de rotinas específicas ligadas ao dia-a-dia brasileiro.

Para tanto, além das features (validações de CPF/CNPJ, conversões de medidas, normalização de endereços, e outras), é preciso contemplar aspectos não-funcionais, como compatibilidade entre diferentes versões do JDK e da própria BrazilUtils.

A confiabilidade da biblioteca está ligada à previsibilidade de seu comportamento. Exatamente por isso, a meta é não alterar a API da BrazilUtils. Mas, ao mesmo tempo, uma certa dose de flexibilidade é necessária para que a biblioteca possa evoluir.

Os usuários devem estar cientes sobre quais API’s estão maduras e estáveis e quais podem ser alteradas no futuro. Para tanto, a BrazilUtils possui o seu núcleo (core) e uma incubadora.

As API’s no núcleo da BrazilUtils não serão alteradas no futuro, garantindo a compatibilidade entre versões. A incubadora permitirá colocar código novo com mais liberdade. Será o local para ousar, aprender, inovar.

Geralmente, novas funcionalidades serão inseridas na incubadora; dependendo de sua evolução, de sua utilidade e do feedback dos usuários, serão promovidas ao núcleo. O core da BrazilUtils será distribuído separadamente da incubadora, que é opcional.

Sempre que houver mudanças importantes em cada lançamento da BrazilUtils, como a promoção de uma feature ou mudanças na API, essas mudanças serão noticiadas à comunidade.

Finalmente, comecei a melhorar o código fonte da BrazilUtils com o PMD. Por enquanto, só modifiquei as fontes da API de geração de código de barra. Dependendo do resultado, eu começo a alterar as outras API’s estáveis da v0.1.1.

Então mandem feedback e vejam se eu não fiz besteira. Eu testei, e parece que está tudo ok. As alterações já estão disponíveis no CVS. Qualquer coisa é só desfazer.

Algumas mudanças foram simples, como:

  • definir variáveis e parãmetros como final (final para todo lado)
  • colocar {} em if’s, for’s, etc
  • substituir throw RuntimeException e NullPointerException por IllegalArgumentException
  • retirar public das interfaces
  • eliminar imports (não utilizados)

Como podem notar, algumas mudanças foram referentes ao estilo. Isso é mais interessante de ser feito com o Checkstyle, pois assim cada um pode codificar da forma que quiser, mas, antes de enviar o código ao repositório, utilizá-se o Checkstyle para manter o estilo uniforme.

Mas acho que isso não é necessário por enquanto. A não ser que vocês se oponham a alguma convenção especifica como {} em if’s, etc, a retirada de public das interfaces e por aí vai.

Outras mudanças que considero mais importantes:

  • eliminei algumas variáveis (não utilizadas)

  • retornar cópia de vetores, ao invés do vetor original, evitando expor a estrutura interna da classe. Ex: [code]
    // Ao inves de …
    public int[] getWeights() {
    return this.weights;
    }

     // Temos
     public int[] getWeights() {
        final int length = this.weights.length;
        int[] copyWeights = new int[length];
        System.arraycopy(this.weights, 0, copyWeights, 0, length);
        return copyWeights;
    }[/code]
    

O inverso também é verdadeiro agora. Um método recebe um vetor diretamente do cliente, mas armazena e trabalha com uma cópia. Ex: [code]
// Antes…
public void setWeights(final int[] weights) {
if (weights == null) {
throw new NullPointerException(“Weights cannot be null.”);
}
this.weights = weigths;
}

   // Depois
   public void setWeights(final int[] weights) {
        if (weights == null) {
              throw new IllegalArgumentException("Weights cannot be null.");
        }
        final int length = weights.length;
        final int[] copyWeigths = new int[length];
        System.arraycopy(weights, 0, copyWeigths, 0, length);                            
        this.weights = copyWeigths;
  }[/code]

E por aí vai.

Continuando, agora na API de métricas. Surgiram dúvidas enquanto eu fazia as análises. Vamos primeiro às modificações que já fiz.

  • final para todo lado
  • conformidade com as convenções do JavaBeans. Na prática isso significa o uso de transient e mudança do nome de uma variável.
  • simplifiquei um pouco alguns métodos.

As dúvidas:

  1. Aquela classe BrazilianMetrics só está confundindo. Ironlynx, se você desistiu dela, por que ela ainda está por aí? (Ver http://guj.com.br/posts/list/30/53808.java#285534).

  2. Tem uma regra de degin no PMD que diz que não é uma boa ter constantes definidas em interfaces, pois estas devem definir apenas comportamento. Ex: [code]
    public interface LengthUnits {
    /**

    • meter is the standard basis
      */
      Unit METER=new Unit(“m”,new BigDecimal(String.valueOf(1)));
      Unit BRACES=new Unit(“br”,new BigDecimal(String.valueOf(0.546806649)));
      Unit CADEIAS=new Unit(“ca”,new BigDecimal(String.valueOf(0.0497096954)));
      Unit YARD=new Unit(“y”,new BigDecimal(String.valueOf(1.093613298)));

    Unit MILES=new Unit(“mi”,new BigDecimal(String.valueOf(0.000621371)));
    Unit NAUTIC_MILES=new Unit(“nmi”,new BigDecimal(String.valueOf(0.000539956803)));
    Unit FEET=new Unit(“f”,new BigDecimal(String.valueOf(3.280839895)));
    Unit INCH=new Unit(“in”,new BigDecimal(String.valueOf(39.37007874)));
    Unit KILOMETER=new Unit(“km”,new BigDecimal(String.valueOf(0.001)));
    }
    [/code]O que acha?

  3. A descrição de Area diz Area is the class which allow an application to convert area metrics into other area metrics, porém várias outra classes que não tem nada a ver com Area, como Temperature, utilizam Area. Por que? Não estou criticando, é que não entendi mesmo.

  4. Isso eu acho até grave: os métodos da interface Temperature começam com caixa alta, tipo CelsiusToKelvin().

  5. Cadê os testes unitários para a API de métricas?

  6. Não seria melhor utilizar BigDecimal do que double? double talvez não tenha muito utilidade quando alguém precisar dos valores exatos. Que tal double e Bigdecimal?

  7. Por que não utilizar métodos estáticos? Ex: na classe Power, ao invés de [code]
    public class Power {

    public double hpToWatt(final double energy){
    return energy*745.7;
    }

    public double wattToHp(final double energy){
    return energy/745.7;
    }
    }
    [/code] teriámos [code]
    public class Power {

    private Power() {
    }

    public static double hpToWatt(final double energy){
    return energy * 745.7;
    }

    public static double wattToHp(final double energy){
    return energy / 745.7;
    }
    }[/code]

Rafael eu já tinha pedido anteriormente para limparem!!!
Lembra do email que eu disse que tava com problemas no Elipse de comitar código lá no java.net?Sua role lhe permite isso, dá uma limpada lá…
Deve ter misturado tudo…na última vez tinha código de 2004 no meio…damn

[quote]2) Tem uma regra de degin no PMD que diz que não é uma boa ter constantes definidas em interfaces, pois estas devem definir apenas
comportamento.[/quote]
Na verdade eu cheguei a perguntar aqui e alguns concordaram que iria para interface e parte para uma UtilityClass.Eu, para fins práticos, prefiro uma interface(poucas constantes), mas acho que deveria sim estar numa Classe de Utilidades, devido ao número, e para não deixar uma interface sem comportamento.Sinta-se livre para refatorar isso.

Acho que os testes não subiram, e essa classe Temperature pode esqueçer.Com a JSR-275, vamos nos concentrar no que existam métricas internacionais, mas que existam também as nacionais(como as unidades de área).
Double???Caralho, essas classes com double são de 2004!!!Tem que ser TUDO String(se necessário) e BD!!!
Sinta-se livre para refatorar isso, pq no momento eu já tô quase tomando
Haldol aqui lidando com tantos clientes burros.(OBS.:Não estou falando de máquinas isoladas da rede, os chamados terminais burros não, estou falando de antas, antílopes e energúmenos que acham que podem mudar de requisitos como quem troca de roupa)

Depois eu vou lhe pedir dicas de como mexer no PMD. :wink:

Já excluí a BrazilianMetrics. Estou a fim passar a borracha no pacote org.brazilutils.currency, que também só está servindo para confundir.


Pode me enviar os testes de unidade? Por e-mail mesmo.


Estava assim: [code]
public interface VelocityUnits {

Unit KILOMETER_PER_HOUR = new Unit("km/h", new BigDecimal(String.valueOf(1)));
Unit METER_PER_SECOND = new Unit("m/s", new BigDecimal(String.valueOf(0.27777)));
Unit MILES_PER_HOUR = new Unit("mi/h", new BigDecimal(String.valueOf(1.609)));
Unit NAUTIC_MILES_PER_HOUR = new Unit("nmi/h", new BigDecimal(String.valueOf(1.852)));
Unit BASE=KILOMETER_PER_HOUR;

}[/code]

[code]
public class Velocity implements UnitWithValue, VelocityUnits {
private static final long serialVersionUID = 211046785217178583L;
private Unit unit;
private transient BigDecimal value;
private final transient BigDecimal base;

public Velocity(BigDecimal value,Unit unit){
	this.base = value.multiply(unit.getValueOnBaseUnit());
	this.value = value;
	this.unit = unit;
}
	
public UnitWithValue convertTo(
		final Unit unit, final int scale, final int roundingmode) {
	
	return new Area(
			base.divide(unit.getValueOnBaseUnit(),scale,roundingmode),
			unit);
}
	
public Unit getUnit(){
	return unit;
}

public void setUnit(final Unit u) {
	this.unit = u;
	this.value = base.divide(unit.getValueOnBaseUnit());
}

public BigDecimal getValue(){
	return value;
}

public String toString() {
	return getValue().toString();
}

}[/code] Ficou assim: [code]
public class Velocity implements UnitWithValue {
private static final long serialVersionUID = 211046785217178583L;

public static final Unit KILOMETER_PER_HOUR = new Unit("km/h", new BigDecimal(String.valueOf(1)));
public static final Unit METER_PER_SECOND = new Unit("m/s", new BigDecimal(String.valueOf(0.27777)));
public static final Unit MILES_PER_HOUR = new Unit("mi/h", new BigDecimal(String.valueOf(1.609)));
public static final Unit NAUTIC_MILES_PER_HOUR = new Unit("nmi/h", new BigDecimal(String.valueOf(1.852)));
public static final Unit BASE = KILOMETER_PER_HOUR;

private Unit unit;
private transient BigDecimal value;
private final transient BigDecimal base;

public Velocity(BigDecimal value,Unit unit){
	this.base = value.multiply(unit.getValueOnBaseUnit());
	this.value = value;
	this.unit = unit;
}
	
. . .

}[/code]
Que tal? Acho que não precisa de uma classe de utilidades.


Há 3 classes envolvidas com temperatura: org.brazilutils.metrics.Temperature, org.brazilutils.metrics.TemperatureUnits e org.brazilutils.metrics.conversion.Temperature Excluo as três?


Então já andou fuçando na JSR 275?
Provavelmente a API de métricas da BrazilUtils terá que lidar com a JSR 275. Será uma extensão dessa especificação? De alguma forma as duas API’s terão que se relacionar. Melhor repensar a missão da nossa API de métricas, não?

Pelo que vi, eles já estão pensando em internacionalização. Mas, como você mesmo me disse e como está subentendido na página da JSR 275, eles não irão cobrir todas as unidades de medidas em uso na Terra.


Era assim: [code]
public class Power {

public double hpToWatt(final double energy){
return energy * 745.7;
}

. . .
}[/code] Ficou: [code]
public class Power {

private static final BigDecimal CONSTANT = new BigDecimal("745.7");

public BigDecimal hpToWatt(final BigDecimal energy) {
	return energy.multiply(CONSTANT);
}

public BigDecimal hpToWatt(final String energy) {
	return hpToWatt(new BigDecimal(energy));
}

. . .
}[/code]
Está de acordo?

CONSTANT é porque não sei qual o nome da constante (magic number, né?). Depois você terá que rever o nome dessa e demais constantes.


Boa sorte com os seus usuários! Quando for a minha vez de apanhar deles, me dê umas dicas para que eu também dispense o Haldol! :stuck_out_tongue:

Cara, agora eu não sei onde foi que eu pûs(até pq eu mudei várias vezes), mas foi algo mais ou menos assim pegando um esboço aqui (usando o JUnit antigo, que não usa anotações para compatibilidades com java 1.4):

[code]

public class MetricsTestCase extends TestCase {
protected Area firstValue;
protected Area secondValue;
protected Area thirdValue;
protected Area stringValue;

public void setUp(){
	firstValue=new Area(new BigDecimal(10000),Area.M2);
	secondValue=new Area(new BigDecimal(234000012),Area.M2);
	thirdValue=new Area(new BigDecimal(789234012.12),Area.M2);
}

public void testConversionSquareMetersToHectaresMustNeverLostPrecisionValue(){
	assertEquals(new BigDecimal(1.0000000000000000000000000000000000),firstValue.convertTo(Area.HECTARE,34, BigDecimal.ROUND_HALF_EVEN));
}//irá falhar	
public void testConversionSquareMetersToHectaresWithTenDecimalPlacesMustNeverLostPrecision(){
	assertEquals(new BigDecimal(1.0000000000),firstValue.convertTo(Area.HECTARE,10, BigDecimal.ROUND_HALF_EVEN));	
}//irá falhar	
public void testConversionSquareMetersToAcresMustNeverLostPrecisionValue(){
	assertEquals(new BigDecimal(2.4710538146716534224824392919880626),firstValue.convertTo(Area.ACRE,34, BigDecimal.ROUND_HALF_EVEN));
	
}//irá falhar	
public void testIfObjectIsNull(){
	assertNotNull("O objeto está com valor null!!!",secondValue);
}//jamais falha	

}[/code]

Kill!!!

Nem sabemos se irá a frente né…algumas coisas estão meio turvas na minha cabeça aqui:

será que dará m… com as métricas não SI?

Exato. :?

Y!, mas nem era para essa classe estar aí…(quanto mais esses doubles) era só para estar as unidades de área,peso e comprimento.(Lembrando que eu uso o onlineconversion como base para pegar as constantes).

O problema do método getWeights não é o array ser modificado é o próprio método em si. Os pesos são fixos, ninguém em sua perfeita sanidade mental os irá alterar. Se pensa que esse tipo de pessoas existe, então não retorne um array de int , retorne uma coleção inalterável de Integer ou, melhor ainda um objecto que encapsule os pesos.
Mas se o método for protected, como deveria, o fato de retornar copias é irrelevante pois a responsablidade continua na mesma classe, ou numa filha O próprio método deveria ser removido e subtituido por um método de calculo que recebe o outro array. Isso simplifica o problema e inverte a responsabilidade. Outras soluções são possiveis, como a que está contida no codigo que passei antes.

Fazer cópias de arrays para um métodos como esse é um exemplo de sobre engenharia.

[quote=RafaelRio]
2) Tem uma regra de degin no PMD que diz que não é uma boa ter constantes definidas em interfaces, pois estas devem definir apenas comportamento. Ex: [code]
public interface LengthUnits {
/**
* meter is the standard basis
*/
Unit METER=new Unit(“m”,new BigDecimal(String.valueOf(1)));
Unit BRACES=new Unit(“br”,new BigDecimal(String.valueOf(0.546806649)));
Unit CADEIAS=new Unit(“ca”,new BigDecimal(String.valueOf(0.0497096954)));
Unit YARD=new Unit(“y”,new BigDecimal(String.valueOf(1.093613298)));

Unit MILES=new Unit("mi",new BigDecimal(String.valueOf(0.000621371)));
Unit NAUTIC_MILES=new Unit("nmi",new BigDecimal(String.valueOf(0.000539956803)));
Unit FEET=new Unit("f",new BigDecimal(String.valueOf(3.280839895)));
Unit INCH=new Unit("in",new BigDecimal(String.valueOf(39.37007874)));
Unit KILOMETER=new Unit("km",new BigDecimal(String.valueOf(0.001)));

}
[/code]O que acha?[/quote]

Use o design pattern enum. Este design pattern foi criado para eliminar o problema que o PMD indica. O padrão é tão bom que virou um dos tipos do java no java 5.0 , mas pode ser criado facilmente no 1.4 usando um construtor privado e constantes estáticas e publicas .Exemplo


public class Unit {

  public final static Unit MILES=new Unit("mi",new BigDecimal(String.valueOf(0.000621371)));

  private Unit (...) 

  ...
}

P.S. Se não quiser o contrutor private pode ser public, mas ai não será o padrão enum. Contudo, resolve o problema de não ter constantes em interfaces.

Hum, procede…
Sérgio, estamos agora usando o forum do java.net para não criarmos tantos tópicos sobre o BU aqui, é só ir lá:
https://brazilutils.dev.java.net/servlets/ProjectForumView
E postar a vontade!!!

Eu não sei se poderia estar postando esta duvida aqui, mais como eu faço para rodar ele num sisteminha web?

Olá pessoal!!

Parabéns a todos que estão participando do BrasilUtilz!!
Estou usando e gostei mt e está se encaixando na aplicação que trabalho hoje.
Tenho uma duvida referente a documentação, vocês tem a documentação que se basearam para validar uma Inscrição Estadual.
Tenho que ter uma base para afirmar que a inscrição é inválida, ou seja é invalida pelo motivo x ou y.

Grato
Léo

Usa o Caellum Stella, BrazilUtils tá morto há muito tempo.

Caraca, não vi nada do tipo… que encerraram e tal, mas blz.
Já fiz algumas coisinhas com ele agora, jogo fora ou as regras utilizadas tem algum embasamento?

Quanto às regras de inscrições estaduais, pegamos daqui:

http://www.sintegra.gov.br/insc_est.html

tem os fontes que retratam sobre Inscrição Estadual disponíveis?

ops… nao precisa, eu tenho aqui no jar.

vlw