<?xml version="1.0" encoding="UTF-8"?>
<!--

    Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.

    This program and the accompanying materials are made available under the
    terms of the Eclipse Public License v. 2.0, which is available at
    http://www.eclipse.org/legal/epl-2.0.

    This Source Code may also be made available under the following Secondary
    Licenses when the conditions for such availability set forth in the
    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
    version 2 with the GNU Classpath Exception, which is available at
    https://www.gnu.org/software/classpath/license.html.

    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0

-->

<project name="hello-jsp" default="default" basedir=".">
    <property file="build.properties"/>
    <property file="${ws.root}/gfproject/${deploy.platform}-config.properties"/>


    <description>

Builds, tests, and runs an integration test to verify that the way
glassfish uses JSR-303 Bean Validation is correctly supported by the
implementation of Bean Validation provided in glassfish.

The following classes were examined for usage patterns for JSR 303 Bean
Validation.

connectors/connectors-runtime/src/main/java/com/sun/enterprise/connectors/module/ConnectorDeployer.java

- This class loads validation mappings from an XML file so it can obtain
  a jakarta.validation.Validator instance, which it then puts in the
  ConnectorRegistry.

  In method registerBeanValidator(),

 Validator beanValidator = null;
            ValidatorFactory validatorFactory = null;

                    GenericBootstrap bootstrap = Validation.byDefaultProvider();
                    Configuration config = bootstrap.configure();

                    InputStream inputStream = null;

                        for (String fileName : mappingsList) {
                            inputStream = archive.getEntry(fileName);
                            config.addMapping(inputStream);
                        }
                        validatorFactory = config.buildValidatorFactory();
                        ValidatorContext validatorContext = validatorFactory.usingContext();
                        beanValidator = validatorContext.getValidator();

  fileName is the name of a file conforming to

  xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd"

  If we don't have a Validator instance after the above, we get a default one:

            if (beanValidator == null) {
                validatorFactory = Validation.byDefaultProvider().configure().buildValidatorFactory();
                beanValidator = validatorFactory.getValidator();
            }

            ConnectorRegistry registry = ConnectorRegistry.getInstance();
            registry.addBeanValidator(rarName, beanValidator);

  This validator is used in
  connectors/connectors-runtime/src/main/java/com/sun/enterprise/connectors/util/ConnectorJavaBeanValidator.java method validateJavaBean().

    public void validateJavaBean(Object bean, String rarName) {
        if (bean != null) {
            Validator validator = ConnectorRegistry.getInstance().getBeanValidator(rarName);
            if (validator != null) {
                BeanDescriptor bd =
                        validator.getConstraintsForClass(bean.getClass());
                bd.getConstraintDescriptors();

                Class array[] = new Class[]{};
                Set constraintViolations = validator.validate(bean, array);


                if (constraintViolations != null AND.size() > 0) {
                    ConstraintViolationException cve = new ConstraintViolationException(constraintViolations);
                    StringBuffer msg = new StringBuffer();

                    Iterator it = constraintViolations.iterator();
                    while (it.hasNext()) {
                        ConstraintViolation cv = (ConstraintViolation) it.next();
                        msg.append("\n Bean Class : ").append(cv.getRootBeanClass());
                        msg.append("\n Bean : ").append(cv.getRootBean());
                        msg.append("\n Property path : " ).append(cv.getPropertyPath());
                        msg.append("\n Violation Message : " ).append(cv.getMessage());
                    }

                    Object[] args = new Object[]{bean.getClass(), rarName, msg.toString()};
                    _logger.log(Level.SEVERE, "validation.constraints.violation",args);
                    throw cve;
                }
            } else {
                if(_logger.isLoggable(Level.FINEST)){
                   _logger.log(Level.FINEST, "No Bean Validator is available for RAR [ " + rarName + " ]");
                }
            }
        }


    </description>
    <import file="${ws.root}/gfproject/build-impl.xml"/>
    <import file="${ws.root}/gfproject/${deploy.platform}-targets.xml"/>

    <target name="all" depends="build,deploy,runtest,undeploy" />
    <target name="build-deploy" depends="build,deploy" />

    <target name="build" depends="compile-tests">
        <antcall target="build-impl"/>
    </target>

    <target name="deploy">
        <antcall target="deploy-${deploy.platform}-impl"/>
    </target>

    <target  name="runtest">
        <antcall target="runtest-impl">
        <param name="contextroot" value="${contextroot}"/>
        <param name="testng.test.name" value="${testng.test.name}"/>
        <param name="testng.testclient" value="IntegrationBVServletTestNG"/>
        </antcall>

    </target>

    <target name="undeploy">
        <antcall target="undeploy-${deploy.platform}-impl"/>
    </target>


</project>
