Getting booking-faces back in working order. The build is going to break because of one of Keith's tests that I'm going to let him fix.

This commit is contained in:
Jeremy Grelle
2008-03-06 00:16:36 +00:00
parent ae5abe1f41
commit c0fb6c0b98
23 changed files with 487 additions and 78 deletions

View File

@@ -35,7 +35,11 @@ public class ELExpression implements Expression {
public Object getValue(Object context) throws EvaluationException {
ELContext ctx = elContextFactory.getELContext(context);
try {
return valueExpression.getValue(ctx);
Object result = valueExpression.getValue(ctx);
if (result == null && !ctx.isPropertyResolved()) {
throw new EvaluationException(new EvaluationAttempt(this, context), null);
}
return result;
} catch (ELException ex) {
throw new EvaluationException(new EvaluationAttempt(this, context), ex);
}
@@ -45,6 +49,9 @@ public class ELExpression implements Expression {
ELContext ctx = elContextFactory.getELContext(context);
try {
valueExpression.setValue(ctx, value);
if (!ctx.isPropertyResolved()) {
throw new EvaluationException(new EvaluationAttempt(this, context), null);
}
} catch (ELException ex) {
throw new EvaluationException(new EvaluationAttempt(this, context), ex);
}

View File

@@ -3,10 +3,12 @@ package org.springframework.faces.expression;
import javax.el.CompositeELResolver;
import javax.faces.el.VariableResolver;
import org.springframework.util.ClassUtils;
import org.springframework.webflow.expression.el.ImplicitFlowVariableELResolver;
import org.springframework.webflow.expression.el.RequestContextELResolver;
import org.springframework.webflow.expression.el.ScopeSearchingELResolver;
import org.springframework.webflow.expression.el.SpringBeanWebFlowELResolver;
import org.springframework.webflow.expression.el.SpringSecurityELResolver;
/**
* Assembles {@link RequestContextELResolver} and {@link ScopeSearchingELResolver} into a composite that may be used
@@ -20,6 +22,9 @@ public class CompositeFlowVariableResolver extends ELDelegatingVariableResolver
static {
composite.add(new RequestContextELResolver());
if (ClassUtils.isPresent("org.springframework.security.context.SecurityContextHolder")) {
composite.add(new SpringSecurityELResolver());
}
composite.add(new SpringBeanWebFlowELResolver());
composite.add(new ImplicitFlowVariableELResolver());
composite.add(new ScopeSearchingELResolver());

View File

@@ -20,6 +20,7 @@ import javax.faces.event.PhaseId;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.webflow.execution.View;
/**
* Customizes the behavior of an existing UIViewRoot with Ajax-aware processing.
@@ -42,7 +43,7 @@ public class AjaxViewRoot extends DelegatingViewRoot {
private String[] renderIds;
private static final String RENDER_IDS_EXPRESSION = "#{renderIds}";
private static final String RENDER_IDS_EXPRESSION = "#{" + View.RENDER_FRAGMENTS_ATTRIBUTE + "}";
private final ValueBinding renderIdsExpr;
@@ -267,12 +268,11 @@ public class AjaxViewRoot extends DelegatingViewRoot {
if (renderIds == null) {
FacesContext context = FacesContext.getCurrentInstance();
String renderIdsValue = (String) renderIdsExpr.getValue(context);
if (StringUtils.hasText(renderIdsValue)) {
renderIds = StringUtils.delimitedListToStringArray(renderIdsValue, ",", " ");
renderIds = removeNestedChildren(context, getRenderIds());
} else {
renderIds = (String[]) renderIdsExpr.getValue(context);
if (renderIds == null || renderIds.length == 0) {
renderIds = getProcessIds();
} else {
renderIds = removeNestedChildren(context, renderIds);
}
}
return renderIds;

View File

@@ -14,6 +14,7 @@ import org.apache.shale.test.mock.MockResponseWriter;
import org.springframework.faces.webflow.JSFMockHelper;
import org.springframework.faces.webflow.MockViewHandler;
import org.springframework.util.StringUtils;
import org.springframework.webflow.execution.View;
public class AjaxViewRootTests extends TestCase {
@@ -72,7 +73,8 @@ public class AjaxViewRootTests extends TestCase {
public void testEncodeAll_RenderIdsExpr() throws IOException {
jsf.externalContext().getRequestMap().put("renderIds", "foo:bar,foo:baz");
jsf.externalContext().getRequestMap().put(View.RENDER_FRAGMENTS_ATTRIBUTE,
StringUtils.delimitedListToStringArray("foo:bar,foo:baz", ",", " "));
AjaxViewRoot ajaxRoot = new AjaxViewRoot(testTree);

View File

@@ -1,11 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry excluding="**/*.java" kind="src" path="src/main/resources"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry kind="src" path="src/test/resources"/>
<classpathentry excluding="**/*.java" kind="src" output="target/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
<classpathentry kind="lib" path="lib/test/junit.jar"/>
<classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
<classpathentry kind="var" path="M2_REPO/commons-collections/commons-collections/2.1.1/commons-collections-2.1.1.jar"/>
<classpathentry kind="var" path="M2_REPO/commons-codec/commons-codec/1.3/commons-codec-1.3.jar"/>
<classpathentry kind="var" path="M2_REPO/org/apache/myfaces/core/myfaces-api/1.2.2/myfaces-api-1.2.2.jar"/>
<classpathentry kind="var" path="M2_REPO/ognl/ognl/2.6.9/ognl-2.6.9.jar"/>
<classpathentry kind="var" path="M2_REPO/commons-digester/commons-digester/1.8/commons-digester-1.8.jar"/>
<classpathentry kind="var" path="M2_REPO/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar"/>
<classpathentry kind="var" path="M2_REPO/net/sf/ehcache/ehcache/1.2.3/ehcache-1.2.3.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-webmvc/2.5.2/spring-webmvc-2.5.2.jar"/>
<classpathentry kind="var" path="M2_REPO/asm/asm/1.5.3/asm-1.5.3.jar"/>
<classpathentry kind="var" path="M2_REPO/org/apache/shale/shale-test/1.0.4/shale-test-1.0.4.jar"/>
<classpathentry kind="var" path="M2_REPO/antlr/antlr/2.7.6/antlr-2.7.6.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-entitymanager/3.3.1.ga/hibernate-entitymanager-3.3.1.ga.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-web/2.5.2/spring-web-2.5.2.jar"/>
<classpathentry kind="var" path="M2_REPO/jboss/jboss-common-core/2.0.4.GA/jboss-common-core-2.0.4.GA.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-annotations/3.3.0.ga/hibernate-annotations-3.3.0.ga.jar"/>
<classpathentry kind="var" path="M2_REPO/commons-logging/commons-logging/1.0.4/commons-logging-1.0.4.jar"/>
<classpathentry kind="var" path="M2_REPO/jboss/javassist/3.3.ga/javassist-3.3.ga.jar"/>
<classpathentry kind="var" path="M2_REPO/commons-discovery/commons-discovery/0.4/commons-discovery-0.4.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-commons-annotations/3.0.0.ga/hibernate-commons-annotations-3.0.0.ga.jar"/>
<classpathentry kind="var" path="M2_REPO/javax/servlet/jstl/1.1.2/jstl-1.1.2.jar"/>
<classpathentry kind="var" path="M2_REPO/concurrent/concurrent/1.3.4/concurrent-1.3.4.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate/3.2.5.ga/hibernate-3.2.5.ga.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-aop/2.5.2/spring-aop-2.5.2.jar"/>
<classpathentry kind="var" path="M2_REPO/taglibs/standard/1.1.2/standard-1.1.2.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-webflow/2.0-m4-SNAPSHOT/spring-webflow-2.0-m4-SNAPSHOT.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-context-support/2.5.2/spring-context-support-2.5.2.jar"/>
<classpathentry kind="var" path="M2_REPO/cglib/cglib/2.1_3/cglib-2.1_3.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/security/spring-security-core/2.0-M2/spring-security-core-2.0-M2.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-orm/2.5.2/spring-orm-2.5.2.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-jdbc/2.5.2/spring-jdbc-2.5.2.jar"/>
<classpathentry kind="var" path="M2_REPO/commons-beanutils/commons-beanutils/1.7.0/commons-beanutils-1.7.0.jar"/>
<classpathentry kind="var" path="M2_REPO/org/jboss/seam/jboss-el/2.0.0.GA/jboss-el-2.0.0.GA.jar"/>
<classpathentry kind="var" path="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-support/2.0.6/spring-support-2.0.6.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-tx/2.5.2/spring-tx-2.5.2.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-core/2.5.2/spring-core-2.5.2.jar"/>
<classpathentry kind="var" path="M2_REPO/javax/persistence/persistence-api/1.0/persistence-api-1.0.jar"/>
<classpathentry kind="var" path="M2_REPO/asm/asm-attrs/1.5.3/asm-attrs-1.5.3.jar"/>
<classpathentry kind="var" path="M2_REPO/hsqldb/hsqldb/1.8.0.7/hsqldb-1.8.0.7.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-context/2.5.2-SNAPSHOT/spring-context-2.5.2-SNAPSHOT.jar"/>
<classpathentry kind="var" path="M2_REPO/log4j/log4j/1.2.14/log4j-1.2.14.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-binding/2.0-m4-SNAPSHOT/spring-binding-2.0-m4-SNAPSHOT.jar"/>
<classpathentry kind="var" path="M2_REPO/javax/transaction/jta/1.0.1B/jta-1.0.1B.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-faces/2.0-m4-SNAPSHOT/spring-faces-2.0-m4-SNAPSHOT.jar" sourcepath="/WORKSPACE/spring-faces-2.0/src/main/java"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-beans/2.5.2/spring-beans-2.5.2.jar"/>
<classpathentry kind="var" path="M2_REPO/org/apache/myfaces/core/myfaces-impl/1.2.2/myfaces-impl-1.2.2.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-validator/3.0.0.ga/hibernate-validator-3.0.0.ga.jar"/>
<classpathentry kind="var" path="M2_REPO/com/sun/facelets/jsf-facelets/1.1.13/jsf-facelets-1.1.13.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-project guid="swf-sellitem-jsf_107f67bf14a_bdd5802912dd9f2" version="5">
<web-app guid="webapp_107f67bf14a_eee4f0d2979070f0">
<root-path-uri>src/webapp</root-path-uri>
<web-app-type>com.m7.webapp.java</web-app-type>
</web-app>
<properties>
<property name="validation.compile" value="true"/>
<property name="validation.missingFile" value="true"/>
<property name="validation.unresolvedVar" value="false"/>
<property name="validation" value="true"/>
<property name="taglib.downloadRemote" value="true"/>
<property name="validation.unresolvedType" value="false"/>
<property name="validation.compile.jspQuotation" value="false"/>
</properties>
</web-project>

View File

@@ -1,42 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>swf-booking-faces</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.springframework.ide.eclipse.core.springbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.hibernate.eclipse.console.hibernateBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.springframework.ide.eclipse.core.springnature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.hibernate.eclipse.console.hibernateNature</nature>
</natures>
</projectDescription>
<name>swf-booking-faces</name>
<comment>Spring Web Flow Number Guess JSF Example</comment>
<projects/>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
</buildCommand>
<buildCommand>
<name>org.springframework.ide.eclipse.core.springbuilder</name>
</buildCommand>
<buildCommand>
<name>org.hibernate.eclipse.console.hibernateBuilder</name>
</buildCommand>
</buildSpec>
<natures>
<nature>org.springframework.ide.eclipse.core.springnature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.hibernate.eclipse.console.hibernateNature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,182 @@
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>swf-booking-faces</artifactId>
<packaging>war</packaging>
<name>Spring Web Flow Hotel Booking JSF Example</name>
<version>2.0-m4-SNAPSHOT</version>
<description>Spring Web Flow Number Guess JSF Example</description>
<url>http://www.springframework.org</url>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<connection>scm:svn:https://svn.sourceforge.net/svnroot/springframework/spring-projects</connection>
<developerConnection>scm:svn:https://svn.sourceforge.net/svnroot/springframework/spring-projects</developerConnection>
<tag>1.0.2</tag>
<url>http://svn.sourceforge.net/viewcvs.cgi/springframework/spring-projects</url>
</scm>
<organization>
<name>Spring Framework</name>
<url>http://www.springframework.org/</url>
</organization>
<repositories>
<repository>
<id>java.net</id>
<url>http://download.java.net/maven/1</url>
<layout>legacy</layout>
</repository>
<repository>
<id>jboss</id>
<url>http://repository.jboss.com/maven2</url>
</repository>
<repository>
<id>spring-snapshot</id>
<name>Spring Portfolio Snapshot Repository</name>
<url>http://s3.amazonaws.com/maven.springframework.org/snapshot</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>com.sun.facelets</groupId>
<artifactId>jsf-facelets</artifactId>
<version>1.1.13</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-faces</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflow</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-binding</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>2.0-M2</version>
</dependency>
<dependency>
<groupId>org.jboss.seam</groupId>
<artifactId>jboss-el</artifactId>
<version>2.0.0.GA</version>
<exclusions>
<exclusion>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.5.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.3.1.ga</version>
</dependency>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.1</version>
<configuration>
<connectors>
<connector
implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>7001</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
<scanIntervalSeconds>10</scanIntervalSeconds>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -13,7 +13,7 @@ public interface BookingService {
* @param username the user's name
* @return their bookings
*/
public List<Booking> findBookings(User user);
public List<Booking> findBookings(String username);
/**
* Find hotels available for booking by some criteria.
@@ -34,4 +34,11 @@ public interface BookingService {
* @param id the booking id
*/
public void cancelBooking(Booking booking);
/**
* Lookup a user based on their username
* @param username the user's username
* @return the user
*/
public User findUser(String username);
}

View File

@@ -8,13 +8,14 @@ import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
/**
* A JPA-based implementation of the Booking Service. Delegates to a JPA entity manager to issue data access calls
* against the backing repository. The EntityManager reference is provided by the managing container (Spring)
* automatically.
*/
@Service
@Service("bookingService")
@Repository
public class JpaBookingService implements BookingService {
@@ -27,15 +28,20 @@ public class JpaBookingService implements BookingService {
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public List<Booking> findBookings(User user) {
return em.createQuery("select b from Booking b where b.user.username = :username order by b.checkinDate")
.setParameter("username", user.getName()).getResultList();
public List<Booking> findBookings(String username) {
if (username != null) {
return em.createQuery("select b from Booking b where b.user.username = :username order by b.checkinDate")
.setParameter("username", username).getResultList();
} else {
return null;
}
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public List<Hotel> findHotels(SearchCriteria criteria) {
String pattern = getSearchPattern(criteria);
String pattern = !StringUtils.hasText(criteria.getSearchString()) ? "'%'" : "'%"
+ criteria.getSearchString().toLowerCase().replace('*', '%') + "%'";
return em.createQuery(
"select h from Hotel h where lower(h.name) like " + pattern + " or lower(h.city) like " + pattern
+ " or lower(h.zip) like " + pattern + " or lower(h.address) like " + pattern).setMaxResults(
@@ -47,11 +53,19 @@ public class JpaBookingService implements BookingService {
return em.find(Hotel.class, id);
}
// read-write transactional methods
@Transactional(readOnly = true)
public User findUser(String username) {
return (User) em.createQuery("select u from User u where u.username = :username").setParameter("username",
username).getSingleResult();
}
// read-write transactional methods
@Transactional
public void cancelBooking(Booking booking) {
em.remove(booking);
booking = em.find(Booking.class, booking.getId());
if (booking != null) {
em.remove(booking);
}
}
// helpers

View File

@@ -1,4 +1,6 @@
insert into Customer (username, password, name) values ('springer', 'springrocks', 'Springer')
insert into Customer (username, name) values ('rod', 'Rod')
insert into Customer (username, name) values ('dianne', 'Dianne')
insert into Customer (username, name) values ('scott', 'Scott')
insert into Hotel (id, price, name, address, city, state, zip, country) values (1, 199, 'Westin Diplomat', '3555 S. Ocean Drive', 'Hollywood', 'FL', '33019', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (2, 120, 'Marriott Courtyard', 'Tower Place, Buckhead', 'Atlanta', 'GA', '30305', 'USA')
insert into Hotel (id, price, name, address, city, state, zip, country) values (3, 180, 'Doubletree', 'Tower Place, Buckhead', 'Atlanta', 'GA', '30305', 'USA')

View File

@@ -31,6 +31,10 @@
<level value="debug" />
</logger>
<logger name="org.springframework.faces">
<level value="debug" />
</logger>
<logger name="org.springframework.webflow">
<level value="debug" />
</logger>

View File

@@ -3,19 +3,21 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<secured authorities="ROLE_USER" />
<persistence-context/>
<input name="#{id}" value="#{flowScope.id}"/>
<on-start>
<evaluate expression="#{bookingService.findHotelById(id)}" result="#{flowScope.hotel}" />
<evaluate expression="#{hotel.createBooking(currentUser)}" result="#{flowScope.booking}" />
<evaluate expression="${hotel.createBooking(bookingService.findUser(currentUser.name))}" result="${flowScope.booking}" />
<evaluate expression="#{entityManager.persist(booking)}" />
</on-start>
<view-state id="enterBookingDetails">
<transition on="proceed" to="reviewBooking">
<evaluate expression="booking.validate(messageContext)" />
<evaluate expression="#{booking.validate(messageContext)}" />
</transition>
<transition on="cancel" to="bookingCancelled" />
</view-state>

View File

@@ -7,7 +7,7 @@
<view-state id="enterSearchCriteria">
<on-render>
<evaluate expression="#{bookingService.findBookings(currentUser)}" result="#{flowScope.bookings}" result-type="dataModel" />
<evaluate expression="#{bookingService.findBookings(currentUser.name)}" result="#{flowScope.bookings}" result-type="dataModel" />
</on-render>
<transition on="search" to="reviewHotels" />
<transition on="cancelBooking">
@@ -17,7 +17,7 @@
<view-state id="reviewHotels">
<on-render>
<evaluate expression="#{bookingService.searchHotels(searchCriteria)}" result="#{flowScope.hotels}" result-type="dataModel" />
<evaluate expression="#{bookingService.findHotels(searchCriteria)}" result="#{flowScope.hotels}" result-type="dataModel" />
</on-render>
<transition on="previous">
<evaluate expression="#{searchCriteria.previousPage()}" />

View File

@@ -38,7 +38,7 @@
</h:column>
<h:column>
<f:facet name="header">Action</f:facet>
<sf:commandLink id="viewHotelLink" value="View Hotel" action="selectHotel"/>
<sf:commandLink id="viewHotelLink" value="View Hotel" action="select"/>
</h:column>
</h:dataTable>
<div class="next">

View File

@@ -4,7 +4,7 @@
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:sf="http://www.springframework.org/tags/faces"
template="/template.xhtml">
template="layouts/standard.xhtml">
<ui:define name="content">
@@ -32,7 +32,7 @@
<li>Spring IDE integration, with support for graphical flow modeling</li>
</ul>
<p align="right">
<a href="spring/main">Start your hotel booking experience</a>
<a href="flows/main">Start your hotel booking experience</a>
</p>
</div>

View File

@@ -1,7 +1,8 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jstl/core">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Spring Faces: Hotel Booking Sample Application</title>
@@ -21,7 +22,9 @@
<div id="welcome">
<div class="left">Spring Faces: Hotel Booking Sample Application</div>
<div class="right">
Welcome, #{currentUser.name}
<c:if test="${currentUser.name != 'roleAnonymous'}">
Welcome, ${currentUser.name}
</c:if>
</div>
</div>
<div id="branding" class="spring">

View File

@@ -0,0 +1,60 @@
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jstl/core"
template="layouts/standard.xhtml">
<ui:define name="content">
<h1>Login</h1>
<c:if test="${not empty param.login_error}">
<div class="errors">
Your login attempt was not successful, try again.<br /><br />
Reason: #{sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message}
</div>
</c:if>
<div class="section">
<p>Valid users:</p>
<ul>
<li>rod/koala</li>
<li>dianne/emu</li>
<li>scott/wombat</li>
</ul>
</div>
<div class="section">
<form name="f" action="${request.contextPath}/spring/login-process" method="post">
<fieldset>
<div class="field">
<div class="label">User:</div>
<div class="output">
<c:if test="${not empty param.login_error}">
<c:set var="username" value="${sessionScope.SPRING_SECURITY_LAST_USERNAME}"/>
</c:if>
<input type="text" name="j_username" value="#{username}"/>
</div>
</div>
<div class="field">
<div class="label">Password:</div>
<div class="output">
<input type="password" name="j_password" />
</div>
</div>
<div class="field">
<div class="label">Don't ask for my password for two weeks:</div>
<div class="output">
<input type="checkbox" name="_spring_security_remember_me"/>
</div>
</div>
</fieldset>
<div class="buttonGroup">
<input name="submit" type="submit" value="Login" />
</div>
</form>
</div>
</ui:define>
</ui:composition>

View File

@@ -0,0 +1,16 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<tiles:insertTemplate template="/WEB-INF/layouts/standard.jsp">
<tiles:putAttribute name="content">
<div class="section">
<h1>Logout</h1>
<p>You have successfully logged out.</p>
</div>
</tiles:putAttribute>
</tiles:insertTemplate>

View File

@@ -5,6 +5,7 @@
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
xmlns:faces="http://www.springframework.org/schema/faces-config"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
@@ -15,7 +16,9 @@
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd
http://www.springframework.org/schema/faces-config
http://www.springframework.org/schema/faces-config/spring-faces-config-2.0.xsd">
http://www.springframework.org/schema/faces-config/spring-faces-config-2.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-2.0.xsd">
<!-- Activates annotation-based bean configuration -->
<context:annotation-config />
@@ -35,14 +38,15 @@
<bean id="jsfViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.faces.mvc.JsfView"/>
<property name="prefix" value="WEB-INF/" />
<property name="prefix" value="/WEB-INF/" />
<property name="suffix" value=".xhtml" />
</bean>
<!-- Executes flows: the central entry point into the Spring Web Flow system -->
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
<webflow:flow-execution-listeners>
<webflow:listener ref="jpaFlowExecutionListener" criteria="*" />
<webflow:listener ref="jpaFlowExecutionListener" />
<webflow:listener ref="securityFlowExecutionListener" />
</webflow:flow-execution-listeners>
</webflow:flow-executor>
@@ -61,6 +65,9 @@
<constructor-arg ref="entityManagerFactory" />
<constructor-arg ref="transactionManager" />
</bean>
<!-- Installs a listener to apply Spring Security authorities -->
<bean id="securityFlowExecutionListener" class="org.springframework.webflow.security.SecurityFlowExecutionListener" />
<!-- Drives transactions using local JPA APIs -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
@@ -82,5 +89,34 @@
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<!-- Configure Spring Security -->
<security:http auto-config="true">
<!-- restrict URLs based on role -->
<security:intercept-url pattern="/spring/login*" access="ROLE_ANONYMOUS" />
<security:intercept-url pattern="/spring/logout-success*" access="ROLE_ANONYMOUS" />
<security:intercept-url pattern="/spring/logout*" access="ROLE_USER" />
<!-- override default login and logout pages -->
<security:form-login login-page="/spring/login" login-url="/spring/login-process" default-target-url="/spring/flows/main" authentication-failure-url="/spring/login?login_error=1" />
<security:logout logout-url="/spring/logout" logout-success-url="/spring/logout-success" />
</security:http>
<!--
Define local authentication provider, a real app would use an external provider (JDBC, LDAP, CAS, etc)
usernames/passwords are:
rod/koala
dianne/emu
scott/wombat
-->
<security:authentication-provider>
<security:password-encoder hash="md5" />
<security:user-service>
<security:user name="rod" password="a564de63c2d0da68cf47586ee05984d7" authorities="ROLE_USER, ROLE_SUPERVISOR" />
<security:user name="dianne" password="65d15fe9156f9c4bbffd98085992a44e" authorities="ROLE_USER" />
<security:user name="scott" password="2b58af6dddbd072ed27ffc86725d7d3a" authorities="ROLE_USER" />
</security:user-service>
</security:authentication-provider>
</beans>

View File

@@ -4,6 +4,13 @@
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/web-application-config.xml
</param-value>
</context-param>
<!-- Use JSF view templates saved as *.xhtml, for use with Facelets -->
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
@@ -21,6 +28,20 @@
<param-name>facelets.REFRESH_PERIOD</param-name>
<param-value>1</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Serves static resource content from .jar files such as spring-faces.jar -->
<servlet>

View File

@@ -40,9 +40,6 @@ public class ImplicitFlowVariableELResolver extends ELResolver {
return null;
}
RequestContext requestContext = RequestContextHolder.getRequestContext();
if (requestContext == null) {
return null;
}
if (ImplicitVariables.matches(property)) {
context.setPropertyResolved(true);
return ImplicitVariables.value(context, requestContext, property);

View File

@@ -18,7 +18,7 @@ public class SpringBeanWebFlowELResolver extends SpringBeanELResolver {
protected BeanFactory getBeanFactory(ELContext elContext) {
RequestContext rc = RequestContextHolder.getRequestContext();
if (rc.getActiveFlow().getBeanFactory() != null) {
if (rc != null && rc.getActiveFlow().getBeanFactory() != null) {
return rc.getActiveFlow().getBeanFactory();
} else {
return EMPTY_BEAN_FACTORY;