br.com.nordestefomento.jrimum.vallia.digitoverificador.Modulo.java Source code

Java tutorial

Introduction

Here is the source code for br.com.nordestefomento.jrimum.vallia.digitoverificador.Modulo.java

Source

/* 
 * 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
     *   +---+---+---+---+---+-&gt;
     * </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 &lt;= ( 1 + 2 &lt;==12 ) ] = 24
     *   +---+---+---+---+---+-&gt; = (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);
    }
}