diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..6c41c3314 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,30 @@ +name: Java CI +on: + push: + branches: + - master + +env: + MAVEN_OPTS: -Dmaven.artifact.threads=256 -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn +jobs: + build: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, '[ci skip]')" + + steps: + - uses: actions/checkout@v4 + - name: Setup Java JDK + uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: 11 + - name: 'Cache Maven packages' + uses: actions/cache@v4 + with: + path: ~/.m2 + key: 'cache' + restore-keys: 'cache' + - name: 'Build with Maven' + run: mvn -B install --file pom.xml + - name: 'Remove Snapshots Before Caching' + run: find ~/.m2 -name '*SNAPSHOT' | xargs rm -Rf diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml new file mode 100644 index 000000000..671670592 --- /dev/null +++ b/.github/workflows/pr-validation.yml @@ -0,0 +1,28 @@ +name: Pull Request +on: + pull_request: + branches: + - master + +env: + MAVEN_OPTS: -Dmaven.artifact.threads=256 -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup Java JDK + uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: 11 + - name: 'Cache Maven packages' + uses: actions/cache@v4 + with: + path: ~/.m2 + key: 'cache' + restore-keys: 'cache' + - name: 'Build with Maven' + run: mvn -B install --file pom.xml + - name: 'Remove Snapshots Before Caching' + run: find ~/.m2 -name '*SNAPSHOT' | xargs rm -Rf diff --git a/.github/workflows/sonatype-publish.yml b/.github/workflows/sonatype-publish.yml new file mode 100644 index 000000000..0b3c25a39 --- /dev/null +++ b/.github/workflows/sonatype-publish.yml @@ -0,0 +1,77 @@ + +name: Maven Release + +on: + workflow_dispatch: + inputs: + releaseVersion: + description: "Define the release version" + required: true + default: "" + developmentVersion: + description: "Define the snapshot version" + required: true + default: "" + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Configure Git User + run: | + git config user.email "actions@github.com" + git config user.name "GitHub Actions" + echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV + - name: Import SSH Key + uses: shimataro/ssh-key-action@v2 + with: + key: ${{ secrets.SSH_PRIVATE_KEY }} + name: id_rsa + known_hosts: unnecessary_just_github + + - name: Import GPG Key + uses: crazy-max/ghaction-import-gpg@v5.0.0 + with: + gpg_private_key: ${{ secrets.GPG_KEY }} + passphrase: ${{ secrets.GPG_PASSPHRASE }} + - name: 'Cache Maven packages' + uses: actions/cache@v4 + with: + path: ~/.m2 + key: 'cache' + restore-keys: 'cache' + + - name: Setup Java JDK + uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: 11 + + - name: 'Build with Maven' + run: mvn -B install --file pom.xml + + - name: Verify Whether a Release is Ready + id: release + shell: bash + run: | + if [ "${{ github.event.inputs.releaseVersion }}" != "" ] && [ "${{ github.event.inputs.developmentVersion }}" != "" ]; then + echo "auto_release=true" >> $GITHUB_ENV + else + echo "auto_release=false" >> $GITHUB_ENV + fi + - name: Release With Maven + run: | + mvn -B -U \ + -PsonatypeDeploy \ + release:prepare \ + release:perform \ + javadoc:jar \ + source:jar \ + -s settings.xml \ + -Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }} \ + -DreleaseVersion=${{ github.event.inputs.releaseVersion }} \ + -DdevelopmentVersion=${{ github.event.inputs.developmentVersion }} + env: + MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 690842fc4..000000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: java - -jdk: -- openjdk8 - -before_install: - - wget https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.tar.gz - - tar xzvf apache-maven-3.6.0-bin.tar.gz - - export PATH=`pwd`/apache-maven-3.6.0/bin:$PATH - - mvn -v - -script: -- mvn test verify --batch-mode diff --git a/examples/faces-example-1x/pom.xml b/examples/faces-example-1x/pom.xml index 9ed14b262..2f871c078 100644 --- a/examples/faces-example-1x/pom.xml +++ b/examples/faces-example-1x/pom.xml @@ -4,7 +4,7 @@ br.com.caelum.stella caelum-stella - 2.1.7-SNAPSHOT + 2.1.8-SNAPSHOT ../../pom.xml faces-example-1x diff --git a/examples/faces-example-2x/pom.xml b/examples/faces-example-2x/pom.xml index 826864d5c..cb0439e4d 100644 --- a/examples/faces-example-2x/pom.xml +++ b/examples/faces-example-2x/pom.xml @@ -4,7 +4,7 @@ br.com.caelum.stella caelum-stella - 2.1.7-SNAPSHOT + 2.1.8-SNAPSHOT ../../pom.xml faces-example-2x diff --git a/examples/hibernate-persistence-example/pom.xml b/examples/hibernate-persistence-example/pom.xml index f8a407e2f..6dc0497b5 100644 --- a/examples/hibernate-persistence-example/pom.xml +++ b/examples/hibernate-persistence-example/pom.xml @@ -4,7 +4,7 @@ br.com.caelum.stella caelum-stella - 2.1.7-SNAPSHOT + 2.1.8-SNAPSHOT ../../pom.xml hibernate-persistence-example diff --git a/examples/vraptor-validator-example/pom.xml b/examples/vraptor-validator-example/pom.xml index 952848bf1..8a2ba3faf 100644 --- a/examples/vraptor-validator-example/pom.xml +++ b/examples/vraptor-validator-example/pom.xml @@ -3,7 +3,7 @@ br.com.caelum.stella caelum-stella - 2.1.7-SNAPSHOT + 2.1.8-SNAPSHOT ../../pom.xml vraptor-validator-example diff --git a/pom.xml b/pom.xml index 838c130c5..e3ee138a6 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ br.com.caelum.stella caelum-stella pom - 2.1.7-SNAPSHOT + 2.1.8-SNAPSHOT Caelum Stella Caelum Stella is a set of validators, formatters and converters @@ -73,6 +73,18 @@ 1.8.5 test + + + jakarta.xml.bind + jakarta.xml.bind-api + 2.3.2 + + + + org.glassfish.jaxb + jaxb-runtime + 2.3.2 + @@ -94,6 +106,14 @@ mockito-all 1.8.5 + + jakarta.xml.bind + jakarta.xml.bind-api + + + org.glassfish.jaxb + jaxb-runtime + @@ -106,15 +126,18 @@ org.apache.maven.plugins maven-compiler-plugin - - 1.6 - 1.6 - UTF-8 - + 3.8.1 + + 11 + 1.8 + 1.8 + true + org.apache.maven.plugins maven-javadoc-plugin + 3.3.0 attach-javadoc @@ -128,8 +151,6 @@ http://java.sun.com/j2se/1.5/docs/api - utf-8 - utf-8 @@ -149,7 +170,7 @@ maven-surefire-plugin - 2.4.2 + 3.0.0-M5 once true @@ -181,6 +202,14 @@ + + maven-release-plugin + 3.1.1 + + [ci skip] + @{project.version} + + @@ -207,7 +236,7 @@ org.apache.maven.plugins maven-compiler-plugin - 2.3.2 + 3.8.0 org.apache.maven.plugins @@ -216,7 +245,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.8 + 3.3.0 org.apache.maven.plugins @@ -414,12 +443,71 @@ + + + sonatypeDeploy + + ${env.GPG_PASSPHRASE} + ${env.GPG_KEY_ID} + ${env.GPG_PASSPHRASE} + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true + + ossrh + https://oss.sonatype.org/ + + false + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.6.3 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 3.1.0 + + + sign-artifacts + verify + + sign + + + + --pinentry-mode + loopback + + + + + + + + scm:git:git://github.com/caelum/caelum-stella scm:git:git@github.com:caelum/caelum-stella.git https://github.com/caelum/caelum-stella + HEAD @@ -454,12 +542,12 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.8 + 3.3.0 org.apache.maven.plugins maven-surefire-plugin - 2.8.1 + 3.0.0-M5 org.codehaus.mojo diff --git a/settings.xml b/settings.xml new file mode 100644 index 000000000..0a08dd1ee --- /dev/null +++ b/settings.xml @@ -0,0 +1,12 @@ + + + + + ossrh + ${env.MAVEN_USERNAME} + ${env.MAVEN_PASSWORD} + + + \ No newline at end of file diff --git a/stella-bean-validation/pom.xml b/stella-bean-validation/pom.xml index 6ba899ee2..4082bd5ea 100644 --- a/stella-bean-validation/pom.xml +++ b/stella-bean-validation/pom.xml @@ -3,7 +3,7 @@ br.com.caelum.stella caelum-stella - 2.1.7-SNAPSHOT + 2.1.8-SNAPSHOT caelum-stella-bean-validation jar diff --git a/stella-boleto/pom.xml b/stella-boleto/pom.xml index 33fc30a44..a7cc5a46c 100644 --- a/stella-boleto/pom.xml +++ b/stella-boleto/pom.xml @@ -1,188 +1,181 @@ - 4.0.0 + 4.0.0 br.com.caelum.stella caelum-stella - 2.1.7-SNAPSHOT + 2.1.8-SNAPSHOT - caelum-stella-boleto - jar - Stella Boleto + caelum-stella-boleto + jar + Stella Boleto br.com.caelum.stella caelum-stella-core - 2.1.7-SNAPSHOT + 2.1.8-SNAPSHOT - - net.sf.jasperreports - jasperreports - 5.5.0 - - - jfree - * - - - com.fasterxml.jackson.core - * - - - org.bouncycastle - * - - - bouncycastle - * - - - eclipse - * - - - org.codehaus.castor - * - - - xml-apis - * - - - + + net.sf.jasperreports + jasperreports + 6.1.0 + + + xml-apis + xml-apis + + + org.glassfish.jersey.media + * + + + - - - net.sourceforge.barbecue - barbecue - 1.5-beta1 - + + + net.sourceforge.barbecue + barbecue + 1.5-beta1 + - - - pdfbox - pdfbox - 0.7.3 - test - + + + pdfbox + pdfbox + 0.7.3 + test + - - - javax.servlet - javax.servlet-api - 3.0.1 - provided - true - - + + + javax.servlet + javax.servlet-api + 3.0.1 + provided + true + + - - - doclint-java8-disable - - [1.8,) - + + + doclint-java8-disable + + [1.8,) + - - - - org.apache.maven.plugins - maven-javadoc-plugin - - -Xdoclint:none - - - - - - + + + + org.apache.maven.plugins + maven-javadoc-plugin + + -Xdoclint:none + + + + + + - - - - - net.sourceforge.maven-taglib - maven-taglib-plugin - 2.4 - - - - taglibdocjar - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.codehaus.mojo - jasperreports-maven-plugin - [1.0-beta-2,) - - compile-reports - - - - - - - - - - - - + + + + + net.sourceforge.maven-taglib + maven-taglib-plugin + 2.4 + + + + taglibdocjar + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.codehaus.mojo + jasperreports-maven-plugin + [1.0-beta-2,) + + compile-reports + + + + + + + + + + + + - - - net.sourceforge.maven-taglib - maven-taglib-plugin - 2.4 - + + + net.sourceforge.maven-taglib + maven-taglib-plugin + 2.4 + - - org.codehaus.mojo - jasperreports-maven-plugin - 1.0-beta-2 - - src/main/resources - 1.6 - 1.6 - net.sf.jasperreports.engine.design.JRJdtCompiler - - - - net.sf.jasperreports - jasperreports - 5.5.0 - - - org.mortbay.jetty - servlet-api - 3.0.20100224 - - - - - compile - - compile-reports - - - - - - + + org.codehaus.mojo + jasperreports-maven-plugin + 1.0-beta-2 + + src/main/resources + 1.8 + 1.8 + net.sf.jasperreports.engine.design.JRJdtCompiler + + + + net.sf.jasperreports + jasperreports + 6.1.0 + + + org.mortbay.jetty + servlet-api + 3.0.20100224 + + + + + compile + + compile-reports + + + + + + + + + jaspersoft-third-party + https://jaspersoft.jfrog.io/jaspersoft/third-party-ce-artifacts/ + + + + + + jaspersoft-third-party + https://jaspersoft.jfrog.io/jaspersoft/third-party-ce-artifacts/ + + diff --git a/stella-core/pom.xml b/stella-core/pom.xml index f9c3d3e8b..8fd28476a 100644 --- a/stella-core/pom.xml +++ b/stella-core/pom.xml @@ -3,7 +3,7 @@ br.com.caelum.stella caelum-stella - 2.1.7-SNAPSHOT + 2.1.8-SNAPSHOT caelum-stella-core jar diff --git a/stella-core/src/main/java/br/com/caelum/stella/DigitoPara.java b/stella-core/src/main/java/br/com/caelum/stella/DigitoPara.java index e66914c69..9f3c83149 100644 --- a/stella-core/src/main/java/br/com/caelum/stella/DigitoPara.java +++ b/stella-core/src/main/java/br/com/caelum/stella/DigitoPara.java @@ -35,6 +35,7 @@ */ public class DigitoPara { + private static final int ZERO_ASCII = 48; private LinkedList numero; private List multiplicadores = new ArrayList(); private boolean complementar; @@ -56,7 +57,7 @@ public DigitoPara(String trecho) { this.numero = new LinkedList(); char[] digitos = trecho.toCharArray(); for (char digito : digitos) { - this.numero.add(Character.getNumericValue(digito)); + this.numero.add(((int) digito) - ZERO_ASCII); } Collections.reverse(numero); } diff --git a/stella-core/src/main/java/br/com/caelum/stella/type/Estado.java b/stella-core/src/main/java/br/com/caelum/stella/type/Estado.java index 97991779a..f14c9cfed 100644 --- a/stella-core/src/main/java/br/com/caelum/stella/type/Estado.java +++ b/stella-core/src/main/java/br/com/caelum/stella/type/Estado.java @@ -38,163 +38,163 @@ */ public enum Estado { - AC(12) { + AC(12, "24") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IEAcreValidator(messageProducer, isFormatted); } }, - AL(27) { + AL(27, "17") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IEAlagoasValidator(messageProducer, isFormatted); } }, - AP(16) { + AP(16, "25") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IEAmapaValidator(messageProducer, isFormatted); } }, - AM(13) { + AM(13, "22") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IEAmazonasValidator(messageProducer, isFormatted); } }, - BA(29) { + BA(29, "05") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IEBahiaValidator(messageProducer, isFormatted); } }, - CE(23) { + CE(23, "07") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IECearaValidator(messageProducer, isFormatted); } }, - DF(53) { + DF(53, "20") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IEDistritoFederalValidator(messageProducer, isFormatted); } }, - ES(32) { + ES(32, "14") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IEEspiritoSantoValidator(messageProducer, isFormatted); } }, - GO(52) { + GO(52, "10") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IEGoiasValidator(messageProducer, isFormatted); } }, - MA(21) { + MA(21, "11") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IEMaranhaoValidator(messageProducer, isFormatted); } }, - MT(51) { + MT(51, "18") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IEMatoGrossoValidator(messageProducer, isFormatted); } }, - MS(50) { + MS(50, "19") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IEMatoGrossoDoSulValidator(messageProducer, isFormatted); } }, - MG(31) { + MG(31, "02") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IEMinasGeraisValidator(messageProducer, isFormatted); } }, - PA(15) { + PA(15, "13") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IEParaValidator(messageProducer, isFormatted); } }, - PB(25) { + PB(25, "12") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IEParaibaValidator(messageProducer, isFormatted); } }, - PR(41) { + PR(41, "06") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IEParanaValidator(messageProducer, isFormatted); } }, - PE(26) { + PE(26, "08") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IEPernambucoValidator(messageProducer, isFormatted); } }, - PI(22) { + PI(22, "15") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IEPiauiValidator(messageProducer, isFormatted); } }, - RJ(33) { + RJ(33, "03") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IERioDeJaneiroValidator(messageProducer, isFormatted); } }, - RN(24) { + RN(24, "16") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IERioGrandeDoNorteValidator(messageProducer, isFormatted); } }, - RS(43) { + RS(43, "04") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IERioGrandeDoSulValidator(messageProducer, isFormatted); } }, - RO(11) { + RO(11, "23") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IERondoniaValidator(messageProducer, isFormatted); } }, - RR(14) { + RR(14, "26") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IERoraimaValidator(messageProducer, isFormatted); } }, - SC(42) { + SC(42, "09") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IESantaCatarinaValidator(messageProducer, isFormatted); } }, - SP(35) { + SP(35, "01") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IESaoPauloValidator(messageProducer, isFormatted); } }, - SE(28) { + SE(28, "21") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IESergipeValidator(messageProducer, isFormatted); } }, - TO(17) { + TO(17, "27") { public Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted) { return new IETocantinsValidator(messageProducer, isFormatted); } @@ -202,6 +202,8 @@ public Validator getIEValidator(MessageProducer messageProducer, boolean }; private final int codigoIBGE; + + private final String codigoEleitoral; /** * Retorna um validador de Inscrição Estadual. @@ -215,15 +217,20 @@ public Validator getIEValidator(MessageProducer messageProducer, boolean */ public abstract Validator getIEValidator(MessageProducer messageProducer, boolean isFormatted); - private Estado(int codigoIBGE) { + private Estado(int codigoIBGE, String codigoEleitoral) { this.codigoIBGE = codigoIBGE; + this.codigoEleitoral = codigoEleitoral; } public int getCodigoIBGE() { return codigoIBGE; } + + public String getCodigoEleitoral() { + return codigoEleitoral; + } - /** + /** * A região do território brasileiro em que esse estado está localizado. * * @return Retorna a região em que esse estado está localizado. @@ -249,4 +256,17 @@ public Regiao regiao() { public boolean localizadoEm(Regiao regiao) { return regiao() == regiao; } + + public static Estado deCodigoEleitoral(String codigo) { + + Estado[] estados = Estado.values(); + + for (Estado estado : estados) { + if (estado.getCodigoEleitoral().equals(codigo)) { + return estado; + } + } + + throw new IllegalStateException("Não foi possível determinar o estado a partir do código eleitoral " + codigo); + } } diff --git a/stella-core/src/main/java/br/com/caelum/stella/validation/AgenciaBancariaValidator.java b/stella-core/src/main/java/br/com/caelum/stella/validation/AgenciaBancariaValidator.java new file mode 100644 index 000000000..21a0a6c73 --- /dev/null +++ b/stella-core/src/main/java/br/com/caelum/stella/validation/AgenciaBancariaValidator.java @@ -0,0 +1,110 @@ +package br.com.caelum.stella.validation; + +import br.com.caelum.stella.DigitoGenerator; +import br.com.caelum.stella.MessageProducer; +import br.com.caelum.stella.SimpleMessageProducer; +import br.com.caelum.stella.ValidationMessage; +import br.com.caelum.stella.validation.error.AgenciaBancariaError; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Representa um validador de agencia bancária. + * + * @author Thiago Nascimento + */ +public class AgenciaBancariaValidator implements Validator { + + public static final Pattern COM_DV = Pattern.compile("(\\d+)\\-([\\dX])"); + public static final Pattern SEM_DV = Pattern.compile("\\d+"); + + private boolean isComDigito = true; + private MessageProducer messageProducer; + + public AgenciaBancariaValidator() { + this.messageProducer = new SimpleMessageProducer(); + } + + public AgenciaBancariaValidator(boolean isComDigito) { + this(); + this.isComDigito = isComDigito; + } + + @Override + public void assertValid(String agencia) { + + List errors = this.invalidMessagesFor(agencia); + + if (!errors.isEmpty()) { + throw new InvalidStateException(errors); + } + } + + @Override + public List invalidMessagesFor(String agencia) { + + List errors = new ArrayList(); + + if (this.isEligible(agencia)) { + + if (this.isComDigito) { + + Matcher matcher = COM_DV.matcher(agencia); + + if (!matcher.find()) { + throw new InvalidStateException(this.messageProducer.getMessage(AgenciaBancariaError.INVALID_FORMAT)); + } + + String dvInformado = matcher.group(2); + String dvComputado = this.computarDigitoVerificador(matcher.group(1)); + + if (!dvInformado.equals(dvComputado)) { + errors.add(this.messageProducer.getMessage(AgenciaBancariaError.INVALID_CHECK_DIGIT)); + } + + } else { + errors.add(this.messageProducer.getMessage(AgenciaBancariaError.CHECK_DIGIT_NOT_FOUND)); + } + + } else { + errors.add(this.messageProducer.getMessage(AgenciaBancariaError.INVALID_FORMAT)); + } + + return errors; + } + + @Override + public boolean isEligible(String value) { + + if (value == null || value.trim().isEmpty()) { + return false; + } + + return this.isComDigito ? + COM_DV.matcher(value).matches() : SEM_DV.matcher(value).matches(); + } + + @Override + public String generateRandomValid() { + final String agenciaSemDigitos = new DigitoGenerator().generate(4); + return String.format("%s-%s", agenciaSemDigitos, this.computarDigitoVerificador(agenciaSemDigitos)); + } + + public String computarDigitoVerificador(String agenciaSemDV) { + + String[] algarisms = agenciaSemDV.split(""); + int multiplier = 9; + int sum = 0; + + for (int index = algarisms.length - 1; index >= 0; --index) { + sum += Integer.valueOf(algarisms[index]) * multiplier--; + } + + int rest = sum % 11; + return rest == 10 ? "X" : String.valueOf(rest); + } + +} diff --git a/stella-core/src/main/java/br/com/caelum/stella/validation/CNPJValidator.java b/stella-core/src/main/java/br/com/caelum/stella/validation/CNPJValidator.java index fc6429b35..0fa3728b4 100644 --- a/stella-core/src/main/java/br/com/caelum/stella/validation/CNPJValidator.java +++ b/stella-core/src/main/java/br/com/caelum/stella/validation/CNPJValidator.java @@ -19,8 +19,10 @@ */ public class CNPJValidator implements Validator { - public static final Pattern FORMATED = Pattern.compile("(\\d{2})[.](\\d{3})[.](\\d{3})/(\\d{4})-(\\d{2})"); - public static final Pattern UNFORMATED = Pattern.compile("(\\d{2})(\\d{3})(\\d{3})(\\d{4})(\\d{2})"); + public static final Pattern FORMATED = Pattern.compile( + "([0-9A-Z]{2})[.]([0-9A-Z]{3})[.]([0-9A-Z]{3})/([0-9A-Z]{4})-([0-9A-Z]{2})"); + public static final Pattern UNFORMATED = Pattern.compile( + "([0-9A-Z]{2})([0-9A-Z]{3})([0-9A-Z]{3})([0-9A-Z]{4})([0-9A-Z]{2})"); private boolean isFormatted = false; private boolean isIgnoringRepeatedDigits; @@ -97,8 +99,8 @@ private List getInvalidValues(String cnpj) { errors.add(messageProducer.getMessage(CNPJError.INVALID_DIGITS)); return errors; } - - if(unformatedCNPJ.length() != 14 || !unformatedCNPJ.matches("[0-9]*")){ + + if (unformatedCNPJ.length() != 14 || !unformatedCNPJ.matches("[0-9A-Z]*")) { errors.add(messageProducer.getMessage(CNPJError.INVALID_DIGITS)); } diff --git a/stella-core/src/main/java/br/com/caelum/stella/validation/TituloEleitoralValidator.java b/stella-core/src/main/java/br/com/caelum/stella/validation/TituloEleitoralValidator.java index 08b7f51cb..a4a2303fb 100644 --- a/stella-core/src/main/java/br/com/caelum/stella/validation/TituloEleitoralValidator.java +++ b/stella-core/src/main/java/br/com/caelum/stella/validation/TituloEleitoralValidator.java @@ -1,6 +1,7 @@ package br.com.caelum.stella.validation; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.regex.Pattern; @@ -11,6 +12,7 @@ import br.com.caelum.stella.SimpleMessageProducer; import br.com.caelum.stella.ValidationMessage; import br.com.caelum.stella.format.TituloEleitoralFormatter; +import br.com.caelum.stella.type.Estado; import br.com.caelum.stella.validation.error.TituloEleitoralError; /** @@ -80,6 +82,8 @@ public class TituloEleitoralValidator implements Validator { public static final Pattern FORMATED = Pattern.compile("(\\d{10})/(\\d{2})"); public static final Pattern UNFORMATED = Pattern.compile("(\\d{10})(\\d{2})"); + private static final List estadosSubstitoresDigito = Arrays.asList(Estado.SP, Estado.MG); + private boolean isFormatted = false; private MessageProducer messageProducer; @@ -160,24 +164,50 @@ private List getInvalidValues(String tituloDeEleitor) { } return errors; } - + private String calculaDigitos(String tituloSemDigito) { + int length = tituloSemDigito.length(); String sequencial = tituloSemDigito.substring(0,length - 2); - String digito1 = new DigitoPara(sequencial).complementarAoModulo().trocandoPorSeEncontrar("0",10,11).mod(11).calcula(); + String codigoEstado = tituloSemDigito.substring(length - 2, length); + boolean ehEstadoSubstitutorDigito = estadosSubstitoresDigito.contains(Estado.deCodigoEleitoral(codigoEstado)); + + String digito1 = this.geraDigito(ehEstadoSubstitutorDigito, sequencial); + String digito2 = this.geraDigito(ehEstadoSubstitutorDigito, codigoEstado + digito1); - String codigoEstado = tituloSemDigito.substring(length - 2, length); - String digito2 = new DigitoPara(codigoEstado + digito1).complementarAoModulo().trocandoPorSeEncontrar("0",10,11).mod(11).calcula(); - return digito1 + digito2; } + private String geraDigito(boolean ehEstadoSubstitutorDigito, String base) { + + String digito = new DigitoPara(base).mod(11).calcula(); + + if (!ehEstadoSubstitutorDigito) { + + if (digito.equals("1") || digito.equals("0")) { + return "0"; + } + + return new DigitoPara(base).complementarAoModulo().mod(11).calcula(); + } + + if (digito.equals("1")) { + return "0"; + } + + if (digito.equals("0")) { + return "1"; + } + + return new DigitoPara(base).complementarAoModulo().mod(11).calcula(); + } + private boolean hasCodigoDeEstadoInvalido(String tituloDeEleitor) { int codigo= Integer.parseInt(tituloDeEleitor.substring(tituloDeEleitor.length() - 4, tituloDeEleitor.length() - 2)); return !(codigo >= 01 && codigo <= 28); } - + public boolean isEligible(String value) { boolean result; if (isFormatted) { diff --git a/stella-core/src/main/java/br/com/caelum/stella/validation/error/AgenciaBancariaError.java b/stella-core/src/main/java/br/com/caelum/stella/validation/error/AgenciaBancariaError.java new file mode 100644 index 000000000..4f21e3572 --- /dev/null +++ b/stella-core/src/main/java/br/com/caelum/stella/validation/error/AgenciaBancariaError.java @@ -0,0 +1,7 @@ +package br.com.caelum.stella.validation.error; + +import br.com.caelum.stella.validation.InvalidValue; + +public enum AgenciaBancariaError implements InvalidValue { + INVALID_CHECK_DIGIT, CHECK_DIGIT_NOT_FOUND, INVALID_FORMAT +} diff --git a/stella-core/src/test/java/br/com/caelum/stella/validation/AgenciaBancariaValidatorTest.java b/stella-core/src/test/java/br/com/caelum/stella/validation/AgenciaBancariaValidatorTest.java new file mode 100644 index 000000000..d55a9b1e2 --- /dev/null +++ b/stella-core/src/test/java/br/com/caelum/stella/validation/AgenciaBancariaValidatorTest.java @@ -0,0 +1,70 @@ +package br.com.caelum.stella.validation; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.Test; + +import br.com.caelum.stella.MessageProducer; +import br.com.caelum.stella.SimpleMessageProducer; +import br.com.caelum.stella.validation.error.AgenciaBancariaError; + +/** + * @author Thiago Nascimento + */ +public class AgenciaBancariaValidatorTest { + + private MessageProducer messageProducer = new SimpleMessageProducer(); + + @Test + public void shouldAcceptEligibleAgenciasComDV() { + AgenciaBancariaValidator validator = new AgenciaBancariaValidator(); + assertTrue(validator.isEligible("3610-2")); + assertFalse(validator.isEligible("3610")); + } + + @Test + public void shouldAcceptEligibleAgenciasSemDV() { + AgenciaBancariaValidator validator = new AgenciaBancariaValidator(false); + assertFalse(validator.isEligible("3610-2")); + assertTrue(validator.isEligible("3610")); + } + + @Test + public void shouldReturnNoValidationMessagesForCorrectAgenciasComDV() { + AgenciaBancariaValidator validator = new AgenciaBancariaValidator(); + assertTrue(validator.invalidMessagesFor("3610-2").isEmpty()); + assertTrue(validator.invalidMessagesFor("3793-1").isEmpty()); + assertTrue(validator.invalidMessagesFor("197-X").isEmpty()); + assertTrue(validator.invalidMessagesFor("4158-0").isEmpty()); + assertTrue(validator.invalidMessagesFor("2121-0").isEmpty()); + assertTrue(validator.invalidMessagesFor("1284-X").isEmpty()); + } + + @Test + public void shouldReturnInvalidCheckDigitForIncorrectDV() { + + AgenciaBancariaValidator validator = new AgenciaBancariaValidator(); + + try { + validator.assertValid("2121-9"); + fail(); + } catch (InvalidStateException e) { + e.getInvalidMessages().contains(this.messageProducer.getMessage(AgenciaBancariaError.INVALID_CHECK_DIGIT)); + } + } + + @Test + public void shouldReturnCheckDigitNotFoundForAgenciaSemDV() { + + AgenciaBancariaValidator validator = new AgenciaBancariaValidator(); + + try { + validator.assertValid("1103"); + fail(); + } catch (InvalidStateException e) { + e.getInvalidMessages().contains(this.messageProducer.getMessage(AgenciaBancariaError.CHECK_DIGIT_NOT_FOUND)); + } + } +} diff --git a/stella-core/src/test/java/br/com/caelum/stella/validation/CNPJValidatorTest.java b/stella-core/src/test/java/br/com/caelum/stella/validation/CNPJValidatorTest.java index c2b28dd61..7070b0d27 100644 --- a/stella-core/src/test/java/br/com/caelum/stella/validation/CNPJValidatorTest.java +++ b/stella-core/src/test/java/br/com/caelum/stella/validation/CNPJValidatorTest.java @@ -21,7 +21,11 @@ public class CNPJValidatorTest { private final String validString = "26.637.142/0001-58"; private final String validStringNotFormatted = "26637142000158"; + private final String validStringAlpha = "12.ABC.345/01DE-35"; + private final String validStringAlphaNotFormatted = "12ABC34501DE35"; + private final String firstCheckDigitWrongNotFormatted = "26637142000168"; + private final String alphaFirstCheckDigitWrongNotFormatted = "12ABC34501DE45"; @Test public void shouldHaveDefaultConstructorThatUsesSimpleMessageProducerAndAssumesThatStringIsNotFormatted() { @@ -34,6 +38,14 @@ public void shouldHaveDefaultConstructorThatUsesSimpleMessageProducerAndAssumesT InvalidStateException invalidStateException = (InvalidStateException) e; assertMessage(invalidStateException, INVALID_CHECK_DIGITS); } + + try { + new CNPJValidator().assertValid(alphaFirstCheckDigitWrongNotFormatted); + fail("Test expected to throw exception"); + } catch (InvalidStateException e) { + InvalidStateException invalidStateException = (InvalidStateException) e; + assertMessage(invalidStateException, INVALID_CHECK_DIGITS); + } } private void assertMessage(InvalidStateException invalidStateException, String expected) { @@ -87,6 +99,7 @@ public void shouldValidateValidCNPJ() { validator.assertValid("63025530002409"); validator.assertValid("61519128000150"); validator.assertValid("68745386000102"); + validator.assertValid("12ABC34501DE35"); } @Test @@ -186,6 +199,9 @@ public void shouldBeEligibleDefaultConstructor() { final CNPJValidator cnpjValidator = new CNPJValidator(); assertTrue(cnpjValidator.isEligible(validStringNotFormatted)); assertFalse(cnpjValidator.isEligible(validString)); + + assertTrue(cnpjValidator.isEligible(validStringAlphaNotFormatted)); + assertFalse(cnpjValidator.isEligible(validStringAlpha)); } @Test @@ -193,6 +209,9 @@ public void shouldBeEligibleConstructorNotFormatted() { final CNPJValidator cnpjValidator = new CNPJValidator(false); assertTrue(cnpjValidator.isEligible(validStringNotFormatted)); assertFalse(cnpjValidator.isEligible(validString)); + + assertTrue(cnpjValidator.isEligible(validStringAlphaNotFormatted)); + assertFalse(cnpjValidator.isEligible(validStringAlpha)); } @Test @@ -200,6 +219,9 @@ public void shouldBeEligibleConstructorFormatted() { final CNPJValidator cnpjValidator = new CNPJValidator(true); assertFalse(cnpjValidator.isEligible(validStringNotFormatted)); assertTrue(cnpjValidator.isEligible(validString)); + + assertFalse(cnpjValidator.isEligible(validStringAlphaNotFormatted)); + assertTrue(cnpjValidator.isEligible(validStringAlpha)); } @Test diff --git a/stella-core/src/test/java/br/com/caelum/stella/validation/TituloEleitoralValidatorTest.java b/stella-core/src/test/java/br/com/caelum/stella/validation/TituloEleitoralValidatorTest.java index ed9dea9b3..611a27dc2 100644 --- a/stella-core/src/test/java/br/com/caelum/stella/validation/TituloEleitoralValidatorTest.java +++ b/stella-core/src/test/java/br/com/caelum/stella/validation/TituloEleitoralValidatorTest.java @@ -12,10 +12,12 @@ public class TituloEleitoralValidatorTest { private final String[] validStrings = { "543275360116","142501480248", "557833330370", "013785610434", "253346440540", "033734180663", "585353130710", "884328631058", "553505611201", "028565701333", - "245770031481", "713782341503", "403374181694", "452083221724" }; + "245770031481", "713782341503", "403374181694", "452083221724", "162749070141" }; + private final String[] validStringsFormatted = { "5432753601/16","1425014802/48", "5578333303/70", "0137856104/34", "2533464405/40", "0337341806/63", "5853531307/10", "8843286310/58", "5535056112/01", "0285657013/33", - "2457700314/81", "7137823415/03", "4033741816/94", "4520832217/24"}; + "2457700314/81", "7137823415/03", "4033741816/94", "4520832217/24", "2800440202/05"}; + private final String[] invalidFirstDigitStrings = { "543275360106", "452083221714", "253346440520", "553505611231", "884328631048" }; diff --git a/stella-faces/pom.xml b/stella-faces/pom.xml index d274ba30f..0713b7036 100644 --- a/stella-faces/pom.xml +++ b/stella-faces/pom.xml @@ -4,7 +4,7 @@ br.com.caelum.stella caelum-stella - 2.1.7-SNAPSHOT + 2.1.8-SNAPSHOT caelum-stella-faces diff --git a/stella-frete/pom.xml b/stella-frete/pom.xml index 9ddae80ed..988285a00 100644 --- a/stella-frete/pom.xml +++ b/stella-frete/pom.xml @@ -3,7 +3,7 @@ br.com.caelum.stella caelum-stella - 2.1.7-SNAPSHOT + 2.1.8-SNAPSHOT caelum-stella-frete diff --git a/stella-hibernate-user-types/pom.xml b/stella-hibernate-user-types/pom.xml index 5d0484709..89d320d0a 100644 --- a/stella-hibernate-user-types/pom.xml +++ b/stella-hibernate-user-types/pom.xml @@ -3,7 +3,7 @@ br.com.caelum.stella caelum-stella - 2.1.7-SNAPSHOT + 2.1.8-SNAPSHOT caelum-stella-hibernate-user-types jar