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 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /WEB-INF/**/views.xml - - - - - 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 @@ Login Information

- +
-

- +
- +