spring-batch OrderValidator 源码
spring-batch OrderValidator 代码
文件路径:/spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/order/internal/validator/OrderValidator.java
/*
* Copyright 2014-2021 the original author or authors.
*
* 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
*
* https://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.
*/
package org.springframework.batch.sample.domain.order.internal.validator;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.batch.sample.domain.order.Address;
import org.springframework.batch.sample.domain.order.BillingInfo;
import org.springframework.batch.sample.domain.order.Customer;
import org.springframework.batch.sample.domain.order.LineItem;
import org.springframework.batch.sample.domain.order.Order;
import org.springframework.batch.sample.domain.order.ShippingInfo;
import org.springframework.util.StringUtils;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
public class OrderValidator implements Validator {
private static final List<String> CARD_TYPES = new ArrayList<>();
private static final List<String> SHIPPER_IDS = new ArrayList<>();
private static final List<String> SHIPPER_TYPES = new ArrayList<>();
private static final long MAX_ID = 9999999999L;
private static final BigDecimal BD_MIN = new BigDecimal("0.0");
private static final BigDecimal BD_MAX = new BigDecimal("99999999.99");
private static final BigDecimal BD_PERC_MAX = new BigDecimal("100.0");
private static final int MAX_QUANTITY = 9999;
private static final BigDecimal BD_100 = new BigDecimal("100.00");
static {
CARD_TYPES.add("VISA");
CARD_TYPES.add("AMEX");
CARD_TYPES.add("ECMC");
CARD_TYPES.add("DCIN");
CARD_TYPES.add("PAYP");
SHIPPER_IDS.add("FEDX");
SHIPPER_IDS.add("UPS");
SHIPPER_IDS.add("DHL");
SHIPPER_IDS.add("DPD");
SHIPPER_TYPES.add("STD");
SHIPPER_TYPES.add("EXP");
SHIPPER_TYPES.add("AMS");
SHIPPER_TYPES.add("AME");
}
@Override
public boolean supports(Class<?> arg0) {
return arg0.isAssignableFrom(Order.class);
}
@Override
public void validate(Object arg0, Errors errors) {
Order item = null;
try {
item = (Order) arg0;
}
catch (ClassCastException cce) {
errors.reject("Incorrect type");
}
if (item != null) {
validateOrder(item, errors);
validateCustomer(item.getCustomer(), errors);
validateAddress(item.getBillingAddress(), errors, "billingAddress");
validateAddress(item.getShippingAddress(), errors, "shippingAddress");
validatePayment(item.getBilling(), errors);
validateShipping(item.getShipping(), errors);
validateLineItems(item.getLineItems(), errors);
}
}
protected void validateLineItems(List<LineItem> lineItems, Errors errors) {
boolean ids = true;
boolean prices = true;
boolean discounts = true;
boolean shippingPrices = true;
boolean handlingPrices = true;
boolean quantities = true;
boolean totalPrices = true;
for (LineItem lineItem : lineItems) {
if (lineItem.getItemId() <= 0 || lineItem.getItemId() > MAX_ID) {
ids = false;
}
if ((BD_MIN.compareTo(lineItem.getPrice()) > 0) || (BD_MAX.compareTo(lineItem.getPrice()) < 0)) {
prices = false;
}
if (BD_MIN.compareTo(lineItem.getDiscountPerc()) != 0) {
// DiscountPerc must be between 0.0 and 100.0
if ((BD_MIN.compareTo(lineItem.getDiscountPerc()) > 0)
|| (BD_PERC_MAX.compareTo(lineItem.getDiscountPerc()) < 0)
|| (BD_MIN.compareTo(lineItem.getDiscountAmount()) != 0)) { // only
// one
// of
// DiscountAmount
// and
// DiscountPerc
// should
// be
// non-zero
discounts = false;
}
}
else {
// DiscountAmount must be between 0.0 and item.price
if ((BD_MIN.compareTo(lineItem.getDiscountAmount()) > 0)
|| (lineItem.getPrice().compareTo(lineItem.getDiscountAmount()) < 0)) {
discounts = false;
}
}
if ((BD_MIN.compareTo(lineItem.getShippingPrice()) > 0)
|| (BD_MAX.compareTo(lineItem.getShippingPrice()) < 0)) {
shippingPrices = false;
}
if ((BD_MIN.compareTo(lineItem.getHandlingPrice()) > 0)
|| (BD_MAX.compareTo(lineItem.getHandlingPrice()) < 0)) {
handlingPrices = false;
}
if ((lineItem.getQuantity() <= 0) || (lineItem.getQuantity() > MAX_QUANTITY)) {
quantities = false;
}
if ((BD_MIN.compareTo(lineItem.getTotalPrice()) > 0) || (BD_MAX.compareTo(lineItem.getTotalPrice()) < 0)) {
totalPrices = false;
}
// calculate total price
// discount coefficient = (100.00 - discountPerc) / 100.00
BigDecimal coef = BD_100.subtract(lineItem.getDiscountPerc()).divide(BD_100, 4, RoundingMode.HALF_UP);
// discountedPrice = (price * coefficient) - discountAmount
// at least one of discountPerc and discountAmount is 0 - this is validated by
// ValidateDiscountsFunction
BigDecimal discountedPrice = lineItem.getPrice().multiply(coef).subtract(lineItem.getDiscountAmount());
// price for single item = discountedPrice + shipping + handling
BigDecimal singleItemPrice = discountedPrice.add(lineItem.getShippingPrice())
.add(lineItem.getHandlingPrice());
// total price = singleItemPrice * quantity
BigDecimal quantity = new BigDecimal(lineItem.getQuantity());
BigDecimal totalPrice = singleItemPrice.multiply(quantity).setScale(2, RoundingMode.HALF_UP);
// calculatedPrice should equal to item.totalPrice
if (totalPrice.compareTo(lineItem.getTotalPrice()) != 0) {
totalPrices = false;
}
}
String lineItemsFieldName = "lineItems";
if (!ids) {
errors.rejectValue(lineItemsFieldName, "error.lineitems.id");
}
if (!prices) {
errors.rejectValue(lineItemsFieldName, "error.lineitems.price");
}
if (!discounts) {
errors.rejectValue(lineItemsFieldName, "error.lineitems.discount");
}
if (!shippingPrices) {
errors.rejectValue(lineItemsFieldName, "error.lineitems.shipping");
}
if (!handlingPrices) {
errors.rejectValue(lineItemsFieldName, "error.lineitems.handling");
}
if (!quantities) {
errors.rejectValue(lineItemsFieldName, "error.lineitems.quantity");
}
if (!totalPrices) {
errors.rejectValue(lineItemsFieldName, "error.lineitems.totalprice");
}
}
protected void validateShipping(ShippingInfo shipping, Errors errors) {
if (!SHIPPER_IDS.contains(shipping.getShipperId())) {
errors.rejectValue("shipping.shipperId", "error.shipping.shipper");
}
if (!SHIPPER_TYPES.contains(shipping.getShippingTypeId())) {
errors.rejectValue("shipping.shippingTypeId", "error.shipping.type");
}
if (StringUtils.hasText(shipping.getShippingInfo())) {
validateStringLength(shipping.getShippingInfo(), errors, "shipping.shippingInfo",
"error.shipping.shippinginfo.length", 100);
}
}
protected void validatePayment(BillingInfo billing, Errors errors) {
if (!CARD_TYPES.contains(billing.getPaymentId())) {
errors.rejectValue("billing.paymentId", "error.billing.type");
}
if (!billing.getPaymentDesc().matches("[A-Z]{4}-[0-9]{10,11}")) {
errors.rejectValue("billing.paymentDesc", "error.billing.desc");
}
}
protected void validateAddress(Address address, Errors errors, String prefix) {
if (address != null) {
if (StringUtils.hasText(address.getAddressee())) {
validateStringLength(address.getAddressee(), errors, prefix + ".addressee",
"error.baddress.addresse.length", 60);
}
validateStringLength(address.getAddrLine1(), errors, prefix + ".addrLine1",
"error.baddress.addrline1.length", 50);
if (StringUtils.hasText(address.getAddrLine2())) {
validateStringLength(address.getAddrLine2(), errors, prefix + ".addrLine2",
"error.baddress.addrline2.length", 50);
}
validateStringLength(address.getCity(), errors, prefix + ".city", "error.baddress.city.length", 30);
validateStringLength(address.getZipCode(), errors, prefix + ".zipCode", "error.baddress.zipcode.length", 5);
if (StringUtils.hasText(address.getZipCode()) && !address.getZipCode().matches("[0-9]{5}")) {
errors.rejectValue(prefix + ".zipCode", "error.baddress.zipcode.format");
}
if ((!StringUtils.hasText(address.getState()) && ("United States".equals(address.getCountry()))
|| StringUtils.hasText(address.getState()) && address.getState().length() != 2)) {
errors.rejectValue(prefix + ".state", "error.baddress.state.length");
}
validateStringLength(address.getCountry(), errors, prefix + ".country", "error.baddress.country.length",
50);
}
}
protected void validateStringLength(String string, Errors errors, String field, String message, int length) {
if (!StringUtils.hasText(string) || string.length() > length) {
errors.rejectValue(field, message);
}
}
protected void validateCustomer(Customer customer, Errors errors) {
if (!customer.isRegistered() && customer.isBusinessCustomer()) {
errors.rejectValue("customer.registered", "error.customer.registration");
}
if (!StringUtils.hasText(customer.getCompanyName()) && customer.isBusinessCustomer()) {
errors.rejectValue("customer.companyName", "error.customer.companyname");
}
if (!StringUtils.hasText(customer.getFirstName()) && !customer.isBusinessCustomer()) {
errors.rejectValue("customer.firstName", "error.customer.firstname");
}
if (!StringUtils.hasText(customer.getLastName()) && !customer.isBusinessCustomer()) {
errors.rejectValue("customer.lastName", "error.customer.lastname");
}
if (customer.isRegistered()
&& (customer.getRegistrationId() < 0 || customer.getRegistrationId() >= 99999999L)) {
errors.rejectValue("customer.registrationId", "error.customer.registrationid");
}
}
protected void validateOrder(Order item, Errors errors) {
if (item.getOrderId() < 0 || item.getOrderId() > 9999999999L) {
errors.rejectValue("orderId", "error.order.id");
}
if (new Date().compareTo(item.getOrderDate()) < 0) {
errors.rejectValue("orderDate", "error.order.date.future");
}
if (item.getLineItems() != null && item.getTotalLines() != item.getLineItems().size()) {
errors.rejectValue("totalLines", "error.order.lines.badcount");
}
}
}
相关信息
相关文章
spring-batch MavenWrapperDownloader 源码
spring-batch DefaultJobKeyGenerator 源码
spring-batch ItemProcessListener 源码
spring-batch ItemReadListener 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦