diff --git a/booking-faces/pom.xml b/booking-faces/pom.xml
index 76192e2..798b298 100644
--- a/booking-faces/pom.xml
+++ b/booking-faces/pom.xml
@@ -10,7 +10,7 @@
3.2.0.RELEASE
- 2.3.3.RELEASE
+ 2.4.0.BUILD-SNAPSHOT
1.6.1
2.2.5
4.0
@@ -156,8 +156,8 @@
javax.servlet
- servlet-api
- 2.5
+ javax.servlet-api
+ 3.0.1
provided
diff --git a/booking-faces/src/main/java/org/springframework/webflow/samples/booking/HotelLazyDataModel.java b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/HotelLazyDataModel.java
index 5d48baa..6093396 100644
--- a/booking-faces/src/main/java/org/springframework/webflow/samples/booking/HotelLazyDataModel.java
+++ b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/HotelLazyDataModel.java
@@ -8,25 +8,30 @@ import java.util.Map;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
+import org.springframework.beans.factory.annotation.Autowired;
public class HotelLazyDataModel extends LazyDataModel {
private static final long serialVersionUID = -8832831134966938627L;
- SearchCriteria searchCriteria;
+ private SearchCriteria searchCriteria;
- BookingService bookingService;
+ private BookingService bookingService;
private List hotels;
private Hotel selected;
- public HotelLazyDataModel(SearchCriteria searchCriteria, BookingService bookingService) {
- this.searchCriteria = searchCriteria;
+ @Autowired
+ public void setBookingService(BookingService bookingService) {
this.bookingService = bookingService;
}
+ public void setSearchCriteria(SearchCriteria searchCriteria) {
+ this.searchCriteria = searchCriteria;
+ }
+
@Override
public List load(int first, int pageSize, String sortField, SortOrder order, Map filters) {
this.searchCriteria.setCurrentPage(first / pageSize + 1);
diff --git a/booking-faces/src/main/java/org/springframework/webflow/samples/booking/SearchCriteria.java b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/SearchCriteria.java
index 9888777..8bf2cd7 100755
--- a/booking-faces/src/main/java/org/springframework/webflow/samples/booking/SearchCriteria.java
+++ b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/SearchCriteria.java
@@ -2,8 +2,6 @@ package org.springframework.webflow.samples.booking;
import java.io.Serializable;
-import javax.faces.model.DataModel;
-
/**
* A backing bean for the main hotel search form. Encapsulates the criteria needed to perform a hotel search.
*/
@@ -26,13 +24,6 @@ public class SearchCriteria implements Serializable {
*/
private int currentPage = 1;
- /**
- * Returns a {@link DataModel} based on the search criteria.
- * @param bookingService the service to use to retrieve hotels.
- */
- public DataModel getDataModel(BookingService bookingService) {
- return new HotelLazyDataModel(this, bookingService);
- }
public String getSearchString() {
return searchString;
diff --git a/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/AppConfig.java b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/AppConfig.java
new file mode 100644
index 0000000..96ef724
--- /dev/null
+++ b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/AppConfig.java
@@ -0,0 +1,16 @@
+package org.springframework.webflow.samples.booking.config;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+@Configuration
+@ComponentScan(basePackages="org.springframework.webflow.samples.booking")
+@Import(value={
+ DataAccessConfig.class,
+ WebMvcConfig.class,
+ WebFlowConfig.class
+ })
+public class AppConfig {
+
+}
diff --git a/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/DataAccessConfig.java b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/DataAccessConfig.java
new file mode 100644
index 0000000..7167a1b
--- /dev/null
+++ b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/DataAccessConfig.java
@@ -0,0 +1,44 @@
+package org.springframework.webflow.samples.booking.config;
+
+import java.util.Collections;
+
+import javax.persistence.EntityManagerFactory;
+import javax.sql.DataSource;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.DriverManagerDataSource;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@Configuration
+@EnableTransactionManagement(proxyTargetClass=true)
+public class DataAccessConfig {
+
+ @Bean
+ public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
+ JpaTransactionManager txManager = new JpaTransactionManager();
+ txManager.setEntityManagerFactory(emf);
+ return txManager;
+ }
+
+ @Bean
+ public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
+ LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
+ emf.setDataSource(dataSource());
+ emf.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
+ emf.setJpaPropertyMap(Collections.singletonMap("hibernate.session_factory_name", "mySessionFactory"));
+ return emf;
+ }
+
+ @Bean
+ public DataSource dataSource() {
+ DriverManagerDataSource dataSource = new DriverManagerDataSource("jdbc:hsqldb:mem:booking", "sa", "");
+ dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
+ return dataSource;
+ }
+
+}
diff --git a/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/DispatcherServletInitializer.java b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/DispatcherServletInitializer.java
new file mode 100644
index 0000000..a73d6db
--- /dev/null
+++ b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/DispatcherServletInitializer.java
@@ -0,0 +1,54 @@
+package org.springframework.webflow.samples.booking.config;
+
+import javax.faces.webapp.FacesServlet;
+import javax.servlet.Filter;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+
+import org.springframework.web.filter.CharacterEncodingFilter;
+import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
+
+import com.sun.faces.config.ConfigureListener;
+
+public class DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
+
+ @Override
+ protected Class>[] getRootConfigClasses() {
+ return new Class>[] { SecurityConfig.class, AppConfig.class };
+ }
+
+ @Override
+ protected Class>[] getServletConfigClasses() {
+ return null;
+ }
+
+ @Override
+ protected String[] getServletMappings() {
+ return new String[] { "/spring/*" };
+ }
+
+ @Override
+ protected Filter[] getServletFilters() {
+ return new Filter[] { new CharacterEncodingFilter() };
+ }
+
+ @Override
+ public void onStartup(ServletContext servletContext) throws ServletException {
+
+ // Use JSF view templates saved as *.xhtml, for use with Facelets
+ servletContext.setInitParameter("javax.faces.DEFAULT_SUFFIX", ".xhtml");
+ // Enable special Facelets debug output during development
+ servletContext.setInitParameter("javax.faces.PROJECT_STAGE", "Development");
+ // Causes Facelets to refresh templates during development
+ servletContext.setInitParameter("javax.faces.FACELETS_REFRESH_PERIOD", "1");
+ // Declare Spring Security Facelets tag library
+ servletContext.setInitParameter("javax.faces.FACELETS_LIBRARIES", "/WEB-INF/springsecurity.taglib.xml");
+
+ servletContext.addListener(ConfigureListener.class);
+
+ // Let the DispatcherServlet be registered
+ super.onStartup(servletContext);
+ }
+
+}
diff --git a/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/SecurityConfig.java b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/SecurityConfig.java
new file mode 100644
index 0000000..8898767
--- /dev/null
+++ b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/SecurityConfig.java
@@ -0,0 +1,49 @@
+package org.springframework.webflow.samples.booking.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
+
+@Configuration
+@EnableWebSecurity
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+
+ http
+ .formLogin()
+ .loginPage("/spring/login")
+ .loginProcessingUrl("/spring/loginProcess")
+ .defaultSuccessUrl("/spring/main")
+ .failureUrl("/spring/login?login_error=1")
+ .and()
+ .logout()
+ .logoutUrl("/spring/logout")
+ .logoutSuccessUrl("/spring/logoutSuccess")
+ .and()
+
+ // Disable CSRF (won't work with JSF) but ensure last HTTP POST request is saved
+ // See https://jira.springsource.org/browse/SEC-2498
+
+ .csrf().disable()
+ .requestCache()
+ .requestCache(new HttpSessionRequestCache());
+
+ }
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ auth.inMemoryAuthentication()
+ .passwordEncoder(new Md5PasswordEncoder())
+ .withUser("keith").password("417c7382b16c395bc25b5da1398cf076").roles("USER", "SUPERVISOR").and()
+ .withUser("erwin").password("12430911a8af075c6f41c6976af22b09").roles("USER", "SUPERVISOR").and()
+ .withUser("jeremy").password("57c6cbff0d421449be820763f03139eb").roles("USER").and()
+ .withUser("scott").password("942f2339bf50796de535a384f0d1af3e").roles("USER");
+ }
+
+}
diff --git a/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/SecurityWebApplicationInitializer.java b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/SecurityWebApplicationInitializer.java
new file mode 100644
index 0000000..df49deb
--- /dev/null
+++ b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/SecurityWebApplicationInitializer.java
@@ -0,0 +1,10 @@
+package org.springframework.webflow.samples.booking.config;
+
+import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
+
+/**
+ * ServletContext initializer for Spring Security specific configuration such as
+ * the chain of Spring Security filters.
+ */
+public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
+}
diff --git a/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/WebFlowConfig.java b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/WebFlowConfig.java
new file mode 100644
index 0000000..97d98cb
--- /dev/null
+++ b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/WebFlowConfig.java
@@ -0,0 +1,36 @@
+package org.springframework.webflow.samples.booking.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.faces.config.AbstractFacesFlowConfiguration;
+import org.springframework.faces.webflow.FlowFacesContextLifecycleListener;
+import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
+import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
+import org.springframework.webflow.executor.FlowExecutor;
+import org.springframework.webflow.security.SecurityFlowExecutionListener;
+
+@Configuration
+public class WebFlowConfig extends AbstractFacesFlowConfiguration {
+
+ @Bean
+ public FlowExecutor flowExecutor() {
+ return getFlowExecutorBuilder(flowRegistry())
+ .addFlowExecutionListener(new FlowFacesContextLifecycleListener())
+ .addFlowExecutionListener(new SecurityFlowExecutionListener())
+ .build();
+ }
+
+ @Bean
+ public FlowDefinitionRegistry flowRegistry() {
+ return getFlowDefinitionRegistryBuilder(flowBuilderServices())
+ .setBasePath("/WEB-INF/flows")
+ .addFlowLocationPattern("/**/*-flow.xml")
+ .build();
+ }
+
+ @Bean
+ public FlowBuilderServices flowBuilderServices() {
+ return getFlowBuilderServicesBuilder().setDevelopmentMode(true).build();
+ }
+
+}
diff --git a/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/WebMvcConfig.java b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/WebMvcConfig.java
new file mode 100644
index 0000000..b599e80
--- /dev/null
+++ b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/WebMvcConfig.java
@@ -0,0 +1,52 @@
+package org.springframework.webflow.samples.booking.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.faces.mvc.JsfView;
+import org.springframework.faces.webflow.JsfFlowHandlerAdapter;
+import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
+import org.springframework.web.servlet.mvc.UrlFilenameViewController;
+import org.springframework.web.servlet.view.UrlBasedViewResolver;
+import org.springframework.webflow.mvc.servlet.FlowHandlerAdapter;
+import org.springframework.webflow.mvc.servlet.FlowHandlerMapping;
+
+
+@Configuration
+public class WebMvcConfig {
+
+ @Autowired
+ private WebFlowConfig webFlowConfig;
+
+ @Bean
+ public FlowHandlerMapping flowHandlerMapping() {
+ FlowHandlerMapping mapping = new FlowHandlerMapping();
+ mapping.setOrder(1);
+ mapping.setFlowRegistry(this.webFlowConfig.flowRegistry());
+ /* If no flow matches, map the path to a view, e.g. "/intro" maps to a view named "intro" */
+ mapping.setDefaultHandler(new UrlFilenameViewController());
+ return mapping;
+ }
+
+ @Bean
+ public FlowHandlerAdapter flowHandlerAdapter() {
+ JsfFlowHandlerAdapter adapter = new JsfFlowHandlerAdapter();
+ adapter.setFlowExecutor(this.webFlowConfig.flowExecutor());
+ return adapter;
+ }
+
+ @Bean
+ public UrlBasedViewResolver faceletsViewResolver() {
+ UrlBasedViewResolver resolver = new UrlBasedViewResolver();
+ resolver.setViewClass(JsfView.class);
+ resolver.setPrefix("/WEB-INF/");
+ resolver.setSuffix(".xhtml");
+ return resolver;
+ }
+
+ @Bean
+ public SimpleControllerHandlerAdapter simpleControllerHandlerAdapter() {
+ return new SimpleControllerHandlerAdapter();
+ }
+
+}
diff --git a/booking-faces/src/main/webapp/WEB-INF/config/data-access-config.xml b/booking-faces/src/main/webapp/WEB-INF/config/data-access-config.xml
deleted file mode 100644
index 2d654bc..0000000
--- a/booking-faces/src/main/webapp/WEB-INF/config/data-access-config.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/booking-faces/src/main/webapp/WEB-INF/config/security-config.xml b/booking-faces/src/main/webapp/WEB-INF/config/security-config.xml
deleted file mode 100644
index 09a6009..0000000
--- a/booking-faces/src/main/webapp/WEB-INF/config/security-config.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/booking-faces/src/main/webapp/WEB-INF/config/web-application-config.xml b/booking-faces/src/main/webapp/WEB-INF/config/web-application-config.xml
deleted file mode 100644
index 5791b17..0000000
--- a/booking-faces/src/main/webapp/WEB-INF/config/web-application-config.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/booking-faces/src/main/webapp/WEB-INF/config/webflow-config.xml b/booking-faces/src/main/webapp/WEB-INF/config/webflow-config.xml
deleted file mode 100644
index 51efb44..0000000
--- a/booking-faces/src/main/webapp/WEB-INF/config/webflow-config.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/booking-faces/src/main/webapp/WEB-INF/config/webmvc-config.xml b/booking-faces/src/main/webapp/WEB-INF/config/webmvc-config.xml
deleted file mode 100644
index b5581ad..0000000
--- a/booking-faces/src/main/webapp/WEB-INF/config/webmvc-config.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/booking-faces/src/main/webapp/WEB-INF/flows/main/main-flow.xml b/booking-faces/src/main/webapp/WEB-INF/flows/main/main-flow.xml
index 0ad4cc8..c08aa87 100755
--- a/booking-faces/src/main/webapp/WEB-INF/flows/main/main-flow.xml
+++ b/booking-faces/src/main/webapp/WEB-INF/flows/main/main-flow.xml
@@ -4,12 +4,13 @@
xsi:schemaLocation="
http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
-
-
+
+
-
+
@@ -18,9 +19,10 @@
-
-
-
+
+
+
+
diff --git a/booking-faces/src/main/webapp/WEB-INF/login.xhtml b/booking-faces/src/main/webapp/WEB-INF/login.xhtml
index b37fb94..e48cc16 100755
--- a/booking-faces/src/main/webapp/WEB-INF/login.xhtml
+++ b/booking-faces/src/main/webapp/WEB-INF/login.xhtml
@@ -37,12 +37,12 @@
-
+
Password:
-
+
diff --git a/booking-faces/src/main/webapp/WEB-INF/web.xml b/booking-faces/src/main/webapp/WEB-INF/web.xml
deleted file mode 100755
index 9a4ac64..0000000
--- a/booking-faces/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,117 +0,0 @@
-
-
-
-
-
- contextConfigLocation
-
- /WEB-INF/config/web-application-config.xml
-
-
-
-
-
- javax.faces.DEFAULT_SUFFIX
- .xhtml
-
-
-
-
- javax.faces.PROJECT_STAGE
- Development
-
-
-
-
- javax.faces.FACELETS_REFRESH_PERIOD
- 1
-
-
-
-
-
-
-
- javax.faces.FACELETS_LIBRARIES
- /WEB-INF/springsecurity.taglib.xml
-
-
-
-
- charEncodingFilter
- org.springframework.web.filter.CharacterEncodingFilter
-
- encoding
- UTF-8
-
-
- forceEncoding
- true
-
-
-
-
- charEncodingFilter
- /*
-
-
-
-
- springSecurityFilterChain
- org.springframework.web.filter.DelegatingFilterProxy
-
-
-
- springSecurityFilterChain
- /*
-
-
-
-
- org.springframework.web.context.ContextLoaderListener
-
-
-
-
- Spring MVC Dispatcher Servlet
- org.springframework.web.servlet.DispatcherServlet
-
- contextConfigLocation
-
-
- 2
-
-
-
-
- Spring MVC Dispatcher Servlet
- /spring/*
-
-
-
-
- Faces Servlet
- javax.faces.webapp.FacesServlet
- 1
-
-
-
-
- Faces Servlet
- *.faces
-
-
-
- index.html
-
-
-
diff --git a/booking-faces/src/test/java/org/springframework/webflow/samples/booking/MainFlowExecutionTests.java b/booking-faces/src/test/java/org/springframework/webflow/samples/booking/MainFlowExecutionTests.java
index 9feca43..29811dd 100644
--- a/booking-faces/src/test/java/org/springframework/webflow/samples/booking/MainFlowExecutionTests.java
+++ b/booking-faces/src/test/java/org/springframework/webflow/samples/booking/MainFlowExecutionTests.java
@@ -78,7 +78,7 @@ public class MainFlowExecutionTests extends AbstractXmlFlowExecutionTests {
hotel.setId(1L);
hotel.setName("Jameson Inn");
hotels.add(hotel);
- HotelLazyDataModel dataModel = new HotelLazyDataModel(null, null);
+ HotelLazyDataModel dataModel = new HotelLazyDataModel();
dataModel.setSelected(hotel);
getViewScope().put("hotels", dataModel);
diff --git a/booking-mvc/pom.xml b/booking-mvc/pom.xml
index fad2efe..8897eda 100644
--- a/booking-mvc/pom.xml
+++ b/booking-mvc/pom.xml
@@ -10,12 +10,12 @@
3.2.0.RELEASE
- 2.3.3.RELEASE
+ 2.4.0.BUILD-SNAPSHOT
1.7.5
- 2.0.15
- 2.0.0
- 2.0.0
- 2.0.0
+ 2.1.2.RELEASE
+ 2.1.1.RELEASE
+ 2.1.1.RELEASE
+ 2.1.0.RELEASE
2.2.2
@@ -54,12 +54,12 @@
org.thymeleaf
- thymeleaf-spring3
+ thymeleaf-spring4
${thymeleaf-version}
org.thymeleaf.extras
- thymeleaf-extras-tiles2
+ thymeleaf-extras-tiles2-spring4
${thymeleaf-extras-tiles2-version}
@@ -178,8 +178,8 @@
javax.servlet
- servlet-api
- 2.5
+ javax.servlet-api
+ 3.0.1
provided
diff --git a/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/DataAccessConfig.java b/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/DataAccessConfig.java
new file mode 100644
index 0000000..53166aa
--- /dev/null
+++ b/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/DataAccessConfig.java
@@ -0,0 +1,46 @@
+package org.springframework.webflow.samples.booking.config;
+
+import java.util.Collections;
+
+import javax.persistence.EntityManagerFactory;
+import javax.sql.DataSource;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.DriverManagerDataSource;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@Configuration
+@EnableTransactionManagement
+@ComponentScan(basePackages="org.springframework.webflow.samples.booking")
+public class DataAccessConfig {
+
+ @Bean
+ public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
+ JpaTransactionManager txManager = new JpaTransactionManager();
+ txManager.setEntityManagerFactory(emf);
+ return txManager;
+ }
+
+ @Bean
+ public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
+ LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
+ emf.setDataSource(dataSource());
+ emf.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
+ emf.setJpaPropertyMap(Collections.singletonMap("hibernate.session_factory_name", "mySessionFactory"));
+ return emf;
+ }
+
+ @Bean
+ public DataSource dataSource() {
+ DriverManagerDataSource dataSource = new DriverManagerDataSource("jdbc:hsqldb:mem:booking", "sa", "");
+ dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
+ return dataSource;
+ }
+
+}
diff --git a/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/DispatcherServletInitializer.java b/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/DispatcherServletInitializer.java
new file mode 100644
index 0000000..c86c1e0
--- /dev/null
+++ b/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/DispatcherServletInitializer.java
@@ -0,0 +1,35 @@
+package org.springframework.webflow.samples.booking.config;
+
+import javax.servlet.Filter;
+
+import org.springframework.web.filter.HiddenHttpMethodFilter;
+import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
+
+public class DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
+
+ @Override
+ protected Class>[] getRootConfigClasses() {
+ return new Class>[] {
+ SecurityConfig.class,
+ DataAccessConfig.class,
+ WebMvcConfig.class,
+ WebFlowConfig.class
+ };
+ }
+
+ @Override
+ protected Class>[] getServletConfigClasses() {
+ return null;
+ }
+
+ @Override
+ protected String[] getServletMappings() {
+ return new String[] { "/" };
+ }
+
+ @Override
+ protected Filter[] getServletFilters() {
+ return new Filter[] { new HiddenHttpMethodFilter() };
+ }
+
+}
diff --git a/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/SecurityConfig.java b/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/SecurityConfig.java
new file mode 100644
index 0000000..c05e755
--- /dev/null
+++ b/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/SecurityConfig.java
@@ -0,0 +1,38 @@
+package org.springframework.webflow.samples.booking.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
+
+@Configuration
+@EnableWebMvcSecurity
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .formLogin()
+ .loginPage("/login")
+ .loginProcessingUrl("/loginProcess")
+ .defaultSuccessUrl("/hotels/search")
+ .failureUrl("/login?login_error=1")
+ .and()
+ .logout()
+ .logoutUrl("/logout")
+ .logoutSuccessUrl("/logoutSuccess");
+ }
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ auth.inMemoryAuthentication()
+ .passwordEncoder(new Md5PasswordEncoder())
+ .withUser("keith").password("417c7382b16c395bc25b5da1398cf076").roles("USER", "SUPERVISOR").and()
+ .withUser("erwin").password("12430911a8af075c6f41c6976af22b09").roles("USER", "SUPERVISOR").and()
+ .withUser("jeremy").password("57c6cbff0d421449be820763f03139eb").roles("USER").and()
+ .withUser("scott").password("942f2339bf50796de535a384f0d1af3e").roles("USER");
+ }
+
+}
diff --git a/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/SecurityWebApplicationInitializer.java b/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/SecurityWebApplicationInitializer.java
new file mode 100644
index 0000000..df49deb
--- /dev/null
+++ b/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/SecurityWebApplicationInitializer.java
@@ -0,0 +1,10 @@
+package org.springframework.webflow.samples.booking.config;
+
+import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
+
+/**
+ * ServletContext initializer for Spring Security specific configuration such as
+ * the chain of Spring Security filters.
+ */
+public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
+}
diff --git a/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/WebFlowConfig.java b/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/WebFlowConfig.java
new file mode 100644
index 0000000..d269d2b
--- /dev/null
+++ b/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/WebFlowConfig.java
@@ -0,0 +1,59 @@
+package org.springframework.webflow.samples.booking.config;
+
+import java.util.Arrays;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
+import org.springframework.web.servlet.ViewResolver;
+import org.springframework.webflow.config.AbstractFlowConfiguration;
+import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
+import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
+import org.springframework.webflow.executor.FlowExecutor;
+import org.springframework.webflow.mvc.builder.MvcViewFactoryCreator;
+import org.springframework.webflow.security.SecurityFlowExecutionListener;
+
+@Configuration
+public class WebFlowConfig extends AbstractFlowConfiguration {
+
+ @Autowired
+ private WebMvcConfig webMvcConfig;
+
+ @Bean
+ public FlowExecutor flowExecutor() {
+ return getFlowExecutorBuilder(flowRegistry())
+ .addFlowExecutionListener(new SecurityFlowExecutionListener(), "*")
+ .build();
+ }
+
+ @Bean
+ public FlowDefinitionRegistry flowRegistry() {
+ return getFlowDefinitionRegistryBuilder(flowBuilderServices())
+ .setBasePath("/WEB-INF")
+ .addFlowLocationPattern("/**/*-flow.xml").build();
+ }
+
+ @Bean
+ public FlowBuilderServices flowBuilderServices() {
+ return getFlowBuilderServicesBuilder()
+ .setViewFactoryCreator(mvcViewFactoryCreator())
+ .setValidator(validator())
+ .setDevelopmentMode(true)
+ .build();
+ }
+
+ @Bean
+ public MvcViewFactoryCreator mvcViewFactoryCreator() {
+ MvcViewFactoryCreator factoryCreator = new MvcViewFactoryCreator();
+ factoryCreator.setViewResolvers(Arrays.asList(this.webMvcConfig.tilesViewResolver()));
+ factoryCreator.setUseSpringBeanBinding(true);
+ return factoryCreator;
+ }
+
+ @Bean
+ public LocalValidatorFactoryBean validator() {
+ return new LocalValidatorFactoryBean();
+ }
+
+}
diff --git a/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/WebMvcConfig.java b/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/WebMvcConfig.java
new file mode 100644
index 0000000..9977aed
--- /dev/null
+++ b/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/config/WebMvcConfig.java
@@ -0,0 +1,109 @@
+package org.springframework.webflow.samples.booking.config;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.webflow.mvc.servlet.FlowHandlerAdapter;
+import org.springframework.webflow.mvc.servlet.FlowHandlerMapping;
+import org.springframework.webflow.samples.booking.BookingFlowHandler;
+import org.thymeleaf.dialect.IDialect;
+import org.thymeleaf.extras.conditionalcomments.dialect.ConditionalCommentsDialect;
+import org.thymeleaf.extras.springsecurity3.dialect.SpringSecurityDialect;
+import org.thymeleaf.extras.tiles2.dialect.TilesDialect;
+import org.thymeleaf.extras.tiles2.spring4.web.configurer.ThymeleafTilesConfigurer;
+import org.thymeleaf.extras.tiles2.spring4.web.view.FlowAjaxThymeleafTilesView;
+import org.thymeleaf.spring4.SpringTemplateEngine;
+import org.thymeleaf.spring4.view.AjaxThymeleafViewResolver;
+import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
+
+@EnableWebMvc
+@Configuration
+public class WebMvcConfig extends WebMvcConfigurerAdapter {
+
+ @Autowired
+ private WebFlowConfig webFlowConfig;
+
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+ registry.addResourceHandler("/resources/**").addResourceLocations("/", "classpath:/META-INF/web-resources/");
+ }
+
+ @Override
+ public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
+ configurer.enable();
+ }
+
+ @Override
+ public void addViewControllers(ViewControllerRegistry registry) {
+ registry.addViewController("/").setViewName("intro");
+ registry.addViewController("/login");
+ registry.addViewController("/logoutSuccess");
+ }
+
+ @Bean
+ public FlowHandlerMapping flowHandlerMapping() {
+ FlowHandlerMapping handlerMapping = new FlowHandlerMapping();
+ handlerMapping.setOrder(-1);
+ handlerMapping.setFlowRegistry(this.webFlowConfig.flowRegistry());
+ return handlerMapping;
+ }
+
+ @Bean
+ public FlowHandlerAdapter flowHandlerAdapter() {
+ FlowHandlerAdapter handlerAdapter = new FlowHandlerAdapter();
+ handlerAdapter.setFlowExecutor(this.webFlowConfig.flowExecutor());
+ handlerAdapter.setSaveOutputToFlashScopeOnRedirect(true);
+ return handlerAdapter;
+ }
+
+ @Bean(name="hotels/booking")
+ public BookingFlowHandler BookingFlowHandler() {
+ return new BookingFlowHandler();
+ }
+
+ @Bean
+ public AjaxThymeleafViewResolver tilesViewResolver() {
+ AjaxThymeleafViewResolver viewResolver = new AjaxThymeleafViewResolver();
+ viewResolver.setViewClass(FlowAjaxThymeleafTilesView.class);
+ viewResolver.setTemplateEngine(templateEngine());
+ return viewResolver;
+ }
+
+ @Bean
+ public SpringTemplateEngine templateEngine(){
+
+ Set dialects = new LinkedHashSet();
+ dialects.add(new TilesDialect());
+ dialects.add(new SpringSecurityDialect());
+ dialects.add(new ConditionalCommentsDialect());
+
+ SpringTemplateEngine templateEngine = new SpringTemplateEngine();
+ templateEngine.setTemplateResolver(templateResolver());
+ templateEngine.setAdditionalDialects(dialects);
+ return templateEngine;
+ }
+
+ @Bean
+ public ServletContextTemplateResolver templateResolver() {
+ ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
+ templateResolver.setPrefix("/WEB-INF/");
+ templateResolver.setTemplateMode("HTML5");
+ return templateResolver;
+ }
+
+ @Bean
+ public ThymeleafTilesConfigurer tilesConfigurer() {
+ ThymeleafTilesConfigurer configurer = new ThymeleafTilesConfigurer();
+ configurer.setDefinitions("/WEB-INF/**/views.xml");
+ return configurer;
+ }
+
+}
diff --git a/booking-mvc/src/main/webapp/WEB-INF/config/data-access-config.xml b/booking-mvc/src/main/webapp/WEB-INF/config/data-access-config.xml
deleted file mode 100644
index 924ede3..0000000
--- a/booking-mvc/src/main/webapp/WEB-INF/config/data-access-config.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- hibernate.session_factory_name=mySessionFactory
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/booking-mvc/src/main/webapp/WEB-INF/config/security-config.xml b/booking-mvc/src/main/webapp/WEB-INF/config/security-config.xml
deleted file mode 100644
index 741607c..0000000
--- a/booking-mvc/src/main/webapp/WEB-INF/config/security-config.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/booking-mvc/src/main/webapp/WEB-INF/config/web-application-config.xml b/booking-mvc/src/main/webapp/WEB-INF/config/web-application-config.xml
deleted file mode 100644
index 10ebcf5..0000000
--- a/booking-mvc/src/main/webapp/WEB-INF/config/web-application-config.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/booking-mvc/src/main/webapp/WEB-INF/config/webflow-config.xml b/booking-mvc/src/main/webapp/WEB-INF/config/webflow-config.xml
deleted file mode 100644
index 06cb11a..0000000
--- a/booking-mvc/src/main/webapp/WEB-INF/config/webflow-config.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/booking-mvc/src/main/webapp/WEB-INF/config/webmvc-config.xml b/booking-mvc/src/main/webapp/WEB-INF/config/webmvc-config.xml
deleted file mode 100644
index 6a3c53b..0000000
--- a/booking-mvc/src/main/webapp/WEB-INF/config/webmvc-config.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/booking-mvc/src/main/webapp/WEB-INF/login.html b/booking-mvc/src/main/webapp/WEB-INF/login.html
index b1bf112..4d85943 100644
--- a/booking-mvc/src/main/webapp/WEB-INF/login.html
+++ b/booking-mvc/src/main/webapp/WEB-INF/login.html
@@ -77,31 +77,31 @@
-
+
-
-
+
-
+