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/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..18a9065 --- /dev/null +++ b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/DispatcherServletInitializer.java @@ -0,0 +1,55 @@ +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.Dynamic; + +import org.springframework.web.filter.CharacterEncodingFilter; +import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; + +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"); + + // Add this so the JSF implementation can initialize, *not* used for request processing + Dynamic facesServlet = servletContext.addServlet("facesServlet", new FacesServlet()); + facesServlet.addMapping("*.faces"); + facesServlet.setLoadOnStartup(0); + + // 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..03d2007 --- /dev/null +++ b/booking-faces/src/main/java/org/springframework/webflow/samples/booking/config/SecurityConfig.java @@ -0,0 +1,44 @@ +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() + .requestCache() + .requestCache(new HttpSessionRequestCache()) + .and() + .csrf().disable(); + } + + @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/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 - - -