<?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:p="http://www.springframework.org/schema/p" 
	xmlns:tx="http://www.springframework.org/schema/tx" 
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:security="http://www.springframework.org/schema/security" 
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">

	<!-- Root Context: defines shared resources visible to all other web components -->

	<context:annotation-config />
	<context:component-scan base-package="info.bukova.isspst,org.zkoss.spring.beans.zkcomponents"></context:component-scan>
	
	<task:annotation-driven/>

	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" id="propertyConfigurer">
		<property name="locations">
			<list>
				<value>/WEB-INF/jdbc.properties</value>
				<value>/WEB-INF/ldap.properties</value>
				<value>/WEB-INF/mail.properties</value>
				<value>/WEB-INF/gmail.properties</value>
				<value>/WEB-INF/ad.properties</value>
			</list>
		</property>
	</bean>

	<!-- Database -->
	<bean id="dataSource"
        class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
        p:driverClassName="${jdbc.driverClassName}"
        p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
        p:password="${jdbc.password}">
        	<property name="validationQuery" value="SELECT 1"/>
        	<property name="testOnBorrow" value="true"/>
        </bean>
        
	<bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${jdbc.dialect}</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.search.default.directory_provider">filesystem</prop>
                <prop key="hibernate.search.default.indexBase">./</prop>
                <prop key="hibernate.search.analyzer">org.apache.lucene.analysis.cz.CzechAnalyzer</prop>
                <!-- <prop key="hibernate.enable_lazy_load_no_trans">true</prop> -->
            </props>
        </property>
    </bean>
    
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
    
    <!-- Security -->
    <security:global-method-security pre-post-annotations="enabled">
		<security:expression-handler ref="expressionHandler" />
	</security:global-method-security>
 

	<bean id="expressionHandler"
  		class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
		<property name="permissionEvaluator" ref="permissionEvaluator" />
	</bean>
	
	<bean id="permissionEvaluator" class="info.bukova.isspst.security.IsPermissionEvaluator">
		<!-- <property name="workgroupService" ref="workgroupServiceNoTx"/> -->
	</bean>
	
	<bean id="serviceEval" class="info.bukova.isspst.security.ServiceEvaluator"/>
	
	<bean id="wgServiceEval" class="info.bukova.isspst.security.WorkgroupAwareServiceEvaluator">
		<constructor-arg ref="workgroupServiceNoTx"/>
	</bean>
	
	<bean id="requirementEval" class="info.bukova.isspst.security.RequirementFilterEvaluator">
		<constructor-arg ref="workgroupServiceNoTx"/>
	</bean>
	
	<bean id="reqEditEval" class="info.bukova.isspst.security.RequirementEvaluator"/>
	
	<bean id="tripReqEditEval" class="info.bukova.isspst.security.TripRequirementEvaluator"/>
	
	<bean id="userEvaluator" class="info.bukova.isspst.security.UserEvaluator"/>
	
	<bean id="evalHolder" class="info.bukova.isspst.security.EvaluatorsHolder">
		<property name="globalEvaluators">
			<map>
				<entry key="#{T(info.bukova.isspst.services.Service)}" value-ref="serviceEval"/>
				<entry key="#{T(info.bukova.isspst.data.Requirement)}" value-ref="reqEditEval"/>
				<entry key="#{T(info.bukova.isspst.data.TripRequirement)}" value-ref="tripReqEditEval"/>
				<entry key="#{T(info.bukova.isspst.data.User)}" value-ref="userEvaluator"/>
				<entry key="#{T(info.bukova.isspst.services.FullTextService)}" value-ref="serviceEval"/>
			</map>
		</property>
		<property name="specialEvaluators">
			<map>
				<entry key="#{T(info.bukova.isspst.services.Service)}" value-ref="wgServiceEval"/>
				<entry key="#{T(info.bukova.isspst.data.RequirementBase)}" value-ref="requirementEval"/>
				<entry key="#{T(info.bukova.isspst.data.JoinedItem)}" value-ref="requirementEval"/>
			</map>
		</property>
	</bean>
    
	<security:http auto-config="true" use-expressions="true">
		<security:intercept-url pattern="/app/**" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')"/>
		<security:intercept-url pattern="/admin/users/**" access="hasRole('PERM_READ_USERS')"/>
		<security:intercept-url pattern="/admin/permissions/**" access="hasRole('PERM_READ_PERMISSIONS')"/>
		<security:intercept-url pattern="/admin/addressbook/**" access="hasRole('PERM_READ_ADDRESSBOOK')"/>
		<security:intercept-url pattern="/munits/**" access="hasRole('PERM_READ_MUNITS')"/>
		<security:form-login login-page="/login.zhtml"
			authentication-failure-handler-ref="loginFail"
			authentication-success-handler-ref="loginSuccess"/>
		<security:http-basic/>
		
		<security:openid-login authentication-failure-handler-ref="loginFail"
			authentication-success-handler-ref="loginSuccess" 
			user-service-ref="gmailUserService">
			<security:attribute-exchange identifier-match="https://www.google.com/.*">
                <security:openid-attribute name="email" type="http://schema.openid.net/contact/email" required="true" />
                <security:openid-attribute name="firstName" type="http://axschema.org/namePerson/first" required="true" />
                <security:openid-attribute name="lastName" type="http://axschema.org/namePerson/last" required="true" />
            </security:attribute-exchange>
		</security:openid-login>
		
		<security:logout invalidate-session="true"/>
	</security:http>

	<!-- Authentication methods -->
	<import resource="database-auth.xml"/>
	<!-- <import resource="ldap-auth.xml"/> 
	<import resource="ad-auth.xml"/> -->
	<import resource="gmail-auth.xml"/>
		
	<import resource="mail-services.xml"/>

	<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
		<property name="targetClass" value="org.springframework.security.core.context.SecurityContextHolder" />
		<property name="targetMethod" value="setStrategyName" />
		<property name="arguments" value="MODE_INHERITABLETHREADLOCAL" />
	</bean>
	
	<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder"/>
	
	<bean id="loginFail" class="info.bukova.isspst.security.LoginFailHandler"/>
	
	<bean id="loginSuccess" class="info.bukova.isspst.security.LoginSuccessHandler"/>
	
	<!-- Reporting -->
	<bean id="reportDefinition" class="info.bukova.isspst.reporting.ReportDefinition" scope="session">
		<aop:scoped-proxy/>
	</bean>
	
	<bean id="paramFiller" class="info.bukova.isspst.reporting.ParamFiller"/>
	
	<bean id="genFactory" class="info.bukova.isspst.reporting.GeneratorFactory"/>
	
	<!-- File storage -->
	<bean id="storage" class="info.bukova.isspst.storage.LocalFileStorage">
		<property name="context" ref="servletContext"/>
		<property name="rootPath" value="/WEB-INF/upload"/>
	</bean>
	
	<!-- Session data -->
	<bean id="sessionData" class="info.bukova.isspst.SessionData" scope="session">
		<aop:scoped-proxy/>
	</bean>
    
    <!-- DAO -->
    <bean id="queryDao" class="info.bukova.isspst.dao.jpa.QueryDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="userDao" class="info.bukova.isspst.dao.jpa.UserDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="roleDao" class="info.bukova.isspst.dao.jpa.RoleDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="buildingDao" class="info.bukova.isspst.dao.jpa.BuildingDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="munitDao" class="info.bukova.isspst.dao.jpa.MUnitDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="addressDao" class="info.bukova.isspst.dao.jpa.AddressDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="permissionDao" class="info.bukova.isspst.dao.jpa.PermissionDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="materialDao" class="info.bukova.isspst.dao.jpa.MaterialDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="commissionDao" class="info.bukova.isspst.dao.jpa.WorkgroupDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <bean id="requirementDao" class="info.bukova.isspst.dao.jpa.RequirementDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <bean id="requirementItemDao" class="info.bukova.isspst.dao.jpa.RequirementItemDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <bean id="numericSeriesDao" class="info.bukova.isspst.dao.jpa.NumberSeriesDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="reqTypeDao" class="info.bukova.isspst.dao.jpa.RequirementTypeDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="serviceItemDao" class="info.bukova.isspst.dao.jpa.ServiceItemDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="settingsDao" class="info.bukova.isspst.dao.jpa.GlobalSettingsDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="tripReqDao" class="info.bukova.isspst.dao.jpa.TripRequirementDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="tripBillDao" class="info.bukova.isspst.dao.jpa.TripBillDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="orderDao" class="info.bukova.isspst.dao.jpa.OrderDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="invoicingDao" class="info.bukova.isspst.dao.jpa.InvoicingDaoJPA">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <!-- Business logic -->
    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
    
	<bean id="userService" class="info.bukova.isspst.services.users.UserServiceImpl">
		<constructor-arg name="marshaller" ref="marshallerUsrSettings"/>
		<constructor-arg name="unmarshaller" ref="unmarshallerUsrSettings"/>
		<property name="dao" ref="userDao" />
		<property name="encoder" ref="passwordEncoder" />
	</bean>
	
	<bean id="xmlCtxUsrSettings" class="org.castor.spring.xml.XMLContextFactoryBean">
		<property name="castorProperties">
			<props>
				<prop key="org.exolab.castor.xml.introspector.primitive.nodetype">element</prop>
			</props>
		</property>
	</bean>
	
	<bean id="unmarshallerUsrSettings" class="org.castor.spring.xml.CastorUnmarshallerFactoryBean">
		<property name="xmlContext" ref="xmlCtxUsrSettings" />
	</bean>
	
	<bean id="marshallerUsrSettings" class="org.castor.spring.xml.CastorMarshallerFactoryBean">
		<property name="xmlContext" ref="xmlCtxUsrSettings" />
	</bean>

	<bean id="roleService" class="info.bukova.isspst.services.users.RoleServiceImpl">
		<property name="dao" ref="roleDao" />
	</bean>

	<bean id="buildingService" class="info.bukova.isspst.services.buildings.BuildingServiceImpl">
		<property name="dao" ref="buildingDao" />
		<property name="validator" ref="validator" />
	</bean>

	<bean id="munitService" class="info.bukova.isspst.services.munits.MUnitServiceImpl">
		<property name="dao" ref="munitDao" />
		<property name="validator" ref="validator" />
	</bean>
	
	<bean id="adbService" class="info.bukova.isspst.services.addressbook.AdbServiceImpl">
		<property name="dao" ref="addressDao" />
		<property name="validator" ref="validator" />
	</bean>

	<bean id="addressFinderAres" class="info.bukova.isspst.services.addressbook.AddressFinderAres">
		<property name="aresUrl" value="http://wwwinfo.mfcr.cz/cgi-bin/ares/darv_std.cgi" />
		<property name="unmarsheller" ref="unmarshallerAres" />
	</bean>

	<bean id="addressFinderTaxID" class="info.bukova.isspst.services.addressbook.AddressFinderTaxID">
		<property name="aresDicUrl" value="http://wwwinfo.mfcr.cz/cgi-bin/ares/darv_bas.cgi" />
	</bean>

	<bean id="xmlCtxAres" class="org.castor.spring.xml.XMLContextFactoryBean">
		<property name="mappingLocations">
			<list>
				<value>info/bukova/isspst/services/addressbook/mappingAres.xml</value>
			</list>
		</property>
	</bean>

	<bean id="unmarshallerAres" class="org.castor.spring.xml.CastorUnmarshallerFactoryBean">
		<property name="xmlContext" ref="xmlCtxAres" />
	</bean>

	<bean id="approvedService" class="info.bukova.isspst.services.orders.ApprovedServiceImpl"/>
		
	<bean id="permissionService" class="info.bukova.isspst.services.users.PermissionServiceImpl">
		<property name="dao" ref="permissionDao"/>
	</bean>
	
	<bean id="materialService" class="info.bukova.isspst.services.reqsubjects.MaterialServiceImpl">
		<property name="dao" ref="materialDao"/>
		<property name="validator" ref="validator"/>
	</bean>
	
	<bean id="workgroupService" class="info.bukova.isspst.services.workgroups.WorkgroupServiceImpl">
		<property name="dao" ref="commissionDao"/>
		<property name="validator" ref="validator"/>
	</bean>
	
	<bean id="workgroupServiceNoTx" class="info.bukova.isspst.services.workgroups.WorkgroupServiceImpl">
		<property name="dao" ref="commissionDao"/>
	</bean>
	
	<bean id="reqTypeService" class="info.bukova.isspst.services.requirement.RequirementTypeServiceImpl">
		<property name="dao" ref="reqTypeDao"/>
		<property name="validator" ref="validator"/>
	</bean>
		
	<bean id="requirementService" class="info.bukova.isspst.services.requirement.RequirementServiceImpl">
		<property name="dao" ref="requirementDao" />
		<property name="validator" ref="validator" />
		<property name="numberSeriesService" ref="numericSeriesService" />
	</bean>

	<bean id="reqMaterialService" class="info.bukova.isspst.services.requirement.ReqMaterialServiceImpl">
		<property name="dao" ref="requirementDao" />
		<property name="validator" ref="validator" />
		<property name="numberSeriesService" ref="numericSeriesService" />
	</bean>

	<bean id="reqServicesService" class="info.bukova.isspst.services.requirement.ReqServicesServiceImpl">
		<property name="dao" ref="requirementDao" />
		<property name="validator" ref="validator" />
		<property name="numberSeriesService" ref="numericSeriesService" />
	</bean>

	<bean id="numericSeriesService" class="info.bukova.isspst.services.numberseries.NumberSeriesServiceImpl">
		<property name="dao" ref="numericSeriesDao" />
		<property name="validator" ref="validator" />
	</bean>
	
	<bean id="serviceItemService" class="info.bukova.isspst.services.reqsubjects.ServiceItemServiceImpl">
		<property name="dao" ref="serviceItemDao" />
		<property name="validator" ref="validator" />
	</bean>
	
	<bean id="settingsService" class="info.bukova.isspst.services.settings.GlobalSettingServiceImpl">
		<constructor-arg name="marshaller" ref="marshallerSettings"/>
		<constructor-arg name="unmarshaller" ref="unmarshallerSettings"/>
		<property name="dao" ref="settingsDao"/>
	</bean>
	
	<bean id="xmlCtxSettings" class="org.castor.spring.xml.XMLContextFactoryBean">
		<property name="castorProperties">
			<props>
				<prop key="org.exolab.castor.xml.introspector.primitive.nodetype">element</prop>
			</props>
		</property>
		<property name="mappingLocations">
			<list>
				<value>info/bukova/isspst/services/settings/mappingSettings.xml</value>
			</list>
		</property>
	</bean>
	
	<bean id="unmarshallerSettings" class="org.castor.spring.xml.CastorUnmarshallerFactoryBean">
		<property name="xmlContext" ref="xmlCtxSettings" />
	</bean>
	
	<bean id="marshallerSettings" class="org.castor.spring.xml.CastorMarshallerFactoryBean">
		<property name="xmlContext" ref="xmlCtxSettings" />
	</bean>
	
	<bean id="tripRequirementService" class="info.bukova.isspst.services.requirement.TripRequirementServiceImpl">
		<property name="dao" ref="tripReqDao"/>
		<property name="validator" ref="validator"/>
		<property name="numberSeriesService" ref="numericSeriesService"/>
	</bean>
	
	<bean id="tripBillService" class="info.bukova.isspst.services.tripbill.TripBillServiceImpl">
		<property name="dao" ref="tripBillDao"/>
		<property name="validator" ref="validator"/>
	</bean>
	
	<bean id="orderService" class="info.bukova.isspst.services.orders.OrderServiceImpl">
		<property name="dao" ref="orderDao"/>
		<property name="validator" ref="validator"/>
		<property name="numberSeriesService" ref="numericSeriesService"/>
	</bean>
	
	<bean id="invoicingService" class="info.bukova.isspst.services.invoicing.InvoicingServiceImpl">
		<property name="dao" ref="invoicingDao"/>
		<property name="validator" ref="validator"/>
	</bean>
	
	<bean id="fulltextService" class="info.bukova.isspst.services.FullTextServiceImpl"/>
	
</beans>
