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

    Licensed to Jasig under one or more contributor license
    agreements. See the NOTICE file distributed with this work
    for additional information regarding copyright ownership.
    Jasig licenses this file to you 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:

    http://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.

-->

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
    
    <!-- ********** User Information Support Beans ********** -->
    <!--
     | Provides user name for the current portal user if the thread is handling a request
     +-->
    <bean id="currentUserProvider" class="org.jasig.portal.persondir.support.PersonManagerCurrentUserProvider">
        <property name="personManager" ref="personManager" />
        <property name="portalRequestUtils" ref="portalRequestUtils" />
    </bean>
    
    <!--
     | Provides the default username attribute to use to the rest of the DAOs
     +-->
    <bean id="usernameAttributeProvider" class="org.jasig.services.persondir.support.SimpleUsernameAttributeProvider">
        <property name="usernameAttribute" value="username" />
    </bean>
    
    
    
    <!-- ********** Overwriting attribute beans for Attribute Swapper ********** -->
    <!-- 
     | Overrides DAO acts as the root, it handles incorporating attributes from the attribute swapper utility, wraps
     | the caching DAO
     +-->
    <bean id="personAttributeDao" class="org.jasig.portal.portlets.swapper.OverwritingPersonAttributeDao">
        <property name="delegatePersonAttributeDao" ref="requestAttributeMergingDao" />
        <property name="attributeOverridesMap" ref="sessionAttributesOverridesMap" />
    </bean>
    
    <!--
     | Store attribute overrides in a session scoped map to ensure overrides don't show up for
     | other users and swapped attributes will be cleaned up on user logout.
     +-->
    <bean id="sessionAttributesOverridesMap" class="java.util.concurrent.ConcurrentHashMap" scope="globalSession">
        <aop:scoped-proxy />
    </bean>
    
    
    
    <!-- ********** Beans for Attributes from the HttpServletRequest **********-->
    <!-- 
     | Merges attributes from the request with those from other DAOs
     +-->
    <bean id="requestAttributeMergingDao" class="org.jasig.services.persondir.support.MergingPersonAttributeDaoImpl">
        <property name="usernameAttributeProvider" ref="usernameAttributeProvider" />
        <property name="merger">
            <bean class="org.jasig.services.persondir.support.merger.ReplacingAttributeAdder" />
        </property>
        <property name="personAttributeDaos">
            <list>
                <ref bean="requestAttributesDao"/>
                <ref bean="cachingMergedPersonAttributeDao"/>
            </list>
        </property>
    </bean>
            
    <!-- 
     | Servlet filter that creates an attribute for the serverName
     +-->
    <bean id="requestAttributeSourceFilter" class="org.jasig.services.persondir.support.web.RequestAttributeSourceFilter">
        <property name="additionalDescriptors" ref="requestAdditionalDescriptors" />
        <property name="serverNameAttribute" value="serverName" />
        <property name="processingPosition" value="BOTH" />
    </bean>
    
    <!-- 
     | Session-scoped descriptors object. One of these will exist for each user in their session. It will store the
     | attributes from the reques set by the requestAttributeSourceFilter
     +-->
    <bean id="requestAdditionalDescriptors" class="org.jasig.services.persondir.support.AdditionalDescriptors" scope="globalSession">
        <aop:scoped-proxy />
    </bean>
    
    <!-- 
     | The person attributes DAO that returns the attributes from the request. Uses a currentUserProvider since the
     | username may not always be provided by the request object.
     +-->
    <bean id="requestAttributesDao" class="org.jasig.services.persondir.support.AdditionalDescriptorsPersonAttributeDao">
        <property name="descriptors" ref="requestAdditionalDescriptors" />
        <property name="usernameAttributeProvider" ref="usernameAttributeProvider" />
        <property name="currentUserProvider" ref="currentUserProvider" />
    </bean>
    
    
    
    <!-- ********** Data source attribute DAOs **********-->
    <!-- 
     | Merging DAOs that define the order that the data providing DAOs are called, results are cached by the outer
     | caching DAO
     +-->
    <bean id="cachingMergedPersonAttributeDao" class="org.jasig.services.persondir.support.CachingPersonAttributeDaoImpl">
        <property name="usernameAttributeProvider" ref="usernameAttributeProvider" />
        <property name="cacheNullResults" value="true" />
        <property name="userInfoCache">
            <bean class="org.jasig.portal.utils.cache.MapCacheFactoryBean">
                <property name="cacheFactory" ref="cacheFactory" />
                <property name="cacheName" value="org.jasig.services.persondir.USER_INFO.merged" />
            </bean>
        </property>
        <property name="cacheKeyGenerator" ref="userAttributeCacheKeyGenerator" />
        <property name="cachedPersonAttributesDao" >
            <bean class="org.jasig.services.persondir.support.MergingPersonAttributeDaoImpl">
                <property name="usernameAttributeProvider" ref="usernameAttributeProvider" />
                <property name="merger">
                    <bean class="org.jasig.services.persondir.support.merger.ReplacingAttributeAdder" />
                </property>
                <property name="personAttributeDaos">
                    <list>
                        <ref bean="uPortalLdapAttributeSource"/>
			<ref bean="uPortalStudLdapAttributeSource"/>
                        <ref bean="cachinguPortalJdbcAttributeSource"/>
                        <ref bean="cachinguPortalJdbcUserSource"/>
                    </list>
                </property>
            </bean>
        </property>
    </bean>
    
    <!--
     | Looks in the base UP_USER table, doesn't find attributes but will ensure a result if it the user exists in the
     | portal database and is searched for by username, results are cached by the outer caching DAO
     +-->
    <bean id="cachinguPortalJdbcUserSource" class="org.jasig.services.persondir.support.CachingPersonAttributeDaoImpl">
        <property name="usernameAttributeProvider" ref="usernameAttributeProvider" />
        <property name="cacheNullResults" value="true" />
        <property name="userInfoCache">
            <bean class="org.jasig.portal.utils.cache.MapCacheFactoryBean">
                <property name="cacheFactory" ref="cacheFactory" />
                <property name="cacheName" value="org.jasig.services.persondir.USER_INFO.up_user" />
            </bean>
        </property>
        <property name="cacheKeyGenerator" ref="userAttributeCacheKeyGenerator" />
        <property name="cachedPersonAttributesDao" >
            <bean class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
                <constructor-arg index="0" ref="PersonDB" />
                <constructor-arg>
                    <value> 
                        SELECT USER_NAME
                        FROM UP_USER
                        WHERE {0}
                    </value>
                </constructor-arg>
                <property name="usernameAttributeProvider" ref="usernameAttributeProvider" />
                <property name="queryAttributeMapping">
                    <map>
                        <entry key="username" value="USER_NAME" />
                    </map>
                </property>
                <property name="resultAttributeMapping">
                    <map>
                        <entry key="USER_NAME">
                            <set>
                                <value>uid</value>
                                <value>username</value>
                                <value>user.login.id</value>
                            </set>
                        </entry>
                    </map>
                </property>
            </bean>
        </property>
    </bean>

    <!--
     | Looks in the local person-directory table. This table is only used for portal-local users such as fragment owners
     | All attributes are searchable via this configuration, results are cached by the outer caching DAO
     +-->
    <bean id="cachinguPortalJdbcAttributeSource" class="org.jasig.services.persondir.support.CachingPersonAttributeDaoImpl">
        <property name="usernameAttributeProvider" ref="usernameAttributeProvider" />
        <property name="cacheNullResults" value="true" />
        <property name="userInfoCache">
            <bean class="org.jasig.portal.utils.cache.MapCacheFactoryBean">
                <property name="cacheFactory" ref="cacheFactory" />
                <property name="cacheName" value="org.jasig.services.persondir.USER_INFO.up_person_dir" />
            </bean>
        </property>
        <property name="cacheKeyGenerator" ref="userAttributeCacheKeyGenerator" />
        <property name="cachedPersonAttributesDao" >
            <bean class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
                <constructor-arg index="0" ref="PersonDB" />
                <constructor-arg>
                    <value> 
                        SELECT FIRST_NAME||' '||LAST_NAME AS FIRST_LAST, FIRST_NAME, LAST_NAME, EMAIL, USER_NAME 
                        FROM UP_PERSON_DIR 
                        WHERE {0}
                    </value>
                </constructor-arg>
                <property name="usernameAttributeProvider" ref="usernameAttributeProvider" />
                <!-- Allow for querying using any field in the table -->
                <property name="queryAttributeMapping">
                    <map>
                        <entry key="username"   value="USER_NAME" />
                        <entry key="givenName"  value="FIRST_NAME" />
                        <entry key="sn"         value="LAST_NAME" />
                        <entry key="mail"       value="EMAIL" />
                    </map>
                </property>
                <!-- Map the table fields to P3P attribute names -->
                <property name="resultAttributeMapping">
                    <map>
                        <entry key="FIRST_LAST" value="displayName" />
                        <entry key="FIRST_NAME">
                            <set>
                                <value>givenName</value>
                                <value>user.name.given</value>
                            </set>
						</entry>
                        <entry key="LAST_NAME">
                            <set>
                                <value>sn</value>
                                <value>user.name.family</value>
                            </set>
						</entry>
                        <entry key="EMAIL">
                            <set>
                                <value>mail</value>
                                <value>user.home-info.online.email</value>
                            </set>
						</entry>
                        <entry key="USER_NAME">
                            <set>
                                <value>uid</value>
                                <value>username</value>
                                <value>user.login.id</value>
                            </set>
                        </entry>
                    </map>
                </property>
            </bean>
        </property>
    </bean>
    <bean id="uPortalLdapAttributeSource" class="org.jasig.services.persondir.support.ldap.LdapPersonAttributeDao">
		<property name="contextSource" ref="defaultLdapContext" />
                <property name="baseDN" value="ou=UserAccounts,dc=HS,dc=local" />
                <property name="queryAttributeMapping">
                    <map>
                        <entry key="username" value="sAMAccountName"/>
                    </map>
                </property>

                <property name="resultAttributeMapping">
                    <map>
                        <entry key="eduPersonPrimaryAffiliation">
                            <value>uPortalTemplateUserName</value>
                        </entry>
                        <entry key="eduPersonAffiliation">
                            <value>eduPersonAffiliation</value>
                        </entry>
                        <entry key="eduPersonNickname">
                            <set>
                                <value>eduPersonNickname</value>
                                <value>user.name.nickName</value>
                            </set>
                        </entry>
                        <entry key="eduPersonOrgDN">
                            <set>
                                <value>eduPersonOrgDN</value>
                                <value>user.employer</value>
                            </set>
                        </entry>
                        <entry key="eduPersonOrgUnitDN">
                            <set>
                                <value>eduPersonOrgUnitDN</value>
                                <value>user.department</value>
                            </set>
                        </entry>
                        <entry key="eduPersonPrimaryAffiliation">
                            <value>eduPersonPrimaryAffiliation</value>
                        </entry>
                        <entry key="eduPersonPrincipalName">
                            <value>eduPersonPrincipalName</value>
                        </entry>
                        <entry key="c">
                            <value>c</value>
                        </entry>
                        <entry key="cn">
                            <value>cn</value>
                        </entry>
                        <entry key="description">
                            <value>description</value>
                        </entry>
                        <entry key="displayName">
                            <value>displayName</value>
                        </entry>
                        <entry key="facsimileTelephoneNumber">
                            <value>facsimileTelephoneNumber</value>
                        </entry>
                        <entry key="givenName">
                            <set>
                                <value>givenName</value>
                                <value>user.name.given</value>
                            </set>
                        </entry>
                        <entry key="homePhone">
                            <value>homePhone</value>
                        </entry>
                        <entry key="homePostalAddress">
                            <value>homePostalAddress</value>
                        </entry>
                        <entry key="initials">
                            <value>initials</value>
                        </entry>
                        <entry key="jpegPhoto">
                            <value>jpegPhoto</value>
                        </entry>
                        <entry key="l">
                            <value>l</value>
                        </entry>
                        <entry key="labeledURI">
                            <value>labeledURI</value>
                        </entry>
                        <entry key="mail">
                            <set>
                                <value>mail</value>
                                <value>user.home-info.online.email</value>
                            </set>
                        </entry>
                        <entry key="mobile">
                            <value>mobile</value>
                        </entry>
                        <entry key="o">
                            <value>o</value>
                        </entry>
                        <entry key="ou">
                            <value>ou</value>
                        </entry>
                        <entry key="pager">
                            <value>pager</value>
                        </entry>
                        <entry key="postalAddress">
                            <value>postalAddress</value>
                        </entry>
                        <entry key="postalCode">
                            <value>postalCode</value>
                        </entry>
                        <entry key="postOfficeBox">
                            <value>postOfficeBox</value>
                        </entry>
                        <entry key="preferredLanguage">
                            <value>preferredLanguage</value>
                        </entry>
                        <entry key="seeAlso">
                            <value>seeAlso</value>
                        </entry>
                        <entry key="sn">
                            <set>
                                <value>sn</value>
                                <value>user.name.family</value>
                            </set>
                        </entry>
                        <entry key="st">
                            <value>st</value>
                        </entry>
                        <entry key="street">
                            <value>street</value>
                        </entry>
                        <entry key="telephoneNumber">
                            <value>telephoneNumber</value>
                        </entry>
                        <entry key="uid">
                            <value>uid</value>
                        </entry>
                        <entry key="userCertificate">
                            <value>userCertificate</value>
                        </entry>
                        <entry key="userSMIMECertificate">
                            <value>userSMIMECertificate</value>
                        </entry>
                    </map>
                </property>
	</bean> 

    <bean id="uPortalStudLdapAttributeSource" class="org.jasig.services.persondir.support.ldap.LdapPersonAttributeDao">
		<property name="contextSource" ref="studLdapContext" />
                <property name="baseDN" value="dc=HIS,dc=local" />
                <property name="queryAttributeMapping">
                    <map>
                        <entry key="username" value="sAMAccountName"/>
                    </map>
                </property>

                <property name="resultAttributeMapping">
                    <map>
                        <entry key="eduPersonPrimaryAffiliation">
                            <value>uPortalTemplateUserName</value>
                        </entry>
                        <entry key="eduPersonAffiliation">
                            <value>eduPersonAffiliation</value>
                        </entry>
                        <entry key="eduPersonNickname">
                            <set>
                                <value>eduPersonNickname</value>
                                <value>user.name.nickName</value>
                            </set>
                        </entry>
                        <entry key="eduPersonOrgDN">
                            <set>
                                <value>eduPersonOrgDN</value>
                                <value>user.employer</value>
                            </set>
                        </entry>
                        <entry key="eduPersonOrgUnitDN">
                            <set>
                                <value>eduPersonOrgUnitDN</value>
                                <value>user.department</value>
                            </set>
                        </entry>
                        <entry key="eduPersonPrimaryAffiliation">
                            <value>eduPersonPrimaryAffiliation</value>
                        </entry>
                        <entry key="eduPersonPrincipalName">
                            <value>eduPersonPrincipalName</value>
                        </entry>
                        <entry key="c">
                            <value>c</value>
                        </entry>
                        <entry key="cn">
                            <value>cn</value>
                        </entry>
                        <entry key="description">
                            <value>description</value>
                        </entry>
                        <entry key="displayName">
                            <value>displayName</value>
                        </entry>
                        <entry key="facsimileTelephoneNumber">
                            <value>facsimileTelephoneNumber</value>
                        </entry>
                        <entry key="givenName">
                            <set>
                                <value>givenName</value>
                                <value>user.name.given</value>
                            </set>
                        </entry>
                        <entry key="homePhone">
                            <value>homePhone</value>
                        </entry>
                        <entry key="homePostalAddress">
                            <value>homePostalAddress</value>
                        </entry>
                        <entry key="initials">
                            <value>initials</value>
                        </entry>
                        <entry key="jpegPhoto">
                            <value>jpegPhoto</value>
                        </entry>
                        <entry key="l">
                            <value>l</value>
                        </entry>
                        <entry key="labeledURI">
                            <value>labeledURI</value>
                        </entry>
                        <entry key="mail">
                            <set>
                                <value>mail</value>
                                <value>user.home-info.online.email</value>
                            </set>
                        </entry>
                        <entry key="mobile">
                            <value>mobile</value>
                        </entry>
                        <entry key="o">
                            <value>o</value>
                        </entry>
                        <entry key="ou">
                            <value>ou</value>
                        </entry>
                        <entry key="pager">
                            <value>pager</value>
                        </entry>
                        <entry key="postalAddress">
                            <value>postalAddress</value>
                        </entry>
                        <entry key="postalCode">
                            <value>postalCode</value>
                        </entry>
                        <entry key="postOfficeBox">
                            <value>postOfficeBox</value>
                        </entry>
                        <entry key="preferredLanguage">
                            <value>preferredLanguage</value>
                        </entry>
                        <entry key="seeAlso">
                            <value>seeAlso</value>
                        </entry>
                        <entry key="sn">
                            <set>
                                <value>sn</value>
                                <value>user.name.family</value>
                            </set>
                        </entry>
                        <entry key="st">
                            <value>st</value>
                        </entry>
                        <entry key="street">
                            <value>street</value>
                        </entry>
                        <entry key="telephoneNumber">
                            <value>telephoneNumber</value>
                        </entry>
                        <entry key="uid">
                            <value>uid</value>
                        </entry>
                        <entry key="userCertificate">
                            <value>userCertificate</value>
                        </entry>
                        <entry key="userSMIMECertificate">
                            <value>userSMIMECertificate</value>
                        </entry>
                    </map>
                </property>
	</bean> 


    <bean id="userAttributeCacheKeyGenerator" class="org.jasig.services.persondir.support.AttributeBasedCacheKeyGenerator">
        <property name="useAllAttributes" value="true" />
        <property name="ignoreEmptyAttributes" value="true" />
    </bean>
    
    <bean class="org.jasig.portal.user.UserAttributesCacheCleaner" />
</beans>
