001/* Copyright (C) 2014 konik.io
002 *
003 * This file is part of the Konik library.
004 *
005 * The Konik library is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * The Konik library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with the Konik library. If not, see <http://www.gnu.org/licenses/>.
017 */
018package io.konik.validation;
019
020import io.konik.validator.annotation.Comfort;
021import io.konik.validator.annotation.Extended;
022import io.konik.zugferd.Invoice;
023import io.konik.zugferd.profile.ConformanceLevel;
024
025import java.util.Set;
026
027import javax.inject.Inject;
028import javax.inject.Named;
029import javax.inject.Singleton;
030import javax.validation.ConstraintViolation;
031import javax.validation.Validation;
032import javax.validation.Validator;
033import javax.validation.ValidatorFactory;
034import javax.validation.groups.Default;
035
036import org.apache.bval.jsr.DefaultMessageInterpolator;
037
038/**
039 * Validates the invoice against the declared invoice profile.
040 */
041@Named
042@Singleton
043public class InvoiceValidator {
044
045        private final Validator validator;
046        private final MonetarySummationValidator monetarySummationValidator;
047
048        /**
049         * Instantiates a new invoice validator.
050         *
051         * @param validator the validator
052         * @param monetarySummationValidator 
053         */
054        @Inject
055        public InvoiceValidator(Validator validator, MonetarySummationValidator monetarySummationValidator) {
056                super();
057                this.validator = validator;
058                this.monetarySummationValidator = monetarySummationValidator;
059        }
060
061        /**
062         * Instantiates a new invoice validator.
063         *
064         * @param validator the validator
065         */
066        public InvoiceValidator(Validator validator) {
067                super();
068                this.validator = validator;
069                this.monetarySummationValidator = new MonetarySummationValidator(new DefaultMessageInterpolator());
070        }
071
072        /**
073         * Instantiates a new default invoice validator, based on the Bean Validation provider
074         */
075        public InvoiceValidator() {
076                ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
077                this.validator = factory.getValidator();
078                this.monetarySummationValidator = new MonetarySummationValidator(new DefaultMessageInterpolator());
079        }
080
081
082        /**
083         * Validate the invoice
084         *
085         * @param invoice the invoice
086         * @return the sets the
087         */
088        public Set<ConstraintViolation<Invoice>> validate(Invoice invoice) {
089                ConformanceLevel conformanceLevel = invoice.getContext().getGuideline().getConformanceLevel();
090                Class<?>[] validationGroups = resolveIntoValidationGroups(conformanceLevel);
091                Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice, validationGroups);
092                if (monetarySummationValidator != null) {
093                        violations.addAll(monetarySummationValidator.validate(invoice, validationGroups));
094                }
095                return violations;
096        }
097
098        /**
099         * Resolve the given profile into bean validation groups.
100         *
101         * @param conformanceLevel the given profile
102         * @return the class[] list of validation group classes
103         */
104        public static Class<?>[] resolveIntoValidationGroups(ConformanceLevel conformanceLevel) {
105                switch (conformanceLevel) {
106                        case BASIC:
107                                return new Class[]{Default.class};
108                        case COMFORT:
109                                return new Class[]{Default.class, Comfort.class};
110                        case EXTENDED:
111                                return new Class[]{Default.class, Comfort.class, Extended.class};
112                        default:
113                                throw new IllegalArgumentException("Provided Profile:" + conformanceLevel + "not covered");
114                }
115        }
116}