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: 30/03/2008 - 18:07:11 * * ================================================================================ * * 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: 30/03/2008 - 18:07:11 * */ package org.jrimum.bopepo.campolivre; import static java.lang.String.format; import static java.math.BigDecimal.ZERO; import static org.jrimum.domkee.financeiro.banco.febraban.Banco.isCodigoDeCompensacaoOK; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.jrimum.bopepo.BancosSuportados; import org.jrimum.domkee.financeiro.banco.febraban.Titulo; import org.jrimum.utilix.Objects; import org.jrimum.utilix.text.AbstractLineOfFields; import org.jrimum.utilix.text.Field; import org.jrimum.utilix.text.Strings; /** * <p> * Esta classe responsvel por determinar a interface campo livre e tambm * determinar qual implementao de campo livre se aplica a um determinado * ttulo. * </p> * * <p> * Uma outra forma de analisar esta classe sob o prisma de uma Abstract * Factory. * </p> * * <p> * <dl> * <dt><strong>Field Livre:</strong> * <dd> um espao reservado no cdigo de barras e a sua implementao varia de * banco para banco.</dd></dt> * </dl> * </p> * * * @author <a href="http://gilmatryx.googlepages.com/">Gilmar P.S.L</a> * @author <a href="mailto:misaelbarreto@gmail.com">Misael Barreto</a> * @author <a href="mailto:romulomail@gmail.com">Rmulo Augusto</a> * @author <a href="mailto:lukas.antunes@virtualsistemas.com.br">Lukas * Antunes</a> - Colaborador com o banco Intermedium (077) * @author <a href="mailto:fernandobgi@gmail.com">Fernando Dias</a> - * Colaborador com o banco Rural (453) * @author <a href="mailto:pporto@gmail.com">Paulo Porto</a> - * Colaborador com o Banco do Nordeste do Brasil (004). * * @since 0.2 * * @version 0.2 */ abstract class AbstractCampoLivre extends AbstractLineOfFields implements CampoLivre { /** * {@code serialVersionUID = 4605730904122445595L} */ private static final long serialVersionUID = 4605730904122445595L; /** * Looger. */ private static Logger log = Logger.getLogger(Objects.class); /** * Nosso nmero com 7 posies. */ static final int NN7 = 7; /** * Nosso nmero com 8 posies. */ static final int NN8 = 8; /** * Nosso nmero com 9 posies. */ static final int NN9 = 9; /** * Nosso nmero com 10 posies. */ static final int NN10 = 10; /** * Nosso nmero com 11 posies. */ static final int NN11 = 11; /** * Nosso nmero com 14 posies. */ static final int NN14 = 14; /** * Nosso nmero com 15 posies. */ static final int NN15 = 15; /** * Nosso nmero com 17 posies. */ static final int NN17 = 17; /** * <p>Subclasses no precisam definir o tamanho.</p> */ private AbstractCampoLivre(Integer fieldsLength, Integer stringLength) { super(fieldsLength, stringLength); } /** * <p>Cria um campo livre com um determinado nmero de campos</p> * * @param fieldsLength - Nmero de campos */ protected AbstractCampoLivre(Integer fieldsLength) { super(fieldsLength, CampoLivre.STRING_LENGTH); } /** * <p> * Cria um campo livre a partir dos dados contidos no ttulo fornecido. * </p> * * @param titulo * com todos os dados para a gerao do campo livre * @return instncia de campo livre ou nulo. * @throws NotSupportedBancoException * Caso o banco informado na conta bancria no tenha nenhuma * implementao de campo livre. * @throws NotSupportedCampoLivreException * Caso exista implementaes de campo livre para o banco * informa na conta bancria, mas nenhuma dessas implementaes * foram adequadas para os dados do ttulo. * @throws CampoLivreException * Caso ocorra algum problema na gerao do campo livre. */ protected static CampoLivre create(Titulo titulo) throws NotSupportedBancoException, NotSupportedCampoLivreException, CampoLivreException { if (log.isTraceEnabled()) { log.trace("Instanciando Campo livre"); } if (log.isDebugEnabled()) { log.debug("titulo instance : " + titulo); } try { checkTituloNotNull(titulo); checkContaBancariaNotNull(titulo); checkBancoNotNull(titulo); if (log.isDebugEnabled()) { log.debug(format("Campo Livre do Banco: %s", titulo.getContaBancaria().getBanco().getNome())); } if (BancosSuportados.isSuportado( titulo.getContaBancaria().getBanco().getCodigoDeCompensacaoBACEN().getCodigoFormatado())) { final BancosSuportados banco = BancosSuportados.suportados.get( titulo.getContaBancaria().getBanco().getCodigoDeCompensacaoBACEN().getCodigoFormatado()); switch (banco) { case BANCO_BRADESCO: return AbstractCLBradesco.create(titulo); case BANCO_DO_BRASIL: return AbstractCLBancoDoBrasil.create(titulo); case BANCO_DO_NORDESTE_DO_BRASIL: return AbstractCLBancoDoNordesteDoBrasil.create(titulo); case BANCO_ABN_AMRO_REAL: return AbstractCLBancoReal.create(titulo); case CAIXA_ECONOMICA_FEDERAL: return AbstractCLCaixaEconomicaFederal.create(titulo); case HSBC: return AbstractCLHSBC.create(titulo); case UNIBANCO: return AbstractCLUnibanco.create(titulo); case BANCO_ITAU: return AbstractCLItau.create(titulo); case BANCO_SAFRA: return AbstractCLBancoSafra.create(titulo); case BANCO_DO_ESTADO_DO_RIO_GRANDE_DO_SUL: return AbstractCLBanrisul.create(titulo); case MERCANTIL_DO_BRASIL: return AbstractCLMercantilDoBrasil.create(titulo); case NOSSA_CAIXA: return AbstractCLNossaCaixa.create(titulo); case BANCO_DO_ESTADO_DO_ESPIRITO_SANTO: return AbstractCLBanestes.create(titulo); case BANCO_RURAL: return AbstractCLBancoRural.create(titulo); case BANCO_SANTANDER: return AbstractCLSantander.create(titulo); case BANCO_INTEMEDIUM: return AbstractCLBancoIntermedium.create(titulo); case BANCO_SICREDI: return AbstractCLSicredi.create(titulo); case BANCOOB: return AbstractCLBancoob.create(titulo); default: /* * Se chegar neste ponto e nenhum campo livre foi definido, ento * sinal de que existe implementaes de campo livre para o banco em * questo, s que nenhuma destas implementaes serviu e a classe * abstrata responsvel por fornecer o campo livre no gerou a * exceo NotSupportedCampoLivreException. Trata-se de uma mensagem * genrica que ser utilizada somente em ltimo caso. */ throw new NotSupportedCampoLivreException( "No h implementaes de campo livre para o banco " + titulo.getContaBancaria().getBanco().getCodigoDeCompensacaoBACEN() .getCodigoFormatado() + " compatveis com as " + "caracterticas do ttulo informado."); } } else { /* * Se chegar at este ponto, sinal de que para o banco em * questo, apesar de estar definido no EnumBancos, no h * implementaes de campo livre, logo considera-se o banco com * no suportado. */ throw new NotSupportedBancoException(); } } catch (CampoLivreException e) { /* * Caso seja uma exceo esperada. */ throw e; } catch (Exception e) { /* * Encapsula-se qualquer outra exceo. */ throw new CampoLivreException(e); } } /** * <p> * Constri um campo livre aps executar os mtodos * {@link #checkValues(Titulo)} e {@link #addFields(Titulo)}, retornando em * seguida esta instncia pronta para escrita. * </p> * * @param titulo * * @return a instncia pronta para escrita * * @since 0.2 */ protected final CampoLivre build(Titulo titulo) { checkValues(titulo); addFields(titulo); return this; } /** * <p> * Usado pelo mtodo {@link #build(Titulo)} para verificar a consistncia do * campo livre. Se algum inconsistncia for verificada, este mtodo dever * lana-la. * </p> * * @param titulo * * @since 0.2 */ protected abstract void checkValues(Titulo titulo); /** * <p> * Usado pelo mtodo {@link #build(Titulo)}, adiciona os campos do campo * livre deixando-o pronto para escrita. * </p> * * @param titulo * * @since 0.2 */ protected abstract void addFields(Titulo titulo); /** * <p> * Gera o campo livre a parir dos campos armazenados sem verificar se est * compatvel com nmero de fields declarado pelo campo livre. Isso implica * que a string retornada poder ser menor do que 25 caracteres. * </p> * * @return string a partir dos campos contidos at o momento. * * @since 0.2 */ protected final String writeFields() { StringBuilder campoLivreAtual = new StringBuilder(); for (Field<?> f : this) { campoLivreAtual.append(f.write()); } return campoLivreAtual.toString(); } /* * Validaes inicias. */ /** * <p> * Verifica se o ttulo no nulo, seno lana uma {@code * IllegalArgumentException}. * </p> * * @param titulo * * @since 0.2 */ private static void checkTituloNotNull(Titulo titulo) { Objects.checkNotNull(titulo, "Ttulo no pode ser nulo!"); } /** * <p> * Verifica se a conta bancria do ttulo no nula, seno lana uma * {@code IllegalArgumentException}. * </p> * * @param titulo * * @since 0.2 */ private static void checkContaBancariaNotNull(Titulo titulo) { Objects.checkNotNull(titulo.getContaBancaria(), "Conta bancria do ttulo no pode ser nula!"); } /** * <p> * Verifica se o banco da conta bancria do ttulo no nulo, seno lana * uma {@code IllegalArgumentException}. * </p> * * @param titulo * * @since 0.2 */ private static void checkBancoNotNull(Titulo titulo) { Objects.checkNotNull(titulo.getContaBancaria().getBanco(), "Banco da conta bancria do ttulo no pode ser nulo!"); boolean expression = isCodigoDeCompensacaoOK( titulo.getContaBancaria().getBanco().getCodigoDeCompensacaoBACEN().getCodigoFormatado()); Objects.checkArgument(expression, format("Cdigo de compensao [%s] invlido!", titulo.getContaBancaria().getBanco().getCodigoDeCompensacaoBACEN().getCodigoFormatado())); } /* * Validaes para subclasses. */ /** * <p> * Verifica se a carteira da conta bancria do ttulo no nula, seno * lana uma {@code IllegalArgumentException}. * </p> * * @param titulo * * @since 0.2 */ protected final static void checkCarteiraNotNull(Titulo titulo) { Objects.checkNotNull(titulo.getContaBancaria().getCarteira(), "Carteira da conta bancria do ttulo no pode ser nula!"); } /** * <p> * Verifica se o tipo da carteira da conta bancria do ttulo no nulo, * seno lana uma {@code IllegalArgumentException}. * </p> * * @param titulo * * @since 0.2 */ protected final static void checkRegistroDaCarteiraNotNull(Titulo titulo) { Objects.checkNotNull(titulo.getContaBancaria().getCarteira().getTipoCobranca(), "Tipo de cobrana (COM ou SEM registro) da carteira no pode ser nulo!"); } /** * <p> * Verifica se o cdigo da carteira da conta bancria do ttulo no nulo e * se um nmero > 0, caso contrrio lana uma {@code * IllegalArgumentException}. * </p> * * @param titulo * * @since 0.2 */ protected final static void checkCodigoDaCarteira(Titulo titulo) { Objects.checkNotNull(titulo.getContaBancaria().getCarteira().getCodigo(), "Cdigo da carteira no pode ser nulo!"); boolean expression = titulo.getContaBancaria().getCarteira().getCodigo() > 0; Objects.checkArgument(expression, format("Cdigo da carteira deve ser um nmero inteiro natural positivo e no [%s].", titulo.getContaBancaria().getCarteira().getCodigo())); } /** * <p> * Verifica se o cdigo da carteira da conta bancria do ttulo um nmero * menor que ou igual ao limite informado, caso contrrio lana uma {@code * IllegalArgumentException}. * </p> * * @param titulo * @param limite - Limite mximo permitido * * @since 0.2 */ protected final static void checkCodigoDaCarteiraMenorOuIgualQue(Titulo titulo, int limite) { boolean expression = titulo.getContaBancaria().getCarteira().getCodigo() <= limite; Objects.checkArgument(expression, format("Cdigo [%s] da carteira deve ser um nmero menor que ou igual a [%s].", titulo.getContaBancaria().getCarteira().getCodigo(), limite)); } /** * <p> * Verifica se a agncia da conta bancria do ttulo no nula, seno lana * uma {@code IllegalArgumentException}. * </p> * * @param titulo * * @since 0.2 */ protected final static void checkAgenciaNotNull(Titulo titulo) { Objects.checkNotNull(titulo.getContaBancaria().getAgencia(), "Agncia bancria do ttulo no pode ser nula!"); } /** * <p> * Verifica se o cdigo do nmero da agncia bancria no nulo e se * um nmero > 0, caso contrrio lana uma {@code IllegalArgumentException}. * </p> * * @param titulo * * @since 0.2 */ protected final static void checkCodigoDaAgencia(Titulo titulo) { Objects.checkNotNull(titulo.getContaBancaria().getAgencia().getCodigo(), "Cdigo da agncia bancria no pode ser nulo!"); boolean expression = titulo.getContaBancaria().getAgencia().getCodigo() > 0; Objects.checkArgument(expression, format("Cdigo da agncia bancria deve ser um nmero inteiro natural positivo e no [%s].", titulo.getContaBancaria().getAgencia().getCodigo())); } /** * <p> * Verifica se o cdigo do nmero da agncia da conta bancria do ttulo * um nmero menor que ou igual ao limite informado, caso contrrio lana uma {@code * IllegalArgumentException}. * </p> * * @param titulo * @param limite * - Limite mximo permitido * * @since 0.2 */ protected final static void checkCodigoDaAgenciaMenorOuIgualQue(Titulo titulo, int limite) { boolean expression = titulo.getContaBancaria().getAgencia().getCodigo() <= limite; Objects.checkArgument(expression, format("Cdigo [%s] da agncia deve ser um nmero menor que ou igual a [%s].", titulo.getContaBancaria().getAgencia().getCodigo(), limite)); } /** * <p> * Verifica se o dgito verificador da agncia da conta bancria no nulo, * no vazio e se numrico, caso contrrio lana uma {@code * IllegalArgumentException}. * </p> * * @param titulo * * @since 0.2 */ protected final static void checkDigitoDoCodigoDaAgencia(Titulo titulo) { Objects.checkNotNull(titulo.getContaBancaria().getAgencia().getDigitoVerificador(), "Dgito verificador da agncia bancria no pode ser nulo!"); Strings.checkNotBlank(titulo.getContaBancaria().getAgencia().getDigitoVerificador(), format("Dgito verificador [\"%s\"] da agncia bancria no pode ser vazio!", titulo.getContaBancaria().getAgencia().getDigitoVerificador())); Strings.checkNotNumeric(titulo.getContaBancaria().getAgencia().getDigitoVerificador(), format("Nesse contexto o dgito verificador [\"%s\"] da agncia bancria deve ser numrico!", titulo.getContaBancaria().getNumeroDaConta().getDigitoDaConta())); } /** * <p> * Verifica se o nmero da conta da conta bancria do ttulo no nulo, * seno lana uma {@code IllegalArgumentException}. * </p> * * @param titulo * * @since 0.2 */ protected final static void checkNumeroDaContaNotNull(Titulo titulo) { Objects.checkNotNull(titulo.getContaBancaria().getNumeroDaConta(), "Nmero da conta bancria do ttulo no pode ser nulo!"); } /** * <p> * Verifica se o cdigo do do nmero da conta bancria no nulo e se um * nmero > 0, caso contrrio lana uma {@code IllegalArgumentException}. * </p> * * @param titulo * * @since 0.2 */ protected final static void checkCodigoDoNumeroDaConta(Titulo titulo) { Objects.checkNotNull(titulo.getContaBancaria().getNumeroDaConta().getCodigoDaConta(), "Cdigo do nmero da conta bancria no pode ser nulo!"); boolean expression = titulo.getContaBancaria().getNumeroDaConta().getCodigoDaConta() > 0; Objects.checkArgument(expression, format( "Cdigo do nmero da conta bancria deve ser um nmero inteiro natural positivo e no [%s].", titulo.getContaBancaria().getNumeroDaConta().getCodigoDaConta())); } /** * <p> * Verifica se o cdigo do nmero da conta bancria do ttulo um nmero * menor que ou igual ao limite informado, caso contrrio lana uma {@code * IllegalArgumentException}. * </p> * * @param titulo * @param limite - Limite mximo permitido * * @since 0.2 */ protected final static void checkCodigoDoNumeroDaContaMenorOuIgualQue(Titulo titulo, int limite) { boolean expression = titulo.getContaBancaria().getNumeroDaConta().getCodigoDaConta() <= limite; Objects.checkArgument(expression, format("Cdigo [%s] do nmero da conta deve ser um nmero menor que ou igual a [%s].", titulo.getContaBancaria().getNumeroDaConta().getCodigoDaConta(), limite)); } /** * <p> * Verifica se o dgito verificador do nmero da conta bancria no nulo, * no vazio e se numrico, caso contrrio lana uma {@code * IllegalArgumentException}. * </p> * * @param titulo * * @since 0.2 */ protected final static void checkDigitoDoCodigoDoNumeroDaConta(Titulo titulo) { Objects.checkNotNull(titulo.getContaBancaria().getNumeroDaConta().getDigitoDaConta(), "Dgito verificador do nmero da conta bancria no pode ser nulo!"); Strings.checkNotBlank(titulo.getContaBancaria().getNumeroDaConta().getDigitoDaConta(), format("Dgito verificador [\"%s\"] do nmero da conta bancria no pode ser vazio!", titulo.getContaBancaria().getNumeroDaConta().getDigitoDaConta())); Strings.checkNotNumeric(titulo.getContaBancaria().getNumeroDaConta().getDigitoDaConta(), format("Nesse contexto o dgito verificador [\"%s\"] do nmero da conta deve ser numrico!", titulo.getContaBancaria().getNumeroDaConta().getDigitoDaConta())); } /** * <p> * Verifica se onosso nmero do ttulo no nulo, no vazio e se * numrico, caso contrrio lana uma {@code IllegalArgumentException}. * </p> * * @param titulo * * @since 0.2 */ protected final static void checkNossoNumero(Titulo titulo) { Objects.checkNotNull(titulo.getNossoNumero(), "Nosso nmero do ttulo no pode ser nulo!"); Strings.checkNotBlank(titulo.getNossoNumero(), format("Nosso nmero [\"%s\"] do ttulo no pode ser vazio!", titulo.getNossoNumero())); Strings.checkNotNumeric(titulo.getNossoNumero(), format("Nosso nmero [\"%s\"] do ttulo deve conter somente dgitos numricos!", titulo.getNossoNumero())); } /** * <p> * Verifica se o nosso nmero do ttulo tem o tamanho determinado, caso * contrrio lana uma {@code IllegalArgumentException} com a mensagem * <tt>"Tamanho do nosso nmero [%s] diferente do esperado [%s]!"</tt>. * </p> * * @param titulo * @param length * - Tamanho que deve ser * * @since 0.2 */ protected final static void checkTamanhoDoNossoNumero(Titulo titulo, int length) { checkTamanhoNossoNumero(titulo, length, format("Tamanho [%s] do nosso nmero [\"%s\"] diferente do esperado [%s]!", StringUtils.length(titulo.getNossoNumero()), titulo.getNossoNumero(), length)); } /** * <p> * Verifica se o nosso nmero do ttulo tem o tamanho determinado, caso * contrrio lana uma {@code IllegalArgumentException} com a mensagem * determinada. * </p> * * @param titulo * @param length * - Tamanho que deve ser * @param msg * - Mensagem para erro * * @since 0.2 */ protected final static void checkTamanhoNossoNumero(Titulo titulo, int length, String msg) { Objects.checkArgument(titulo.getNossoNumero().length() == length, msg); } /** * <p> * Verifica se o dgito verificador do nosso nmero do ttulo no nulo, * no vazio e se numrico, caso contrrio lana uma {@code * IllegalArgumentException}. * </p> * * @param titulo * * @since 0.2 */ protected final static void checkDigitoDoNossoNumero(Titulo titulo) { Objects.checkNotNull(titulo.getDigitoDoNossoNumero(), "Dgito verificador do nosso nmero do ttulo no pode ser nulo!"); Strings.checkNotBlank(titulo.getDigitoDoNossoNumero(), format("Dgito verificador [\"%s\"] do nosso nmero do ttulo no pode ser vazio!", titulo.getDigitoDoNossoNumero())); Strings.checkNotNumeric(titulo.getNossoNumero(), format("Nesse contexto o dgito verificador [\"%s\"] do nosso nmero deve ser numrico!", titulo.getDigitoDoNossoNumero())); } /** * <p> * Verifica se o dgito do nosso nmero do ttulo tem o tamanho determinado, caso * contrrio lana uma {@code IllegalArgumentException} com a mensagem * <tt>"Tamanho [%s] do dgito do nosso nmero [\"%s\"] diferente do esperado [%s]!"</tt>. * </p> * * @param titulo * @param length * - Tamanho que deve ser * * @since 0.2 */ protected final static void checkTamanhoDigitoDoNossoNumero(Titulo titulo, int length) { checkTamanhoDigitoDoNossoNumero(titulo, length, format("Tamanho [%s] do dgito do nosso nmero [\"%s\"] diferente do esperado [%s]!", StringUtils.length(titulo.getDigitoDoNossoNumero()), titulo.getDigitoDoNossoNumero(), length)); } /** * <p> * Verifica se o dgito do nosso nmero do ttulo tem o tamanho determinado, caso * contrrio lana uma {@code IllegalArgumentException} com a mensagem * determinada. * </p> * * @param titulo * @param length * - Tamanho que deve ser * @param msg * - Mensagem para erro * * @since 0.2 */ protected final static void checkTamanhoDigitoDoNossoNumero(Titulo titulo, int length, String msg) { Objects.checkArgument(titulo.getDigitoDoNossoNumero().length() == length, msg); } /** * <p> * Verifica se o valor do ttulo no nulo e positivo, caso contrrio lana uma * {@code IllegalArgumentException}. * </p> * * @param titulo * * @since 0.2 */ protected final static void checkValor(Titulo titulo) { Objects.checkNotNull(titulo.getValor(), "Valor do ttulo no pode ser nulo!"); Objects.checkArgument(titulo.getValor().compareTo(ZERO) >= 0, format("O valor do ttulo deve ser um nmero positivo ou zero e no [%s].", titulo.getValor())); } /** * <p> * Verifica se o ttulo contm {@code ParametrosBancariosMap} e se este * contm um valor no nulo do parmetro determinado, caso contrrio lana * uma {@code IllegalArgumentException}. * </p> * * @param titulo * @param param * - Parmetro a ser validado * * @since 0.2 */ protected final static void checkParametrosBancarios(Titulo titulo, String param) { Objects.checkNotNull(titulo.getParametrosBancarios(), format("O parmetro bancrio [\"%s\"] necessrio! [titulo.getParametrosBancarios() == null]", param)); Objects.checkArgument(titulo.getParametrosBancarios().contemComNome(param), format("Parmetro bancrio [\"%s\"] no encontrado!", param)); Objects.checkNotNull(titulo.getParametrosBancarios().getValor(param), format("Parmetro bancrio [\"%s\"] no contm valor!", param)); } /** * @see java.lang.Object#toString() */ @Override public String toString() { return Objects.toString(this); } }