org.agatom.springatom.data.vin.validator.VinNumberValidator.java Source code

Java tutorial

Introduction

Here is the source code for org.agatom.springatom.data.vin.validator.VinNumberValidator.java

Source

/**************************************************************************************************
 * This file is part of [SpringAtom] Copyright [kornicameister@gmail.com][2014]                   *
 * *
 * [SpringAtom] is free software: you can redistribute it and/or modify                           *
 * it under the terms of the GNU General Public License as published by                           *
 * the Free Software Foundation, either version 3 of the License, or                              *
 * (at your option) any later version.                                                            *
 * *
 * [SpringAtom] is distributed in the hope that it will be useful,                                *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of                                 *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                  *
 * GNU General Public License for more details.                                                   *
 * *
 * You should have received a copy of the GNU General Public License                              *
 * along with [SpringAtom].  If not, see <http://www.gnu.org/licenses/gpl.html>.                  *
 **************************************************************************************************/

package org.agatom.springatom.data.vin.validator;

import com.google.common.base.Preconditions;
import org.agatom.springatom.data.model.vin.VinNumber;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;

@Component
class VinNumberValidator implements VinValidator {
    private static final Logger LOGGER = LoggerFactory.getLogger(VinNumberValidator.class);
    private static final int VIN_LENGTH = 17;
    private static final int[] WEIGHTS = { 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 };

    @Override
    public void validate(final Object target, final Errors errors) {
        Preconditions.checkNotNull(target, "target");
        final String vinNumber = ((VinNumber) target).getNumber();
        if (!this.validate(vinNumber)) {
            errors.reject("number", String.format("Invalid checksum of vin=%s", vinNumber));
        }
    }

    protected boolean validate(final String vinNumber) {
        int crc = 0;
        for (int i = 0; i < VIN_LENGTH; i++) {
            crc += WEIGHTS[i] * this.resolveCharacterValue(vinNumber.charAt(i));
        }
        final char checksum = (crc %= 11) == 10 ? 'X' : Character.forDigit(crc, 10);
        final boolean valid = this.isChecksumValid(vinNumber, checksum);
        if (valid && LOGGER.isDebugEnabled()) {
            LOGGER.debug(String.format("VinNumber=%s is valid [checksum=%s]", vinNumber, checksum));
        } else if (!valid) {
            LOGGER.warn(String.format("VinNumber=%s is invalid [checksum=%s]", vinNumber, checksum));
        }
        return valid;
    }

    private int resolveCharacterValue(final int c) {
        return c <= '9' ? c - '0' : ((c >= 'S' ? c + 1 : c) - 'A') % 9 + 1;
    }

    private boolean isChecksumValid(final String number, final char checksum) {
        return number.charAt(8) == checksum;
    }
}