Package br.com.caelum.stella.validation

Source Code of br.com.caelum.stella.validation.RenavamValidator

package br.com.caelum.stella.validation;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import br.com.caelum.stella.DigitoPara;
import br.com.caelum.stella.MessageProducer;
import br.com.caelum.stella.SimpleMessageProducer;
import br.com.caelum.stella.ValidationMessage;
import br.com.caelum.stella.format.RenavamFormatter;
import br.com.caelum.stella.validation.error.RenavamError;

/**
* <p>
* Verifica se uma cadeia (String) representa um Renavam válido.
* </p>
*
* <p>
* O Renavam, ou Registro nacional de veículos automotores, é o número único de
* cada veículo e é composto de 10 (dez) dígitos, mais um digito verificador.
* </p>
*
* Formato do Renavam: "dddd.dddddd-d" onde "d" é um digito decimal.
*
* @author Rafael Carvalho
*/
public class RenavamValidator implements Validator<String> {

  public static final Pattern FORMATED = Pattern.compile("(\\d{4})[.](\\d{6})-(\\d{1})");
  public static final Pattern UNFORMATED = Pattern.compile("(\\d{4})(\\d{6})(\\d{1})");

    private boolean isFormatted = false;
    private MessageProducer messageProducer;

    /**
     * Construtor padrão de validador do Renavam. Este considera, por padrão,
     * que as cadeias estão formatadas e utiliza um
     * {@linkplain SimpleMessageProducer} para geração de mensagens.
     */
    public RenavamValidator() {
      this.messageProducer = new SimpleMessageProducer();
    }

    /**
     * Construtor de validador de Renavam. O validador utiliza um
     * {@linkplain SimpleMessageProducer} para geração de mensagens.
     *
     * @param isFormatted
     *            Informa se a cadeia de caracteres a ser validada está ou não
     *            formatada
     */
    public RenavamValidator(boolean isFormatted) {
        this.isFormatted = isFormatted;
        this.messageProducer = new SimpleMessageProducer();
    }

    /**
     * <p>
     * Construtor do validador de Renavam
     * </p>
     *
     * @param messageProducer
     *            produtor de mensagem de erro.
     * @param isFormatted
     *            Informa se a cadeia de caracteres a ser validada está ou não
     *            formatada
     */
    public RenavamValidator(MessageProducer messageProducer, boolean isFormatted) {
        this.isFormatted = isFormatted;
        this.messageProducer = messageProducer;
    }

    public void assertValid(String renavam) {
        List<ValidationMessage> errors = getInvalidValues(renavam);
        if (!errors.isEmpty()) {
      throw new InvalidStateException(errors);
    }
    }

    public List<ValidationMessage> invalidMessagesFor(String renavam) {
        return getInvalidValues(renavam);
    }

    /**
     * Valida se a cadeia está de acordo com as regras de validação do Renavam.
     *
     * @see br.com.caelum.stella.validation.Validator#assertValid(java.lang.Object)
     *
     * @param renavam
     *            Cadeia de caracteres representando o Renavam a ser validado
     * @return Uma lista de {@linkplain ValidationMessage} com os erros encontrados
     *         ou uma lista vazia, caso não haja nenhum erro.
     */
    private List<ValidationMessage> getInvalidValues(String renavam) {
        List<ValidationMessage> errors = new ArrayList<ValidationMessage>();
    if (renavam != null) {

      renavam = formataPadraoNovo(renavam);
     
      if (isFormatted && !FORMATED.matcher(renavam).matches()) {
        errors.add(messageProducer.getMessage(RenavamError.INVALID_FORMAT));
      }

      String unformatedRenavam = null;
      try {
        unformatedRenavam = new RenavamFormatter().unformat(renavam);
      } catch (IllegalArgumentException e) {
        errors.add(messageProducer.getMessage(RenavamError.INVALID_DIGITS));
        return errors;
      }
     
      if (unformatedRenavam.length() != 11 || !unformatedRenavam.matches("[0-9]*")) {
        errors.add(messageProducer.getMessage(RenavamError.INVALID_DIGITS));
      }

      String renavamSemDigito = unformatedRenavam.substring(0, unformatedRenavam.length() - 1);
      String digito = unformatedRenavam.substring(unformatedRenavam.length() - 1);

      String digitoCalculado = calculaDigito(renavamSemDigito);

      if (!digito.equals(digitoCalculado)) {
        errors.add(messageProducer.getMessage(RenavamError.INVALID_CHECK_DIGIT));
      }
    }
    return errors;
    }

  private String formataPadraoNovo(String renavam) {
    if ((isFormatted && renavam.length() == 11) || (!isFormatted && renavam.length() == 9)) {
      return "00" + renavam;
    }
    return renavam;
  }

  private String calculaDigito(String renavamSemDigito) {
      return new DigitoPara(renavamSemDigito).complementarAoModulo().trocandoPorSeEncontrar("0",10,11).mod(11).calcula();
  }

  public boolean isEligible(String renavam) {
        boolean isEligible;
        if (isFormatted) {
            isEligible = RenavamFormatter.FORMATTED.matcher(renavam).matches();
        } else {
            isEligible = RenavamFormatter.UNFORMATTED.matcher(renavam).matches();
        }
        return isEligible;
    }

}
TOP

Related Classes of br.com.caelum.stella.validation.RenavamValidator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.