Java tutorial
/* * Copyright 2008 JRimum Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * Created at: 20/04/2008 - 18:11:05 * * ================================================================================ * * Direitos autorais 2008 JRimum Project * * Licenciado sob a Licena Apache, Verso 2.0 ("LICENA"); voc no pode * usar esse arquivo exceto em conformidade com a esta LICENA. Voc pode obter uma * cpia desta LICENA em http://www.apache.org/licenses/LICENSE-2.0 A menos que * haja exigncia legal ou acordo por escrito, a distribuio de software sob esta * LICENA se dar COMO EST??, SEM GARANTIAS OU CONDIES DE QUALQUER TIPO, sejam * expressas ou tcitas. Veja a LICENA para a redao especfica a reger permisses * e limitaes sob esta LICENA. * * Criado em: 20/04/2008 - 18:11:05 * */ package br.com.nordestefomento.jrimum.vallia.digitoverificador; import static br.com.nordestefomento.jrimum.utilix.ObjectUtil.isNotNull; import static br.com.nordestefomento.jrimum.vallia.digitoverificador.TipoDeModulo.MODULO10; import static br.com.nordestefomento.jrimum.vallia.digitoverificador.TipoDeModulo.MODULO11; import org.apache.commons.lang.StringUtils; import br.com.nordestefomento.jrimum.utilix.ObjectUtil; /** * <p> * Representa o mdulo no contexto de autenticao, ou seja, uma rotina que * auxilia no clculo do dgito verificador. * </p> * <p> * As rotinas tradicionais so Mdulo 10 e Mdulo 11. * </p> * * @author <a href="http://gilmatryx.googlepages.com/">Gilmar P.S.L.</a> * * @version 0.2 * * @since 0.2 */ public class Modulo { /** * */ private static final long serialVersionUID = -3612368544258125201L; /** * <p> * Mensagem da exceo lanada no mtodo calcular. * </p> */ private static final String O_ARGUMENTO_DEVE_CONTER_APENAS_NUMEROS = "O argumento deve conter apenas nmeros !"; /** *<p> * Valor inteiro do mdulo 10 * </p> */ public static final int MOD10 = TipoDeModulo.MODULO10.valor(); /** *<p> * Valor inteiro do mdulo 11 * </p> */ public static final int MOD11 = TipoDeModulo.MODULO11.valor(); /** *<p> * Tipo do mdulo * </p> */ private TipoDeModulo mod; /** *<p> * Valor inteiro do "peso" mnimo mutiplicador utilizado no clculo do * mdulo. * </p> */ private int limiteMaximo; /** *<p> * Valor inteiro do "peso" mximo mutiplicador utilizado no clculo do * mdulo. * </p> */ private int limiteMinimo; /** * <p> * Inicializa um mdulo com valores default. * </p> * * @param mod * tipo do mdulo * @see #initDefault * @see #calcule(String) * @since 0.2 */ public Modulo(TipoDeModulo mod) { super(); if (isNotNull(mod, "modulo")) { this.mod = mod; initDefault(); } } /** * <p> * Inicializa um mdulo com o tipo definido com valores default. * </p> * * @param limiteMaximo * peso mximo * @param limiteMinimo * peso mnimo * @param mod * tipo do mdulo * @see #calcule(String) * @since 0.2 */ public Modulo(TipoDeModulo mod, int limiteMaximo, int limiteMinimo) { super(); if (isNotNull(mod, "modulo")) { this.limiteMaximo = limiteMaximo; this.limiteMinimo = limiteMinimo; this.mod = mod; } } /** * <p> * Retorna o valor da instncia do mdulo de acordo com a <code>enum</code> * da instncia. * </p> * * <p> * Se por um acaso a instncia <code>enum</code> for nula uma * <code>NullPointerException</code> ser lanada. Caso a <code>enum</code> * contenha um mdulo no implementado por essa classe o retorno ser * <tt>-1</tt> * </p> * * @return valor da instncia do mdulo. * * @since 0.2 */ public int valor() { switch (mod) { case MODULO10: return MODULO10.valor(); case MODULO11: return MODULO11.valor(); default: return -1; } } /** * <p> * Executa o cculo do mdulo 11 com os limites definidos. * </p> * * <p> * Executa o mtodo <code>calculeSomaSequencialMod11</code> e aplica o * resultado em % 11 * </p> * * @param numero * @param limiteMin * @param limiteMax * @return resultado de calculeSomaSequencialMod11 % 11 * * @since 0.2 * @see #calculeSomaSequencialMod11(String, int, int) */ public static int calculeMod11(String numero, int limiteMin, int limiteMax) throws IllegalArgumentException { return (calculeSomaSequencialMod11(numero, limiteMin, limiteMax) % 11); } /** * <p> * Executa o cculo do mdulo 11 com os limites definidos. * </p> * * <p> * Transforma o <code>numero</code> em string e executa o mtodo * calculeMod11 * </p> * * @param numero * @param limiteMin * @param limiteMax * @return resultado do clculo * * @since 0.2 * @see #calculeMod11(String, int, int) */ public static int calculeMod11(long numero, int limiteMin, int limiteMax) { return calculeMod11(String.valueOf(numero), limiteMin, limiteMax); } /** * <p> * Realiza o clculo da soma na forma do mdulo 11. * </p> * <p> * O mdulo 11 funciona da seguinte maneira: * </p> * <p> * Cada dgito do nmero, comeando da direita para a esquerda (menos * significativo para o mais significativo), multiplicado pelo nmeros * limite mnimo, limite mnimo + 1, limite mnimo + 2 e assim * sucessivamente at o limite mxmio definido, ento inicia-se novamente a * contagem. * </p> * <p> * Exemplo para o nmero <tt>654321</tt>: * * <pre> * +---+---+---+---+---+---+ * | 6 | 5 | 4 | 3 | 2 | 1 | * +---+---+---+---+---+---+ * | | | | | | * x7 x6 x5 x4 x3 x2 * | | | | | | * =42 =30 =20 =12 =6 =2 * +---+---+---+---+---+-> * </pre * * </p> * * @param numero * @param limiteMin * @param limiteMax * @return * @throws IllegalArgumentException * * @since 0.2 */ public static int calculeSomaSequencialMod11(String numero, int limiteMin, int limiteMax) throws IllegalArgumentException { int peso = 0; int soma = 0; if (StringUtils.isNotBlank(numero) && StringUtils.isNumeric(numero)) { StringBuilder sb = new StringBuilder(numero); sb.reverse(); peso = limiteMin; for (char c : sb.toString().toCharArray()) { soma += peso * Character.getNumericValue(c); peso++; if (peso > limiteMax) peso = limiteMin; } } else throw new IllegalArgumentException(O_ARGUMENTO_DEVE_CONTER_APENAS_NUMEROS); return soma; } /** * <p> * Executa o cculo do mdulo 10 com os limites definidos. * </p> * * <p> * Transforma o <code>numero</code> em string e executa o mtodo * calculeMod10 * </p> * * @param numero * @param limiteMin * @param limiteMax * @return resultado do clculo * * @since 0.2 * @see #calculeMod10(String, int, int) */ public static int calculeMod10(long numero, int limiteMin, int limiteMax) { return calculeMod10(String.valueOf(numero), limiteMin, limiteMax); } /** * <p> * Executa o cculo do mdulo 10 com os limites definidos. * </p> * * <p> * Executa o mtodo <code>calculeSomaSequencialMod10</code> e aplica o * resultado em % 10 * </p> * * @param numero * @param limiteMin * @param limiteMax * @return resultado de calculeSomaSequencialMod10 % 10 * * @since 0.2 * @see #calculeSomaSequencialMod10(String, int, int) */ public static int calculeMod10(String numero, int limiteMin, int limiteMax) throws IllegalArgumentException { return (calculeSomaSequencialMod10(numero, limiteMin, limiteMax) % 10); } /** * <p> * Realiza o clculo da soma na forma do mdulo 10. * </p> * <p> * O mdulo 10 funciona da seguinte maneira: * </p> * <p> * Cada dgito do nmero, comeando da direita para a esquerda (menos * significativo para o mais significativo), multiplicado pelo nmeros * limite mnimo, limite mnimo + 1, limite mnimo + 2 e assim * sucessivamente at o limite mxmio definido, ento inicia-se novamente a * contagem. * </p> * <p> * Exemplo para o nmero <tt>123456</tt>: * * <pre> * +---+---+---+---+---+---+ * | 1 | 2 | 3 | 4 | 5 | 6 | * +---+---+---+---+---+---+ * | | | | | | * x1 x2 x1 x2 x1 x2 * | | | | | | * =1 =4 =3 =8 =5 =[ 3 <= ( 1 + 2 <==12 ) ] = 24 * +---+---+---+---+---+-> = (24 / 10) = 3, resto 3; Ento o mdulo igual a 3. * </pre> * * </p> * * <p> * Geralmente os limites para o mdulo 10 so mnimo 1 e mximo 2 apenas. * </p> * * @param numero * @param limiteMin * @param limiteMax * @return soma sequencial usada no clculo do mdulo * @throws IllegalArgumentException * * @since 0.2 */ public static int calculeSomaSequencialMod10(String numero, int limiteMin, int limiteMax) throws IllegalArgumentException { int produto = 0; int peso = 0; int soma = 0; if (StringUtils.isNotBlank(numero) && StringUtils.isNumeric(numero)) { StringBuilder sb = new StringBuilder(numero); sb.reverse(); peso = limiteMax; for (char c : sb.toString().toCharArray()) { produto = peso * Character.getNumericValue(c); if (produto > 9) { soma += produto / 10; soma += produto % 10; } else soma += produto; peso = (peso == limiteMax) ? limiteMin : limiteMax; } } else throw new IllegalArgumentException(O_ARGUMENTO_DEVE_CONTER_APENAS_NUMEROS); return soma; } /** * <p> * Executa o cculo do mdulo da instncia. * </p> * * @param numero * @return * @throws IllegalArgumentException * * @since 0.2 */ public int calcule(String numero) throws IllegalArgumentException { int modulo = 0; switch (mod) { case MODULO10: modulo = calculeMod10(numero, getLimiteMinimo(), getLimiteMaximo()); break; case MODULO11: modulo = calculeMod11(numero, getLimiteMinimo(), getLimiteMaximo()); break; } return modulo; } /** * <p> * Executa o cculo do mdulo da instncia. * </p> * * @param numero * @return * * @since 0.2 */ public int calcule(long numero) { return calcule(String.valueOf(numero)); } /** * <p> * Inicializa as variveis <code>limiteMaximo</code> e * <code>limiteMinimo</code> com os valores padres de acordo com a * instncia do mdulo da classe. * </p> * * <p> * Valores padres: <br /> * <br /> * <code>MODULO10</code>: (limiteMinimo = 1 e limiteMaximo = 2)<br /> * * <code>MODULO11</code>: (limiteMinimo = 2 e limiteMaximo = 9)<br /> * </p> * * @since 0.2 */ private void initDefault() { switch (mod) { case MODULO10: setLimiteMinimo(1); setLimiteMaximo(2); break; case MODULO11: setLimiteMinimo(2); setLimiteMaximo(9); break; } } /** * @return the limiteMaximo */ public int getLimiteMaximo() { return limiteMaximo; } /** * @param limiteMaximo * the limiteMaximo to set */ public void setLimiteMaximo(int limiteMaximo) { this.limiteMaximo = limiteMaximo; } /** * @return the limiteMinimo */ public int getLimiteMinimo() { return limiteMinimo; } /** * @param limiteMinimo * the limiteMinimo to set */ public void setLimiteMinimo(int limiteMinimo) { this.limiteMinimo = limiteMinimo; } /** * @return the mod */ public TipoDeModulo getMod() { return mod; } /** * @param mod * the mod to set */ public void setMod(TipoDeModulo mod) { this.mod = mod; } @Override public String toString() { return ObjectUtil.toString(this); } }