<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:security="http://www.springframework.org/schema/security"
    xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
		http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-5.4.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!--
        DispatcherServlet Context: defines this servlet's request-processing infrastructure
    -->

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!-- Imports user-defined @Controller beans that process client requests -->
    <!--<import resource="controllers.xml" />-->
    <mvc:view-controller path="/logout" view-name="login"/>
    <mvc:view-controller path="/sso/loggedout" view-name="loggedout"/>
    <mvc:view-controller path="/samllogin" view-name="saml_login"/>
    <mvc:view-controller path="/" view-name="redirect:/home.html"/>
    <mvc:view-controller path="/oauth/loggedout" view-name="oauth-loggedout"/>

    <!-- Scan for Spring beans declared via annotations. -->
    <!--<context:component-scan base-package="com.armedia.acm.web"/>-->
    <context:component-scan base-package="org.springframework.security.saml.web"/>
    <context:property-placeholder ignore-resource-not-found="true" ignore-unresolvable="true"/>
    
    <bean id="jacksonDeserializationHandler" class="com.armedia.acm.web.api.handler.JacksonDeserializationHandler"/>
    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetObject" ref="sourceObjectMapper"/>
        <property name="targetMethod" value="addHandler"/>
        <property name="arguments" ref="jacksonDeserializationHandler"/>
    </bean>

    <bean id="acmJacksonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <property name="objectMapper" ref="sourceObjectMapper"/>
    </bean>

    <bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="packagesToScan" value="com.armedia.**"/>
    </bean>

    <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
        <property name="defaultContentType" value="application/json"/>
        <property name="favorPathExtension" value="false"/>
        <property name="mediaTypes">
            <props>
                <prop key="xml">text/xml</prop>
                <prop key="xml">text/css</prop>
                <prop key="json">application/json</prop>
            </props>
        </property>
    </bean>

    <!-- Enables the Spring MVC @Controller programming model -->
    <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
        <mvc:message-converters>
            <!-- We configure the Jackson mapper to output dates in ISO801 format. This requires adding our
            customized Jackson mapper to the list of Spring MVC message converters. But, if we just add our bean here
            all by itself, it will handle requests it should not handle, e.g. encoding strings.  So we need to add the
            other standard message converters here too, and make sure to put the customized Jackson converter AFTER the
            string converter. -->

            <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
            <bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
                <property name="marshaller" ref="jaxb2Marshaller"/>
                <property name="unmarshaller" ref="jaxb2Marshaller"/>
            </bean>
            <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
            <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
            <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
            <ref bean="acmJacksonConverter"/>
            <bean class="org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter"/>
            <!-- atom feed requires com.sun.syndication package ...   -->
            <!--<bean class="org.springframework.http.converter.feed.AtomFeedHttpMessageConverter"/>-->
            <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
            <bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
            <bean class="org.springframework.http.converter.xml.Jaxb2CollectionHttpMessageConverter"/>

        </mvc:message-converters>
    </mvc:annotation-driven>
    <!--<context:spring-configured/>-->
    <!--<context:annotation-config/>-->

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <ref bean="acmAuditRequestInterceptor"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/plugin/**"/>
            <mvc:mapping path="/api/*/plugin/**"/>
            <mvc:mapping path="/api/*/service/**"/>
            <mvc:mapping path="/modules/*/views/**.html"/>
            <mvc:mapping path="/api/*/authenticationtoken/**"/>
            <mvc:mapping path="/api/*forms/**"/>
            <mvc:mapping path="/api/*/functionalaccess/**"/>
            <mvc:mapping path="/api/*/users/**"/>
            <mvc:mapping path="/api/*/milestonebyname/**"/>
            <ref bean="acmPluginRoleBasedAccessInterceptor"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/plugin/**"/>
            <mvc:mapping path="/api/**"/>
            <ref bean="acmAuditPropertyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

    <!--
        Enable serving of classpath with Spring 3 resource serving mechanism. For example:
        /webflow-primefaces-showcase/app/resources/styles/blueprint/print.css
    -->
    <mvc:default-servlet-handler/>

    <!-- provided max-age value is in seconds. In this example max-age = 30 days, and s-maxage = 365 days -->
    <mvc:resources mapping="/lib/**" location="/lib/">
        <mvc:cache-control max-age="2592000" s-maxage="31536000" cache-public="false" cache-private="true"/>
        <mvc:resource-chain resource-cache="true" auto-registration="false">
            <mvc:resolvers>
                <bean class="org.springframework.web.servlet.resource.PathResourceResolver"/>
            </mvc:resolvers>
        </mvc:resource-chain>
    </mvc:resources>

    <!--All files under /assets/dist  will be versioned, and we could cache as long as possible. If file is changed, newer version will be used.-->

    <mvc:resources mapping="/assets/dist/**" location="/assets/dist/">
        <mvc:cache-control max-age="2592000" cache-public="true" s-maxage="2592000" cache-private="true"/>
    </mvc:resources>

    <!--Cache for 30 min, allow proxy to cache for 15 min-->
    <mvc:resources mapping="/assets/css/**" location="/assets/css/">
        <mvc:cache-control max-age="1800" cache-public="true" s-maxage="900" cache-private="true"/>
    </mvc:resources>

    <!--Cache for 30 min, allow proxy to cache for 15 min-->
    <mvc:resources mapping="/assets/img/**" location="/assets/img/">
        <mvc:cache-control max-age="1800" cache-public="true" s-maxage="900" cache-private="true"/>
    </mvc:resources>

    <!--Cache for 30 min, allow proxy to cache for 15 min-->
    <mvc:resources mapping="/modules_config/**" location="/modules_config/">
        <mvc:cache-control max-age="1800" cache-public="true" s-maxage="900" cache-private="true"/>
    </mvc:resources>

    <!-- Cache external resources which are not possible to add version to the name of the file. Strategy is: Cache for 1 hour, and than check for etag if changed, if not cache for 1 more hour, etc...-->
    <mvc:resources mapping="/assets/js/**" location="/assets/js/">
        <mvc:cache-control max-age="3600" cache-public="true" s-maxage="900" cache-private="true"/>
        <mvc:resource-chain resource-cache="true" auto-registration="false">
            <mvc:resolvers>
                <bean class="com.armedia.acm.web.api.PathResourceResolverWithETag"/>
            </mvc:resolvers>
        </mvc:resource-chain>
    </mvc:resources>


    <mvc:default-servlet-handler/>

    <!-- File upload support -->
    <bean id="multipartResolver" class="com.armedia.acm.web.api.AcmMultipartResolver"/>

    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
        <property name="defaultLocale" value="en"/>
    </bean>

    <mvc:interceptors>
        <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
            <property name="paramName" value="lang"/>
        </bean>
    </mvc:interceptors>

    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="classpath:messages"/>
        <property name="defaultEncoding" value="UTF-8"/>
    </bean>

    <!-- data access control -->
    <security:global-method-security pre-post-annotations="enabled">
        <security:expression-handler ref="mvcExpressionHandler"/>
    </security:global-method-security>

    <bean id="mvcExpressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
        <property name="permissionEvaluator" ref="arkPermissionEvaluator"/>
    </bean>

    <!-- Swagger documentation configuration class -->
    <bean id="swagger2Config" class="springfox.documentation.swagger2.configuration.Swagger2DocumentationConfiguration"></bean>

    <!-- default servlet handler so that spring auto-detects the default servlet for the container on startup -->
    <mvc:default-servlet-handler/>
</beans>
